annotate SkeletonKey/ActionTemplates.lua @ 63:2409fe9b81e1

- check macro spells when considering whether a binding should be treated as a talent - clean up talent binding data when releasing/unbinding slots with a related macro/spell
author Nenue
date Thu, 08 Sep 2016 16:52:55 -0400
parents 04c23ceaf9e0
children 178d489f387c
rev   line source
Nenue@16 1 -- SkeletonKey
Nenue@27 2 -- ActionTemplates.lua
Nenue@16 3 -- Created: 7/29/2016 9:14 PM
Nenue@16 4 -- %file-revision%
Nenue@27 5 -- Code dealing with the implementation of action hotkeys
Nenue@27 6
Nenue@21 7 local tostring, tonumber, pairs, ipairs = tostring, tonumber, pairs, ipairs
Nenue@21 8 local unpack, SetBinding = unpack, SetBinding
Nenue@21 9 local tinsert, tContains, select, wipe = tinsert, tContains, select, table.wipe
Nenue@21 10 local GetSpellBookItemInfo, GetSpellBookItemName, GetSpellInfo = GetSpellBookItemInfo, GetSpellBookItemName, GetSpellInfo
Nenue@21 11 local GetSpecialization, GetSpecializationInfo, IsPassiveSpell, IsTalentSpell = GetSpecialization, GetSpecializationInfo, IsPassiveSpell, IsTalentSpell
Nenue@21 12 local PetHasSpellbook, PetHasActionBar, GetPetActionInfo, HasPetSpells = PetHasSpellbook, PetHasActionBar, GetPetActionInfo, HasPetSpells
Nenue@21 13 local GetProfessions, GetProfessionInfo, GetTalentInfo = GetProfessions, GetProfessionInfo, GetTalentInfo
Nenue@21 14 local GetNumBindings, GetBinding = GetNumBindings, GetBinding
Nenue@21 15
Nenue@21 16 local kb, print, wrap = LibStub('LibKraken').register(KeyBinder, 'Info')
Nenue@34 17 local cprint = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('Cfg', ...) end or function() end
Nenue@16 18
Nenue@17 19 local CLICK_KEYBINDER_MACRO = "CLICK KeyBinderMacro:"
Nenue@17 20 local CLICK_KEYBINDER_KEY = "CLICK KeyBinderKey:"
Nenue@21 21 local PET_BASIC_SUBTEXT = 'Basic Attack'
Nenue@21 22 local PET_SPECIAL_SUBTEXT = 'Special Ability'
Nenue@16 23 local PETACTION_SCRIPT = {
Nenue@22 24 [PET_ACTION_MOVE_TO] = {'pet_move_to', SLASH_PET_MOVE_TO1},
Nenue@22 25 [PET_ACTION_ATTACK] = {'pet_attack', SLASH_PET_ATTACK1},
Nenue@22 26 [PET_ACTION_FOLLOW] = {'pet_follow', SLASH_PET_FOLLOW1},
Nenue@22 27 [PET_ACTION_WAIT] = {'pet_stay', SLASH_PET_STAY1 },
Nenue@22 28 [PET_MODE_AGGRESSIVE] = {'pet_aggressive', SLASH_PET_AGGRESSIVE1 },
Nenue@22 29 [PET_MODE_DEFENSIVE] = { 'pet_defensive', SLASH_PET_DEFENSIVE1},
Nenue@22 30 [PET_MODE_PASSIVE] = { 'pet_passive', SLASH_PET_PASSIVE1},
Nenue@22 31 [PET_MODE_ASSIST] = {'pet_assist', SLASH_PET_ASSIST1},
Nenue@16 32 }
Nenue@21 33 local SECONDARY_PROFESSIONS = {
Nenue@21 34 [5] = 3,
Nenue@21 35 [7] = 4,
Nenue@21 36 [9] = 5,
Nenue@21 37 [10] = 6
Nenue@21 38 }
Nenue@54 39 local petSpellCache,petSubtextCache
Nenue@21 40 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544
Nenue@16 41
Nenue@27 42 --kb.ChangedBindings = {}
Nenue@27 43 --kb.ActionTypes = {}
Nenue@19 44
Nenue@19 45 local atype = kb.ActionTypes
Nenue@19 46
Nenue@17 47 --- Caps Lock
Nenue@19 48 atype['mount'] = function(id, name)
Nenue@17 49 if id == SUMMON_RANDOM_FAVORITE_MOUNT_SPELL then
Nenue@24 50 return CLICK_KEYBINDER_MACRO, 'mount_random', "/script C_MountJournal.SummonByID(0)"
Nenue@17 51 else
Nenue@24 52 return CLICK_KEYBINDER_MACRO, 'mount_'..id, "/script C_MountJournal.SummonByID("..id..")"
Nenue@17 53 end
Nenue@16 54 end
Nenue@19 55
Nenue@19 56 atype['macro'] = function(id, name)
Nenue@17 57 return CLICK_KEYBINDER_MACRO, 'macro_' .. tostring(name), id
Nenue@17 58 end
Nenue@19 59
Nenue@19 60 atype['equipset'] = function(id, name)
Nenue@17 61 return CLICK_KEYBINDER_MACRO, 'equipset_'..tostring(name), "/script UseEquipmentSet("..tostring(id)..")"
Nenue@17 62 end
Nenue@19 63
Nenue@19 64 atype['spell'] = function(id, name)
Nenue@17 65 local attributeName = name
Nenue@17 66 if kb.ProfessionCache[id] then
Nenue@17 67 attributeName = "profession_".. kb.ProfessionCache[id].profOffset .. '_' .. kb.ProfessionCache[id].spellNum
Nenue@17 68 end
Nenue@17 69 return CLICK_KEYBINDER_KEY, attributeName, name
Nenue@17 70 end
Nenue@19 71
Nenue@19 72 atype['petaction'] = function(_, name)
Nenue@17 73 -- ID doesn't exist for basic commands, even though they can be picked up
Nenue@17 74 local attributeName, attributeValue = "petaction_" .. tostring(name), "/cast "..tostring(name)
Nenue@54 75
Nenue@54 76 if not petSpellCache then
Nenue@54 77 kb.UpdatePetInfo()
Nenue@54 78 end
Nenue@54 79 -- Compose a multi-macro for subtext abilities
Nenue@54 80 if petSpellCache[name] then
Nenue@54 81 attributeValue = ""
Nenue@54 82 for spellName, enabled in pairs(petSubtextCache[petSpellCache[name]]) do
Nenue@54 83 attributeValue = attributeValue .. "/cast " .. spellName .. "\n"
Nenue@54 84 end
Nenue@54 85 end
Nenue@54 86
Nenue@17 87 if PETACTION_SCRIPT[name] then
Nenue@22 88 attributeName, attributeValue = unpack(PETACTION_SCRIPT[name])
Nenue@19 89 elseif kb.PetCache.special[name] then
Nenue@21 90 attributeName = "petaction_"..kb.PetCache.special[name][3].."_" .. tonumber(kb.PetCache.special[name][6])
Nenue@17 91 end
Nenue@17 92 return CLICK_KEYBINDER_MACRO, attributeName, attributeValue
Nenue@16 93 end
Nenue@16 94
Nenue@19 95 atype['battlepet'] = function(id, name)
Nenue@17 96 return CLICK_KEYBINDER_MACRO, 'battlepet_' .. tostring(name), SLASH_SUMMON_BATTLE_PET1 .. " " .. tostring(name)
Nenue@17 97 end
Nenue@19 98
Nenue@19 99 atype['item'] = function(id, name)
Nenue@17 100 return CLICK_KEYBINDER_KEY, 'item_' .. tostring(name), id
Nenue@17 101 end
Nenue@16 102
Nenue@16 103
Nenue@17 104 --- Resolves the SecureActionButton attribute names used for the given action
Nenue@16 105 kb.RegisterAction = function(actionType, id, name)
Nenue@16 106
Nenue@19 107 assert(atype[actionType], 'Missing actionType handler for `'..tostring(actionType)..'`')
Nenue@19 108 local target, attributeName, attributeValue = atype[actionType](id, name)
Nenue@17 109
Nenue@17 110 local command = target .. attributeName
Nenue@17 111 local baseName, iterative = attributeName, 1
Nenue@17 112 while (kb.macros[attributeName] and kb.macros[attributeName][1] ~= attributeValue) do
Nenue@62 113 --print(' * cannot use|cFF00FF00', attributeName, '|r"'.. tostring(kb.macros[attributeName][1]) .. '"')
Nenue@17 114 attributeName = baseName .. '_' .. iterative
Nenue@17 115 iterative = iterative + 1
Nenue@17 116 end
Nenue@21 117 if attributeName ~= baseName then
Nenue@62 118 --print(' * Creating|cFF00FF00', attributeName)
Nenue@17 119 else
Nenue@62 120 --print(' * Re-using|cFF00FF00', attributeName)
Nenue@17 121 end
Nenue@17 122 kb.macros[attributeName] = {attributeValue, command}
Nenue@17 123
Nenue@17 124
Nenue@62 125 --print('RegisterAction', actionType, id, '->', attributeName, attributeValue, target .. attributeName)
Nenue@17 126 return attributeName, attributeValue, command
Nenue@17 127 end
Nenue@17 128
Nenue@17 129
Nenue@17 130
Nenue@17 131
Nenue@17 132 kb.ApplyTalentBinding = function(talentInfo, cache)
Nenue@17 133 for i = 5, #talentInfo do
Nenue@17 134 local command = CLICK_KEYBINDER_KEY.. talentInfo[2]
Nenue@17 135 SetBinding(talentInfo[i], command)
Nenue@62 136 --cprint(' **', talentInfo[i], '->', command)
Nenue@17 137 tinsert(cache, talentInfo[i])
Nenue@17 138 end
Nenue@17 139 end
Nenue@17 140 kb.CacheTalentBinding = function(talentInfo, cache)
Nenue@17 141
Nenue@17 142 local spellID = talentInfo[4]
Nenue@19 143 cache[spellID] = cache[spellID] or {}
Nenue@19 144 cache[spellID] = {select(5,unpack(talentInfo)) }
Nenue@19 145 --cprint(spellID, unpack(kb.TalentBindings[spellID]))
Nenue@17 146 end
Nenue@17 147
Nenue@27 148
Nenue@17 149 do
Nenue@63 150 local commandActions = {}
Nenue@17 151 local bindings = kb.bindings
Nenue@17 152 local key, macro = KeyBinderKey, KeyBinderMacro
Nenue@17 153 kb.LoadBinding = function(command, name, icon, actionType, actionID, macroName, macroText )
Nenue@17 154
Nenue@63 155 local indexKey = actionType..'_'..actionID
Nenue@62 156 local buttonTypeKey, buttonTypeValue = "*type-"..name, actionType
Nenue@62 157 local buttonActionKey, buttonActionValue = "*"..actionType.."-"..name, actionID
Nenue@62 158 local button = key
Nenue@17 159 if actionType == 'spell' then
Nenue@62 160 buttonTypeKey = "*type-"..name
Nenue@62 161 buttonTypeValue = actionType
Nenue@62 162 buttonActionKey = "*"..actionType.."-"..name
Nenue@62 163 buttonActionValue = name
Nenue@17 164 elseif actionType == 'item' then
Nenue@62 165 buttonTypeKey = "*type-"..name
Nenue@62 166 buttonTypeValue = actionType
Nenue@62 167 buttonActionKey = "*"..actionType.."-"..name
Nenue@62 168 buttonActionValue = actionID
Nenue@17 169 elseif actionType == 'macro' then
Nenue@62 170 button = macro
Nenue@62 171 buttonTypeKey = "*macro-"..macroName
Nenue@62 172 buttonTypeValue = actionID
Nenue@62 173 buttonActionKey = nil
Nenue@16 174 else
Nenue@62 175 button = macro
Nenue@62 176 buttonTypeKey = "*macrotext-"..macroName
Nenue@62 177 buttonTypeValue = macroText
Nenue@62 178 buttonActionKey = nil
Nenue@16 179 end
Nenue@62 180
Nenue@62 181 --cprint(actionType, actionID, name)
Nenue@62 182 kb.SecureAttribute(button, buttonTypeKey, buttonTypeValue)
Nenue@62 183 if buttonActionKey then
Nenue@62 184 --cprint(button:GetName(), buttonActionKey,'=', buttonActionValue)
Nenue@62 185 kb.SecureAttribute(button, buttonActionKey, buttonActionValue)
Nenue@62 186 end
Nenue@62 187
Nenue@63 188 kb.bindings[indexKey] = kb.bindings[indexKey] or {}
Nenue@63 189 kb.bindings[command] = kb.bindings[indexKey]
Nenue@63 190 commandActions[command] = indexKey
Nenue@50 191 return bindings[indexKey], actionID
Nenue@16 192 end
Nenue@16 193
Nenue@17 194 kb.ApplyBindings = function (profile)
Nenue@62 195 --cprint('binding profile', profile)
Nenue@63 196
Nenue@17 197 for slot, data in pairs(profile.buttons) do
Nenue@63 198 local bindsTable, actionID = kb.LoadBinding(unpack(data))
Nenue@63 199 local command = data[1]
Nenue@17 200 end
Nenue@17 201
Nenue@17 202 for key, command in pairs(profile.bindings) do
Nenue@63 203 cprint('|cFF00FFFF'.. key .. '|r to|cFF00FF00', command, commandActions[command])
Nenue@17 204 SetBinding(key, command)
Nenue@63 205 if kb.bindings[command] then
Nenue@63 206 tinsert(kb.bindings[command], key)
Nenue@17 207 end
Nenue@17 208 end
Nenue@17 209
Nenue@17 210 for spellName, talentInfo in pairs(profile.talents) do
Nenue@17 211 local dummy = GetSpellInfo(spellName)
Nenue@17 212 local func = kb.CacheTalentBinding
Nenue@19 213 local dest = kb.TalentBindings
Nenue@17 214 if dummy then
Nenue@62 215 --cprint('|cFFBBFF00Active:|r', dummy)
Nenue@17 216 local macroName, spellName, actionType, actionID = unpack(talentInfo)
Nenue@50 217 local indexKey = actionType .. '_' .. actionID
Nenue@63 218 kb.bindings[indexKey] = {}
Nenue@17 219 func = kb.ApplyTalentBinding
Nenue@50 220 dest = kb.bindings[indexKey]
Nenue@17 221 else
Nenue@17 222
Nenue@62 223 --cprint('|cFFFF4400Inactive:|r', talentInfo[2])
Nenue@17 224 end
Nenue@17 225 func(talentInfo, dest)
Nenue@17 226 end
Nenue@17 227
Nenue@17 228 end
Nenue@17 229
Nenue@17 230 kb.ApplyAllBindings =function ()
Nenue@21 231 wipe(kb.TalentBindings)
Nenue@62 232 wipe(kb.bindings)
Nenue@63 233 --kb:print('Loading binding profile', kb.profileName)
Nenue@17 234
Nenue@17 235 -- reflect action key settings
Nenue@17 236 if GetCVarBool("ActionButtonUseKeyDown") then
Nenue@17 237 KeyBinderMacro:RegisterForClicks("AnyDown")
Nenue@17 238 KeyBinderKey:RegisterForClicks("AnyDown")
Nenue@17 239 else
Nenue@17 240 KeyBinderMacro:RegisterForClicks("AnyUp")
Nenue@17 241 KeyBinderKey:RegisterForClicks("AnyUp")
Nenue@17 242 end
Nenue@17 243
Nenue@17 244 for i, profile in ipairs(kb.orderedProfiles) do
Nenue@17 245 kb.ApplyBindings(profile)
Nenue@17 246 end
Nenue@17 247 -- do this after to ensure that profession binds are properly overridden
Nenue@17 248 kb.UpdateProfessionInfo()
Nenue@17 249
Nenue@17 250 SaveBindings(GetCurrentBindingSet())
Nenue@17 251 end
Nenue@19 252 end
Nenue@19 253
Nenue@19 254
Nenue@19 255 kb.specInfo = {}
Nenue@19 256 kb.UpdateSpecInfo = function()
Nenue@19 257 kb.specInfo.id = GetSpecialization()
Nenue@19 258 kb.specInfo.globalID, kb.specInfo.name, kb.specInfo.desc, kb.specInfo.texture = GetSpecializationInfo(kb.specInfo.id)
Nenue@19 259 end
Nenue@19 260
Nenue@63 261 kb.UpdateMacroInfo = function()
Nenue@63 262 for i = 1, GetNumMacros() do
Nenue@63 263 local name = GetMacroInfo(index)
Nenue@63 264 kb.SecureAttribute(KeyBinderMacro, "*macro_"..tostring(name), i)
Nenue@63 265 end
Nenue@63 266 end
Nenue@63 267
Nenue@19 268 kb.UpdateTalentInfo = function()
Nenue@19 269 if kb.talentsPushed then
Nenue@19 270 return
Nenue@19 271 end
Nenue@21 272 wipe(kb.TalentCache)
Nenue@19 273 for row =1, MAX_TALENT_TIERS do
Nenue@19 274 for col = 1, NUM_TALENT_COLUMNS do
Nenue@19 275 local talentID, talentName, icon, selected, available, spellID = GetTalentInfo(row, col, 1)
Nenue@19 276 local talentInfo = kb.TalentCache[spellID] or {}
Nenue@19 277 talentInfo.row = 1
Nenue@19 278 talentInfo.col = col
Nenue@19 279 talentInfo.name = talentName
Nenue@19 280 talentInfo.talentID = talentID
Nenue@19 281 talentInfo.selected = selected
Nenue@19 282 talentInfo.available = available
Nenue@19 283 talentInfo.spellID = spellID
Nenue@19 284 kb.TalentCache[spellID] = talentInfo
Nenue@19 285 kb.TalentCache[talentName] = talentInfo
Nenue@62 286 --print('Talent ', row, col, spellID, talentName)
Nenue@19 287 end
Nenue@19 288 end
Nenue@19 289 kb.talentsPushed = true
Nenue@19 290
Nenue@19 291 kb.UpdateDynamicButtons('talent')
Nenue@19 292 end
Nenue@19 293
Nenue@19 294 kb.UpdateProfessionInfo = function()
Nenue@21 295 wipe(kb.ProfessionCache)
Nenue@19 296 local profs = {GetProfessions() }
Nenue@62 297 --print(GetProfessions())
Nenue@19 298 local primaryNum = 0
Nenue@30 299 for i = 1, 6 do
Nenue@30 300 if profs[i] then
Nenue@30 301 local index = profs[i]
Nenue@30 302 local profName, texture, _, _, numSpells, spellOffset = GetProfessionInfo(index)
Nenue@62 303 --print(i, index, profName, numSpells, spellOffset)
Nenue@30 304 if not SECONDARY_PROFESSIONS[index] then
Nenue@30 305 primaryNum = primaryNum + 1
Nenue@30 306 end
Nenue@30 307 local profNum = SECONDARY_PROFESSIONS[index] or primaryNum
Nenue@62 308 --print(i, profNum)
Nenue@19 309
Nenue@19 310
Nenue@30 311 kb.ProfessionCache[profNum] = kb.ProfessionCache[profNum] or {}
Nenue@19 312
Nenue@30 313 for j = 1, numSpells do
Nenue@30 314 local spellName, _, icon, _, _, _, spellID = GetSpellInfo(spellOffset+j, BOOKTYPE_PROFESSION)
Nenue@19 315
Nenue@30 316 local profInfo = {
Nenue@30 317 spellName = spellName,
Nenue@30 318 spellID = spellID,
Nenue@30 319 icon = icon,
Nenue@30 320 profOffset = i,
Nenue@30 321 profIndex = index,
Nenue@30 322 spellOffset = (spellOffset+j),
Nenue@30 323 spellNum = j
Nenue@30 324 }
Nenue@26 325
Nenue@30 326 kb.SecureAttribute(KeyBinderKey, "*type-profession_"..i .. '_' ..j, "spell")
Nenue@30 327 kb.SecureAttribute(KeyBinderKey, "*spell-profession_"..i .. '_' ..j, spellName)
Nenue@19 328
Nenue@30 329 kb.ProfessionCache[i .. '_' .. j] = profInfo
Nenue@30 330 kb.ProfessionCache[spellName] = profInfo
Nenue@30 331 kb.ProfessionCache[spellID] = profInfo
Nenue@62 332 --print(' |cFF0088FF['..i..']|r|cFFFF44BB['..spellOffset+i..']|r', spellName, "profession_"..i .. '_' ..j)
Nenue@30 333 end
Nenue@19 334 end
Nenue@19 335
Nenue@19 336 end
Nenue@19 337
Nenue@19 338 kb.UpdateDynamicButtons('profession')
Nenue@19 339 end
Nenue@19 340
Nenue@19 341
Nenue@19 342
Nenue@19 343 kb.UpdatePetInfo = function()
Nenue@19 344 local hasPetSpells, petType = HasPetSpells()
Nenue@34 345
Nenue@56 346 -- reconcile saved data if it becomes available
Nenue@56 347 if kb.db then
Nenue@56 348 kb.db.petSpellsDB = kb.db.petSpellsDB or {}
Nenue@56 349 kb.db.petSpellsDB.subtext = kb.db.petSpellsDB.subtext or {}
Nenue@56 350 kb.db.petSpellsDB.spell = kb.db.petSpellsDB.spell or {}
Nenue@56 351 local spellCache = kb.db.petSpellsDB.spell
Nenue@56 352 local subtextCache = kb.db.petSpellsDB.subtext
Nenue@56 353 if petSpellCache then
Nenue@56 354 for k,v in pairs(petSpellCache) do
Nenue@56 355 if not spellCache[k] then
Nenue@56 356 spellCache[k] = v
Nenue@56 357 end
Nenue@56 358 end
Nenue@56 359 end
Nenue@57 360 petSpellCache = spellCache
Nenue@56 361 if petSubtextCache then
Nenue@56 362 for k,v in pairs(petSubtextCache) do
Nenue@56 363 if not subtextCache[k] then
Nenue@56 364 subtextCache[k] = v
Nenue@56 365 end
Nenue@56 366 end
Nenue@56 367 end
Nenue@57 368 petSubtextCache = subtextCache
Nenue@56 369 else
Nenue@56 370 petSpellCache = {}
Nenue@56 371 petSubtextCache = {}
Nenue@56 372 end
Nenue@54 373
Nenue@19 374 if PetHasSpellbook() then
Nenue@62 375 --print('PET SPELLBOOK')
Nenue@19 376 local i = 1
Nenue@21 377 local specialNum = {}
Nenue@19 378 repeat
Nenue@19 379
Nenue@19 380 local spellType, spellID = GetSpellBookItemInfo(i, BOOKTYPE_PET)
Nenue@19 381 local spellName, subText = GetSpellBookItemName(i, BOOKTYPE_PET)
Nenue@21 382 local texture = GetSpellBookItemTexture(i, BOOKTYPE_PET)
Nenue@19 383 local isPassive = IsPassiveSpell(i, BOOKTYPE_PET)
Nenue@19 384 if not isPassive then
Nenue@19 385 if spellName then
Nenue@21 386 kb.PetCache.spellslot[spellName] = {i, spellName, subText, spellID, texture}
Nenue@62 387 --print('|cFF00FF88spellslot['..spellName..']|r', '=>', i, subText)
Nenue@19 388
Nenue@21 389 if subText then
Nenue@34 390 -- make sure that pet specialization subtext maps correctly
Nenue@34 391 --if match(subText, kb.PetCache.specName) then
Nenue@34 392 -- subText = 'specialization'
Nenue@34 393 --end
Nenue@21 394 kb.PetCache.subtext[subText] = kb.PetCache.subtext[subText] or {}
Nenue@21 395 specialNum[subText] = (specialNum[subText] or 0) + 1
Nenue@21 396
Nenue@54 397 petSpellCache[spellName] = subText
Nenue@54 398 petSubtextCache[subText] = petSubtextCache[subText] or {}
Nenue@54 399
Nenue@54 400 -- add to the list
Nenue@54 401 if not petSubtextCache[subText][spellName] then
Nenue@54 402 petSubtextCache[subText][spellName] = true
Nenue@54 403
Nenue@54 404 local macrotext = ""
Nenue@54 405 for spellName, enabled in pairs(petSubtextCache[subText]) do
Nenue@54 406 macrotext = macrotext .. "/cast " .. spellName .. "\n"
Nenue@54 407 end
Nenue@54 408 kb.SecureAttribute(KeyBinderMacro, "*macrotext-petaction_"..subText.."_"..specialNum[subText], macrotext)
Nenue@62 409 --print('|cFF00FFFFspecial['..spellName..']|r', '\n','|cFF00FFFFsubtext['..subText..']['..specialNum[subText]..']|r', '=>', i, spellName, subText, spellID, texture, specialNum[subText])
Nenue@54 410 end
Nenue@54 411
Nenue@54 412
Nenue@54 413
Nenue@21 414 local entry = {i, spellName, subText, spellID, texture, specialNum[subText]}
Nenue@21 415
Nenue@21 416 kb.PetCache.special[spellName] = entry
Nenue@21 417 kb.PetCache.subtext[subText][specialNum[subText]] = entry
Nenue@19 418 end
Nenue@19 419
Nenue@19 420 if spellID then
Nenue@19 421 kb.PetCache.spell[i] = {spellID, spellName, subText}
Nenue@62 422 --print('|cFF0088FFspell['..i..']|r', '=>', spellID, spellName, subText)
Nenue@19 423 end
Nenue@19 424 end
Nenue@19 425
Nenue@19 426
Nenue@19 427 end
Nenue@19 428
Nenue@19 429 i = i + 1
Nenue@19 430 until spellType == nil
Nenue@19 431 else
Nenue@62 432 --print('NO PET SPELLBOOK')
Nenue@21 433 wipe(kb.PetCache.spell)
Nenue@21 434 wipe(kb.PetCache.spellslot)
Nenue@19 435 end
Nenue@19 436
Nenue@19 437 if PetHasActionBar() then
Nenue@62 438 --print('PET ACTION BAR')
Nenue@19 439 for i = 1, 10 do
Nenue@19 440
Nenue@19 441
Nenue@19 442 local name, subtext, texture, isToken, isActive = GetPetActionInfo(i)
Nenue@19 443 if name then
Nenue@19 444 kb.PetCache.action[i] = {name, subtext, texture, isToken, isActive }
Nenue@19 445
Nenue@19 446
Nenue@19 447 end
Nenue@62 448 --print('|cFFFFFF00action['..i..']|r', name, subtext, texture)
Nenue@19 449 end
Nenue@19 450 else
Nenue@62 451 --print('NO PET ACTION BAR')
Nenue@21 452 wipe(kb.PetCache.action)
Nenue@19 453 end
Nenue@19 454
Nenue@19 455 kb.UpdateDynamicButtons('petaction')
Nenue@19 456
Nenue@19 457 end
Nenue@19 458
Nenue@19 459 kb.UpdateSystemBinds = function()
Nenue@21 460 wipe(kb.SystemBindings)
Nenue@19 461 local n = GetNumBindings()
Nenue@19 462 for i=1, n do
Nenue@19 463 local command, key1, key2 = GetBinding(i)
Nenue@34 464 if not command:match('ACTION.*%d+') then
Nenue@34 465 if key1 then
Nenue@34 466 kb.SystemBindings[key1] = command
Nenue@34 467 end
Nenue@34 468 if key2 then
Nenue@34 469 kb.SystemBindings[key2] = command
Nenue@34 470 end
Nenue@34 471 else
Nenue@62 472 --print('ignoring action button binding', command)
Nenue@19 473 end
Nenue@19 474 end
Nenue@19 475 end
Nenue@19 476
Nenue@19 477 kb.UpdateDynamicButtons = function(dynamicType)
Nenue@19 478 for i, button in ipairs(kb.buttons) do
Nenue@19 479 if button.isDynamic == dynamicType then
Nenue@19 480 kb.UpdateSlot(button, true)
Nenue@19 481 end
Nenue@19 482 end
Nenue@26 483 end
Nenue@26 484
Nenue@26 485 kb.pendingAttributes = {}
Nenue@26 486 kb.SecureAttribute = function(target, name, value)
Nenue@26 487 if InCombatLockdown() then
Nenue@34 488 if #kb.pendingAttributes == 0 then
Nenue@49 489 kb:print(kb.L('Key bindings will be applied when you exit combat.'))
Nenue@34 490 end
Nenue@34 491
Nenue@26 492 tinsert(kb.pendingAttributes, {target, name, value})
Nenue@26 493 kb:RegisterEvent('PLAYER_REGEN_ENABLED')
Nenue@34 494
Nenue@26 495 else
Nenue@26 496
Nenue@63 497 cprint('|cFFFF4444' .. target:GetName()..'|r.|cFFFFFF00'.. tostring(name)..'|r = "'..tostring(value)..'"')
Nenue@26 498 target:SetAttribute(name, value)
Nenue@26 499 end
Nenue@26 500 end
Nenue@26 501
Nenue@26 502 kb.PLAYER_REGEN_ENABLED = function()
Nenue@26 503 if #kb.pendingAttributes >= 1 then
Nenue@26 504 local args = tremove(kb.pendingAttributes)
Nenue@26 505 while args do
Nenue@26 506 local target, name, value = unpack(args)
Nenue@62 507 --print(target:GetName(), 'attribute', '"'.. tostring(name)..'" = "'..tostring(value)..'"')
Nenue@63 508 cprint('deferred', target:GetName(), 'attribute', '"'.. tostring(name)..'" = "'..tostring(value)..'"')
Nenue@26 509 target:SetAttribute(name, value)
Nenue@26 510 args = tremove(kb.pendingAttributes)
Nenue@26 511 end
Nenue@26 512 end
Nenue@27 513
Nenue@27 514 if #kb.pendingCalls >= 1 then
Nenue@27 515
Nenue@27 516 local func = tremove(kb.pendingCalls)
Nenue@27 517 while func do
Nenue@27 518 func()
Nenue@27 519 end
Nenue@27 520 end
Nenue@27 521 end
Nenue@27 522
Nenue@27 523 kb.UpdateBindingsCache = function(actionType, actionID, bindings)
Nenue@50 524 local indexKey = actionType .. '_' .. actionID
Nenue@50 525 kb.bindings[indexKey] = bindings
Nenue@27 526
Nenue@62 527 --print('|cFF00FF00'..indexKey..'|r = {', table.concat(bindings,', '), '}')
Nenue@27 528 tinsert(kb.ChangedBindings, {actionType, actionID})
Nenue@16 529 end