flickerstreak@134: local ReAction = ReAction flickerstreak@134: local L = ReAction.L flickerstreak@134: local _G = _G flickerstreak@134: local CreateFrame = CreateFrame flickerstreak@134: local format = string.format flickerstreak@134: local GetCVar = GetCVar flickerstreak@134: local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor flickerstreak@134: local CooldownFrame_SetTimer = CooldownFrame_SetTimer flickerstreak@134: local InCombatLockdown = InCombatLockdown flickerstreak@134: local GetNumShapeshiftForms = GetNumShapeshiftForms flickerstreak@134: local GetShapeshiftFormInfo = GetShapeshiftFormInfo flickerstreak@134: local IsUsableSpell = IsUsableSpell flickerstreak@134: local GetSpellInfo = GetSpellInfo flickerstreak@134: flickerstreak@134: ReAction:UpdateRevision("$Revision: 154 $") flickerstreak@134: flickerstreak@134: -- flickerstreak@134: -- private flickerstreak@134: -- flickerstreak@134: local playerClass = select(2,UnitClass("player")) flickerstreak@134: flickerstreak@134: local aspects = { flickerstreak@134: -- All rank one, so that the usable check works flickerstreak@134: GetSpellInfo(13163), -- monkey flickerstreak@134: GetSpellInfo(13165), -- hawk flickerstreak@134: GetSpellInfo(5118), -- cheetah flickerstreak@134: GetSpellInfo(34074), -- viper flickerstreak@134: GetSpellInfo(13161), -- beast flickerstreak@134: GetSpellInfo(13159), -- pack flickerstreak@134: GetSpellInfo(20043), -- wild flickerstreak@134: GetSpellInfo(61846), -- dragonhawk flickerstreak@134: } flickerstreak@134: flickerstreak@134: local aspectLinks = { } flickerstreak@134: flickerstreak@134: local eventList = { flickerstreak@134: "PLAYER_REGEN_ENABLED", flickerstreak@134: "PLAYER_ENTERING_WORLD", flickerstreak@134: "UPDATE_SHAPESHIFT_FORM", flickerstreak@134: "UPDATE_SHAPESHIFT_FORMS", flickerstreak@134: "UPDATE_SHAPESHIFT_USABLE", flickerstreak@134: "UPDATE_SHAPESHIFT_COOLDOWN", flickerstreak@134: -- "UPDATE_INVENTORY_ALERTS" -- WTF? flickerstreak@134: } flickerstreak@134: flickerstreak@134: local eventListHunter = { flickerstreak@134: "PLAYER_REGEN_ENABLED", flickerstreak@134: "PLAYER_ENTERING_WORLD", flickerstreak@134: "SPELL_UPDATE_COOLDOWN", flickerstreak@134: "SPELL_UPDATE_USABLE", flickerstreak@134: "UNIT_AURA", flickerstreak@134: "SPELLS_CHANGED" flickerstreak@134: } flickerstreak@134: flickerstreak@134: if playerClass == "HUNTER" then flickerstreak@134: eventList = eventListHunter flickerstreak@134: end flickerstreak@134: flickerstreak@134: -- flickerstreak@134: -- Stance Button class flickerstreak@134: -- flickerstreak@134: local Super = ReAction.Button flickerstreak@134: local Stance = setmetatable( { }, { __index = Super } ) flickerstreak@134: ReAction.Button.Stance = Stance flickerstreak@134: flickerstreak@134: function Stance:New( idx, moduleConfig, bar, idHint ) flickerstreak@134: local name = format("ReAction_%s_Stance_%d",bar:GetName(),idx) flickerstreak@134: flickerstreak@134: self = Super.New(self, name, moduleConfig.buttons[bar:GetName()][idx], bar, idx, "SecureActionButtonTemplate, ActionButtonTemplate" ) flickerstreak@134: self.moduleConfig = moduleConfig flickerstreak@134: self.hunterIdx = 1 flickerstreak@134: flickerstreak@134: local f = self:GetFrame() flickerstreak@134: local barFrame = bar:GetFrame() flickerstreak@134: local config = self:GetConfig() flickerstreak@134: flickerstreak@134: -- set up the base stance ID flickerstreak@134: self:SetActionIDPool("stance",8) flickerstreak@134: config.stanceID = self:AcquireActionID(config.stanceID, idHint, true) flickerstreak@134: flickerstreak@134: -- attribute setup flickerstreak@134: f:SetAttribute("type","spell") flickerstreak@134: self:UpdateAction() flickerstreak@134: flickerstreak@134: -- non secure scripts flickerstreak@134: f:SetScript("OnEvent", function(frame, ...) self:OnEvent(...) end) flickerstreak@134: f:SetScript("OnEnter", function(frame) self:OnEnter() end) flickerstreak@134: f:SetScript("OnLeave", function(frame) self:OnLeave() end) flickerstreak@134: f:SetScript("PreClick", function(frame, ...) self:PreClick(...) end) flickerstreak@134: flickerstreak@134: -- secure handlers flickerstreak@134: -- (none) flickerstreak@134: flickerstreak@134: -- event registration flickerstreak@134: f:EnableMouse(true) flickerstreak@134: f:RegisterForClicks("AnyUp") flickerstreak@134: for _, evt in pairs(eventList) do flickerstreak@134: f:RegisterEvent(evt) flickerstreak@134: end flickerstreak@134: flickerstreak@134: -- attach to skinner flickerstreak@134: bar:SkinButton(self) flickerstreak@134: flickerstreak@134: -- initial display flickerstreak@134: if ReAction:GetConfigMode() then flickerstreak@134: self:GetFrame():Show() flickerstreak@134: end flickerstreak@134: flickerstreak@134: self:Refresh() flickerstreak@134: flickerstreak@134: return self flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:GetModuleConfig() flickerstreak@134: -- this is the Stance module config structure, flickerstreak@134: -- not the config structure of the bar itself flickerstreak@134: return self.moduleConfig flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:GetActionID() flickerstreak@134: return self.config.stanceID flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:UpdateAction() flickerstreak@134: if InCombatLockdown() then flickerstreak@134: self.updatePending = true flickerstreak@134: else flickerstreak@134: self.updatePending = false flickerstreak@134: local idx = self:GetActionID() flickerstreak@134: local f = self:GetFrame() flickerstreak@134: local c = self:GetModuleConfig() flickerstreak@134: if playerClass == "HUNTER" then flickerstreak@134: if c.showHunterAspects then flickerstreak@134: -- re-map the index in the case of "hide monkey/hawk" flickerstreak@134: if c.hideMonkeyHawk then flickerstreak@134: local usable, outOfMana = IsUsableSpell(aspects[8]) flickerstreak@134: if usable or outOfMana then flickerstreak@134: idx = idx + 2 flickerstreak@134: if idx > 8 then flickerstreak@134: f:Hide() flickerstreak@134: return flickerstreak@134: end flickerstreak@134: end flickerstreak@134: end flickerstreak@134: self.hunterIdx = idx flickerstreak@134: -- cache the highest rank spellID flickerstreak@134: if not aspectLinks[aspects[idx]] then flickerstreak@134: aspectLinks[aspects[idx]] = GetSpellLink(aspects[idx],"") flickerstreak@134: end flickerstreak@134: local usable, outOfMana = IsUsableSpell(aspects[idx]) flickerstreak@134: if usable or outOfMana then flickerstreak@134: f:SetAttribute("spell",aspects[idx]) flickerstreak@134: f:Show() flickerstreak@134: self:Update() flickerstreak@134: else flickerstreak@134: -- haven't learned this spell yet flickerstreak@134: f:Hide() flickerstreak@134: end flickerstreak@134: else flickerstreak@134: f:Hide() flickerstreak@134: end flickerstreak@134: elseif idx > GetNumShapeshiftForms() or flickerstreak@134: playerClass == "PALADIN" and c.hidePaladinAuras or flickerstreak@134: playerClass == "DEATHKNIGHT" and c.hideDKPresences then flickerstreak@134: f:Hide() flickerstreak@134: else flickerstreak@134: f:SetAttribute("spell", select(2,GetShapeshiftFormInfo(idx))) flickerstreak@134: f:Show() flickerstreak@134: self:Update() flickerstreak@134: end flickerstreak@134: end flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:Refresh() flickerstreak@134: Super.Refresh(self) flickerstreak@136: self:UpdateAction() flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:Update() flickerstreak@134: local texture, isActive, isCastable flickerstreak@134: if playerClass == "HUNTER" then flickerstreak@134: local name, rank flickerstreak@134: local spell = aspects[self.hunterIdx] flickerstreak@134: name, rank, texture = GetSpellInfo(spell) flickerstreak@134: isCastable = IsUsableSpell(spell) flickerstreak@134: for i = 1, 40 do flickerstreak@134: local buff = UnitBuff("player",i,true) flickerstreak@134: if not buff then break end flickerstreak@134: if buff == spell then flickerstreak@134: isActive = true flickerstreak@134: texture = "Interface\\Icons\\Spell_Nature_WispSplode" flickerstreak@134: break flickerstreak@134: end flickerstreak@134: end flickerstreak@134: else flickerstreak@134: local _ flickerstreak@134: texture, _, isActive, isCastable = GetShapeshiftFormInfo(self:GetActionID()) flickerstreak@134: end flickerstreak@134: flickerstreak@134: local icon = self.frames.icon flickerstreak@134: icon:SetTexture(texture) flickerstreak@134: self:GetFrame():SetChecked( isActive and 1 or 0 ) flickerstreak@134: if isCastable then flickerstreak@134: icon:SetVertexColor(1.0, 1.0, 1.0) flickerstreak@134: else flickerstreak@134: icon:SetVertexColor(0.4, 0.4, 0.4) flickerstreak@134: end flickerstreak@134: flickerstreak@134: self:UpdateCooldown() flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:UpdateCooldown() flickerstreak@134: local start, duration, enabled flickerstreak@134: if playerClass == "HUNTER" then flickerstreak@134: local spell = aspects[self.hunterIdx] flickerstreak@134: if spell then flickerstreak@134: start, duration, enabled = GetSpellCooldown(spell) flickerstreak@134: end flickerstreak@134: else flickerstreak@134: start, duration, enabled = GetShapeshiftFormCooldown(self:GetActionID()) flickerstreak@134: end flickerstreak@134: if start then flickerstreak@134: CooldownFrame_SetTimer(self.frames.cooldown, start, duration, enabled) flickerstreak@134: end flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:SetTooltip() flickerstreak@134: if GetCVar("UberTooltips") == "1" then flickerstreak@134: GameTooltip_SetDefaultAnchor(GameTooltip, self:GetFrame()) flickerstreak@134: else flickerstreak@134: GameTooltip:SetOwner(self:GetFrame(), "ANCHOR_RIGHT") flickerstreak@134: end flickerstreak@134: if playerClass == "HUNTER" then flickerstreak@134: local aspect = aspects[self.hunterIdx] flickerstreak@134: if aspect and aspectLinks[aspect] then flickerstreak@134: GameTooltip:SetHyperlink(aspectLinks[aspect]) flickerstreak@134: end flickerstreak@134: else flickerstreak@134: GameTooltip:SetShapeshift(self:GetActionID()) flickerstreak@134: end flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:OnEnter() flickerstreak@134: self:SetTooltip() flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:OnLeave() flickerstreak@134: GameTooltip:Hide() flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:PreClick() flickerstreak@134: local f = self:GetFrame() flickerstreak@134: f:SetChecked( not f:GetChecked() ) flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:OnEvent(event, arg) flickerstreak@134: if event == "PLAYER_REGEN_ENABLED" then flickerstreak@134: if self.updatePending then flickerstreak@134: self:UpdateAction() flickerstreak@134: end flickerstreak@134: elseif event == "UPDATE_SHAPESHIFT_COOLDOWN" then flickerstreak@134: self:UpdateCooldown() flickerstreak@134: elseif event == "UPDATE_SHAPESHIFT_FORMS" or flickerstreak@134: event == "SPELLS_CHANGED" then flickerstreak@134: aspectLinks = { } -- force repopulate of the spellIDs flickerstreak@134: self:UpdateAction() flickerstreak@134: elseif event == "UNIT_AURA" then flickerstreak@134: if arg == "player" then flickerstreak@134: self:Update() flickerstreak@134: end flickerstreak@134: else flickerstreak@134: self:Update() flickerstreak@134: end flickerstreak@134: end flickerstreak@134: flickerstreak@134: function Stance:ShowGridTemp(show) flickerstreak@134: if show then flickerstreak@134: self:GetFrame():Show() flickerstreak@134: else flickerstreak@134: self:UpdateAction() flickerstreak@134: end flickerstreak@134: end