Mercurial > wow > skeletonkey
comparison ActionTemplates.lua @ 70:131d9190db6b
Curseforge migration
| author | Nenue |
|---|---|
| date | Wed, 28 Dec 2016 16:31:15 -0500 |
| parents | |
| children | ca3118127e5e |
comparison
equal
deleted
inserted
replaced
| 69:b14d0611c8d9 | 70:131d9190db6b |
|---|---|
| 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 = ... | |
| 17 local print = (DEVIAN_PNAME == 'SkeletonKey') and function(...) print('SK', ...) end or nop | |
| 18 local cprint = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('Cfg', ...) end or nop | |
| 19 | |
| 20 local CLICK_KEYBINDER_MACRO = "CLICK SkeletonKeyMacro:" | |
| 21 local CLICK_KEYBINDER_KEY = "CLICK SkeletonKeyKey:" | |
| 22 local PET_BASIC_SUBTEXT = 'Basic Attack' | |
| 23 local PET_SPECIAL_SUBTEXT = 'Special Ability' | |
| 24 local PETACTION_SCRIPT = { | |
| 25 [PET_ACTION_MOVE_TO] = {'pet_move_to', SLASH_PET_MOVE_TO1}, | |
| 26 [PET_ACTION_ATTACK] = {'pet_attack', SLASH_PET_ATTACK1}, | |
| 27 [PET_ACTION_FOLLOW] = {'pet_follow', SLASH_PET_FOLLOW1}, | |
| 28 [PET_ACTION_WAIT] = {'pet_stay', SLASH_PET_STAY1 }, | |
| 29 [PET_MODE_AGGRESSIVE] = {'pet_aggressive', SLASH_PET_AGGRESSIVE1 }, | |
| 30 [PET_MODE_DEFENSIVE] = { 'pet_defensive', SLASH_PET_DEFENSIVE1}, | |
| 31 [PET_MODE_PASSIVE] = { 'pet_passive', SLASH_PET_PASSIVE1}, | |
| 32 [PET_MODE_ASSIST] = {'pet_assist', SLASH_PET_ASSIST1}, | |
| 33 } | |
| 34 local SECONDARY_PROFESSIONS = { | |
| 35 [5] = 3, | |
| 36 [7] = 4, | |
| 37 [9] = 5, | |
| 38 [10] = 6 | |
| 39 } | |
| 40 local petSpellCache,petSubtextCache | |
| 41 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544 | |
| 42 | |
| 43 --kb.ChangedBindings = {} | |
| 44 --kb.ActionTypes = {} | |
| 45 | |
| 46 local atype = kb.ActionTypes | |
| 47 | |
| 48 --- Caps Lock | |
| 49 atype['mount'] = function(id, name) | |
| 50 if id == SUMMON_RANDOM_FAVORITE_MOUNT_SPELL then | |
| 51 return CLICK_KEYBINDER_MACRO, 'mount_random', "/script C_MountJournal.SummonByID(0)", SkeletonKeyMacro | |
| 52 else | |
| 53 return CLICK_KEYBINDER_MACRO, 'mount_'..id, "/script C_MountJournal.SummonByID("..id..")", SkeletonKeyMacro | |
| 54 end | |
| 55 end | |
| 56 | |
| 57 atype['macro'] = function(id, name) | |
| 58 local _, _, text = GetMacroInfo(id) | |
| 59 return CLICK_KEYBINDER_MACRO, 'macro_' .. tostring(name), name, SkeletonKeyMacro | |
| 60 end | |
| 61 | |
| 62 atype['equipset'] = function(id, name) | |
| 63 return CLICK_KEYBINDER_MACRO, 'equipset_'..tostring(name), "/script UseEquipmentSet("..tostring(id)..")", SkeletonKeyMacro | |
| 64 end | |
| 65 | |
| 66 atype['spell'] = function(id, name) | |
| 67 local attributeName = name | |
| 68 if kb.ProfessionCache[id] then | |
| 69 attributeName = "profession_".. kb.ProfessionCache[id].dynamicIndex .. '_' .. kb.ProfessionCache[id].dynamicSubIndex | |
| 70 end | |
| 71 return CLICK_KEYBINDER_KEY, attributeName, name, SkeletonKeyKey | |
| 72 end | |
| 73 | |
| 74 atype['petaction'] = function(_, name) | |
| 75 -- ID doesn't exist for basic commands, even though they can be picked up | |
| 76 local attributeName, attributeValue = "petaction_" .. tostring(name), "/cast "..tostring(name) | |
| 77 | |
| 78 if not petSpellCache then | |
| 79 kb.UpdatePetInfo() | |
| 80 end | |
| 81 -- Compose a multi-macro for subtext abilities | |
| 82 if petSpellCache[name] then | |
| 83 attributeValue = "" | |
| 84 for spellName, enabled in pairs(petSubtextCache[petSpellCache[name]]) do | |
| 85 attributeValue = attributeValue .. "/cast " .. spellName .. "\n" | |
| 86 end | |
| 87 end | |
| 88 | |
| 89 if PETACTION_SCRIPT[name] then | |
| 90 attributeName, attributeValue = unpack(PETACTION_SCRIPT[name]) | |
| 91 elseif kb.PetCache.special[name] then | |
| 92 attributeName = "petaction_"..kb.PetCache.special[name][3].."_" .. tonumber(kb.PetCache.special[name][6]) | |
| 93 end | |
| 94 return CLICK_KEYBINDER_MACRO, attributeName, attributeValue, SkeletonKeyMacro | |
| 95 end | |
| 96 | |
| 97 atype['battlepet'] = function(id, name) | |
| 98 return CLICK_KEYBINDER_MACRO, 'battlepet_' .. tostring(name), SLASH_SUMMON_BATTLE_PET1 .. " " .. tostring(name), SkeletonKeyMacro | |
| 99 end | |
| 100 | |
| 101 atype['item'] = function(id, name) | |
| 102 return CLICK_KEYBINDER_KEY, tostring(name), id, SkeletonKeyKey | |
| 103 end | |
| 104 | |
| 105 | |
| 106 --- Resolves the SecureActionButton attribute names used for the given action | |
| 107 kb.RegisterAction = function(actionType, id, name) | |
| 108 assert(atype[actionType], 'Missing actionType handler for `'..tostring(actionType)..'`') | |
| 109 local target, attributeName, attributeValue, button = atype[actionType](id, name) | |
| 110 local command = target .. attributeName | |
| 111 | |
| 112 return attributeName, attributeValue, command, target, button | |
| 113 end | |
| 114 | |
| 115 | |
| 116 | |
| 117 | |
| 118 kb.ApplyTalentBinding = function(talentInfo, cache) | |
| 119 talentInfo.assignedKeys = talentInfo.assignedKeys or {} | |
| 120 for i , key in pairs(talentInfo.assignedKeys) do | |
| 121 local command = CLICK_KEYBINDER_KEY.. talentInfo.actionName | |
| 122 SetBinding(key, command) | |
| 123 cprint(' **', i, '->', command) | |
| 124 tinsert(cache, talentInfo) | |
| 125 end | |
| 126 end | |
| 127 kb.CacheTalentBinding = function(talentInfo, cache) | |
| 128 | |
| 129 local spellID = talentInfo.actionID | |
| 130 cache[spellID] = cache[spellID] or {} | |
| 131 cache[spellID] = talentInfo | |
| 132 cprint(spellID, unpack(kb.TalentBindings[spellID])) | |
| 133 end | |
| 134 | |
| 135 | |
| 136 do | |
| 137 local commandActions = {} | |
| 138 local bindings = kb.bindings | |
| 139 local key, macro = SkeletonKeyKey, SkeletonKeyMacro | |
| 140 kb.LoadBinding = function( configTable) | |
| 141 if configTable.command then | |
| 142 configTable.command = configTable.command:gsub('KeyBinder', 'SkeletonKey') | |
| 143 end | |
| 144 | |
| 145 local command, name, icon, actionType, actionID, macroName, macroText = | |
| 146 configTable.command, configTable.actionName, configTable.iconPath, configTable.actionType, | |
| 147 configTable.actionID, configTable.macroName, configTable.macroText | |
| 148 | |
| 149 | |
| 150 local indexKey = actionType..'_'..actionID | |
| 151 local actionPrefix = "*"..actionType.."-" | |
| 152 local button = SkeletonKeyKey | |
| 153 local isAvailable = true | |
| 154 local specialButtonType | |
| 155 if actionType == 'spell' then | |
| 156 if not GetSpellInfo(actionID) then | |
| 157 isAvailable = nil | |
| 158 end | |
| 159 local dynamicInfo = kb.TalentCache[name] or kb.ProfessionCache[name] | |
| 160 if dynamicInfo then | |
| 161 cprint('|cFF00FFFFDynamicInfo:|r', name) | |
| 162 for k, v in pairs(dynamicInfo) do | |
| 163 cprint(' --', k, v) | |
| 164 configTable[k] = v | |
| 165 end | |
| 166 end | |
| 167 else | |
| 168 if actionType ~= 'macro' then | |
| 169 actionPrefix = '*macrotext-' | |
| 170 end | |
| 171 | |
| 172 specialButtonType = 'macro' | |
| 173 end | |
| 174 | |
| 175 local attributeSuffix, attributeValue, command, target, button = kb.RegisterAction(actionType, actionID, name) | |
| 176 local actionKey = actionPrefix .. attributeSuffix | |
| 177 cprint('|cFF00FF88LoadBinding()|r', button:GetName(), "*type-"..attributeSuffix, actionType, '|cFFFFFF00'..actionKey, attributeValue) | |
| 178 | |
| 179 | |
| 180 | |
| 181 if isAvailable then | |
| 182 kb.SecureAttribute(button, "*type-"..attributeSuffix, specialButtonType or actionType) | |
| 183 kb.SecureAttribute(button, actionKey, attributeValue) | |
| 184 kb.bindings[indexKey] = configTable.assignedKeys | |
| 185 commandActions[command] = kb.bindings[indexKey] | |
| 186 return command, kb.bindings[indexKey] | |
| 187 else | |
| 188 return nil | |
| 189 end | |
| 190 end | |
| 191 | |
| 192 local usedSlots = {} | |
| 193 kb.ApplyBindings = function (profile) | |
| 194 cprint('|cFF0088FFApplyBindings()') | |
| 195 --cprint('binding profile', profile) | |
| 196 | |
| 197 wipe(usedSlots) | |
| 198 for slot, configTable in pairs(profile.buttons) do | |
| 199 | |
| 200 | |
| 201 if #configTable >= 1 then | |
| 202 local command, name, icon, actionType, actionID, macroName, macroText, spellbookSlot, spellbookType = unpack(configTable) | |
| 203 | |
| 204 cprint('|CFFFF4400Fixing pad entry', slot, command, name) | |
| 205 local assignedKeys = {GetBindingKey(command)} | |
| 206 for k,v in pairs(profile.bindings) do | |
| 207 if v == command then | |
| 208 tinsert(assignedKeys, k) | |
| 209 end | |
| 210 end | |
| 211 | |
| 212 configTable = { | |
| 213 command = command, | |
| 214 actionType = actionType, | |
| 215 actionName = name, | |
| 216 actionID = actionID, | |
| 217 macroName = macroName, | |
| 218 macroText = macroText, | |
| 219 iconPath = icon, | |
| 220 spellbookSlot = spellbookSlot, | |
| 221 spellbookType = spellbookType, | |
| 222 assignedKeys = assignedKeys | |
| 223 } | |
| 224 kb.currentProfile.buttons[slot] = configTable | |
| 225 end | |
| 226 if not configTable.actionID then | |
| 227 configTable.actionID = configTable.actionName | |
| 228 end | |
| 229 if not configTable.iconPath then | |
| 230 print('corrected missing icon') | |
| 231 configTable.iconPath = GetSpellTexture(configTable.actionName) | |
| 232 end | |
| 233 | |
| 234 usedSlots[configTable.actionName or configTable.actionID] = true | |
| 235 usedSlots[configTable.command] = true | |
| 236 | |
| 237 if kb.LoadBinding(configTable) then | |
| 238 configTable.isAvailable = true | |
| 239 end | |
| 240 end | |
| 241 | |
| 242 for key, command in pairs(profile.bindings) do | |
| 243 command = command:gsub('KeyBinder', 'SkeletonKey') | |
| 244 profile.bindings[key] = command | |
| 245 cprint('|cFF00FFFF'.. key .. '|r to|cFF00FF00', command) | |
| 246 SetBinding(key, command) | |
| 247 | |
| 248 if commandActions[command] and not tContains(commandActions[command], key) then | |
| 249 tinsert(commandActions[command], key) | |
| 250 end | |
| 251 end | |
| 252 | |
| 253 for spellName, talentInfo in pairs(profile.talents) do | |
| 254 if not usedSlots[spellName] then | |
| 255 cprint('|cFFFF4400Unslotted talent', spellName) | |
| 256 profile.talents[spellName] = nil | |
| 257 end | |
| 258 end | |
| 259 for command in pairs(profile.bound) do | |
| 260 if not usedSlots[command] then | |
| 261 cprint('|cFFFF4400Unslotted bound entry', command) | |
| 262 profile.bound[command] = nil | |
| 263 profile.commands[command] = nil | |
| 264 end | |
| 265 end | |
| 266 for command in pairs(profile.commands) do | |
| 267 if not usedSlots[command] then | |
| 268 cprint('|cFFFF4400Unslotted command entry', command) | |
| 269 profile.commands[command] = nil | |
| 270 end | |
| 271 end | |
| 272 | |
| 273 end | |
| 274 | |
| 275 kb.ApplyAllBindings =function () | |
| 276 cprint('|cFF0088FFApplyAllBindings()') | |
| 277 wipe(kb.TalentBindings) | |
| 278 wipe(kb.bindings) | |
| 279 --kb:print('Loading binding profile', kb.profileName) | |
| 280 | |
| 281 -- reflect action key settings | |
| 282 if GetCVarBool("ActionButtonUseKeyDown") then | |
| 283 SkeletonKeyMacro:RegisterForClicks("AnyDown") | |
| 284 SkeletonKeyKey:RegisterForClicks("AnyDown") | |
| 285 else | |
| 286 SkeletonKeyMacro:RegisterForClicks("AnyUp") | |
| 287 SkeletonKeyKey:RegisterForClicks("AnyUp") | |
| 288 end | |
| 289 | |
| 290 for i, profile in ipairs(kb.orderedProfiles) do | |
| 291 kb.ApplyBindings(profile) | |
| 292 end | |
| 293 -- do this after to ensure that profession binds are properly overridden | |
| 294 kb.UpdateProfessionInfo() | |
| 295 | |
| 296 SaveBindings(GetCurrentBindingSet()) | |
| 297 end | |
| 298 end | |
| 299 | |
| 300 | |
| 301 kb.specInfo = {} | |
| 302 kb.UpdateSpecInfo = function() | |
| 303 kb.specInfo.id = GetSpecialization() | |
| 304 kb.specInfo.globalID, kb.specInfo.name, kb.specInfo.desc, kb.specInfo.texture = GetSpecializationInfo(kb.specInfo.id) | |
| 305 end | |
| 306 | |
| 307 kb.UpdateMacroInfo = function() | |
| 308 print('|cFFFFFF00kb.UpdateMacroInfo()|r') | |
| 309 for index = 1, GetNumMacros() do | |
| 310 local name = GetMacroInfo(index) | |
| 311 kb.SecureAttribute(SkeletonKeyMacro, "*type-macro_"..tostring(name), 'macro') | |
| 312 kb.SecureAttribute(SkeletonKeyMacro, "*macro-macro_"..tostring(name), index) | |
| 313 end | |
| 314 end | |
| 315 | |
| 316 kb.UpdateTalentInfo = function() | |
| 317 print('|cFFFFFF00kb.UpdateTalentInfo()|r') | |
| 318 if kb.talentsPushed then | |
| 319 return | |
| 320 end | |
| 321 wipe(kb.TalentCache) | |
| 322 for row =1, MAX_TALENT_TIERS do | |
| 323 for col = 1, NUM_TALENT_COLUMNS do | |
| 324 local talentID, talentName, icon, selected, available, spellID = GetTalentInfo(row, col, 1) | |
| 325 local talentInfo = kb.TalentCache[spellID] or {} | |
| 326 if spellID then | |
| 327 talentInfo.actionType = 'spell' | |
| 328 talentInfo.actionName = talentName | |
| 329 talentInfo.dynamicType = 'talent' | |
| 330 talentInfo.dynamicID = talentID | |
| 331 talentInfo.dynamicIndex = row | |
| 332 talentInfo.dynamicSubIndex = col | |
| 333 talentInfo.actionID = spellID | |
| 334 talentInfo.isAvailable = selected | |
| 335 kb.TalentCache[spellID] = talentInfo | |
| 336 kb.TalentCache[talentName] = talentInfo | |
| 337 kb.DynamicSpells[spellID] = talentInfo | |
| 338 kb.DynamicSpells[talentName] = talentInfo | |
| 339 end | |
| 340 | |
| 341 --print('Talent ', row, col, spellID, talentName) | |
| 342 end | |
| 343 end | |
| 344 | |
| 345 for row = 1, MAX_PVP_TALENT_TIERS do | |
| 346 for col = 1, MAX_PVP_TALENT_COLUMNS do | |
| 347 local id, name, icon, selected, available, spellID, unlocked = GetPvpTalentInfo(row, col, 1) | |
| 348 if spellID then | |
| 349 local talentInfo = kb.TalentCache[spellID] or {} | |
| 350 talentInfo.actionType = 'spell' | |
| 351 talentInfo.actionName = name | |
| 352 talentInfo.dynamicType = 'talent' | |
| 353 talentInfo.dynamicID = id | |
| 354 talentInfo.actionID = spellID | |
| 355 talentInfo.isAvailable = selected | |
| 356 kb.TalentCache[spellID] = talentInfo | |
| 357 kb.TalentCache[name] = talentInfo | |
| 358 kb.DynamicSpells[spellID] = talentInfo | |
| 359 kb.DynamicSpells[name] = talentInfo | |
| 360 end | |
| 361 end | |
| 362 end | |
| 363 | |
| 364 kb.talentsPushed = true | |
| 365 | |
| 366 kb.UpdateDynamicButtons('talent') | |
| 367 end | |
| 368 | |
| 369 kb.UpdateProfessionInfo = function() | |
| 370 wipe(kb.ProfessionCache) | |
| 371 local profs = {GetProfessions() } | |
| 372 --print(GetProfessions()) | |
| 373 local primaryNum = 0 | |
| 374 for i = 1, 6 do | |
| 375 if profs[i] then | |
| 376 local profID = profs[i] | |
| 377 local profName, texture, _, _, numSpells, spellOffset = GetProfessionInfo(profID) | |
| 378 cprint(i, profID, profName, numSpells, spellOffset) | |
| 379 if not SECONDARY_PROFESSIONS[profID] then | |
| 380 primaryNum = primaryNum + 1 | |
| 381 end | |
| 382 local profNum = SECONDARY_PROFESSIONS[profID] or primaryNum | |
| 383 cprint(i, profNum) | |
| 384 | |
| 385 | |
| 386 kb.ProfessionCache[profNum] = kb.ProfessionCache[profNum] or {} | |
| 387 | |
| 388 for j = 1, numSpells do | |
| 389 local spellName, _, icon, _, _, _, spellID = GetSpellInfo(spellOffset+j, BOOKTYPE_PROFESSION) | |
| 390 cprint(j, spellName) | |
| 391 local profInfo = { | |
| 392 actionType = 'spell', | |
| 393 actionName = spellName, | |
| 394 statusText = 'Profession ' .. i, | |
| 395 actionID = spellID, | |
| 396 iconPath = icon, | |
| 397 dynamicIndex = i, | |
| 398 dynamicSubIndex = j, | |
| 399 dynamicType = 'profession', | |
| 400 spellbookOffset = (spellOffset+j), | |
| 401 spellbookType = BOOKTYPE_PROFESSION, | |
| 402 isAvailable = true, | |
| 403 -- need to check if necessary | |
| 404 uniqueID = profID, | |
| 405 } | |
| 406 | |
| 407 kb.SecureAttribute(SkeletonKeyKey, "*type-profession_"..i .. '_' ..j, "spell") | |
| 408 kb.SecureAttribute(SkeletonKeyKey, "*spell-profession_"..i .. '_' ..j, spellName) | |
| 409 | |
| 410 kb.ProfessionCache[spellName] = profInfo | |
| 411 kb.ProfessionCache[spellID] = profInfo | |
| 412 | |
| 413 kb.DynamicSpells[spellName] = profInfo | |
| 414 kb.DynamicSpells[spellID] = profInfo | |
| 415 | |
| 416 kb.DynamicSpells.profession[i] = kb.DynamicSpells.profession[i] or {} | |
| 417 kb.DynamicSpells.profession[i][j] = profInfo | |
| 418 --print(' |cFF0088FF['..i..']|r|cFFFF44BB['..spellOffset+i..']|r', spellName, "profession_"..i .. '_' ..j) | |
| 419 end | |
| 420 end | |
| 421 | |
| 422 end | |
| 423 | |
| 424 kb.UpdateDynamicButtons('profession') | |
| 425 end | |
| 426 | |
| 427 | |
| 428 | |
| 429 kb.UpdatePetInfo = function() | |
| 430 local hasPetSpells, petType = HasPetSpells() | |
| 431 | |
| 432 -- reconcile saved data if it becomes available | |
| 433 if kb.db then | |
| 434 kb.db.petSpellsDB = kb.db.petSpellsDB or {} | |
| 435 kb.db.petSpellsDB.subtext = kb.db.petSpellsDB.subtext or {} | |
| 436 kb.db.petSpellsDB.spell = kb.db.petSpellsDB.spell or {} | |
| 437 local spellCache = kb.db.petSpellsDB.spell | |
| 438 local subtextCache = kb.db.petSpellsDB.subtext | |
| 439 if petSpellCache then | |
| 440 for k,v in pairs(petSpellCache) do | |
| 441 if not spellCache[k] then | |
| 442 spellCache[k] = v | |
| 443 end | |
| 444 end | |
| 445 end | |
| 446 petSpellCache = spellCache | |
| 447 if petSubtextCache then | |
| 448 for k,v in pairs(petSubtextCache) do | |
| 449 if not subtextCache[k] then | |
| 450 subtextCache[k] = v | |
| 451 end | |
| 452 end | |
| 453 end | |
| 454 petSubtextCache = subtextCache | |
| 455 else | |
| 456 petSpellCache = {} | |
| 457 petSubtextCache = {} | |
| 458 end | |
| 459 | |
| 460 if PetHasSpellbook() then | |
| 461 --print('PET SPELLBOOK') | |
| 462 local spellbookOffset = 1 | |
| 463 local specialNum = {} | |
| 464 local newSubtextItems = false | |
| 465 | |
| 466 repeat | |
| 467 | |
| 468 local spellType, spellID = GetSpellBookItemInfo(spellbookOffset, BOOKTYPE_PET) | |
| 469 local spellName, subText = GetSpellBookItemName(spellbookOffset, BOOKTYPE_PET) | |
| 470 local texture = GetSpellBookItemTexture(spellbookOffset, BOOKTYPE_PET) | |
| 471 if (spellType == 'SPELL') and (not IsPassiveSpell(spellbookOffset, BOOKTYPE_PET)) then | |
| 472 local info = kb.PetCache[spellName] or {} | |
| 473 kb.PetCache.spellslot[spellName] = {spellbookOffset, spellName, subText, spellID, texture} | |
| 474 --print('|cFF00FF88spellslot['..spellName..']|r', '=>', i, subText) | |
| 475 | |
| 476 if subText then | |
| 477 kb.PetCache.subtext[subText] = kb.PetCache.subtext[subText] or {} | |
| 478 specialNum[subText] = (specialNum[subText] or 0) + 1 | |
| 479 | |
| 480 petSpellCache[spellName] = subText | |
| 481 petSubtextCache[subText] = petSubtextCache[subText] or {} | |
| 482 | |
| 483 -- add to the list | |
| 484 if not petSubtextCache[subText][spellName] then | |
| 485 petSubtextCache[subText][spellName] = true | |
| 486 newSubtextItems = true | |
| 487 --print('|cFF00FFFFspecial['..spellName..']|r', '\n','|cFF00FFFFsubtext['..subText..']['..specialNum[subText]..']|r', '=>', i, spellName, subText, spellID, texture, specialNum[subText]) | |
| 488 end | |
| 489 | |
| 490 | |
| 491 | |
| 492 local entry = {spellbookOffset, spellName, subText, spellID, texture, specialNum[subText] } | |
| 493 | |
| 494 | |
| 495 info.spellbookOffset = spellbookOffset | |
| 496 info.spellbookType = BOOKTYPE_PET | |
| 497 info.actionName = spellName | |
| 498 info.spellID = spellID | |
| 499 info.dynamicType = 'petaction' | |
| 500 info.dynamicID = spellID | |
| 501 info.dynamicIndex = subText | |
| 502 info.dynamicSubIndex = specialNum[subText] | |
| 503 info.isAvailable = true | |
| 504 | |
| 505 kb.PetCache.special[spellName] = info | |
| 506 kb.PetCache.subtext[subText][specialNum[subText]] = info | |
| 507 kb.DynamicSpells[spellName] = info | |
| 508 kb.DynamicSpells[spellID] = info | |
| 509 | |
| 510 end | |
| 511 | |
| 512 if spellID then | |
| 513 kb.PetCache.spell[spellbookOffset] = {spellID, spellName, subText} | |
| 514 --print('|cFF0088FFspell['..i..']|r', '=>', spellID, spellName, subText) | |
| 515 end | |
| 516 | |
| 517 kb.PetCache[spellName] = info | |
| 518 end | |
| 519 | |
| 520 spellbookOffset = spellbookOffset + 1 | |
| 521 until spellType == nil | |
| 522 | |
| 523 if newSubtextItems then | |
| 524 | |
| 525 local macrotext = "" | |
| 526 for subText, spells in pairs(petSubtextCache) do | |
| 527 if specialNum[subText] then | |
| 528 for spellName, enabled in pairs(spells) do | |
| 529 macrotext = macrotext .. "/cast " .. spellName .. "\n" | |
| 530 end | |
| 531 kb.SecureAttribute(SkeletonKeyMacro, "*macrotext-petaction_"..subText.."_"..specialNum[subText], macrotext) | |
| 532 end | |
| 533 end | |
| 534 end | |
| 535 | |
| 536 | |
| 537 else | |
| 538 --print('NO PET SPELLBOOK') | |
| 539 wipe(kb.PetCache.spell) | |
| 540 wipe(kb.PetCache.spellslot) | |
| 541 end | |
| 542 | |
| 543 if PetHasActionBar() then | |
| 544 --print('PET ACTION BAR') | |
| 545 for i = 1, 10 do | |
| 546 | |
| 547 | |
| 548 local name, subtext, texture, isToken, isActive = GetPetActionInfo(i) | |
| 549 if name then | |
| 550 kb.PetCache.action[i] = {name, subtext, texture, isToken, isActive } | |
| 551 | |
| 552 | |
| 553 end | |
| 554 --print('|cFFFFFF00action['..i..']|r', name, subtext, texture) | |
| 555 end | |
| 556 else | |
| 557 --print('NO PET ACTION BAR') | |
| 558 wipe(kb.PetCache.action) | |
| 559 end | |
| 560 | |
| 561 kb.UpdateDynamicButtons('petaction') | |
| 562 | |
| 563 end | |
| 564 | |
| 565 kb.UpdateSystemBinds = function() | |
| 566 wipe(kb.SystemBindings) | |
| 567 local n = GetNumBindings() | |
| 568 for i=1, n do | |
| 569 local command, key1, key2 = GetBinding(i) | |
| 570 if not command:match('ACTION.*%d+') then | |
| 571 if key1 then | |
| 572 kb.SystemBindings[key1] = command | |
| 573 end | |
| 574 if key2 then | |
| 575 kb.SystemBindings[key2] = command | |
| 576 end | |
| 577 else | |
| 578 --print('ignoring action button binding', command) | |
| 579 end | |
| 580 end | |
| 581 end | |
| 582 | |
| 583 kb.UpdateDynamicButtons = function(dynamicType) | |
| 584 for i, button in ipairs(kb.buttons) do | |
| 585 if button.isDynamic == dynamicType then | |
| 586 kb.UpdateSlot(button, true) | |
| 587 end | |
| 588 end | |
| 589 end | |
| 590 | |
| 591 kb.pendingAttributes = {} | |
| 592 kb.SecureAttribute = function(target, name, value) | |
| 593 if InCombatLockdown() then | |
| 594 if #kb.pendingAttributes == 0 then | |
| 595 kb:print(kb.L('Key bindings will be applied when you exit combat.')) | |
| 596 end | |
| 597 | |
| 598 tinsert(kb.pendingAttributes, {target, name, value}) | |
| 599 SkeletonKey:RegisterEvent('PLAYER_REGEN_ENABLED') | |
| 600 | |
| 601 else | |
| 602 | |
| 603 --cprint('|cFFFF4444' .. target:GetName()..'|r.|cFFFFFF00'.. tostring(name)..'|r = "'..tostring(value)..'"') | |
| 604 target:SetAttribute(name, value) | |
| 605 end | |
| 606 end | |
| 607 | |
| 608 kb.PLAYER_REGEN_ENABLED = function() | |
| 609 if #kb.pendingAttributes >= 1 then | |
| 610 local args = tremove(kb.pendingAttributes) | |
| 611 while args do | |
| 612 local target, name, value = unpack(args) | |
| 613 --print(target:GetName(), 'attribute', '"'.. tostring(name)..'" = "'..tostring(value)..'"') | |
| 614 cprint('deferred', target:GetName(), 'attribute', '"'.. tostring(name)..'" = "'..tostring(value)..'"') | |
| 615 target:SetAttribute(name, value) | |
| 616 args = tremove(kb.pendingAttributes) | |
| 617 end | |
| 618 end | |
| 619 | |
| 620 if #kb.pendingCalls >= 1 then | |
| 621 | |
| 622 local func = tremove(kb.pendingCalls) | |
| 623 while func do | |
| 624 func() | |
| 625 end | |
| 626 end | |
| 627 end | |
| 628 | |
| 629 kb.UpdateBindingsCache = function(actionType, actionID, bindings) | |
| 630 local indexKey = actionType .. '_' .. actionID | |
| 631 kb.bindings[indexKey] = bindings | |
| 632 | |
| 633 cprint('|cFF00FF00'..indexKey..'|r = {'.. table.concat(bindings,', ').. '}') | |
| 634 tinsert(kb.ChangedBindings, {actionType, actionID}) | |
| 635 end |
