From 02f2945eb28f708d412e8b0c2fd953d38e462cfa Mon Sep 17 00:00:00 2001 From: "Johnny C. Lam" Date: Sun, 10 Nov 2013 00:32:47 +0000 Subject: [PATCH] Remove Eclipse handling in OvaleState in favor of an OvaleEclipse module. OvaleEclipse properly tracks the current Eclipse information as well as keeps Eclipse state for the simulator. git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1157 d5049fe3-3747-40f7-a4b5-f36d6801af5f --- Ovale.toc | 1 + OvaleEclipse.lua | 200 +++++++++++++++++++++++++++++++++++++++++++++ OvalePower.lua | 2 +- OvaleState.lua | 103 ++++------------------- conditions/EclipseDir.lua | 3 +- 5 files changed, 219 insertions(+), 90 deletions(-) create mode 100644 OvaleEclipse.lua diff --git a/Ovale.toc b/Ovale.toc index 8b1514e..b34e42c 100644 --- a/Ovale.toc +++ b/Ovale.toc @@ -52,6 +52,7 @@ OvaleSpellDamage.lua OvaleSwing.lua # OvaleCompile.lua +OvaleEclipse.lua OvaleFuture.lua OvaleIcone.lua OvaleIcone.xml diff --git a/OvaleEclipse.lua b/OvaleEclipse.lua new file mode 100644 index 0000000..2459d9d --- /dev/null +++ b/OvaleEclipse.lua @@ -0,0 +1,200 @@ +--[[-------------------------------------------------------------------- + Ovale Spell Priority + Copyright (C) 2013 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 Eclipse energy information on druids. +--]] + +local _, Ovale = ... +local OvaleEclipse = Ovale:NewModule("OvaleEclipse", "AceEvent-3.0") +Ovale.OvaleEclipse = OvaleEclipse + +-- +local OvaleAura = Ovale.OvaleAura +local OvaleData = Ovale.OvaleData +local OvaleGUID = Ovale.OvaleGUID +local OvalePower = Ovale.OvalePower +local OvaleSpellBook = Ovale.OvaleSpellBook +local OvaleState = Ovale.OvaleState +local SPELL_POWER_ECLIPSE = SPELL_POWER_ECLIPSE + +local select = select +local API_GetEclipseDirection = GetEclipseDirection +local API_UnitClass = UnitClass +local API_UnitPower = UnitPower + +-- Player's GUID. +local self_guid = nil +-- Player's class. +local self_class = select(2, API_UnitClass("player")) + +local LUNAR_ECLIPSE = ECLIPSE_BAR_LUNAR_BUFF_ID +local SOLAR_ECLIPSE = ECLIPSE_BAR_SOLAR_BUFF_ID +local CELESTIAL_ALIGNMENT = 112071 +local EUPHORIA = 81062 +local STARFALL = 48505 +-- + +-- +-- Direction that the eclipse status is moving: -1 = "lunar", 0 = "none", 1 = "solar". +OvaleEclipse.eclipse = 0 +OvaleEclipse.eclipseDirection = 0 +-- + +-- +function OvaleEclipse:OnEnable() + if self_class == "DRUID" then + self_guid = OvaleGUID:GetGUID("player") + self:RegisterEvent("ECLIPSE_DIRECTION_CHANGE", "UpdateEclipseDirection") + self:RegisterEvent("UNIT_POWER") + self:RegisterEvent("UNIT_POWER_FREQUENT", "UNIT_POWER") + self:RegisterMessage("Ovale_SpecializationChanged", "UpdateEclipseDirection") + self:RegisterMessage("Ovale_StanceChanged", "Update") + self:RegisterMessage("Ovale_AuraAdded") + OvaleState:RegisterState(self, self.statePrototype) + end +end + +function OvaleEclipse:OnDisable() + if self_class == "DRUID" then + OvaleState:UnregisterState(self) + self:UnregisterEvent("ECLIPSE_DIRECTION_CHANGE") + self:UnregisterEvent("UNIT_POWER") + self:UnregisterEvent("UNIT_POWER_FREQUENT") + self:UnregisterMessage("Ovale_AuraAdded") + self:UnregisterMessage("Ovale_SpecializationChanged") + self:UnregisterMessage("Ovale_StanceChanged") + end +end + +function OvaleEclipse:UNIT_POWER(event, unitId, powerToken) + if unitId == "player" and powerToken == "ECLIPSE" then + self:Update() + end +end + +function OvaleEclipse:Ovale_AuraAdded(event, timestamp, guid, spellId, caster) + if guid == self_guid then + if spellId == LUNAR_ECLIPSE or spellId == SOLAR_ECLIPSE then + self:UpdateEclipseDirection() + end + end +end + +function OvaleEclipse:Update() + self:UpdateEclipse() + self:UpdateEclipseDirection() +end + +function OvaleEclipse:UpdateEclipse() + self.eclipse = API_UnitPower("player", SPELL_POWER_ECLIPSE) +end + +function OvaleEclipse:UpdateEclipseDirection() + local direction = API_GetEclipseDirection() + if direction == "moon" then + self.eclipseDirection = -1 + elseif direction == "sun" then + self.eclipseDirection = 1 + else -- if direction == "none" then + if self.eclipse < 0 then + self.eclipseDirection = -1 + elseif self.eclipse > 0 then + self.eclipseDirection = 1 + else -- if self.eclipse == 0 then + self.eclipseDirection = 0 + end + end +end +-- + +--[[---------------------------------------------------------------------------- + State machine for simulator. +--]]---------------------------------------------------------------------------- + +-- +OvaleEclipse.statePrototype = { + eclipseDirection = nil, +} +-- + +-- +-- Initialize the state. +function OvaleEclipse:InitializeState(state) + state.eclipseDirection = nil +end + +-- Reset the state to the current conditions. +function OvaleEclipse:ResetState(state) + state.eclipse = self.eclipse or 0 + state.eclipseDirection = self.eclipseDirection +end + +-- Apply the effects of the spell on the player's state, assuming the spellcast completes. +function OvaleEclipse:ApplySpellOnPlayer(state, spellId, startCast, endCast, nextCast, nocd, targetGUID, spellcast) + -- If the spellcast has already ended, then the effects on the player have already occurred. + if endCast <= OvaleState.now then + return + end + + local si = OvaleData.spellInfo[spellId] + if si and si.eclipse then + local eclipse = state.eclipse + local direction = state.eclipseDirection + local energy = si.eclipse + + if energy == 0 then + -- Spell resets Eclipse energy to zero, but leaves the Eclipse direction intact. + eclipse = 0 + else -- if energy ~= 0 then + -- If there is no Eclipse direction yet, then start moving in the direction generated + -- by the energy of the spellcast. + if direction == 0 then + direction = (energy < 0) and -1 or 1 + end + if si.eclipsedir then + energy = energy * direction + end + if state:GetAura("player", CELESTIAL_ALIGNMENT, "HELPFUL", true) then + -- Celestial Alignment prevents gaining Eclipse energy during its duration. + energy = 0 + elseif OvaleSpellBook:IsKnownSpell(EUPHORIA) + and not state:GetAura("player", LUNAR_ECLIPSE, "HELPFUL", true) + and not state:GetAura("player", SOLAR_ECLIPSE, "HELPFUL", true) then + -- Euphoria: While not in an Eclipse state, your spells generate double the normal + -- amount of Solar or Lunar energy. + energy = energy * 2 + end + -- Only adjust Eclipse energy if the spell moves the Eclipse bar in the right direction. + if (direction <= 0 and energy < 0) or (direction >= 0 and energy > 0) then + eclipse = eclipse + energy + end + -- Clamp Eclipse energy to min/max values and note that an Eclipse state will be reached after the spellcast. + if eclipse <= -100 then + eclipse = -100 + direction = 1 + state:AddEclipse(endCast, LUNAR_ECLIPSE) + -- Reaching Lunar Eclipse resets the cooldown of Starfall. + local cd = state:GetCD(STARFALL) + if cd then + cd.start = 0 + cd.duration = 0 + cd.enable = 0 + end + elseif eclipse >= 100 then + eclipse = 100 + direction = -1 + state:AddEclipse(endCast, SOLAR_ECLIPSE) + end + end + state.eclipse = eclipse + state.eclipseDirection = direction + end +end +-- diff --git a/OvalePower.lua b/OvalePower.lua index 1b993cc..6b5f232 100644 --- a/OvalePower.lua +++ b/OvalePower.lua @@ -252,7 +252,7 @@ function OvalePower:ApplySpellOnPlayer(state, spellId, startCast, endCast, nextC end if si then - -- Update power state except for eclipse energy. + -- Update power state except for eclipse energy (handled by OvaleEclipse). for powerType, powerInfo in pairs(self.POWER_INFO) do if powerType ~= "eclipse" then local cost = si[powerType] diff --git a/OvaleState.lua b/OvaleState.lua index 85eb824..9eda4dd 100644 --- a/OvaleState.lua +++ b/OvaleState.lua @@ -9,7 +9,7 @@ --]]-------------------------------------------------------------------- -- Keep the current state in the simulation --- XXX Split out Eclipse and Runes modules (Druid and DeathKnight modules?). +-- XXX Split out Runes module. local _, Ovale = ... local OvaleState = Ovale:NewModule("OvaleState") @@ -18,11 +18,9 @@ Ovale.OvaleState = OvaleState -- local OvaleData = Ovale.OvaleData local OvaleQueue = Ovale.OvaleQueue -local OvaleSpellBook = Ovale.OvaleSpellBook local pairs = pairs local select = select -local API_GetEclipseDirection = GetEclipseDirection local API_GetRuneCooldown = GetRuneCooldown local API_GetRuneType = GetRuneType local API_GetTime = GetTime @@ -38,12 +36,6 @@ local self_runesCD = {} local self_class = select(2, API_UnitClass("player")) -- Whether the state of the simulator has been initialized. local self_stateIsInitialized = false - --- Aura IDs for Eclipse buffs. -local LUNAR_ECLIPSE = 48518 -local SOLAR_ECLIPSE = 48517 --- Spell ID for Starfall (Balance specialization spell). -local STARFALL = 48505 -- -- @@ -212,93 +204,28 @@ function OvaleState:ApplySpellOnPlayer(spellId, startCast, endCast, nextCast, no so only consider spells that have not yet finished casting in the simulator. --]] if endCast > self.now then - -- Adjust the player's resources. - self:ApplySpellCost(spellId, startCast, endCast) - end -end - --- Apply the effects of the spell on the target's state when it lands on the target. -function OvaleState:ApplySpellOnTarget(spellId, startCast, endCast, nextCast, nocd, targetGUID, spellcast) - self:InvokeMethod("ApplySpellOnTarget", spellId, startCast, endCast, nextCast, nocd, targetGUID, spellcast) -end - --- Adjust the player's resources in the simulator from casting the given spell. -function OvaleState:ApplySpellCost(spellId, startCast, endCast) - local si = OvaleData.spellInfo[spellId] - - if si then - -- Eclipse - if si.eclipse then - local energy = si.eclipse - local direction = self:GetEclipseDir() - if si.eclipsedir then - energy = energy * direction + local si = OvaleData.spellInfo[spellId] + if si then + -- Runes + if si.blood and si.blood < 0 then + AddRune(startCast, 1, si.blood) end - -- Euphoria: While not in an Eclipse state, your spells generate double the normal amount of Solar or Lunar energy. - if OvaleSpellBook:IsKnownSpell(81062) - and not self.state:GetAura("player", LUNAR_ECLIPSE, "HELPFUL", true) - and not self.state:GetAura("player", SOLAR_ECLIPSE, "HELPFUL", true) then - energy = energy * 2 + if si.unholy and si.unholy < 0 then + AddRune(startCast, 2, si.unholy) end - -- Only adjust Eclipse energy if the spell moves the Eclipse bar in the right direction. - if (direction < 0 and energy < 0) or (direction > 0 and energy > 0) then - self.state.eclipse = self.state.eclipse + energy + if si.frost and si.frost < 0 then + AddRune(startCast, 3, si.frost) end - -- Clamp Eclipse energy to min/max values and note that an Eclipse state will be reached after the spellcast. - if self.state.eclipse <= -100 then - self.state.eclipse = -100 - self.state:AddEclipse(endCast, LUNAR_ECLIPSE) - -- Reaching Lunar Eclipse resets the cooldown of Starfall. - local cd = self.state:GetCD(STARFALL) - if cd then - cd.start = 0 - cd.duration = 0 - cd.enable = 0 - end - elseif self.state.eclipse >= 100 then - self.state.eclipse = 100 - self.state:AddEclipse(endCast, SOLAR_ECLIPSE) + if si.death and si.death < 0 then + AddRune(startCast, 4, si.death) end end - - -- Runes - if si.blood and si.blood < 0 then - AddRune(startCast, 1, si.blood) - end - if si.unholy and si.unholy < 0 then - AddRune(startCast, 2, si.unholy) - end - if si.frost and si.frost < 0 then - AddRune(startCast, 3, si.frost) - end - if si.death and si.death < 0 then - AddRune(startCast, 4, si.death) - end end end --- Returns 1 if moving toward Solar or -1 if moving toward Lunar. -function OvaleState:GetEclipseDir() - local stacks = select(3, self.state:GetAura("player", SOLAR_ECLIPSE, "HELPFUL", true)) - if stacks and stacks > 0 then - return -1 - else - stacks = select(3, self.state:GetAura("player", LUNAR_ECLIPSE, "HELPFUL", true)) - if stacks and stacks > 0 then - return 1 - elseif self.state.eclipse < 0 then - return -1 - elseif self.state.eclipse > 0 then - return 1 - else - local direction = API_GetEclipseDirection() - if direction == "moon" then - return -1 - else -- direction == "sun" then - return 1 - end - end - end +-- Apply the effects of the spell on the target's state when it lands on the target. +function OvaleState:ApplySpellOnTarget(spellId, startCast, endCast, nextCast, nocd, targetGUID, spellcast) + self:InvokeMethod("ApplySpellOnTarget", spellId, startCast, endCast, nextCast, nocd, targetGUID, spellcast) end -- Returns the cooldown time before all of the required runes are available. diff --git a/conditions/EclipseDir.lua b/conditions/EclipseDir.lua index 2cdf664..4a7352b 100644 --- a/conditions/EclipseDir.lua +++ b/conditions/EclipseDir.lua @@ -18,6 +18,7 @@ do --- Get the current direction of the Eclipse status on the Eclipse bar for balance druids. -- A negative number means heading toward Lunar Eclipse. -- A positive number means heading toward Solar Eclipse. + -- Zero means it can head in either direction. -- @name EclipseDir -- @paramsig number or boolean -- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more. @@ -31,7 +32,7 @@ do local function EclipseDir(condition) local comparator, limit = condition[1], condition[2] - local value = OvaleState:GetEclipseDir() + local value = OvaleState.state.eclipseDirection return Compare(value, comparator, limit) end -- 1.7.9.5