Quantcast

Fix ticket 296 - Ovale double deducting for energy cost

Johnny C. Lam [09-28-13 - 12:49]
Fix ticket 296 - Ovale double deducting for energy cost

Only apply the power cost of the spell if the spellcast hasn't already
finished.  A spellcast that has finished in-game has already had the power
adjusted, which would be picked up when :Reset() is called to reset the
frame state.

Also, make this more readable by splitting out code from :ApplySpell()
method to update the power state into a new method :ApplySpellCost().

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1036 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
OvaleState.lua
diff --git a/OvaleState.lua b/OvaleState.lua
index afc25c9..592e081 100644
--- a/OvaleState.lua
+++ b/OvaleState.lua
@@ -80,11 +80,11 @@ local function ApplySpell(spellId, startCast, endCast, nextCast, nocd, targetGUI
 	self:ApplySpell(spellId, startCast, endCast, nextCast, nocd, targetGUID, stats)
 end

--- Track a new Eclipse buff that starts at endCast.
-local function AddEclipse(endCast, spellId)
+-- Track a new Eclipse buff that starts at timestamp.
+local function AddEclipse(timestamp, spellId)
 	local self = OvaleState
 	local newAura = self:NewAura(OvaleGUID:GetGUID("player"), spellId, "HELPFUL")
-	newAura.start = endCast
+	newAura.start = timestamp
 	newAura.ending = nil
 	newAura.stacks = 1
 end
@@ -229,103 +229,8 @@ function OvaleState:ApplySpell(spellId, startCast, endCast, nextCast, nocd, targ

 	--Effet du sort au moment o il est lanc
 	--(donc si il est dj lanc, on n'en tient pas compte)
-	if endCast >= self.maintenant then
-		--Mana
-		local _, _, _, cost, _, powerType = API_GetSpellInfo(spellId)
-		local power = OvalePower.POWER_TYPE[powerType]
-		if cost and power and (not si or not si[power]) then
-			self.state[power] = self.state[power] - cost
-		end
-
-		if si then
-			-- Update power state, except for eclipse, combo, and runes.
-			for power, v in pairs(OvalePower.POWER) do
-				if si[power] and power ~= "eclipse" then
-					if si[power] == 0 then
-						self.state[power] = 0
-					else
-						self.state[power] = self.state[power] - si[power]
-					end
-					-- Add extra resource generated by presence of a buff.
-					local buffParam = "buff_" .. tostring(power)
-					local buffAmoumtParam = buffParam .. "_amount"
-					if si[power] < 0 and si[buffParam] and self:GetAura("player", si[buffParam], nil, true) then
-						local buffAmount = si[buffAmountParam] or 1
-						self.state[power] = self.state[power] + buffAmount
-					end
-					if self.state[power] < v.mini then
-						self.state[power] = v.mini
-					end
-					local maxi = v.maxi or OvalePower.maxPower[power]
-					if maxi and self.state[power] > maxi then
-						self.state[power] = maxi
-					end
-				end
-			end
-
-			-- Eclipse
-			if si.eclipse then
-				local energy = si.eclipse
-				local direction = self:GetEclipseDir()
-				if si.eclipsedir then
-					energy = energy * direction
-				end
-				-- Euphoria: While not in an Eclipse state, your spells generate double the normal amount of Solar or Lunar energy.
-				if OvaleSpellBook:IsKnownSpell(81062)
-						and not self:GetAura("player", LUNAR_ECLIPSE, "HELPFUL", true)
-						and not self:GetAura("player", SOLAR_ECLIPSE, "HELPFUL", true) then
-					energy = energy * 2
-				end
-				-- Only adjust Eclipse energy if the spell moves the Eclipse bar in the right direction.
-				if (direction < 0 and energy < 0) or (direction > 0 and energy > 0) then
-					self.state.eclipse = self.state.eclipse + energy
-				end
-				-- Clamp Eclipse energy to min/max values and note that an Eclipse state will be reached.
-				if self.state.eclipse <= -100 then
-					self.state.eclipse = -100
-					AddEclipse(endCast, LUNAR_ECLIPSE)
-				elseif self.state.eclipse >= 100 then
-					self.state.eclipse = 100
-					AddEclipse(endCast, SOLAR_ECLIPSE)
-				end
-			end
-
-			-- Combo points
-			if si.combo then
-				if si.combo == 0 then
-					self.state.combo = 0
-				elseif si.combo > 0 then
-					self.state.combo = self.state.combo + si.combo
-					-- Add extra combo points generated by presence of a buff.
-					if si.buff_combo and self:GetAura("player", si.buff_combo, nil, true) then
-						local buffAmount = si.buff_combo_amount or 1
-						self.state.combo = self.state.combo + buffAmount
-					end
-					if self.state.combo > MAX_COMBO_POINTS then
-						self.state.combo = MAX_COMBO_POINTS
-					end
-				else -- si.combo < 0
-					self.state.combo = self.state.combo + si.combo
-					if self.state.combo < 0 then
-						self.state.combo = 0
-					end
-				end
-			end
-
-			--Runes
-			if si.frost then
-				self:AddRune(startCast, 3, si.frost)
-			end
-			if si.death then
-				self:AddRune(startCast, 4, si.death)
-			end
-			if si.blood then
-				self:AddRune(startCast, 1, si.blood)
-			end
-			if si.unholy then
-				self:AddRune(startCast, 2, si.unholy)
-			end
-		end
+	if endCast > self.maintenant then
+		self:ApplySpellCost(spellId, startCast, endCast)
 	end

 	-- Effets du sort au moment o il atteint sa cible
@@ -341,16 +246,15 @@ function OvaleState:ApplySpell(spellId, startCast, endCast, nextCast, nocd, targ
 			else
 				--On vrifie si le buff "buffnocd" est prsent, auquel cas le CD du sort n'est pas dclench
 				if si.buffnocd then
-					local buffStart, buffEnding, buffStacks = self:GetAura("player", si.buffnocd)
-					if buffStart then
-						Ovale:Logf("buffnocd stacks = %s, start = %s, ending = %s, startCast = %f", buffStacks, buffStart, buffEnding, startCast)
-					end
-					if buffStacks and buffStacks > 0 and buffStart and buffStart <= startCast and (not buffEnding or buffEnding > startCast) then
-						cd.duration = 0
+					local start, ending, stacks = self:GetAura("player", si.buffnocd)
+					if start then
+						Ovale:Logf("buffnocd stacks = %s, start = %s, ending = %s, startCast = %f", stacks, start, ending, startCast)
+						if stacks and stacks > 0 and start <= startCast and (not ending or ending > startCast) then
+							cd.duration = 0
+						end
 					end
 				end
 				if si.targetlifenocd then
-					--TODO
 					if API_UnitHealth("target") / API_UnitHealthMax("target") * 100 < si.targetlifenocd then
 						cd.duration = 0
 					end
@@ -464,6 +368,140 @@ function OvaleState:ApplySpell(spellId, startCast, endCast, nextCast, nocd, targ
 	end
 end

+function OvaleState:ApplySpellCost(spellId, startCast, endCast)
+	local si = OvaleData.spellInfo[spellId]
+	local _, _, _, cost, _, powerType = API_GetSpellInfo(spellId)
+
+	-- Update power using information from GetSpellInfo() if there is no user-defined SpellInfo() for the spell's cost.
+	if cost and powerType then
+		local power = OvalePower.POWER_TYPE[powerType]
+		if not si or not si[power] then
+			self.state[power] = self.state[power] - cost
+		end
+	end
+
+	if si then
+		-- Update power state, except for combo points, eclipse energy, and runes.
+		for power, v in pairs(OvalePower.POWER) do
+			if power ~= "eclipse" then
+				local cost = si[power]
+				if cost then
+					--[[
+						cost > 0 means that the spell costs resources.
+						cost < 0 means that the spell generates resources.
+						cost == 0 means that the spell uses all of the resources (zeroes it out).
+					--]]
+					if cost == 0 then
+						self.state[power] = 0
+					else
+						self.state[power] = self.state[power] - cost
+					end
+					--[[
+						Add extra resource generated by presence of a buff.
+						"buff_<power>" is the spell ID of the buff that causes extra resources to be generated or used.
+						"buff_<power>_amount" is the amount of extra resources generated or used, defaulting to -1
+							(one extra resource generated).
+					--]]
+					local buffParam = "buff_" .. tostring(power)
+					local buffAmoumtParam = buffParam .. "_amount"
+					if si[buffParam] and self:GetAura("player", si[buffParam], nil, true) then
+						local buffAmount = si[buffAmountParam] or -1
+						self.state[power] = self.state[power] - buffAmount
+					end
+					-- Clamp self.state[power] to lower and upper limits.
+					local mini = v.mini or 0
+					local maxi = v.maxi or OvalePower.maxPower[power]
+					if mini and self.state[power] < mini then
+						self.state[power] = mini
+					end
+					if maxi and self.state[power] > maxi then
+						self.state[power] = maxi
+					end
+				end
+			end
+		end
+
+		--[[
+			Combo points: This resource is handled specially because it has different semantics
+			from other resources. In particular, it's a resource that's attached to the target
+			and not to the player.
+		--]]
+		if si.combo then
+			local combo = si.combo
+			--[[
+				Combo points have the opposite meaning from other resources:
+
+				combo > 0 means that the spell generates resources.
+				combo < 0 means that the spell costs resources.
+				combo == 0 means that the spell uses all of the combo points.
+			--]]
+			if combo == 0 then
+				self.state.combo = 0
+			else
+				self.state.combo = self.state.combo + combo
+			end
+			--[[
+				Add extra combo points generated by presence of a buff.
+				"buff_combo" is the spell ID of the buff that causes extra points to be generated or used.
+				"buff_combo_amount" is the number of extra points generated or used, defaulting to 1
+					(one extra resource generated).
+			--]]
+			if si.buff_combo and self:GetAura("player", si.buff_combo, nil, true) then
+				local buffAmount = si.buff_combo_amount or 1
+				self.state.combo = self.state.combo + buffAmount
+			end
+			-- Clamp self.state.combo to lower and upper limits.
+			if self.state.combo < 0 then
+				self.state.combo = 0
+			end
+			if self.state.combo > MAX_COMBO_POINTS then
+				self.state.combo = MAX_COMBO_POINTS
+			end
+		end
+
+		-- Eclipse
+		if si.eclipse then
+			local energy = si.eclipse
+			local direction = self:GetEclipseDir()
+			if si.eclipsedir then
+				energy = energy * direction
+			end
+			-- Euphoria: While not in an Eclipse state, your spells generate double the normal amount of Solar or Lunar energy.
+			if OvaleSpellBook:IsKnownSpell(81062)
+					and not self:GetAura("player", LUNAR_ECLIPSE, "HELPFUL", true)
+					and not self:GetAura("player", SOLAR_ECLIPSE, "HELPFUL", true) then
+				energy = energy * 2
+			end
+			-- Only adjust Eclipse energy if the spell moves the Eclipse bar in the right direction.
+			if (direction < 0 and energy < 0) or (direction > 0 and energy > 0) then
+				self.state.eclipse = self.state.eclipse + energy
+			end
+			-- Clamp Eclipse energy to min/max values and note that an Eclipse state will be reached after the spellcast.
+			if self.state.eclipse <= -100 then
+				self.state.eclipse = -100
+				AddEclipse(endCast, LUNAR_ECLIPSE)
+			elseif self.state.eclipse >= 100 then
+				self.state.eclipse = 100
+				AddEclipse(endCast, SOLAR_ECLIPSE)
+			end
+		end
+
+		--Runes
+		if si.frost then
+			self:AddRune(startCast, 3, si.frost)
+		end
+		if si.death then
+			self:AddRune(startCast, 4, si.death)
+		end
+		if si.blood then
+			self:AddRune(startCast, 1, si.blood)
+		end
+		if si.unholy then
+			self:AddRune(startCast, 2, si.unholy)
+		end
+	end
+end
+
 function OvaleState:AddRune(time, type, value)
 	if value<0 then
 		for i=1,6 do