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