Quantcast

Channeled spells cost resources at the start of the channel.

Johnny C. Lam [05-16-14 - 21:54]
Channeled spells cost resources at the start of the channel.

Update the resources in the simulator at the appropriate time based on
whether the spellcast is channeled or not.

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1459 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
OvalePower.lua
OvaleRunes.lua
diff --git a/OvalePower.lua b/OvalePower.lua
index 2545b79..2f1cf03 100644
--- a/OvalePower.lua
+++ b/OvalePower.lua
@@ -291,16 +291,34 @@ function OvalePower:CleanState(state)
 	end
 end

+-- Apply the effects of the spell at the start of the spellcast.
+function OvalePower:ApplySpellStartCast(state, spellId, targetGUID, startCast, endCast, nextCast, isChanneled, nocd, spellcast)
+	-- Channeled spells cost resources at the start of the channel.
+	if isChanneled then
+		state:ApplyPowerCost(spellId)
+	end
+end
+
 -- Apply the effects of the spell on the player's state, assuming the spellcast completes.
 function OvalePower:ApplySpellAfterCast(state, spellId, targetGUID, startCast, endCast, nextCast, isChanneled, nocd, spellcast)
+	-- Instant or cast-time spells cost resources at the end of the spellcast.
+	if not isChanneled then
+		state:ApplyPowerCost(spellId)
+	end
+end
+--</public-static-methods>
+
+--<state-methods>
+-- Update the state of the simulator for the power cost of the given spell.
+statePrototype.ApplyPowerCost = function(state, spellId)
 	local si = OvaleData.spellInfo[spellId]

 	-- Update power using information from GetSpellInfo() if there is no SpellInfo() for the spell's cost.
 	do
 		local _, _, _, cost, _, powerTypeId = API_GetSpellInfo(spellId)
 		if cost and powerTypeId then
-			powerType = self.POWER_TYPE[powerTypeId]
-			if not si or not si[powerType] then
+			powerType = OvalePower.POWER_TYPE[powerTypeId]
+			if state[powerType] and not (si and si[powerType]) then
 				state[powerType] = state[powerType] - cost
 			end
 		end
@@ -308,7 +326,7 @@ function OvalePower:ApplySpellAfterCast(state, spellId, targetGUID, startCast, e

 	if si then
 		-- Update power state except for eclipse energy (handled by OvaleEclipse).
-		for powerType, powerInfo in pairs(self.POWER_INFO) do
+		for powerType, powerInfo in pairs(OvalePower.POWER_INFO) do
 			if powerType ~= "eclipse" then
 				local cost = state:PowerCost(spellId, powerType)
 				local power = state[powerType] or 0
@@ -316,7 +334,7 @@ function OvalePower:ApplySpellAfterCast(state, spellId, targetGUID, startCast, e
 					power = power - cost
 					-- Clamp power to lower and upper limits.
 					local mini = powerInfo.mini or 0
-					local maxi = powerInfo.maxi or self.maxPower[powerType]
+					local maxi = powerInfo.maxi or OvalePower.maxPower[powerType]
 					if mini and power < mini then
 						power = mini
 					end
@@ -329,9 +347,7 @@ function OvalePower:ApplySpellAfterCast(state, spellId, targetGUID, startCast, e
 		end
 	end
 end
---</public-static-methods>

---<state-methods>
 -- Return the number of seconds before all of the primary resources needed by a spell are available.
 statePrototype.TimeToPower = function(state, spellId, powerType)
 	local power = state[powerType]
diff --git a/OvaleRunes.lua b/OvaleRunes.lua
index 699f63e..12960a0 100644
--- a/OvaleRunes.lua
+++ b/OvaleRunes.lua
@@ -252,18 +252,19 @@ function OvaleRunes:CleanState(state)
 	end
 end

+-- Apply the effects of the spell at the start of the spellcast.
+function OvaleRunes:ApplySpellStartCast(state, spellId, targetGUID, startCast, endCast, nextCast, isChanneled, nocd, spellcast)
+	-- Channeled spells cost resources at the start of the channel.
+	if isChanneled then
+		state:ApplyRuneCost(spellId, startCast, spellcast)
+	end
+end
+
 -- Apply the effects of the spell on the player's state, assuming the spellcast completes.
 function OvaleRunes:ApplySpellAfterCast(state, spellId, targetGUID, startCast, endCast, nextCast, isChanneled, nocd, spellcast)
-	local si = OvaleData.spellInfo[spellId]
-	if si then
-		for i, name in ipairs(RUNE_NAME) do
-			local count = si[name] or 0
-			while count > 0 do
-				local atTime = isChanneled and startCast or endCast
-				state:ConsumeRune(atTime, spellId, name, spellcast.snapshot)
-				count = count - 1
-			end
-		end
+	-- Instant or cast-time spells cost resources at the end of the spellcast.
+	if not isChanneled then
+		state:ApplyRuneCost(spellId, endCast, spellcast)
 	end
 end
 --</public-static-methods>
@@ -280,6 +281,21 @@ statePrototype.DebugRunes = function(state)
 	end
 end

+-- Update the rune state with the rune cost of the give spell.
+statePrototype.ApplyRuneCost = function(state, spellId, atTime, spellcast)
+	local si = OvaleData.spellInfo[spellId]
+	if si then
+		for i, name in ipairs(RUNE_NAME) do
+			local count = si[name] or 0
+			while count > 0 do
+				local snapshot = spellcast and spellcast.snapshot or nil
+				state:ConsumeRune(atTime, spellId, name, snapshot)
+				count = count - 1
+			end
+		end
+	end
+end
+
 -- Consume a rune of the given type.  Assume that the required runes are available.
 statePrototype.ConsumeRune = function(state, spellId, atTime, name, snapshot)
 	--[[
@@ -300,6 +316,7 @@ statePrototype.ConsumeRune = function(state, spellId, atTime, name, snapshot)
 		if not consumedRune then
 			-- Search for an active death rune of the given rune type.
 			for _, slot in ipairs(RUNE_SLOTS[runeType]) do
+				local rune = state.rune[slot]
 				if rune.type == DEATH_RUNE and rune:IsActiveRune(atTime) then
 					consumedRune = rune
 					break
@@ -362,7 +379,7 @@ statePrototype.ConsumeRune = function(state, spellId, atTime, name, snapshot)
 		local maxi = OvalePower.maxPower.runicpower
 		state.runicpower = (runicpower < maxi) and runicpower or maxi
 	else
-		Ovale:Errorf("No %s rune available to consume!", RUNE_NAME[runeType])
+		Ovale:FormatPrint("No %s rune available to consume!", RUNE_NAME[runeType])
 	end
 end