Nenue@16: -- SkeletonKey Nenue@16: -- ActionTypes.lua Nenue@16: -- Created: 7/29/2016 9:14 PM Nenue@16: -- %file-revision% Nenue@16: -- Nenue@16: local kb, print, wrap = LibStub('LibKraken').register(KeyBinder) Nenue@17: local cprint = DEVIAN_WORKSPACE and function(...) _G.print('Cfg', ...) end or function() end Nenue@16: Nenue@16: local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544 Nenue@17: local CLICK_KEYBINDER_MACRO = "CLICK KeyBinderMacro:" Nenue@17: local CLICK_KEYBINDER_KEY = "CLICK KeyBinderKey:" Nenue@16: Nenue@16: local PETACTION_SCRIPT = { Nenue@16: [PET_ACTION_MOVE_TO] = {SLASH_PET_MOVE_TO1, 'pet_move_to'}, Nenue@16: [PET_ACTION_ATTACK] = {SLASH_PET_ATTACK1, 'pet_attack'}, Nenue@16: [PET_ACTION_FOLLOW] = {SLASH_PET_FOLLOW1, 'pet_follow'}, Nenue@16: [PET_ACTION_WAIT] = {SLASH_PET_STAY1, 'pet_stay'}, Nenue@16: [PET_MODE_AGGRESSIVE] = {SLASH_PET_AGGRESSIVE1, 'pet_aggressive'}, Nenue@16: [PET_MODE_DEFENSIVE] = {SLASH_PET_DEFENSIVE1, 'pet_defensive'}, Nenue@16: [PET_MODE_PASSIVE] = {SLASH_PET_PASSIVE1, 'pet_passive'}, Nenue@16: [PET_MODE_ASSIST] = {SLASH_PET_ASSIST1, 'pet_assist'}, Nenue@16: } Nenue@16: Nenue@19: kb.ActionTypes = {} Nenue@19: kb.PetCache = {} Nenue@19: kb.TalentCache = {} Nenue@19: kb.ProfessionCache = {} Nenue@19: Nenue@19: local atype = kb.ActionTypes Nenue@19: Nenue@17: --- Caps Lock Nenue@19: atype['mount'] = function(id, name) Nenue@17: if id == SUMMON_RANDOM_FAVORITE_MOUNT_SPELL then Nenue@17: return 'mount_random', "/script C_MountJournal.SummonByID(0)", CLICK_KEYBINDER_MACRO Nenue@17: else Nenue@17: return 'mount_'..id, "/script C_MountJournal.SummonByID("..id..")", CLICK_KEYBINDER_MACRO Nenue@17: end Nenue@16: end Nenue@19: Nenue@19: atype['macro'] = function(id, name) Nenue@17: return CLICK_KEYBINDER_MACRO, 'macro_' .. tostring(name), id Nenue@17: end Nenue@19: Nenue@19: atype['equipset'] = function(id, name) Nenue@17: return CLICK_KEYBINDER_MACRO, 'equipset_'..tostring(name), "/script UseEquipmentSet("..tostring(id)..")" Nenue@17: end Nenue@19: Nenue@19: atype['spell'] = function(id, name) Nenue@17: local attributeName = name Nenue@17: if kb.ProfessionCache[id] then Nenue@17: attributeName = "profession_".. kb.ProfessionCache[id].profOffset .. '_' .. kb.ProfessionCache[id].spellNum Nenue@17: end Nenue@17: return CLICK_KEYBINDER_KEY, attributeName, name Nenue@17: end Nenue@19: Nenue@19: atype['petaction'] = function(_, name) Nenue@17: -- ID doesn't exist for basic commands, even though they can be picked up Nenue@17: local attributeName, attributeValue = "petaction_" .. tostring(name), "/cast "..tostring(name) Nenue@17: if PETACTION_SCRIPT[name] then Nenue@17: attributeValue, attributeName = unpack(PETACTION_SCRIPT[name]) Nenue@19: elseif kb.PetCache.special[name] then Nenue@19: attributeName = "petaction_special" .. tonumber(kb.PetCache.special[name][2]) Nenue@17: end Nenue@17: return CLICK_KEYBINDER_MACRO, attributeName, attributeValue Nenue@16: end Nenue@16: Nenue@19: atype['battlepet'] = function(id, name) Nenue@17: return CLICK_KEYBINDER_MACRO, 'battlepet_' .. tostring(name), SLASH_SUMMON_BATTLE_PET1 .. " " .. tostring(name) Nenue@17: end Nenue@19: Nenue@19: atype['item'] = function(id, name) Nenue@17: return CLICK_KEYBINDER_KEY, 'item_' .. tostring(name), id Nenue@17: end Nenue@16: Nenue@16: Nenue@17: --- Resolves the SecureActionButton attribute names used for the given action Nenue@16: kb.RegisterAction = function(actionType, id, name) Nenue@16: Nenue@19: assert(atype[actionType], 'Missing actionType handler for `'..tostring(actionType)..'`') Nenue@19: local target, attributeName, attributeValue = atype[actionType](id, name) Nenue@17: Nenue@17: local command = target .. attributeName Nenue@17: local baseName, iterative = attributeName, 1 Nenue@17: while (kb.macros[attributeName] and kb.macros[attributeName][1] ~= attributeValue) do Nenue@17: print(' * cannot use|cFF00FF00', attributeName, '|r"'.. tostring(kb.macros[attributeName][1]) .. '"') Nenue@17: attributeName = baseName .. '_' .. iterative Nenue@17: iterative = iterative + 1 Nenue@17: end Nenue@17: if macroName ~= baseName then Nenue@17: print(' * Creating|cFF00FF00', macroName) Nenue@17: else Nenue@17: print(' * Re-using|cFF00FF00', macroName) Nenue@17: end Nenue@17: kb.macros[attributeName] = {attributeValue, command} Nenue@17: Nenue@17: Nenue@17: print('RegisterAction', actionType, id, '->', attributeName, attributeValue, target .. attributeName) Nenue@17: return attributeName, attributeValue, command Nenue@17: end Nenue@17: Nenue@17: Nenue@17: Nenue@17: Nenue@17: kb.ApplyTalentBinding = function(talentInfo, cache) Nenue@17: for i = 5, #talentInfo do Nenue@17: local command = CLICK_KEYBINDER_KEY.. talentInfo[2] Nenue@17: SetBinding(talentInfo[i], command) Nenue@17: cprint(' **', talentInfo[i], '->', command) Nenue@17: tinsert(cache, talentInfo[i]) Nenue@17: end Nenue@17: end Nenue@17: kb.CacheTalentBinding = function(talentInfo, cache) Nenue@17: Nenue@17: local spellID = talentInfo[4] Nenue@19: cache[spellID] = cache[spellID] or {} Nenue@19: cache[spellID] = {select(5,unpack(talentInfo)) } Nenue@19: --cprint(spellID, unpack(kb.TalentBindings[spellID])) Nenue@17: end Nenue@17: Nenue@17: do Nenue@17: local bindings = kb.bindings Nenue@17: local key, macro = KeyBinderKey, KeyBinderMacro Nenue@17: kb.LoadBinding = function(command, name, icon, actionType, actionID, macroName, macroText ) Nenue@17: Nenue@17: if actionType == 'spell' then Nenue@17: key:SetAttribute("*type-"..name, actionType) Nenue@17: key:SetAttribute("*"..actionType.."-"..name, name) Nenue@17: elseif actionType == 'item' then Nenue@17: key:SetAttribute("*type-"..name, actionType) Nenue@17: key:SetAttribute("*"..actionType.."-"..name, name) Nenue@17: elseif actionType == 'macro' then Nenue@17: macro:SetAttribute("*macro-"..macroName, actionID) Nenue@16: else Nenue@17: macro:SetAttribute("*macrotext-"..macroName, macroText) Nenue@16: end Nenue@16: Nenue@17: cprint('Loading binding', actionType, actionID) Nenue@17: bindings[actionType] = bindings[actionType] or {} Nenue@17: bindings[actionType][actionID] = bindings[actionType][actionID] or {} Nenue@17: bindings[command] = bindings[actionType][actionID] Nenue@17: return bindings[actionType], actionID Nenue@16: end Nenue@16: Nenue@17: kb.ApplyBindings = function (profile) Nenue@17: cprint('binding profile', profile) Nenue@17: for slot, data in pairs(profile.buttons) do Nenue@17: kb.LoadBinding(unpack(data)) Nenue@17: end Nenue@17: Nenue@17: for key, command in pairs(profile.bindings) do Nenue@17: Nenue@17: cprint(' *', key, '->', command) Nenue@17: Nenue@17: --_G.print('HotKey','loading', key, command) Nenue@17: SetBinding(key, command) Nenue@17: if bindings[command] and not tContains(bindings[command], key) then Nenue@17: tinsert(bindings[command], key) Nenue@17: end Nenue@17: end Nenue@17: Nenue@17: for spellName, talentInfo in pairs(profile.talents) do Nenue@17: local dummy = GetSpellInfo(spellName) Nenue@17: local func = kb.CacheTalentBinding Nenue@19: local dest = kb.TalentBindings Nenue@17: if dummy then Nenue@17: cprint('|cFFBBFF00Active:|r', dummy) Nenue@17: local macroName, spellName, actionType, actionID = unpack(talentInfo) Nenue@17: bindings[actionType] = bindings[actionType] or {} Nenue@17: bindings[actionType][actionID] = {} Nenue@17: func = kb.ApplyTalentBinding Nenue@17: dest = kb.bindings[actionType][actionID] Nenue@17: else Nenue@17: Nenue@17: cprint('|cFFFF4400Inactive:|r', talentInfo[2]) Nenue@17: end Nenue@17: func(talentInfo, dest) Nenue@17: end Nenue@17: Nenue@17: end Nenue@17: Nenue@17: kb.ApplyAllBindings =function () Nenue@19: table.wipe(kb.TalentBindings) Nenue@17: Nenue@17: Nenue@17: -- reflect action key settings Nenue@17: if GetCVarBool("ActionButtonUseKeyDown") then Nenue@17: KeyBinderMacro:RegisterForClicks("AnyDown") Nenue@17: KeyBinderKey:RegisterForClicks("AnyDown") Nenue@17: else Nenue@17: KeyBinderMacro:RegisterForClicks("AnyUp") Nenue@17: KeyBinderKey:RegisterForClicks("AnyUp") Nenue@17: end Nenue@17: Nenue@17: for i, profile in ipairs(kb.orderedProfiles) do Nenue@17: kb.ApplyBindings(profile) Nenue@17: end Nenue@17: -- do this after to ensure that profession binds are properly overridden Nenue@17: kb.UpdateProfessionInfo() Nenue@17: Nenue@17: Nenue@17: SaveBindings(GetCurrentBindingSet()) Nenue@17: end Nenue@19: end Nenue@19: Nenue@19: Nenue@19: local PET_SPECIAL_SUBTEXT = 'Special Ability' Nenue@19: local SECONDARY_PROFESSIONS = { Nenue@19: [5] = 3, Nenue@19: [7] = 4, Nenue@19: [9] = 5, Nenue@19: [10] = 6 Nenue@19: } Nenue@19: Nenue@19: kb.TalentCache = {} Nenue@19: kb.ProfessionCache = {} Nenue@19: kb.PetCache = {} Nenue@19: kb.specInfo = {} Nenue@19: kb.UpdateSpecInfo = function() Nenue@19: kb.specInfo.id = GetSpecialization() Nenue@19: kb.specInfo.globalID, kb.specInfo.name, kb.specInfo.desc, kb.specInfo.texture = GetSpecializationInfo(kb.specInfo.id) Nenue@19: print('|cFF00FF00current spec:|r', kb.specInfo.id, 'of', GetNumSpecializations()) Nenue@19: end Nenue@19: Nenue@19: kb.UpdateTalentInfo = function() Nenue@19: if kb.talentsPushed then Nenue@19: return Nenue@19: end Nenue@19: table.wipe(kb.TalentCache) Nenue@19: for row =1, MAX_TALENT_TIERS do Nenue@19: for col = 1, NUM_TALENT_COLUMNS do Nenue@19: local talentID, talentName, icon, selected, available, spellID = GetTalentInfo(row, col, 1) Nenue@19: local talentInfo = kb.TalentCache[spellID] or {} Nenue@19: talentInfo.row = 1 Nenue@19: talentInfo.col = col Nenue@19: talentInfo.name = talentName Nenue@19: talentInfo.talentID = talentID Nenue@19: talentInfo.selected = selected Nenue@19: talentInfo.available = available Nenue@19: talentInfo.spellID = spellID Nenue@19: kb.TalentCache[spellID] = talentInfo Nenue@19: kb.TalentCache[talentName] = talentInfo Nenue@19: print('Talent ', row, col, spellID, talentName) Nenue@19: end Nenue@19: end Nenue@19: kb.talentsPushed = true Nenue@19: Nenue@19: kb.UpdateDynamicButtons('talent') Nenue@19: end Nenue@19: Nenue@19: kb.UpdateProfessionInfo = function() Nenue@19: table.wipe(kb.ProfessionCache) Nenue@19: local profs = {GetProfessions() } Nenue@19: local primaryNum = 0 Nenue@19: for i, index in ipairs(profs) do Nenue@19: local profName, texture, rank, maxRank, numSpells, spellOffset = GetProfessionInfo(index) Nenue@19: print(i, index, profName, numSpells, spellOffset) Nenue@19: if not SECONDARY_PROFESSIONS[index] then Nenue@19: primaryNum = primaryNum + 1 Nenue@19: end Nenue@19: local profNum = SECONDARY_PROFESSIONS[index] or primaryNum Nenue@19: Nenue@19: Nenue@19: kb.ProfessionCache[profNum] = kb.ProfessionCache[i] or {} Nenue@19: Nenue@19: for j = 1, numSpells do Nenue@19: local spellName, _, icon, _, _, _, spellID = GetSpellInfo(spellOffset+j, BOOKTYPE_PROFESSION) Nenue@19: Nenue@19: local profInfo = { Nenue@19: spellName = spellName, Nenue@19: spellID = spellID, Nenue@19: icon = icon, Nenue@19: profOffset = i, Nenue@19: profIndex = index, Nenue@19: spellOffset = (spellOffset+j), Nenue@19: spellNum = j Nenue@19: } Nenue@19: KeyBinderKey:SetAttribute("*type-profession_"..i .. '_' ..j, "spell") Nenue@19: KeyBinderKey:SetAttribute("*spell-profession_"..i .. '_' ..j, spellName) Nenue@19: Nenue@19: kb.ProfessionCache[i .. '_' .. j] = profInfo Nenue@19: kb.ProfessionCache[spellName] = profInfo Nenue@19: kb.ProfessionCache[spellID] = profInfo Nenue@19: print(' |cFF0088FF['..i..']|r|cFFFF44BB['..spellOffset+i..']|r', spellName, "profession_"..i .. '_' ..j) Nenue@19: end Nenue@19: Nenue@19: end Nenue@19: Nenue@19: kb.UpdateDynamicButtons('profession') Nenue@19: end Nenue@19: Nenue@19: Nenue@19: Nenue@19: kb.UpdatePetInfo = function() Nenue@19: kb.PetCache.spell = kb.PetCache.spell or {} Nenue@19: kb.PetCache.spellslot = kb.PetCache.spellslot or {} Nenue@19: kb.PetCache.action = kb.PetCache.action or {} Nenue@19: kb.PetCache.special = kb.PetCache.action or {} Nenue@19: local hasPetSpells, petType = HasPetSpells() Nenue@19: if PetHasSpellbook() then Nenue@19: print('PET SPELLBOOK') Nenue@19: local i = 1 Nenue@19: local specialNum = 0 Nenue@19: repeat Nenue@19: Nenue@19: local spellType, spellID = GetSpellBookItemInfo(i, BOOKTYPE_PET) Nenue@19: local spellName, subText = GetSpellBookItemName(i, BOOKTYPE_PET) Nenue@19: local isPassive = IsPassiveSpell(i, BOOKTYPE_PET) Nenue@19: if not isPassive then Nenue@19: if spellName then Nenue@19: kb.PetCache.spellslot[spellName] = {i, spellName, subText} Nenue@19: print('|cFF00FF88spellslot['..spellName..']|r', '=>', i, subText) Nenue@19: Nenue@19: if subText == PET_SPECIAL_SUBTEXT then Nenue@19: specialNum = specialNum + 1 Nenue@19: kb.PetCache.special[spellName] = {i, specialNum, spellID, subText } Nenue@19: print('|cFF00FFFFspecial['..spellName..']|r', '=>', i, specialNum, spellID, subText) Nenue@19: KeyBinderMacro:SetAttribute("*macrotext-pet_special_"..specialNum, "/cast "..spellName) Nenue@19: end Nenue@19: Nenue@19: if spellID then Nenue@19: kb.PetCache.spell[i] = {spellID, spellName, subText} Nenue@19: print('|cFF0088FFspell['..i..']|r', '=>', spellID, spellName, subText) Nenue@19: end Nenue@19: end Nenue@19: Nenue@19: Nenue@19: end Nenue@19: Nenue@19: i = i + 1 Nenue@19: until spellType == nil Nenue@19: else Nenue@19: print('NO PET SPELLBOOK') Nenue@19: table.wipe(kb.PetCache.spell) Nenue@19: table.wipe(kb.PetCache.spellslot) Nenue@19: end Nenue@19: Nenue@19: if PetHasActionBar() then Nenue@19: print('PET ACTION BAR') Nenue@19: for i = 1, 10 do Nenue@19: Nenue@19: Nenue@19: local name, subtext, texture, isToken, isActive = GetPetActionInfo(i) Nenue@19: if name then Nenue@19: kb.PetCache.action[i] = {name, subtext, texture, isToken, isActive } Nenue@19: Nenue@19: Nenue@19: end Nenue@19: print('|cFFFFFF00action['..i..']|r', name, subtext, texture) Nenue@19: end Nenue@19: else Nenue@19: print('NO PET ACTION BAR') Nenue@19: table.wipe(kb.PetCache.action) Nenue@19: end Nenue@19: Nenue@19: kb.UpdateDynamicButtons('petaction') Nenue@19: Nenue@19: end Nenue@19: Nenue@19: kb.UpdateSystemBinds = function() Nenue@19: table.wipe(kb.SystemBindings) Nenue@19: local n = GetNumBindings() Nenue@19: for i=1, n do Nenue@19: local command, key1, key2 = GetBinding(i) Nenue@19: if key1 then Nenue@19: kb.SystemBindings[key1] = command Nenue@19: end Nenue@19: if key2 then Nenue@19: kb.SystemBindings[key2] = command Nenue@19: end Nenue@19: end Nenue@19: end Nenue@19: Nenue@19: kb.UpdateDynamicButtons = function(dynamicType) Nenue@19: for i, button in ipairs(kb.buttons) do Nenue@19: if button.isDynamic == dynamicType then Nenue@19: kb.UpdateSlot(button, true) Nenue@19: end Nenue@19: end Nenue@16: end