Johnny C. Lam [12-27-14 - 20:07]
diff --git a/Future.lua b/Future.lua
index 371fcbd..0fc4b68 100644
--- a/Future.lua
+++ b/Future.lua
@@ -128,6 +128,8 @@ OvaleFuture.combatStartTime = nil
OvaleFuture.counter = {}
-- Most recent spellcast.
OvaleFuture.lastSpellcast = nil
+-- Most recent GCD spellcast.
+OvaleFuture.lastGCDSpellcast = nil
-- Debugging: spells to trace
OvaleFuture.traceSpellList = nil
--</public-static-properties>
@@ -362,6 +364,11 @@ local function UpdateLastSpellcast(spellcast)
end
self_lastSpellcast[targetGUID][spellId] = spellcast
self.lastSpellcast = spellcast
+ local unitId = OvaleGUID:GetUnitId(targetGUID)
+ local gcd = OvaleData:GetSpellInfoProperty(spellId, "gcd", unitId)
+ if not gcd or gcd > 0 then
+ self.lastGCDSpellcast = spellcast
+ end
--[[
If any auras have been added between the start of the spellcast and this event,
@@ -684,7 +691,7 @@ function OvaleFuture:LastInFlightSpell()
if #self_activeSpellcast > 0 then
return self_activeSpellcast[#self_activeSpellcast]
end
- return self.lastSpellcast
+ return self.lastGCDSpellcast
end
function OvaleFuture:UpdateFromSpellcast(dest, spellcast)
@@ -773,12 +780,14 @@ statePrototype.startCast = nil
statePrototype.endCast = nil
-- The time at which the next GCD spell can be cast in the simulator.
statePrototype.nextCast = nil
+-- The most recent time the spell was cast in the simulator.
+statePrototype.lastCast = 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
--- The most recent time the spell was cast in the simulator.
-statePrototype.lastCast = nil
+-- The previous GCD spell cast in the simulator.
+statePrototype.lastGCDSpellId = nil
-- counter[name] = count
statePrototype.counter = nil
--</state-properties>
@@ -800,6 +809,7 @@ function OvaleFuture:ResetState(state)
state.inCombat = self.inCombat
state.combatStartTime = self.combatStartTime or 0
state.lastSpellId = self.lastSpellcast and self.lastSpellcast.spellId
+ state.lastGCDSpellId = self.lastGCDSpellcast and self.lastGCDSpellcast.spellId
state.currentSpellId = nil
state.isChanneling = false
state.nextCast = now
@@ -823,6 +833,7 @@ function OvaleFuture:CleanState(state)
state.nextCast = nil
state.isChanneling = nil
state.lastSpellId = nil
+ state.lastGCDSpellId = nil
for k in pairs(state.lastCast) do
state.lastCast[k] = nil
@@ -885,11 +896,12 @@ end
statePrototype.ApplySpell = function(state, spellId, targetGUID, startCast, endCast, nextCast, isChanneled, spellcast)
OvaleFuture:StartProfiling("OvaleFuture_state_ApplySpell")
if spellId and targetGUID then
+ local target = OvaleGUID:GetUnitId(targetGUID)
+ local gcd = state:GetGCD(spellId, target)
+
-- Handle missing start/end/next cast times.
if not startCast or not endCast or not nextCast then
- local target = OvaleGUID:GetUnitId(targetGUID)
local castTime = OvaleSpellBook:GetCastTime(spellId) or 0
- local gcd = state:GetGCD(spellId, target)
startCast = startCast or state.nextCast
endCast = endCast or (startCast + castTime)
nextCast = (castTime > gcd) and endCast or (startCast + gcd)
@@ -901,8 +913,11 @@ statePrototype.ApplySpell = function(state, spellId, targetGUID, startCast, endC
state.endCast = endCast
state.nextCast = nextCast
state.isChanneling = isChanneled
- state.lastSpellId = spellId
state.lastCast[spellId] = endCast
+ state.lastSpellId = spellId
+ if gcd > 0 then
+ state.lastGCDSpellId = spellId
+ end
-- Set the current time in the simulator to *slightly* after the start of the current cast,
-- or to now if in the past.
diff --git a/SimulationCraft.lua b/SimulationCraft.lua
index 9646d15..d75f7c2 100644
--- a/SimulationCraft.lua
+++ b/SimulationCraft.lua
@@ -1084,6 +1084,7 @@ local EmitOperandDisease = nil
local EmitOperandDot = nil
local EmitOperandGlyph = nil
local EmitOperandPet = nil
+local EmitOperandPreviousSpell = nil
local EmitOperandRaidEvent = nil
local EmitOperandRune = nil
local EmitOperandSeal = nil
@@ -1954,6 +1955,8 @@ EmitOperand = function(parseNode, nodeList, annotation, action)
ok, node = EmitOperandGlyph(operand, parseNode, nodeList, annotation, action)
elseif token == "pet" then
ok, node = EmitOperandPet(operand, parseNode, nodeList, annotation, action)
+ elseif token == "prev" or token == "prev_gcd" then
+ ok, node = EmitOperandPreviousSpell(operand, parseNode, nodeList, annotation, action)
elseif token == "seal" then
ok, node = EmitOperandSeal(operand, parseNode, nodeList, annotation, action)
elseif token == "set_bonus" then
@@ -2512,6 +2515,33 @@ EmitOperandPet = function(operand, parseNode, nodeList, annotation, action)
return ok, node
end
+EmitOperandPreviousSpell = function(operand, parseNode, nodeList, annotation, action)
+ local ok = true
+ local node
+
+ local tokenIterator = gmatch(operand, OPERAND_TOKEN_PATTERN)
+ local token = tokenIterator()
+ if token == "prev" or token == "prev_gcd" then
+ local name = tokenIterator()
+ name = Disambiguate(name, annotation.class, annotation.specialization)
+ local code
+ if token == "prev" then
+ code = format("PreviousSpell(%s)", name)
+ else -- if token == "prev_gcd" then
+ code = format("PreviousGCDSpell(%s)", name)
+ end
+ if ok and code then
+ annotation.astAnnotation = annotation.astAnnotation or {}
+ node = OvaleAST:ParseCode("expression", code, nodeList, annotation.astAnnotation)
+ AddSymbol(annotation, name)
+ end
+ else
+ ok = false
+ end
+
+ return ok, node
+end
+
EmitOperandRaidEvent = function(operand, parseNode, nodeList, annotation, action)
local ok = true
local node
diff --git a/conditions.lua b/conditions.lua
index 902d974..f736b1c 100644
--- a/conditions.lua
+++ b/conditions.lua
@@ -4122,6 +4122,25 @@ do
end
do
+ --- Test if the previous spell cast that invoked the GCD matches the given spell.
+ -- @name PreviousGCDSpell
+ -- @paramsig boolean
+ -- @param id The spell ID.
+ -- @param yesno Optional. If yes, then return true if there is a match. If no, then return true if it doesn't match.
+ -- Default is yes.
+ -- Valid values: yes, no.
+ -- @return A boolean value.
+
+ local function PreviousGCDSpell(condition, state)
+ local spellId, yesno = condition[1], condition[2]
+ local boolean = (spellId == state.lastGCDSpellId)
+ return TestBoolean(boolean, yesno)
+ end
+
+ OvaleCondition:RegisterCondition("previousgcdspell", true, PreviousGCDSpell)
+end
+
+do
--- Test if the previous spell cast matches the given spell.
-- @name PreviousSpell
-- @paramsig boolean