Quantcast

Add GetDamageMultiplier(spellId) method to OvaleState.

Johnny C. Lam [03-23-13 - 21:38]
Add GetDamageMultiplier(spellId) method to OvaleState.

This method accounts for auras that are removed by spells that are still
in flight to their targets.  Use this method in place of the one from
OvaleAura in OvaleCondition since OvaleCondition should only reference the
current frame state.

Change the implementation in OvaleAura to not maintain the current damage
multiplier while scanning the auras and to try to account for stacking
auras.

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@814 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
OvaleAura.lua
OvaleCondition.lua
OvaleState.lua
diff --git a/OvaleAura.lua b/OvaleAura.lua
index 44557ad..cf0f5d0 100644
--- a/OvaleAura.lua
+++ b/OvaleAura.lua
@@ -29,7 +29,6 @@ local tsort = table.sort
 local API_IsHarmfulSpell = IsHarmfulSpell
 local API_UnitAura = UnitAura

-local self_baseDamageMultiplier = 1
 local self_pool = OvalePool:NewPool("OvaleAura_pool")
 -- self_aura[guid][filter][spellId]["mine" or "other"] = { aura properties }
 local self_aura = {}
@@ -147,7 +146,6 @@ function UpdateAuras(unitId, unitGUID)
 	end

 	local i = 1
-
 	local filter = "HELPFUL"
 	local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellId
 	local canApplyAura, isBossDebuff, isCastByPlayer, value1, value2, value3
@@ -168,12 +166,6 @@ function UpdateAuras(unitId, unitGUID)
 				-- should be computed by OvaleState:GetAura
 				AddAura(unitGUID, debuffType, filter, unitCaster, icon, count, debuffType, duration, expirationTime, isStealable, name, value1)
 			end
-
-			if unitId == "player" then
-				if OvaleData.selfDamageBuff[spellId] then
-					damageMultiplier = damageMultiplier * OvaleData.selfDamageBuff[spellId]
-				end
-			end
 			i = i + 1
 		end
 	end
@@ -383,19 +375,30 @@ function OvaleAura:GetAuraOnAnyTarget(spellId, filter, mine, excludingGUID)
 end

 function OvaleAura:GetDamageMultiplier(spellId)
-	local damageMultiplier = self_baseDamageMultiplier
+	-- Calculate the base damage multiplier for all spells.
+	local damageMultiplier = 1
+	local playerGUID = OvaleGUID:GetGUID("player")
+	local count
+	for auraSpellId, multiplier in pairs(OvaleData.selfDamageBuff) do
+		count = select(3, self:GetAuraByGUID(playerGUID, auraSpellId, filter, nil, "player"))
+		if count and count > 0 then
+			-- Try to account for a stacking aura.
+			multiplier = 1 + (multiplier - 1) * count
+			damageMultiplier = damageMultiplier * multiplier
+		end
+	end
+
+	-- Factor in the spell-specific multipliers from SpellDamage{Buff,Debuff} declarations.
 	if spellId then
 		local si = OvaleData.spellInfo[spellId]
 		if si and si.damageAura then
-			local guid = OvaleGUID:GetGUID("player")
-			UpdateAuras("player", guid)
-			local auraTable = self_aura[guid]
-			if auraTable then
-				for filter, filterInfo in pairs(si.damageAura) do
-					for auraSpellId, multiplier in pairs(filterInfo) do
-						if auraTable[filter] and auraTable[filter][auraSpellId] then
-							damageMultiplier = damageMultiplier * multiplier
-						end
+			for filter, auraList in pairs(si.damageAura) do
+				for auraSpellId, multiplier in pairs(auraList) do
+					count = select(3, self:GetAuraByGUID(playerGUID, auraSpellId, filter, nil, "player"))
+					if count and count > 0 then
+						-- Try to account for a stacking aura.
+						multiplier = 1 + (multiplier - 1) * count
+						damageMultiplier = damageMultiplier * multiplier
 					end
 				end
 			end
diff --git a/OvaleCondition.lua b/OvaleCondition.lua
index a408476..3eeae91 100644
--- a/OvaleCondition.lua
+++ b/OvaleCondition.lua
@@ -688,6 +688,7 @@ OvaleCondition.conditions.debuffstacks = OvaleCondition.conditions.buffstacks
 --     Spell(spellsteal)

 OvaleCondition.conditions.buffstealable = function(condition)
