Quantcast

Fix aura tick information for re-applied auras.

Johnny C. Lam [12-05-13 - 08:19]
Fix aura tick information for re-applied auras.

Use the correct snapshot when estimating tick length and tick times of a
periodic aura.

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1235 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
OvaleAura.lua
OvaleData.lua
OvalePaperDoll.lua
conditions/TickTime.lua
diff --git a/OvaleAura.lua b/OvaleAura.lua
index 5c8109d..efbdb45 100644
--- a/OvaleAura.lua
+++ b/OvaleAura.lua
@@ -25,6 +25,9 @@ local OvaleGUID = nil
 local OvalePaperDoll = nil
 local OvaleState = nil

+local abs = math.abs
+local bit_band = bit.band
+local bit_bor = bit.bor
 local floor = math.floor
 local ipairs = ipairs
 local pairs = pairs
@@ -35,6 +38,12 @@ local wipe = table.wipe
 local API_GetTime = GetTime
 local API_UnitAura = UnitAura
 local API_UnitGUID = UnitGUID
+local SCHOOL_MASK_ARCANE = SCHOOL_MASK_ARCANE
+local SCHOOL_MASK_FIRE = SCHOOL_MASK_FIRE
+local SCHOOL_MASK_FROST = SCHOOL_MASK_FROST
+local SCHOOL_MASK_HOLY = SCHOOL_MASK_HOLY
+local SCHOOL_MASK_NATURE = SCHOOL_MASK_NATURE
+local SCHOOL_MASK_SHADOW = SCHOOL_MASK_SHADOW

 -- Player's GUID.
 local self_guid = nil
@@ -86,6 +95,9 @@ local CLEU_TICK_EVENTS = {
 	SPELL_PERIODIC_DRAIN = true,
 	SPELL_PERIODIC_LEECH = true,
 }
+
+-- Spell school bitmask to identify magic effects.
+local CLEU_SCHOOL_MASK_MAGIC = bit_bor(SCHOOL_MASK_ARCANE, SCHOOL_MASK_FIRE, SCHOOL_MASK_FROST, SCHOOL_MASK_HOLY, SCHOOL_MASK_NATURE, SCHOOL_MASK_SHADOW)
 --</private-static-properties>

 --<public-static-properties>
@@ -250,10 +262,21 @@ function OvaleAura:COMBAT_LOG_EVENT_UNFILTERED(event, ...)
 		Ovale:DebugPrintf(OVALE_AURA_DEBUG, "%s: %s", event, unitId)
 		local aura = GetAura(self_aura, destGUID, spellId, self_guid)
 		if self:IsActiveAura(aura) then
+			local name = aura.name or "Unknown spell"
 			local tick, ticksSeen, lastTickTime = aura.tick, aura.ticksSeen, aura.lastTickTime
 			if not lastTickTime then
-				tick = aura.tick or OvaleData:GetTickLength(spellId)
-				ticksSeen = aura.ticksSeen or 0
+				-- This isn't a known periodic aura, but it's ticking so treat this as the first tick.
+				local si = OvaleData.spellInfo[spellId]
+				if si and si.tick then
+					tick = OvaleData:GetTickLength(spellId, aura.snapshot)
+				elseif bit_band(spellSchool, CLEU_SCHOOL_MASK_MAGIC) > 0 then
+					tick = 3 / OvalePaperDoll:GetSpellHasteMultiplier(aura.snapshot)
+				else
+					-- This is a physical DoT, so not affected by haste.
+					tick = 3
+				end
+				ticksSeen = 1
+				Ovale:DebugPrintf(OVALE_AURA_DEBUG, "First tick seen of unknown periodic aura %s (%d) on %s.", name, spellId, destGUID)
 			else
 				-- Tick times tend to vary about the "true" value by a up to a few
 				-- hundredths of a second.  Keep a running average to try to protect
@@ -264,8 +287,7 @@ function OvaleAura:COMBAT_LOG_EVENT_UNFILTERED(event, ...)
 			aura.tick = tick
 			aura.ticksSeen = ticksSeen
 			aura.lastTickTime = timestamp
-			local name = aura.name or "Unknown spell"
-			Ovale:DebugPrintf(OVALE_AURA_DEBUG, "Updating %s (%s) on %s, tick=%f", name, spellId, destGUID, tick)
+			Ovale:DebugPrintf(OVALE_AURA_DEBUG, "Updating %s (%s) on %s, tick=%f, ticksSeen=%d", name, spellId, destGUID, tick, ticksSeen)
 		end
 	end
 end
