From 3c58cbdfad9cd152061c8de3ae02f6eda911d4a2 Mon Sep 17 00:00:00 2001 From: "Johnny C. Lam" Date: Thu, 5 Dec 2013 08:19:15 +0000 Subject: [PATCH] Move spellcast state from OvaleState into OvaleFuture. The following methods from OvaleState are now mix-in methods for the state machine: OvaleState:ApplySpell() --> state:ApplySpell() OvaleState:StartNewFrame() --> state:Initialize() OvaleState:Reset() --> state:Reset() git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1237 d5049fe3-3747-40f7-a4b5-f36d6801af5f --- OvaleBestAction.lua | 2 +- OvaleFrame.lua | 4 +- OvaleFuture.lua | 100 +++++++++++++++++++++++++++++++++++++++++++- OvaleState.lua | 116 ++++----------------------------------------------- 4 files changed, 111 insertions(+), 111 deletions(-) diff --git a/OvaleBestAction.lua b/OvaleBestAction.lua index 0dfb37d..17320f0 100644 --- a/OvaleBestAction.lua +++ b/OvaleBestAction.lua @@ -719,7 +719,7 @@ function OvaleBestAction:OnInitialize() end function OvaleBestAction:StartNewAction(state) - OvaleState:Reset(state) + state:Reset() OvaleFuture:ApplyInFlightSpells(state) self_serial = self_serial + 1 end diff --git a/OvaleFrame.lua b/OvaleFrame.lua index 46a528a..c7ac3ce 100644 --- a/OvaleFrame.lua +++ b/OvaleFrame.lua @@ -175,7 +175,7 @@ do self.lastUpdate = now local state = OvaleState.state - OvaleState:StartNewFrame(state) + state:Initialize() for k,node in pairs(OvaleCompile.masterNodes) do local target if node.params and node.params.target then @@ -265,7 +265,7 @@ do if not spellTarget or spellTarget == "target" then spellTarget = OvaleCondition.defaultTarget end - OvaleState:ApplySpell(state, spellId, OvaleGUID:GetGUID(spellTarget)) + state:ApplySpell(spellId, OvaleGUID:GetGUID(spellTarget)) timeSpan, _, element = OvaleBestAction:Compute(node) start = NextTime(timeSpan, state.currentTime) icons[2]:Update(element, start, OvaleBestAction:GetActionInfo(element)) diff --git a/OvaleFuture.lua b/OvaleFuture.lua index 1baa087..6dff9de 100644 --- a/OvaleFuture.lua +++ b/OvaleFuture.lua @@ -517,7 +517,7 @@ function OvaleFuture:ApplyInFlightSpells(state) local spellcast = self_activeSpellcast[index] Ovale:Logf("now = %f, spellId = %d, endCast = %f", now, spellcast.spellId, spellcast.stop) if now - spellcast.stop < 5 then - OvaleState:ApplySpell(state, spellcast.spellId, spellcast.target, spellcast.start, spellcast.stop, spellcast.stop, spellcast.channeled, spellcast.nocd, spellcast) + state:ApplySpell(spellcast.spellId, spellcast.target, spellcast.start, spellcast.stop, spellcast.stop, spellcast.channeled, spellcast.nocd, spellcast) else tremove(self_activeSpellcast, index) self_pool:Release(spellcast) @@ -589,6 +589,20 @@ local statePrototype = OvaleFuture.statePrototype -- -- +-- The current time in the simulator. +statePrototype.currentTime = nil +-- The spell being cast in the simulator. +statePrototype.currentSpellId = nil +-- The starting cast time of the spell being cast in the simulator. +statePrototype.startCast = nil +-- The ending cast time of the spell being cast in the simulator. +statePrototype.endCast = nil +-- The time at which the next GCD spell can be cast in the simulator. +statePrototype.nextCast = nil +-- Whether the player is channeling a spell in the simulator at the current time. +statePrototype.isChanneling = nil +-- The previous spell cast in the simulator. +statePrototype.lastSpellId = nil -- counter[name] = count statePrototype.counter = nil -- @@ -601,6 +615,15 @@ end -- Reset the state to the current conditions. function OvaleFuture:ResetState(state) + local now = API_GetTime() + state.currentTime = now + Ovale:Logf("Reset state with current time = %f", state.currentTime) + + state.lastSpellId = self.lastSpellcast and self.lastSpellcast.spellId + state.currentSpellId = nil + state.isChanneling = false + state.nextCast = now + for k, v in pairs(self.counter) do state.counter[k] = self.counter[k] end @@ -608,6 +631,14 @@ end -- Release state resources prior to removing from the simulator. function OvaleFuture:CleanState(state) + state.currentTime = nil + state.currentSpellId = nil + state.startCast = nil + state.endCast = nil + state.nextCast = nil + state.isChanneling = nil + state.lastSpellId = nil + for k in pairs(state.counter) do state.counter[k] = nil end @@ -639,4 +670,71 @@ end statePrototype.GetDamageMultiplier = function(state, spellId) return GetDamageMultiplier(spellId, state) end + +--[[ + Cast a spell in the simulator and advance the state of the simulator. + + Parameters: + spellId The ID of the spell to cast. + targetGUID The GUID of the target of the spellcast. + startCast The time at the start of the spellcast. + endCast The time at the end of the spellcast. + nextCast The earliest time at which the next spell can be cast (nextCast >= endCast). + isChanneled The spell is a channeled spell. + nocd The spell's cooldown is not triggered. + spellcast (optional) Table of spellcast information, including a snapshot of player's stats. +--]] +statePrototype.ApplySpell = function(state, ...) + local spellId, targetGUID, startCast, endCast, nextCast, isChanneled, nocd, spellcast = ... + if not spellId or not targetGUID then + return + end + + -- Handle missing start/end/next cast times. + if not startCast or not endCast or not nextCast then + local castTime = 0 + local castTime = select(7, API_GetSpellInfo(spellId)) + castTime = castTime and (castTime / 1000) or 0 + local gcd = OvaleCooldown:GetGCD(spellId) + + startCast = startCast or state.nextCast + endCast = endCast or (startCast + castTime) + nextCast = (castTime > gcd) and endCast or (startCast + gcd) + end + + -- Update the latest spell cast in the simulator. + state.currentSpellId = spellId + state.startCast = startCast + state.endCast = endCast + state.nextCast = nextCast + state.isChanneling = isChanneled + state.lastSpellId = spellId + + -- Set the current time in the simulator to a little after the start of the current cast, + -- or to now if in the past. + local now = API_GetTime() + if startCast >= now then + state.currentTime = startCast + 0.1 + else + state.currentTime = now + end + + Ovale:Logf("Apply spell %d at %f currentTime=%f nextCast=%f endCast=%f targetGUID=%s", spellId, startCast, state.currentTime, nextCast, endCast, targetGUID) + + --[[ + Apply the effects of the spellcast in three phases. + 1. Effects at the beginning of the spellcast. + 2. Effects when the spell has been cast. + 3. Effects when the spellcast hits the target. + --]] + -- If the spellcast has already started, then the effects have already occurred. + if startCast >= now then + OvaleState:InvokeMethod("ApplySpellStartCast", state, ...) + end + -- If the spellcast has already ended, then the effects have already occurred. + if endCast > now then + OvaleState:InvokeMethod("ApplySpellAfterCast", state, ...) + end + OvaleState:InvokeMethod("ApplySpellOnHit", state, ...) +end -- diff --git a/OvaleState.lua b/OvaleState.lua index a074bc9..a94f2dd 100644 --- a/OvaleState.lua +++ b/OvaleState.lua @@ -24,7 +24,6 @@ local OvaleData = nil local OvaleFuture = nil local pairs = pairs -local API_GetTime = GetTime local self_statePrototype = {} local self_stateModules = OvaleQueue:NewQueue("OvaleState_stateModules") @@ -91,83 +90,6 @@ function OvaleState:InvokeMethod(methodName, ...) end end end - -function OvaleState:StartNewFrame(state) - if not state.isInitialized then - self:InvokeMethod("InitializeState", state) - end -end - -function OvaleState:Reset(state) - self:InvokeMethod("ResetState", state) -end - ---[[ - Cast a spell in the simulator and advance the state of the simulator. - - Parameters: - spellId The ID of the spell to cast. - targetGUID The GUID of the target of the spellcast. - startCast The time at the start of the spellcast. - endCast The time at the end of the spellcast. - nextCast The earliest time at which the next spell can be cast (nextCast >= endCast). - isChanneled The spell is a channeled spell. - nocd The spell's cooldown is not triggered. - spellcast (optional) Table of spellcast information, including a snapshot of player's stats. ---]] -function OvaleState:ApplySpell(state, ...) - local spellId, targetGUID, startCast, endCast, nextCast, isChanneled, nocd, spellcast = ... - if not spellId or not targetGUID then - return - end - - -- Handle missing start/end/next cast times. - if not startCast or not endCast or not nextCast then - local castTime = 0 - local castTime = select(7, API_GetSpellInfo(spellId)) - castTime = castTime and (castTime / 1000) or 0 - local gcd = OvaleCooldown:GetGCD(spellId) - - startCast = startCast or state.nextCast - endCast = endCast or (startCast + castTime) - nextCast = (castTime > gcd) and endCast or (startCast + gcd) - end - - -- Update the latest spell cast in the simulator. - state.currentSpellId = spellId - state.startCast = startCast - state.endCast = endCast - state.nextCast = nextCast - state.isChanneling = isChanneled - state.lastSpellId = spellId - - -- Set the current time in the simulator to a little after the start of the current cast, - -- or to now if in the past. - local now = API_GetTime() - if startCast >= now then - state.currentTime = startCast + 0.1 - else - state.currentTime = now - end - - Ovale:Logf("Apply spell %d at %f currentTime=%f nextCast=%f endCast=%f targetGUID=%s", spellId, startCast, state.currentTime, nextCast, endCast, targetGUID) - - --[[ - Apply the effects of the spellcast in three phases. - 1. Effects at the beginning of the spellcast. - 2. Effects when the spell has been cast. - 3. Effects when the spellcast hits the target. - --]] - -- If the spellcast has already started, then the effects have already occurred. - if startCast >= now then - self:InvokeMethod("ApplySpellStartCast", state, ...) - end - -- If the spellcast has already ended, then the effects have already occurred. - if endCast > now then - self:InvokeMethod("ApplySpellAfterCast", state, ...) - end - self:InvokeMethod("ApplySpellOnHit", state, ...) -end -- --[[---------------------------------------------------------------------------- @@ -185,37 +107,17 @@ local statePrototype = OvaleState.statePrototype -- -- Whether the state of the simulator has been initialized. statePrototype.isInitialized = nil --- The current time in the simulator. -statePrototype.currentTime = nil --- The spell being cast in the simulator. -statePrototype.currentSpellId = nil --- The starting cast time of the spell being cast in the simulator. -statePrototype.startCast = nil --- The ending cast time of the spell being cast in the simulator. -statePrototype.endCast = nil --- The time at which the next GCD spell can be cast in the simulator. -statePrototype.nextCast = nil --- Whether the player is channeling a spell in the simulator at the current time. -statePrototype.isChanneling = nil --- The previous spell cast in the simulator. -statePrototype.lastSpellId = nil -- --- --- Initialize the state. -function OvaleState:InitializeState(state) - state.isInitialized = true +-- +statePrototype.Initialize = function(state) + if not state.isInitialized then + OvaleState:InvokeMethod("InitializeState", state) + state.isInitialized = true + end end --- Reset the state to the current conditions. -function OvaleState:ResetState(state) - local now = API_GetTime() - state.currentTime = now - Ovale:Logf("Reset state with current time = %f", state.currentTime) - - state.lastSpellId = OvaleFuture.lastSpellcast and OvaleFuture.lastSpellcast.spellId - state.currentSpellId = nil - state.isChanneling = false - state.nextCast = now +statePrototype.Reset = function(state) + OvaleState:InvokeMethod("ResetState", state) end --- +-- -- 1.7.9.5