--[[-------------------------------------------------------------------- Ovale Spell Priority Copyright (C) 2012 Sidoine Copyright (C) 2012, 2013, 2014 Johnny C. Lam This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License in the LICENSE file accompanying this program. --]]-------------------------------------------------------------------- -- Keep data about the player action bars (key bindings mostly) local _, Ovale = ... local OvaleActionBar = Ovale:NewModule("OvaleActionBar", "AceEvent-3.0") Ovale.OvaleActionBar = OvaleActionBar --<private-static-properties> -- Profiling set-up. local Profiler = Ovale.Profiler local profiler = nil do local group = OvaleActionBar:GetName() Profiler:RegisterProfilingGroup(group) profiler = Profiler:GetProfilingGroup(group) end local gsub = string.gsub local strmatch = string.match local tonumber = tonumber local wipe = table.wipe local API_GetActionInfo = GetActionInfo local API_GetActionText = GetActionText local API_GetBindingKey = GetBindingKey local API_GetBonusBarIndex = GetBonusBarIndex local API_GetMacroItem = GetMacroItem local API_GetMacroSpell = GetMacroSpell local OVALE_ACTIONBAR_DEBUG = "action_bar" --</private-static-properties> --<public-static-properties> -- Maps each action slot (1..120) to the current action: action[slot] = action OvaleActionBar.action = {} -- Maps each action slot (1..120) to its current keybind: keybind[slot] = keybind OvaleActionBar.keybind = {} -- Maps each spell/macro/item ID to its current action slot. -- spell[spellId] = slot OvaleActionBar.spell = {} -- macro[macroName] = slot OvaleActionBar.macro = {} -- item[itemId] = slot OvaleActionBar.item = {} --</public-static-properties> --<private-static-methods> local function GetKeyBinding(slot) --[[ ACTIONBUTTON1..12 => primary (1..12, 13..24), bonus (73..120) MULTIACTIONBAR1BUTTON1..12 => bottom left (61..72) MULTIACTIONBAR2BUTTON1..12 => bottom right (49..60) MULTIACTIONBAR3BUTTON1..12 => top right (25..36) MULTIACTIONBAR4BUTTON1..12 => top left (37..48) --]] local name if slot <= 24 or slot > 72 then name = "ACTIONBUTTON" .. (((slot - 1)%12) + 1) elseif slot <= 36 then name = "MULTIACTIONBAR3BUTTON" .. (slot - 24) elseif slot <= 48 then name = "MULTIACTIONBAR4BUTTON" .. (slot - 36) elseif slot <= 60 then name = "MULTIACTIONBAR2BUTTON" .. (slot - 48) else name = "MULTIACTIONBAR1BUTTON" .. (slot - 60) end local key = name and API_GetBindingKey(name) return key end local function ParseHyperlink(hyperlink) local color, linkType, linkData, text = strmatch(hyperlink, "|?c?f?f?(%x*)|?H?([^:]*):?(%d+)|?h?%[?([^%[%]]*)%]?|?h?|?r?") return color, linkType, linkData, text end --</private-static-methods> --<public-static-methods> function OvaleActionBar:OnEnable() self:RegisterEvent("ACTIONBAR_SLOT_CHANGED") self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED", "UpdateActionSlots") self:RegisterEvent("PLAYER_ENTERING_WORLD", "UpdateActionSlots") self:RegisterEvent("PLAYER_TALENT_UPDATE", "UpdateActionSlots") self:RegisterEvent("UPDATE_BINDINGS") self:RegisterEvent("UPDATE_BONUS_ACTIONBAR", "UpdateActionSlots") end function OvaleActionBar:OnDisable() self:UnregisterEvent("ACTIONBAR_SLOT_CHANGED") self:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED") self:UnregisterEvent("PLAYER_ENTERING_WORLD") self:UnregisterEvent("PLAYER_TALENT_UPDATE") self:UnregisterEvent("UPDATE_BINDINGS") self:UnregisterEvent("UPDATE_BONUS_ACTIONBAR") end function OvaleActionBar:ACTIONBAR_SLOT_CHANGED(event, slot) slot = tonumber(slot) if slot == 0 then self:UpdateActionSlots(event) elseif slot then self:UpdateActionSlot(slot) end end function OvaleActionBar:UPDATE_BINDINGS(event) Ovale:DebugPrintf(OVALE_ACTIONBAR_DEBUG, "%s: Updating key bindings.", event) self:UpdateKeyBindings() end function OvaleActionBar:UpdateActionSlots(event) profiler.Start("OvaleActionBar_UpdateActionSlots") Ovale:DebugPrintf(OVALE_ACTIONBAR_DEBUG, "%s: Updating all action slot mappings.", event) wipe(self.action) wipe(self.item) wipe(self.macro) wipe(self.spell) local start = 1 local bonus = tonumber(API_GetBonusBarIndex()) * 12 if bonus > 0 then start = 13 for slot = bonus - 11, bonus do self:UpdateActionSlot(slot) end end for slot = start, 72 do self:UpdateActionSlot(slot) end profiler.Stop("OvaleActionBar_UpdateActionSlots") end function OvaleActionBar:UpdateActionSlot(slot) profiler.Start("OvaleActionBar_UpdateActionSlot") -- Clear old slot and associated actions. local action = self.action[slot] if self.spell[action] == slot then self.spell[action] = nil elseif self.item[action] == slot then self.item[action] = nil elseif self.macro[action] == slot then self.macro[action] = nil end self.action[slot] = nil -- Map the current action in the slot. local actionType, id, subType = API_GetActionInfo(slot) if actionType == "spell" then id = tonumber(id) if id then if not self.spell[id] or slot < self.spell[id] then self.spell[id] = slot end self.action[slot] = id end elseif actionType == "item" then id = tonumber(id) if id then if not self.item[id] or slot < self.item[id] then self.item[id] = slot end self.action[slot] = id end elseif actionType == "macro" then id = tonumber(id) if id then local actionText = API_GetActionText(slot) if actionText then if not self.macro[actionText] or slot < self.macro[actionText] then self.macro[actionText] = slot end local _, _, spellId = API_GetMacroSpell(id) if spellId then if not self.spell[spellId] or slot < self.spell[spellId] then self.spell[spellId] = slot end self.action[slot] = spellId else local _, hyperlink = API_GetMacroItem(id) if hyperlink then local _, _, linkData = ParseHyperlink(hyperlink) local itemId = gsub(linkData, ":.*", "") itemId = tonumber(itemId) if itemId then if not self.item[itemId] or slot < self.item[itemId] then self.item[itemId] = slot end self.action[slot] = itemId end end end if not self.action[slot] then self.action[slot] = actionText end end end end Ovale:DebugPrintf(OVALE_ACTIONBAR_DEBUG, "Mapping button %s to %s", slot, self.action[slot]) -- Update the keybind for the slot. self.keybind[slot] = GetKeyBinding(slot) profiler.Stop("OvaleActionBar_UpdateActionSlot") end function OvaleActionBar:UpdateKeyBindings() profiler.Start("OvaleActionBar_UpdateKeyBindings") for slot = 1, 120 do self.keybind[slot] = GetKeyBinding(slot) end profiler.Stop("OvaleActionBar_UpdateKeyBindings") end -- Get the action slot that matches a spell ID. function OvaleActionBar:GetForSpell(spellId) return self.spell[spellId] end -- Get the action slot that matches a macro name. function OvaleActionBar:GetForMacro(macroName) return self.macro[macroName] end -- Get the action slot that matches an item ID. function OvaleActionBar:GetForItem(itemId) return self.item[itemId] end -- Get the keybinding for an action slot. function OvaleActionBar:GetBinding(slot) return self.keybind[slot] end --</public-static-methods>