@@ -381,7 +403,7 @@ function OvaleAura:GainedAuraOnGUID(guid, atTime, auraId, casterGUID, filter, ic
 				-- Only set the initial tick information for new auras.
 				if not auraIsActive then
 					aura.ticksSeen = 0
-					aura.tick = OvaleData:GetTickLength(auraId)
+					aura.tick = OvaleData:GetTickLength(auraId, aura.snapshot)
 				end
 			end
 		end
@@ -404,6 +426,11 @@ function OvaleAura:LostAuraOnGUID(guid, atTime, auraId, casterGUID)
 	if aura.ending > atTime then
 		aura.ending = atTime
 	end
+	-- Clear old tick information.
+	aura.tick = nil
+	aura.ticksSeen = nil
+	aura.lastTickTime = nil
+
 	self:SendMessage("Ovale_AuraRemoved", atTime, guid, auraId, aura.source)
 	local unitId = OvaleGUID:GetUnitId(guid)
 	if unitId then
diff --git a/OvaleData.lua b/OvaleData.lua
index 20b628b..2c2ee4e 100644
--- a/OvaleData.lua
+++ b/OvaleData.lua
@@ -331,7 +331,7 @@ function OvaleData:GetDamage(spellId, attackpower, spellpower, mainHandWeaponDam
 	return damage
 end

-function OvaleData:GetTickLength(auraId)
+function OvaleData:GetTickLength(auraId, snapshot)
 	local tick = 3
 	local si = self.spellInfo[auraId]
 	if si then
@@ -339,9 +339,9 @@ function OvaleData:GetTickLength(auraId)
 		local hasteMultiplier = 1
 		if si.haste then
 			if si.haste == "spell" then
-				hasteMultiplier = OvalePaperDoll:GetSpellHasteMultiplier()
+				hasteMultiplier = OvalePaperDoll:GetSpellHasteMultiplier(snapshot)
 			elseif si.haste == "melee" then
-				hasteMultiplier = OvalePaperDoll:GetMeleeHasteMultiplier()
+				hasteMultiplier = OvalePaperDoll:GetMeleeHasteMultiplier(snapshot)
 			end
 			tick = tick / hasteMultiplier
 		end
@@ -364,21 +364,7 @@ local statePrototype = OvaleData.statePrototype

 --<state-methods>
 statePrototype.GetTickLength = function(state, auraId, snapshot)
-	local tick = 3
-	local si = OvaleData.spellInfo[auraId]
-	if si then
-		tick = si.tick or tick
-		local hasteMultiplier = 1
-		if si.haste then
-			if si.haste == "spell" then
-				hasteMultiplier = state:GetSpellHasteMultiplier(snapshot)
-			elseif si.haste == "melee" then
-				hasteMultiplier = state:GetMeleeHasteMultiplier(snapshot)
-			end
-			tick = tick / hasteMultiplier
-		end
-	end
-	return tick
+	return OvaleData:GetTickLength(auraId, snapshot)
 end

 -- Returns the raw duration, DoT duration, tick length, and number of ticks of an aura.
diff --git a/OvalePaperDoll.lua b/OvalePaperDoll.lua
index b834ded..d8f554c 100644
--- a/OvalePaperDoll.lua
+++ b/OvalePaperDoll.lua
@@ -399,23 +399,23 @@ function OvalePaperDoll:UpdateStats(event)
 	self:UpdateDamage(event)
 end

-function OvalePaperDoll:GetMasteryMultiplier()
-	local snapshot = self:CurrentSnapshot()
+function OvalePaperDoll:GetMasteryMultiplier(snapshot)
+	snapshot = snapshot or self:CurrentSnapshot()
 	return 1 + snapshot.masteryEffect / 100
 end

-function OvalePaperDoll:GetMeleeHasteMultiplier()
-	local snapshot = self:CurrentSnapshot()
+function OvalePaperDoll:GetMeleeHasteMultiplier(snapshot)
+	snapshot = snapshot or self:CurrentSnapshot()
 	return 1 + snapshot.meleeHaste / 100
 end

-function OvalePaperDoll:GetRangedHasteMultiplier()
-	local snapshot = self:CurrentSnapshot()
+function OvalePaperDoll:GetRangedHasteMultiplier(snapshot)
+	snapshot = snapshot or self:CurrentSnapshot()
 	return 1 + snapshot.rangedHaste / 100
 end

-function OvalePaperDoll:GetSpellHasteMultiplier()
-	local snapshot = self:CurrentSnapshot()
+function OvalePaperDoll:GetSpellHasteMultiplier(snapshot)
+	snapshot = snapshot or self:CurrentSnapshot()
 	return 1 + snapshot.spellHaste / 100
 end

@@ -527,21 +527,21 @@ end
 --<state-methods>
 statePrototype.GetMasteryMultiplier = function(state, snapshot)
 	snapshot = snapshot or state.snapshot
-	return 1 + snapshot.masteryEffect / 100
+	return OvalePaperDoll:GetMasteryMultiplier(snapshot)
 end

 statePrototype.GetMeleeHasteMultiplier = function(state, snapshot)
 	snapshot = snapshot or state.snapshot
-	return 1 + snapshot.meleeHaste / 100
+	return OvalePaperDoll:GetMeleeHasteMultiplier(snapshot)
 end

 statePrototype.GetRangedHasteMultiplier = function(state, snapshot)
 	snapshot = snapshot or state.snapshot
-	return 1 + snapshot.rangedHaste / 100
+	return OvalePaperDoll:GetRangedHasteMultiplier(snapshot)
 end

 statePrototype.GetSpellHasteMultiplier = function(state, snapshot)
 	snapshot = snapshot or state.snapshot
-	return 1 + snapshot.spellHaste / 100
+	return OvalePaperDoll:GetSpellHasteMultiplier(snapshot)
 end
 --</state-methods>
diff --git a/conditions/TickTime.lua b/conditions/TickTime.lua
index aee890f..5bfd6be 100644
--- a/conditions/TickTime.lua
+++ b/conditions/TickTime.lua
@@ -12,7 +12,6 @@ local _, Ovale = ...

 do
 	local OvaleCondition = Ovale.OvaleCondition
-	local OvaleData = Ovale.OvaleData
 	local OvaleState = Ovale.OvaleState

 	local Compare = OvaleCondition.Compare
@@ -39,8 +38,8 @@ do
 		local auraId, comparator, limit = condition[1], condition[2], condition[3]
 		local target, filter, mine = ParseCondition(condition)
 		local aura = state:GetAura(target, auraId, filter, mine)
-		if state:IsActiveAura(aura) then
-			local value = aura.tick or OvaleData:GetTickLength(auraId)
+		if state:IsActiveAura(aura) and aura.tick then
+			local value = aura.tick
 			return Compare(value, comparator, limit)
 		end
 		return Compare(math.huge, comparator, limit)