comparison SkeletonKey/KeySlot.lua @ 14:82170735e67c

- move co-routine handler to general lib - slightly better handling of pet actions
author Nenue
date Thu, 28 Jul 2016 23:58:53 -0400
parents
children 32d64e42ec9b
comparison
equal deleted inserted replaced
13:eeec4a600064 14:82170735e67c
1 -- SkeletonKey
2 -- KeySlot.lua
3 -- Created: 7/28/2016 11:26 PM
4 -- %file-revision%
5 -- All the internal slot logic is kept here
6
7 local kb, print = LibStub('LibKraken').register(KeyBinder, 'Slot')
8 local CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_PETACTION
9 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544
10 local BORDER_UNASSIGNED = {0.2,0.2,0.2,1 }
11 local BORDER_ASSIGNED = {0.5,0.5,0.5,1 }
12 local BORDER_DYNAMIC = {1,1,0,1}
13 local BORDER_PENDING = {1,0.5,0,1 }
14
15 local BUTTON_HEADERS = {
16 ['spell'] = SPELLS,
17 ['macro'] = MACRO,
18 ['petaction'] = PET,
19 ['mount'] = MOUNT,
20 ['battlepet'] = BATTLEPET,
21
22
23 [5] = PROFESSIONS_FIRST_AID,
24 [7] = PROFESSIONS_COOKING,
25 [9] = PROFESSIONS_FISHING,
26 [10] = PROFESSIONS_ARCHAEOLOGY,
27
28 }
29
30 -- This is needed to identify a spells that aren't reflected by GetCursorInfo()
31 hooksecurefunc("PickupSpellBookItem", function(slot, bookType)
32 print('|cFFFF4400PickupSpellBookItem(..', tostring(slot),', '..tostring(bookType)..')')
33 CURSOR_SPELLSLOT = slot
34 CURSOR_BOOKTYPE = bookType
35 end)
36
37 do
38 -- Pet actions
39 local isPickup
40 hooksecurefunc("PickupPetAction", function(slot, ...)
41 isPickup = GetCursorInfo()
42
43 CURSOR_PETACTION = isPickup and slot
44 print('|cFFFF4400PickupPetAction|r', isPickup, CURSOR_PETACTION)
45 end)
46 end
47
48
49 kb.DropToSlot = function(self)
50 print(self:GetName(),'|cFF0088FFreceived|r')
51 local actionType, actionID, subType, subData = GetCursorInfo()
52 print('GetCursorInfo', GetCursorInfo())
53 if actionType then
54
55 if actionType == 'flyout' then
56 ClearCursor()
57 ResetCursor()
58 return
59 end
60
61
62 local macroName, macroText
63 local command, name, icon, _
64 local pickupID, pickupBook
65
66 if actionType == 'spell' then
67 actionID = subData
68 name, _, icon = GetSpellInfo(actionID)
69
70 elseif actionType == 'macro' then
71 name, icon = GetMacroInfo(actionID)
72 elseif actionType == 'petaction' then
73 if not (CURSOR_SPELLSLOT and CURSOR_BOOKTYPE) then
74
75 ClearCursor()
76 ResetCursor()
77 end
78
79 local bookType, spellID = GetSpellBookItemInfo(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE)
80 actionID = spellID
81 pickupID = CURSOR_SPELLSLOT
82 pickupBook = CURSOR_BOOKTYPE
83 name, _, icon = GetSpellInfo(spellID)
84 elseif actionType == 'mount' then
85 if subType == 0 then
86 name, _, icon = GetSpellInfo(SUMMON_RANDOM_FAVORITE_MOUNT_SPELL)
87 actionID = 0
88 else
89 name, _, icon = C_MountJournal.GetMountInfoByID(actionID)
90 end
91 elseif actionType == 'item' then
92 name = GetItemInfo(actionID)
93 icon = GetItemIcon(actionID)
94 actionID = name
95 elseif actionType == 'battlepet' then
96
97 local speciesID, customName, level, xp, maxXp, displayID, isFavorite, petName, petIcon, petType, creatureID = C_PetJournal.GetPetInfoByPetID(detail);
98 name = customName or petName
99 icon = petIcon
100
101 end
102 macroName, macroText, command = kb.RegisterAction(actionType, actionID, name)
103
104
105 local isAssigned, isBound, assignedBy, boundBy = kb.IsCommandBound(self, command)
106 if isAssigned then
107 local popup = StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"]
108 popup.slot = self
109 popup.text = "Currently assigned in |cFFFFFF00"..tostring(kb.configHeaders[assignedBy]).."|r. Are you sure?"
110 popup.oldProfile = assignedBy
111 popup.args = {command, name, icon, actionType, actionID, macroName, macroText, pickupID, pickupBook }
112 kb:SetScript('OnMouseWheel', nil) -- disable scrolling
113 StaticPopup_Show('SKELETONKEY_CONFIRM_ASSIGN_SLOT')
114 else
115 kb.SetSlot(self, command, name, icon, actionType, actionID, macroName, macroText, pickupID, pickupBook)
116 kb.UpdateSlot(self)
117 self.active = nil
118 ClearCursor()
119 ResetCursor()
120 end
121 end
122 end
123
124
125 do
126 local PickupAction = {
127 spell = _G.PickupSpell,
128 petaction = _G.PickupSpellBookItem,
129 macro = _G.PickupMacro,
130 item = _G.PickupItem,
131 mount = _G.C_MountJournal.Pickup
132 }
133 local GetPickupValue = {
134 spell = function(self) return select(7, GetSpellInfo(self.actionID)) end,
135 petaction = function(self) return self.pickupSlot, self.pickupBook end,
136 }
137 kb.PickupSlot = function(self)
138 if not self.command then
139 return
140 end
141 print(self.actionType)
142 if self.actionType == 'spell' then
143 -- It can't be picked up if SpellInfo(name) returns void
144 local dummy = GetSpellInfo(self.actionName)
145 if not dummy then
146 return
147 end
148 end
149 if PickupAction[self.actionType] then
150 if GetPickupValue[self.actionType] then
151 PickupAction[self.actionType](GetPickupValue[self.actionType](self))
152 else
153 PickupAction[self.actionType](self.actionID)
154 end
155 kb.ReleaseSlot(self)
156 kb.UpdateSlot(self)
157 end
158 end
159 end
160
161
162
163 --- Updates profile assignment and button contents
164 kb.UpdateSlot = function(self, force)
165 local slot = self:GetID()
166
167 if force then
168 if kb.currentProfile.buttons[slot] then
169 kb.SetSlot(self, unpack(kb.currentProfile.buttons[slot]))
170 else
171 kb.ReleaseSlot(self)
172 end
173 end
174
175 if self.command then
176 print('['..slot..'] =', self.command, GetBindingKey(self.command))
177
178 if self.pending then
179 self.border:SetColorTexture(unpack(BORDER_PENDING))
180 elseif self.isDynamic then
181 self.border:SetColorTexture(unpack(BORDER_DYNAMIC))
182 else
183 self.border:SetColorTexture(unpack(BORDER_ASSIGNED))
184 end
185
186 if self.actionType == 'macro' then
187 self.macro:Show()
188 else
189 self.macro:Hide()
190 if self.actionType == 'spell' then
191 local dummy = GetSpellInfo(self.actionName)
192 if not dummy then
193 self.icon:SetDesaturated(true)
194 else
195 self.icon:SetDesaturated(false)
196 end
197
198 end
199 end
200
201 if self.isDynamic then
202 print('|cFFFFBB00UpdateSlot|r: ', self.isDynamic, self.isAvailable, self.actionID)
203 end
204
205 if self.isDynamic == 'profession' then
206 local profText = (self.spellNum == 1) and TRADE_SKILLS or (BUTTON_HEADERS[self.profIndex] or GetProfessionInfo(self.profIndex))
207 if self.isAvailable then
208 print(self.profIndex, 'spnum', type(self.spellNum), (self.spellNum == 1))
209
210 self.statusText = '|cFFFFFF00'..profText..'|r'
211 self.bindingText = kb.BindingString(GetBindingKey(self.command))
212 else
213 self.statusText = '|cFFFF4400'..profText..'|r'
214 self.actionName = '(need to train profession #'..self.profNum..')'
215 self.bindingText ='?'
216 end
217 elseif self.isDynamic == 'talent' then
218
219 self.statusText = '|cFF00FFFF'.. TALENT .. '|r'
220 if self.isAvailable then
221 self.bindingText = kb.BindingString(GetBindingKey(self.command))
222 else
223 if kb.inactiveTalentBindings[self.actionID] then
224 print(self.actionID, #kb.inactiveTalentBindings[self.actionID])
225 self.bindingText= kb.BindingString(unpack(kb.inactiveTalentBindings[self.actionID]))
226 end
227
228 end
229 else
230 self.statusText = '|cFF00FF00'.. (BUTTON_HEADERS[self.actionType] and BUTTON_HEADERS[self.actionType] or self.actionType) .. '|r'
231 self.bindingText = kb.BindingString(GetBindingKey(self.command))
232 end
233
234 local locked, layer = kb.IsCommandBound(self)
235 if locked then
236 self.icon:SetAlpha(0.5)
237 else
238 self.icon:SetAlpha(1)
239 end
240
241 if self.actionType == 'spell' then
242 self.icon:SetTexture(GetSpellTexture(self.actionID))
243 end
244 end
245
246 if not self.isAvailable then
247 self.bind:SetTextColor(0.7,0.7,0.7,1)
248 else
249 self.bind:SetTextColor(1,1,1,1)
250 end
251
252 self.header:SetText(self.statusText)
253 self.bind:SetText(self.bindingText)
254 self.details:SetText(self.actionName)
255 end
256
257 --- Resets button command
258 kb.ReleaseSlot = function(self)
259 local slot = self:GetID()
260
261
262 if kb.currentProfile.buttons[slot] then
263 kb.currentProfile.buttons[slot] = nil
264 end
265 if self.command then
266 kb.currentProfile.commands[self.command] = nil
267 end
268 if self.actionType == 'spell' and IsTalentSpell(self.actionName) then
269 if kb.currentProfile.talents[self.actionID] then
270 kb.currentProfile.talents[self.actionID] = nil
271 end
272 end
273 local droppedKeys = {}
274
275 -- doing removal in second loop to avoid possible iterator shenanigans
276 for k,v in pairs(kb.currentProfile.bindings) do
277 if v == self.command then
278 tinsert(droppedKeys, k)
279 end
280 end
281 if #droppedKeys >=1 then
282 for i, k in ipairs(droppedKeys) do
283 kb.currentProfile.bindings[k] = nil
284 end
285 end
286
287 self.isAvailable = nil
288 self.isDynamic = nil
289 self.bindingText = nil
290 self.statusText = nil
291 self.command = nil
292 self.actionType = nil
293 self.actionID = nil
294 self.actionName = nil
295 self.pickupSlot = nil
296 self.pickupBook = nil
297 self.macroName = nil
298 self.profile = nil
299 self.icon:SetTexture(nil)
300 self.border:SetColorTexture(unpack(BORDER_UNASSIGNED))
301 self:EnableKeyboard(false)
302 self:SetScript('OnKeyDown', nil)
303 end
304
305 kb.SetSlot = function(self, command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook)
306 local slot = self:GetID()
307 local isDynamic, isAvailable
308
309 print('|cFFFFFF00SetSlot|r:', self:GetID())
310 if command then
311
312 if actionType == 'spell' then
313 local professionNum, spellNum = command:match("profession_(%d)_(%d)")
314
315 if (professionNum and spellNum) then
316 isDynamic = 'profession'
317 local cacheInfo = kb.ProfessionCache[professionNum..'_'..spellNum]
318 if cacheInfo then
319 isAvailable = true
320 name = cacheInfo.spellName
321 icon = cacheInfo.icon
322 actionID = cacheInfo.spellID
323 self.profIndex = cacheInfo.profIndex
324 self.spellOffset = cacheInfo.spellOffset
325 end
326 print(' Special slot: |cFF00FFFFProfession|r', professionNum, spellNum, isDynamic, isAvailable)
327
328 self.professionNum = tonumber(professionNum)
329 self.spellNum = tonumber(spellNum)
330
331 else
332 if kb.TalentCache[actionID] then
333 isDynamic = 'talent'
334 print(' Special slot: |cFFBBFF00talent|r', name, isAvailable)
335 end
336
337 isAvailable = GetSpellInfo(name)
338 end
339 elseif actionType == 'macro' then
340 if not actionID then
341 actionID = GetMacroIndexByName(name)
342 end
343 isAvailable = true
344 else
345 --- Journal selections
346 -- todo: consider using the deep end of blizzard action bar instead
347 if not actionID then
348 actionID = command:match("^KeyBinderMacro:(.+)")
349 end
350 isAvailable = true
351 end
352
353 if isAvailable then
354 local oldCommand = command
355 macroName, macroText, command = kb.RegisterAction(actionType, actionID, name)
356 if oldCommand ~= command then
357 print('|cFFFF4400fixing command string', actionType, actionID, name)
358 kb.currentProfile.bound[oldCommand] = nil
359 kb.currentProfile.bound[command] = slot
360 for k,v in pairs(kb.currentProfile.bindings) do
361 if v == oldCommand then
362 kb.currentProfile.bindings[k] = command
363 end
364 end
365 end
366 kb.LoadBinding(command, name, icon, actionType, actionID, macroName, macroText)
367 end
368
369 if actionType == 'petaction' then
370 self.pickupSlot = pickupSlot
371 self.pickupBook = pickupBook
372 else
373 self.pickupSlot = nil
374 self.pickupBook = nil
375 end
376
377 actionID = actionID or 0
378 self:EnableKeyboard(true)
379 print(' |cFF00FF00kb.currentProfile.buttons['..slot..'] |cFF00FFFF=|r |cFF00FFFF"'.. command.. '"|r |cFF00FF00"'.. name, '"|r |cFFFFFF00icon:'.. icon .. '|r |cFFFF8800"'.. actionType, '"|r |cFFFF0088id:'.. actionID ..'|r |cFF00FF00"'.. macroName .. '"|r')
380 kb.currentProfile.buttons[slot] = {command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook}
381
382 -- Clean up conflicting entries for loaded button
383 local previous = kb.currentProfile.commands[command]
384 if previous ~= slot and kb.buttons[previous] then
385 kb.ReleaseSlot(kb.buttons[previous])
386 end
387 kb.currentProfile.commands[command] = slot
388 end
389
390 self.isAvailable = isAvailable
391 self.isDynamic = isDynamic
392
393 self.macroText = macroText
394 self.macroName = macroName
395 self.actionType = actionType
396 self.actionID = actionID
397 self.actionName = name
398 self.command = command
399 self.icon:SetTexture(icon)
400 self.profile = kb.db.bindMode
401 self:RegisterForDrag('LeftButton')
402 end
403
404
405
406 --- Add to blizzard interfaces
407 StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"] = {
408 text = "Confirm moving an assigned command.",
409 button1 = OKAY,
410 button2 = CANCEL,
411 timeout = 0,
412 whileDead = 1,
413 showAlert = 1,
414 OnAccept = kb.AcceptAssignment,
415 OnCancel = function() kb:SetScript('OnMouseWheel', KeyBinder_OnMouseWheel) end
416 }