--[[-------------------------------------------------------------------- Ovale Spell Priority Copyright (C) 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. --]]------------------------------------------------------------------- --[[ This addon tracks the status of the buff from Steady Focus on a MM hunter. Steady Focus description from wowhead.com: When you Steady Shot twice in a row, your ranged attack speed will be increased by 15% and your Steady Shot will generate 3 additional Focus for 20 sec. Mechanically, there is a hidden buff that is added after a Steady Shot is fired that is cleared if any other ranged attack other than Steady Shot is fired next. This addon manages the hidden aura in OvaleAura using events triggered by attacking with ranged attacks. The aura ID of the hidden aura is set to 53224, the spell ID of Steady Focus, and can be checked like any other aura using OvaleAura's public or state methods. --]] local _, Ovale = ... local OvaleSteadyFocus = Ovale:NewModule("OvaleSteadyFocus", "AceEvent-3.0") Ovale.OvaleSteadyFocus = OvaleSteadyFocus --<private-static-properties> -- Forward declarations for module dependencies. local OvaleAura = nil local API_GetTime = GetTime local API_UnitClass = UnitClass local API_UnitGUID = UnitGUID -- Player's class. local _, self_class = API_UnitClass("player") -- Player's GUID. local self_guid = nil -- Steady Focus aura ID for visible buff. local STEADY_FOCUS = 53220 -- Steady Shot spell Id. local STEADY_SHOT = 56641 -- Spell IDs of abilities that clear "pre-Steady Focus". local RANGED_ATTACKS_DAMAGING = { [ 1978] = "Serpent Sting", [ 2643] = "Multi-Shot", [ 3044] = "Arcane Shot", [ 19434] = "Aimed Shot", [ 19503] = "Scatter Shot", [ 53209] = "Chimera Shot", [ 53351] = "Kill Shot", [109259] = "Powershot", [117050] = "Glaive Toss", [120360] = "Barrage", [120361] = "Barrage", [120761] = "Glaive Toss", [121414] = "Glaive Toss", } local RANGED_ATTACKS_ON_CAST = { [ 19801] = "Tranquilizing Shot", [ 34490] = "Silencing Shot", } local RANGED_ATTACKS_BY_DEBUFF = { [118253] = "Serpent Sting", } --</private-static-properties> --<public-static-properties> OvaleSteadyFocus.spellName = "Pre-Steady Focus" -- Steady Focus spell ID from spellbook; re-used as the aura ID of the hidden buff. OvaleSteadyFocus.spellId = 53224 OvaleSteadyFocus.start = 0 OvaleSteadyFocus.start = 0 OvaleSteadyFocus.ending = 0 OvaleSteadyFocus.duration = math.huge OvaleSteadyFocus.stacks = 0 --</public-static-properties> --<public-static-methods> function OvaleSteadyFocus:OnInitialize() -- Resolve module dependencies. OvaleAura = Ovale.OvaleAura end function OvaleSteadyFocus:OnEnable() if self_class == "HUNTER" then self_guid = API_UnitGUID("player") self:RegisterMessage("Ovale_SpecializationChanged") end end function OvaleSteadyFocus:OnDisable() if self_class == "HUNTER" then self:UnregisterMessage("Ovale_SpecializationChanged") end end function OvaleSteadyFocus:Ovale_SpecializationChanged(event, specialization, previousSpecialization) if specialization == "marksmanship" then self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") self:RegisterMessage("Ovale_AuraAdded") self:RegisterMessage("Ovale_AuraChanged", "Ovale_AuraAdded") else self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED") self:UnregisterMessage("Ovale_AuraAdded") self:UnregisterMessage("Ovale_AuraChanged") end end function OvaleSteadyFocus:COMBAT_LOG_EVENT_UNFILTERED(event, timestamp, cleuEvent, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, ...) local arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23 = ... if sourceGUID == self_guid then if cleuEvent == "SPELL_DAMAGE" then local spellId = arg12 if spellId == STEADY_SHOT and self.stacks == 0 then local now = API_GetTime() if now - self.ending > 1 then self:GainedAura(now) end elseif RANGED_ATTACKS_DAMAGING[spellId] and self.stacks > 0 then local now = API_GetTime() self:LostAura(now) end elseif cleuEvent == "SPELL_CAST_SUCCESS" then local spellId = arg12 if RANGED_ATTACKS_ON_CAST[spellId] and self.stacks > 0 then local now = API_GetTime() self:LostAura(now) end end end end function OvaleSteadyFocus:Ovale_AuraAdded(event, timestamp, target, auraId, caster) if self.stacks > 0 then if auraId == STEADY_FOCUS and target == self_guid then self:LostAura(timestamp) elseif RANGED_ATTACKS_BY_DEBUFF[auraId] and caster == self_guid then self:LostAura(timestamp) end end end function OvaleSteadyFocus:GainedAura(atTime) self.start = atTime self.ending = self.start + self.duration self.stacks = self.stacks + 1 OvaleAura:GainedAuraOnGUID(self_guid, self.start, self.spellId, self_guid, "HELPFUL", nil, nil, self.stacks, nil, self.duration, self.ending, nil, self.spellName, nil, nil, nil) end function OvaleSteadyFocus:LostAura(atTime) self.ending = atTime self.stacks = 0 OvaleAura:LostAuraOnGUID(self_guid, atTime, self.spellId, self_guid) end function OvaleSteadyFocus:Debug() local aura = OvaleAura:GetAuraByGUID(self_guid, self.spellId, "HELPFUL", true) if aura then Ovale:FormatPrint("Player has pre-Steady Focus aura with start=%s, end=%s, stacks=%d.", aura.start, aura.ending, aura.stacks) else Ovale:Print("Player has no pre-Steady Focus aura!") end end --</public-static-methods>