+	-- XXX: This should really be checked only against OvaleState.
 	return OvaleAura:GetStealable(getTarget(condition.target))
 end

@@ -1027,7 +1028,7 @@ end
 OvaleCondition.conditions.critdamage = function(condition)
 	local spellId = condition[1]
 	local ret = OvaleData:GetDamage(spellId, OvalePaperDoll.attackPower, OvalePaperDoll.spellBonusDamage, OvaleState.state.combo)
-	return 0, nil, 2 * ret * OvaleAura:GetDamageMultiplier(spellId), 0, 0
+	return 0, nil, 2 * ret * OvaleState:GetDamageMultiplier(spellId), 0, 0
 end

 --- Get the current estimated damage of a spell.
@@ -1047,7 +1048,7 @@ end
 OvaleCondition.conditions.damage = function(condition)
 	local spellId = condition[1]
 	local ret = OvaleData:GetDamage(spellId, OvalePaperDoll.attackPower, OvalePaperDoll.spellBonusDamage, OvaleState.state.combo)
-	return 0, nil, ret * OvaleAura:GetDamageMultiplier(spellId), 0, 0
+	return 0, nil, ret * OvaleState:GetDamageMultiplier(spellId), 0, 0
 end

 --- Get the current damage multiplier of a spell.
@@ -1062,8 +1063,7 @@ end
 --     Spell(rupture)

 OvaleCondition.conditions.damagemultiplier = function(condition)
-	-- TODO: use OvaleState
-	return 0, nil, OvaleAura:GetDamageMultiplier(condition[1]), 0, 0
+	return 0, nil, OvaleState:GetDamageMultiplier(condition[1]), 0, 0
 end

 --- Get the estimated number of seconds remaining before the target is dead.
diff --git a/OvaleState.lua b/OvaleState.lua
index 9510d2c..409031f 100644
--- a/OvaleState.lua
+++ b/OvaleState.lua
@@ -25,6 +25,7 @@ local OvaleStance = Ovale.OvaleStance

 local floor = math.floor
 local pairs = pairs
+local select = select
 local tostring = tostring
 local API_GetRuneCooldown = GetRuneCooldown
 local API_GetRuneType = GetRuneType
@@ -35,6 +36,7 @@ local API_UnitPower = UnitPower
 local API_UnitPowerMax = UnitPowerMax
 local MAX_COMBO_POINTS = MAX_COMBO_POINTS

+local self_damageMultiplier = 1
 local self_runes = {}
 local self_runesCD = {}
 --</private-static-properties>
@@ -168,6 +170,19 @@ function OvaleState:Reset()
 	for k,v in pairs(self.state.counter) do
 		self.state.counter[k] = OvaleFuture.counter[k]
 	end
+
+	-- Calculate the base damage multiplier for all spells.
+	self_damageMultiplier = 1
+	local playerGUID = OvaleGUID:GetGUID("player")
+	local count
+	for auraSpellId, multiplier in pairs(OvaleData.selfDamageBuff) do
+		count = select(3, self:GetAuraByGUID(playerGUID, auraSpellId, filter, nil, "player"))
+		if count and count > 0 then
+			-- Try to account for a stacking aura.
+			multiplier = 1 + (multiplier - 1) * count
+			self_damageMultiplier = self_damageMultiplier * multiplier
+		end
+	end
 end

 -- Apply the effects of spells that are being cast or are in flight, allowing us to
@@ -595,6 +610,27 @@ function OvaleState:NewAura(guid, spellId, filter)
 	return aura
 end

+function OvaleState:GetDamageMultiplier(spellId)
+	local damageMultiplier = self_damageMultiplier
+	if spellId then
+		local si = OvaleData.spellInfo[spellId]
+		if si and si.damageAura then
+			local playerGUID = OvaleGUID:GetGUID("player")
+			local count
+			for filter, auraList in pairs(si.damageAura) do
+				for auraSpellId, multiplier in pairs(auraList) do
+					count = select(3, self:GetAuraByGUID(playerGUID, auraSpellId, filter, nil, "player"))
+					if count and count > 0 then
+						-- Try to account for a stacking aura.
+						multiplier = 1 + (multiplier - 1) * count
+						damageMultiplier = damageMultiplier * multiplier
+					end
+				end
+			end
+		end
+	end
+	return damageMultiplier
+end

 function OvaleState:GetEclipseDir()
 	local stacks = select(3, self:GetAura("player", 48517, "HELPFUL")) -- Solar