comparison SkeletonKey/ActionTemplates.lua @ 27:73df13211b22

- actionbar hotkey text properly updates after hotkeys get switched - remove a unused function call
author Nenue
date Tue, 02 Aug 2016 12:33:13 -0400
parents SkeletonKey/ActionTypes.lua@c081f117c19d
children b0e4d04d428a
comparison
equal deleted inserted replaced
26:c081f117c19d 27:73df13211b22
1 -- SkeletonKey
2 -- ActionTemplates.lua
3 -- Created: 7/29/2016 9:14 PM
4 -- %file-revision%
5 -- Code dealing with the implementation of action hotkeys
6
7 local tostring, tonumber, pairs, ipairs = tostring, tonumber, pairs, ipairs
8 local unpack, SetBinding = unpack, SetBinding
9 local tinsert, tContains, select, wipe = tinsert, tContains, select, table.wipe
10 local GetSpellBookItemInfo, GetSpellBookItemName, GetSpellInfo = GetSpellBookItemInfo, GetSpellBookItemName, GetSpellInfo
11 local GetSpecialization, GetSpecializationInfo, IsPassiveSpell, IsTalentSpell = GetSpecialization, GetSpecializationInfo, IsPassiveSpell, IsTalentSpell
12 local PetHasSpellbook, PetHasActionBar, GetPetActionInfo, HasPetSpells = PetHasSpellbook, PetHasActionBar, GetPetActionInfo, HasPetSpells
13 local GetProfessions, GetProfessionInfo, GetTalentInfo = GetProfessions, GetProfessionInfo, GetTalentInfo
14 local GetNumBindings, GetBinding = GetNumBindings, GetBinding
15
16 local kb, print, wrap = LibStub('LibKraken').register(KeyBinder, 'Info')
17 local cprint = DEVIAN_WORKSPACE and function(...) _G.print('Cfg', ...) end or function() end
18
19 local CLICK_KEYBINDER_MACRO = "CLICK KeyBinderMacro:"
20 local CLICK_KEYBINDER_KEY = "CLICK KeyBinderKey:"
21 local PET_BASIC_SUBTEXT = 'Basic Attack'
22 local PET_SPECIAL_SUBTEXT = 'Special Ability'
23 local PETACTION_SCRIPT = {
24 [PET_ACTION_MOVE_TO] = {'pet_move_to', SLASH_PET_MOVE_TO1},
25 [PET_ACTION_ATTACK] = {'pet_attack', SLASH_PET_ATTACK1},
26 [PET_ACTION_FOLLOW] = {'pet_follow', SLASH_PET_FOLLOW1},
27 [PET_ACTION_WAIT] = {'pet_stay', SLASH_PET_STAY1 },
28 [PET_MODE_AGGRESSIVE] = {'pet_aggressive', SLASH_PET_AGGRESSIVE1 },
29 [PET_MODE_DEFENSIVE] = { 'pet_defensive', SLASH_PET_DEFENSIVE1},
30 [PET_MODE_PASSIVE] = { 'pet_passive', SLASH_PET_PASSIVE1},
31 [PET_MODE_ASSIST] = {'pet_assist', SLASH_PET_ASSIST1},
32 }
33 local SECONDARY_PROFESSIONS = {
34 [5] = 3,
35 [7] = 4,
36 [9] = 5,
37 [10] = 6
38 }
39 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544
40
41 --kb.ChangedBindings = {}
42 --kb.ActionTypes = {}
43
44 local atype = kb.ActionTypes
45
46 --- Caps Lock
47 atype['mount'] = function(id, name)
48 if id == SUMMON_RANDOM_FAVORITE_MOUNT_SPELL then
49 return CLICK_KEYBINDER_MACRO, 'mount_random', "/script C_MountJournal.SummonByID(0)"
50 else
51 return CLICK_KEYBINDER_MACRO, 'mount_'..id, "/script C_MountJournal.SummonByID("..id..")"
52 end
53 end
54
55 atype['macro'] = function(id, name)
56 return CLICK_KEYBINDER_MACRO, 'macro_' .. tostring(name), id
57 end
58
59 atype['equipset'] = function(id, name)
60 return CLICK_KEYBINDER_MACRO, 'equipset_'..tostring(name), "/script UseEquipmentSet("..tostring(id)..")"
61 end
62
63 atype['spell'] = function(id, name)
64 local attributeName = name
65 if kb.ProfessionCache[id] then
66 attributeName = "profession_".. kb.ProfessionCache[id].profOffset .. '_' .. kb.ProfessionCache[id].spellNum
67 end
68 return CLICK_KEYBINDER_KEY, attributeName, name
69 end
70
71 atype['petaction'] = function(_, name)
72 -- ID doesn't exist for basic commands, even though they can be picked up
73 local attributeName, attributeValue = "petaction_" .. tostring(name), "/cast "..tostring(name)
74 if PETACTION_SCRIPT[name] then
75 attributeName, attributeValue = unpack(PETACTION_SCRIPT[name])
76 elseif kb.PetCache.special[name] then
77 attributeName = "petaction_"..kb.PetCache.special[name][3].."_" .. tonumber(kb.PetCache.special[name][6])
78 end
79 return CLICK_KEYBINDER_MACRO, attributeName, attributeValue
80 end
81
82 atype['battlepet'] = function(id, name)
83 return CLICK_KEYBINDER_MACRO, 'battlepet_' .. tostring(name), SLASH_SUMMON_BATTLE_PET1 .. " " .. tostring(name)
84 end
85
86 atype['item'] = function(id, name)
87 return CLICK_KEYBINDER_KEY, 'item_' .. tostring(name), id
88 end
89
90
91 --- Resolves the SecureActionButton attribute names used for the given action
92 kb.RegisterAction = function(actionType, id, name)
93
94 assert(atype[actionType], 'Missing actionType handler for `'..tostring(actionType)..'`')
95 local target, attributeName, attributeValue = atype[actionType](id, name)
96
97 local command = target .. attributeName
98 local baseName, iterative = attributeName, 1
99 while (kb.macros[attributeName] and kb.macros[attributeName][1] ~= attributeValue) do
100 print(' * cannot use|cFF00FF00', attributeName, '|r"'.. tostring(kb.macros[attributeName][1]) .. '"')
101 attributeName = baseName .. '_' .. iterative
102 iterative = iterative + 1
103 end
104 if attributeName ~= baseName then
105 print(' * Creating|cFF00FF00', attributeName)
106 else
107 print(' * Re-using|cFF00FF00', attributeName)
108 end
109 kb.macros[attributeName] = {attributeValue, command}
110
111
112 print('RegisterAction', actionType, id, '->', attributeName, attributeValue, target .. attributeName)
113 return attributeName, attributeValue, command
114 end
115
116
117
118
119 kb.ApplyTalentBinding = function(talentInfo, cache)
120 for i = 5, #talentInfo do
121 local command = CLICK_KEYBINDER_KEY.. talentInfo[2]
122 SetBinding(talentInfo[i], command)
123 cprint(' **', talentInfo[i], '->', command)
124 tinsert(cache, talentInfo[i])
125 end
126 end
127 kb.CacheTalentBinding = function(talentInfo, cache)
128
129 local spellID = talentInfo[4]
130 cache[spellID] = cache[spellID] or {}
131 cache[spellID] = {select(5,unpack(talentInfo)) }
132 --cprint(spellID, unpack(kb.TalentBindings[spellID]))
133 end
134
135
136 do
137 local bindings = kb.bindings
138 local key, macro = KeyBinderKey, KeyBinderMacro
139 kb.LoadBinding = function(command, name, icon, actionType, actionID, macroName, macroText )
140
141 if actionType == 'spell' then
142 key:SetAttribute("*type-"..name, actionType)
143 key:SetAttribute("*"..actionType.."-"..name, name)
144 elseif actionType == 'item' then
145 key:SetAttribute("*type-"..name, actionType)
146 key:SetAttribute("*"..actionType.."-"..name, name)
147 elseif actionType == 'macro' then
148 macro:SetAttribute("*macro-"..macroName, actionID)
149 else
150 macro:SetAttribute("*macrotext-"..macroName, macroText)
151 end
152
153 cprint('Loading binding', actionType, actionID)
154 bindings[actionType] = bindings[actionType] or {}
155 bindings[actionType][actionID] = bindings[actionType][actionID] or {}
156 bindings[command] = bindings[actionType][actionID]
157 return bindings[actionType], actionID
158 end
159
160 kb.ApplyBindings = function (profile)
161 cprint('binding profile', profile)
162 for slot, data in pairs(profile.buttons) do
163 kb.LoadBinding(unpack(data))
164 end
165
166 for key, command in pairs(profile.bindings) do
167
168 cprint(' *', key, '->', command)
169
170 --_G.print('HotKey','loading', key, command)
171 SetBinding(key, command)
172 if bindings[command] and not tContains(bindings[command], key) then
173 tinsert(bindings[command], key)
174 end
175 end
176
177 for spellName, talentInfo in pairs(profile.talents) do
178 local dummy = GetSpellInfo(spellName)
179 local func = kb.CacheTalentBinding
180 local dest = kb.TalentBindings
181 if dummy then
182 cprint('|cFFBBFF00Active:|r', dummy)
183 local macroName, spellName, actionType, actionID = unpack(talentInfo)
184 bindings[actionType] = bindings[actionType] or {}
185 bindings[actionType][actionID] = {}
186 func = kb.ApplyTalentBinding
187 dest = kb.bindings[actionType][actionID]
188 else
189
190 cprint('|cFFFF4400Inactive:|r', talentInfo[2])
191 end
192 func(talentInfo, dest)
193 end
194
195 end
196
197 kb.ApplyAllBindings =function ()
198 wipe(kb.TalentBindings)
199
200
201 -- reflect action key settings
202 if GetCVarBool("ActionButtonUseKeyDown") then
203 KeyBinderMacro:RegisterForClicks("AnyDown")
204 KeyBinderKey:RegisterForClicks("AnyDown")
205 else
206 KeyBinderMacro:RegisterForClicks("AnyUp")
207 KeyBinderKey:RegisterForClicks("AnyUp")
208 end
209
210 for i, profile in ipairs(kb.orderedProfiles) do
211 kb.ApplyBindings(profile)
212 end
213 -- do this after to ensure that profession binds are properly overridden
214 kb.UpdateProfessionInfo()
215
216
217 SaveBindings(GetCurrentBindingSet())
218 end
219 end
220
221
222 kb.specInfo = {}
223 kb.UpdateSpecInfo = function()
224 kb.specInfo.id = GetSpecialization()
225 kb.specInfo.globalID, kb.specInfo.name, kb.specInfo.desc, kb.specInfo.texture = GetSpecializationInfo(kb.specInfo.id)
226 end
227
228 kb.UpdateTalentInfo = function()
229 if kb.talentsPushed then
230 return
231 end
232 wipe(kb.TalentCache)
233 for row =1, MAX_TALENT_TIERS do
234 for col = 1, NUM_TALENT_COLUMNS do
235 local talentID, talentName, icon, selected, available, spellID = GetTalentInfo(row, col, 1)
236 local talentInfo = kb.TalentCache[spellID] or {}
237 talentInfo.row = 1
238 talentInfo.col = col
239 talentInfo.name = talentName
240 talentInfo.talentID = talentID
241 talentInfo.selected = selected
242 talentInfo.available = available
243 talentInfo.spellID = spellID
244 kb.TalentCache[spellID] = talentInfo
245 kb.TalentCache[talentName] = talentInfo
246 print('Talent ', row, col, spellID, talentName)
247 end
248 end
249 kb.talentsPushed = true
250
251 kb.UpdateDynamicButtons('talent')
252 end
253
254 kb.UpdateProfessionInfo = function()
255 wipe(kb.ProfessionCache)
256 local profs = {GetProfessions() }
257 local primaryNum = 0
258 for i, index in ipairs(profs) do
259 local profName, texture, rank, maxRank, numSpells, spellOffset = GetProfessionInfo(index)
260 print(i, index, profName, numSpells, spellOffset)
261 if not SECONDARY_PROFESSIONS[index] then
262 primaryNum = primaryNum + 1
263 end
264 local profNum = SECONDARY_PROFESSIONS[index] or primaryNum
265
266
267 kb.ProfessionCache[profNum] = kb.ProfessionCache[i] or {}
268
269 for j = 1, numSpells do
270 local spellName, _, icon, _, _, _, spellID = GetSpellInfo(spellOffset+j, BOOKTYPE_PROFESSION)
271
272 local profInfo = {
273 spellName = spellName,
274 spellID = spellID,
275 icon = icon,
276 profOffset = i,
277 profIndex = index,
278 spellOffset = (spellOffset+j),
279 spellNum = j
280 }
281
282 kb.SecureAttribute(KeyBinderKey, "*type-profession_"..i .. '_' ..j, "spell")
283 kb.SecureAttribute(KeyBinderKey, "*spell-profession_"..i .. '_' ..j, spellName)
284
285 kb.ProfessionCache[i .. '_' .. j] = profInfo
286 kb.ProfessionCache[spellName] = profInfo
287 kb.ProfessionCache[spellID] = profInfo
288 print(' |cFF0088FF['..i..']|r|cFFFF44BB['..spellOffset+i..']|r', spellName, "profession_"..i .. '_' ..j)
289 end
290
291 end
292
293 kb.UpdateDynamicButtons('profession')
294 end
295
296
297
298 kb.UpdatePetInfo = function()
299 local hasPetSpells, petType = HasPetSpells()
300 if PetHasSpellbook() then
301 print('PET SPELLBOOK')
302 local i = 1
303 local specialNum = {}
304 repeat
305
306 local spellType, spellID = GetSpellBookItemInfo(i, BOOKTYPE_PET)
307 local spellName, subText = GetSpellBookItemName(i, BOOKTYPE_PET)
308 local texture = GetSpellBookItemTexture(i, BOOKTYPE_PET)
309 local isPassive = IsPassiveSpell(i, BOOKTYPE_PET)
310 if not isPassive then
311 if spellName then
312 kb.PetCache.spellslot[spellName] = {i, spellName, subText, spellID, texture}
313 print('|cFF00FF88spellslot['..spellName..']|r', '=>', i, subText)
314
315 if subText then
316 kb.PetCache.subtext[subText] = kb.PetCache.subtext[subText] or {}
317 specialNum[subText] = (specialNum[subText] or 0) + 1
318
319 local entry = {i, spellName, subText, spellID, texture, specialNum[subText]}
320
321 kb.PetCache.special[spellName] = entry
322 kb.PetCache.subtext[subText][specialNum[subText]] = entry
323 kb.SecureAttribute(KeyBinderMacro, "*macrotext-petaction_"..subText.."_"..specialNum[subText], "/cast "..spellName)
324
325 print('|cFF00FFFFspecial['..spellName..']|r', '\n','|cFF00FFFFsubtext['..subText..']['..specialNum[subText]..']|r', '=>', i, spellName, subText, spellID, texture, specialNum[subText])
326 end
327
328 if spellID then
329 kb.PetCache.spell[i] = {spellID, spellName, subText}
330 print('|cFF0088FFspell['..i..']|r', '=>', spellID, spellName, subText)
331 end
332 end
333
334
335 end
336
337 i = i + 1
338 until spellType == nil
339 else
340 print('NO PET SPELLBOOK')
341 wipe(kb.PetCache.spell)
342 wipe(kb.PetCache.spellslot)
343 end
344
345 if PetHasActionBar() then
346 print('PET ACTION BAR')
347 for i = 1, 10 do
348
349
350 local name, subtext, texture, isToken, isActive = GetPetActionInfo(i)
351 if name then
352 kb.PetCache.action[i] = {name, subtext, texture, isToken, isActive }
353
354
355 end
356 print('|cFFFFFF00action['..i..']|r', name, subtext, texture)
357 end
358 else
359 print('NO PET ACTION BAR')
360 wipe(kb.PetCache.action)
361 end
362
363 kb.UpdateDynamicButtons('petaction')
364
365 end
366
367 kb.UpdateSystemBinds = function()
368 wipe(kb.SystemBindings)
369 local n = GetNumBindings()
370 for i=1, n do
371 local command, key1, key2 = GetBinding(i)
372 if key1 then
373 kb.SystemBindings[key1] = command
374 end
375 if key2 then
376 kb.SystemBindings[key2] = command
377 end
378 end
379 end
380
381 kb.UpdateDynamicButtons = function(dynamicType)
382 for i, button in ipairs(kb.buttons) do
383 if button.isDynamic == dynamicType then
384 kb.UpdateSlot(button, true)
385 end
386 end
387 end
388
389 kb.pendingAttributes = {}
390 kb.SecureAttribute = function(target, name, value)
391 if InCombatLockdown() then
392 tinsert(kb.pendingAttributes, {target, name, value})
393 kb:RegisterEvent('PLAYER_REGEN_ENABLED')
394 else
395
396 print(target:GetName(), 'attribute', '"'.. tostring(name)..'" = "'..tostring(value)..'"')
397 target:SetAttribute(name, value)
398 end
399 end
400
401 kb.PLAYER_REGEN_ENABLED = function()
402 if #kb.pendingAttributes >= 1 then
403 local args = tremove(kb.pendingAttributes)
404 while args do
405 local target, name, value = unpack(args)
406 print(target:GetName(), 'attribute', '"'.. tostring(name)..'" = "'..tostring(value)..'"')
407 target:SetAttribute(name, value)
408 args = tremove(kb.pendingAttributes)
409 end
410 end
411
412 if #kb.pendingCalls >= 1 then
413
414 local func = tremove(kb.pendingCalls)
415 while func do
416 func()
417 end
418 end
419 end
420
421 kb.UpdateBindingsCache = function(actionType, actionID, bindings)
422 kb.bindings[actionType] = kb.bindings[actionType] or {}
423 kb.bindings[actionType][actionID] = bindings
424
425 print('|cFF00FF00'..actionType..'-'..actionID..'|r = {', table.concat(bindings,', '), '}')
426 tinsert(kb.ChangedBindings, {actionType, actionID})
427 end