Preserve auras applied by already-cast instant-cast spells between updates.
Johnny C. Lam [05-03-14 - 00:25]
Preserve auras applied by already-cast instant-cast spells between updates.
This fixes the problem where an instant-cast spell cast in the simulator
applies a debuff on the target which is added to the state machine, then
instantly removed before being added to the true aura database. For
example, a subtlety rogue's Hemorrhage applies a DoT on the target, but
there is a small lag betwen the spell hitting the target and the DoT being
applied. When the user casts the spell, OvaleFuture queues it up to the
cast in the simulator, which applies a DoT to the target in the simulator.
However, the simulator's state is reset on every update, so the debuff was
being lost until it appeared on the actual target. During that brief lag,
Ovale thinks Hemorrhage still needs to be cast to apply the DoT.
Instead of dumping the entire state aura database for each update, just
remove state auras that are older than the corresponding auras in the true
aura database. This preserves debuffs applied in the simulator that are
the result of instant-cast spells until they appear in the true aura
database.
git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1354 d5049fe3-3747-40f7-a4b5-f36d6801af5f
diff --git a/OvaleAura.lua b/OvaleAura.lua
index 5788381..ac77f69 100644
--- a/OvaleAura.lua
+++ b/OvaleAura.lua
@@ -199,6 +199,7 @@ local function RemoveAurasOnGUID(auraDB, guid)
for auraId, whoseTable in pairs(auraTable) do
for casterGUID, aura in pairs(whoseTable) do
self_pool:Release(aura)
+ whoseTable[casterGUID] = nil
end
self_pool:Release(whoseTable)
auraTable[auraId] = nil
@@ -418,6 +419,7 @@ function OvaleAura:GainedAuraOnGUID(guid, atTime, auraId, casterGUID, filter, vi
aura.start = atTime
end
aura.gain = atTime
+ aura.lastUpdated = atTime
aura.stacks = count
aura.consumed = nil
aura.filter = filter
@@ -506,6 +508,7 @@ function OvaleAura:LostAuraOnGUID(guid, atTime, auraId, casterGUID)
end
end
end
+ aura.lastUpdated = atTime
self:SendMessage("Ovale_AuraRemoved", atTime, guid, auraId, aura.source)
local unitId = OvaleGUID:GetUnitId(guid)
@@ -632,11 +635,32 @@ end
-- Reset the state to the current conditions.
function OvaleAura:ResetState(state)
- -- Garbage-collect auras in the state machine.
- if not Ovale.enCombat then
- self:CleanState(state)
- end
+ -- Advance age of auras in state machine.
state.serial = state.serial + 1
+
+ -- Garbage-collect auras in the state machine that are more recently updated in the true aura database.
+ for guid, auraTable in pairs(state.aura) do
+ for auraId, whoseTable in pairs(auraTable) do
+ for casterGUID, aura in pairs(whoseTable) do
+ local auraFound = GetAura(self.aura, guid, auraId, casterGUID)
+ if auraFound and aura.lastUpdated <= auraFound.lastUpdated then
+ self_pool:Release(aura)
+ whoseTable[casterGUID] = nil
+ else
+ -- Reset the aura age relative to the state of the simulator.
+ aura.serial = state.serial
+ end
+ end
+ if not next(whoseTable) then
+ self_pool:Release(whoseTable)
+ auraTable[auraId] = nil
+ end
+ end
+ if not next(auraTable) then
+ self_pool:Release(auraTable)
+ state.aura[guid] = nil
+ end
+ end
end
-- Release state resources prior to removing from the simulator.
@@ -1031,6 +1055,7 @@ statePrototype.AddAuraToGUID = function(state, guid, auraId, casterGUID, filter,
local aura = self_pool:Get()
aura.state = true
aura.serial = state.serial
+ aura.lastUpdated = state.currentTime
aura.filter = filter
aura.mine = mine
aura.start = start or 0
@@ -1069,6 +1094,7 @@ statePrototype.RemoveAuraOnGUID = function(state, guid, auraId, filter, mine, at
-- Expire the aura.
aura.stacks = 0
aura.ending = atTime
+ aura.lastUpdated = atTime
end
end