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