Quantcast

Fix ticket 256 - DebuffAttackPower not updating properly on refresh

Johnny C. Lam [07-13-13 - 20:58]
Fix ticket 256 - DebuffAttackPower not updating properly on refresh

Determining whether an aura needs a fresh snapshot requires some state to
be kept.  In this case, we track the most recent spell cast by the player
that preceded the aura being applied.  If that spell is one that doesn't
trigger a new snapshot of the aura, then don't snapshot; but snapshot
otherwise.

Currently doesn't deal with DoTs that are spread by other spells, e.g.,
Inferno Blast and Soul Swap.

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@969 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
Ovale.lua
OvaleAura.lua
OvaleData.lua
OvaleFuture.lua
OvaleState.lua
diff --git a/Ovale.lua b/Ovale.lua
index 70df0bf..5ef72a0 100644
--- a/Ovale.lua
+++ b/Ovale.lua
@@ -39,6 +39,8 @@ local OVALE_TRUE_STRING = tostring(true)
 Ovale.L = L
 --The current time, updated once per frame refresh.
 Ovale.now = API_GetTime()
+-- The spell ID of the most recent spell cast.
+Ovale.lastSpellId = nil
 --The table of check boxes definition
 Ovale.casesACocher = {}
 --the frame with the icons
diff --git a/OvaleAura.lua b/OvaleAura.lua
index ae83ca6..04db796 100644
--- a/OvaleAura.lua
+++ b/OvaleAura.lua
@@ -157,18 +157,21 @@ local function UnitGainedAura(event, guid, spellId, filter, casterGUID, icon, co
 		aura.name = name
 		aura.value = value

-		-- Only snapshot stats for periodic auras that have been applied or re-applied.
-		-- If SPELL_AURA_REFRESH didn't fire, then the aura was extended by adding ticks,
-		-- which doesn't re-snapshot stats.
-		if mine and (not existingAura or event == "SPELL_AURA_REFRESH") then
+		if mine then
 			local si = OvaleData.spellInfo[spellId]
-			if si and si.tick then
-				Ovale:DebugPrintf(OVALE_AURA_DEBUG, "%s: Snapshot stats for %s %s (%s) on %s at %f, gain=%f, aura.serial=%d",
-					event, filter, name, spellId, guid, Ovale.now, aura.gain, aura.serial)
-				aura.ticksSeen = 0
-				aura.tick = OvaleData:GetTickLength(spellId)
-				OvalePaperDoll:SnapshotStats(aura)
-				aura.damageMultiplier = self:GetDamageMultiplier(spellId)
+			if si then
+				-- Only set the initial tick information for new auras.
+				if not existingAura and si.tick then
+					aura.ticksSeen = 0
+					aura.tick = OvaleData:GetTickLength(spellId)
+				end
+				-- Determine whether to snapshot player stats for the aura or to keep the existing stats.
+				if Ovale.lastSpellId and OvaleData:NeedNewSnapshot(spellId, Ovale.lastSpellId) then
+					Ovale:DebugPrintf(OVALE_AURA_DEBUG, "%s: Snapshot stats for %s %s (%s) on %s at %f, gain=%f, aura.serial=%d",
+						event, filter, name, spellId, guid, Ovale.now, aura.gain, aura.serial)
+					OvalePaperDoll:SnapshotStats(aura)
+					aura.damageMultiplier = self:GetDamageMultiplier(spellId)
+				end
 			end
 		end
 	end
diff --git a/OvaleData.lua b/OvaleData.lua
index 6aa2898..8ad7225 100644
--- a/OvaleData.lua
+++ b/OvaleData.lua
@@ -46,6 +46,30 @@ local SPELL_POWER_RAGE = SPELL_POWER_RAGE
 local SPELL_POWER_RUNIC_POWER = SPELL_POWER_RUNIC_POWER
 local SPELL_POWER_SHADOW_ORBS = SPELL_POWER_SHADOW_ORBS
 local SPELL_POWER_SOUL_SHARDS = SPELL_POWER_SOUL_SHARDS
+
+-- Auras that are refreshed by spells that don't trigger a new snapshot.
+self_buffNoSnapshotSpellList =
+{
+	-- Rip (druid)
+	[1079] =
+	{
+		[5221] = true,		-- Shred
+		[6785] = true,		-- Ravage
+		[22568] = true,		-- Ferocious Bite (target below 25%)
+		[33876] = true,		-- Mangle
+		[102545] = true,	-- Ravage!
+	},
+	-- Blood Plague (death knight)
+	[55078] =
+	{
+		[85948] = true,		-- Festering Strike (unholy)
+	},
+	-- Frost Fever (death knight)
+	[55095] =
+	{
+		[85948] = true,		-- Festering Strike (unholy)
+	},
+}
 --</private-static-properties>

 --<public-static-properties>
@@ -433,6 +457,16 @@ function OvaleData:ResetSpellInfo()
 	self.spellInfo = {}
 end

+-- Returns true if spellId triggers a fresh snapshot for auraSpellId.
+-- TODO: Handle spreading DoTs (Inferno Blast, etc.) and Soul Swap effects.
+function OvaleData:NeedNewSnapshot(auraSpellId, spellId)
+	-- Don't snapshot if the aura was applied by an action that shouldn't cause the aura to re-snapshot.
+	if self_buffNoSnapshotSpellList[auraSpellId] and self_buffNoSnapshotSpellList[auraSpellId][spellId] then
+		return false
+	end
+	return true
+end
+
 function OvaleData:GetGCD(spellId)
 	if spellId and self.spellInfo[spellId] then
 		local si = self.spellInfo[spellId]
diff --git a/OvaleFuture.lua b/OvaleFuture.lua
index e50f423..cc2ce99 100644
--- a/OvaleFuture.lua
+++ b/OvaleFuture.lua
@@ -63,8 +63,6 @@ local OVALE_CLEU_SPELLCAST_RESULTS = {
 OvaleFuture.counter = {}
 -- Most recent latency (time between UNIT_SPELLCAST_SENT and UNIT_SPELLCAST_SUCCEEDED events).
 OvaleFuture.latency = 0
--- The spell ID of the most recent spell cast.
-OvaleFuture.lastSpellId = nil
 -- Debugging: spell ID to trace
 OvaleFuture.traceSpellId = nil
 --</public-static-properties>
@@ -110,7 +108,7 @@ local function AddSpellToQueue(spellId, lineId, startTime, endTime, channeled, a
 		Ovale.now, OvaleData:GetSpellName(spellId), spellId, lineId, startTime, endTime, spellcast.target)

 	-- Snapshot the current stats for the spellcast.
-	self.lastSpellId = spellId
+	Ovale.lastSpellId = spellId
 	OvalePaperDoll:SnapshotStats(spellcast)
 	spellcast.damageMultiplier = OvaleAura:GetDamageMultiplier(spellId)
 	tinsert(self_activeSpellcast, spellcast)
diff --git a/OvaleState.lua b/OvaleState.lua
index e19d9cd..14f71fc 100644
--- a/OvaleState.lua
+++ b/OvaleState.lua
@@ -152,7 +152,7 @@ function OvaleState:UpdatePowerRates()
 end

 function OvaleState:Reset()
-	self.lastSpellId = OvaleFuture.lastSpellId
+	self.lastSpellId = Ovale.lastSpellId
 	self.serial = self.serial + 1
 	self.currentTime = self.maintenant
 	Ovale:Logf("Reset state with current time = %f", self.currentTime)