Mercurial > wow > skeletonkey
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 } |