Quantcast

Add new power-type parameters to be used in SpellInfo().

Johnny C. Lam [04-21-14 - 05:02]
Add new power-type parameters to be used in SpellInfo().

- Make the "buff no cost" and "buff half cost" parameters power-specific.

  The new parameters are now:

    buff_<powerType>_none, e.g., "buff_chi_none", "buff_focus_none", etc.
    buff_<powerType>_half, e.g., "buff_energy_half", etc.

- Add "min_<powerType>" parameter for minimum resource requirements.

- Add "max_<powerType>" parameter for maximum resource requirements.

  For example, a holy power "finisher" denoted by holy=0 can be capped at
  using a maximum of 3 holy power.

- Teach state:PowerCost() to properly return the cost of a "finisher"
  spell that consumes all (or some variable portion) of the resource.

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1301 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
OvaleBestAction.lua
OvaleComboPoints.lua
OvaleFuture.lua
OvalePower.lua
diff --git a/OvaleBestAction.lua b/OvaleBestAction.lua
index 888425a..e7f6e61 100644
--- a/OvaleBestAction.lua
+++ b/OvaleBestAction.lua
@@ -741,19 +741,18 @@ function OvaleBestAction:GetActionInfo(element, state)
 				-- Spell requires a stance that player is not in.
 				return nil
 			end
-			if si.combo == 0 then
-				local mincombo = si.mincombo or 1
-				if state.combo < mincombo then
-					-- Spell is a combo point finisher, but player has too few combo points on the target.
+			if si.combo then
+				-- Spell requires combo points.
+				local cost = state:ComboPointCost(spellId)
+				if state.combo < cost then
 					return nil
 				end
 			end
 			for _, powerType in pairs(OvalePower.SECONDARY_POWER) do
 				if si[powerType] then
+					-- Spell requires "secondary" resources, e.g., chi, focus, rage, etc.,
 					local cost = state:PowerCost(spellId, powerType)
-					if cost > state[powerType] then
-						-- Spell requires "secondary" resources, e.g., chi, focus, rage, etc.,
-						-- that the player does not have enough of.
+					if state[powerType] < cost then
 						return nil
 					end
 				end
diff --git a/OvaleComboPoints.lua b/OvaleComboPoints.lua
index 496bbd9..c5d2d7e 100644
--- a/OvaleComboPoints.lua
+++ b/OvaleComboPoints.lua
@@ -1,6 +1,6 @@
 --[[--------------------------------------------------------------------
     Ovale Spell Priority
-    Copyright (C) 2012, 2013 Johnny C. Lam
+    Copyright (C) 2012, 2013, 2014 Johnny C. Lam

     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License in the LICENSE
@@ -139,31 +139,9 @@ end
 function OvaleComboPoints:ApplySpellAfterCast(state, spellId, targetGUID, startCast, endCast, nextCast, isChanneled, nocd, spellcast)
 	local si = OvaleData.spellInfo[spellId]
 	if si and si.combo then
-		local cost = si.combo
-		local power = state.combo or 0
-		--[[
-			cost > 0 means that the spell generates combo points.
-			cost < 0 means that the spell costs combo points.
-			cost == 0 means that the spell uses all of the combo points (finisher).
-		--]]
-		if cost == 0 then
-			power = 0
-		else
-			power = power + cost
-		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 point generated).
-		--]]
-		if si.buff_combo then
-			local aura = state:GetAura("player", si.buff_combo, nil, true)
-			if state:IsActiveAura(aura) then
-				local buffAmount = si.buff_combo_amount or 1
-				power = power + buffAmount
-			end
-		end
+		local cost = state:ComboPointCost(spellId)
+		local power = state.combo
+		power = power - cost
 		-- Clamp combo points to lower and upper limits.
 		if power < 0 then
 			power = 0
@@ -175,3 +153,60 @@ function OvaleComboPoints:ApplySpellAfterCast(state, spellId, targetGUID, startC
 	end
 end
 --</public-static-methods>
+
+--<state-methods>
+-- Return the number of combo points required to cast the given spell.
+statePrototype.ComboPointCost = function(state, spellId)
+	local spellCost = 0
+	local si = OvaleData.spellInfo[spellId]
+	if si and si.combo then
+		local cost = si.combo
+		--[[
+			combo == 0 means the that spell uses no resources.
+			combo > 0 means that the spell generates combo points.
+			combo < 0 means that the spell costs combo points.
+			combo == "finisher" means that the spell uses all of the combo points (zeroes it out).
+		--]]
+		if cost == "finisher" then
+			-- This spell is a finisher so compute the cost based on the amount of resources consumed.
+			cost = state.combo
+			-- Clamp cost between values defined by min_combo and max_combo.
+			local minCost = si.min_combo or si.mincombo or 1
+			local maxCost = si.max_combo
+			if cost < minCost then
+				cost = minCost
+			end
+			if maxCost and cost > maxCost then
+				cost = maxCost
+			end
+		else
+			--[[
+				Add extra combo points generated by presence of a buff.
+				"buff_combo" is the spell ID of the buff that causes extra resources to be generated or used.
+				"buff_combo_amount" is the amount of extra resources generated or used, defaulting to 1
+					(one extra combo point generated).
+			--]]
+			local buffExtra = si.buff_combo
+			if buffExtra then
+				local aura = state:GetAura("player", buffExtra, nil, true)
+				if state:IsActiveAura(aura) then
+					local buffAmount = si.buff_combo_amount or 1
+					cost = cost + buffAmount
+				end
+			end
+			cost = -1 * cost
+		end
+
+		local buffNoCost = si.buff_combo_none
+		if buffNoCost then
+			-- "buff_combo_none" is the spell ID of the buff that makes casting the spell cost zero combo points.
+			local aura = state:GetAura("player", buffNoCost)
+			if state:IsActiveAura(aura) then
+				cost = 0
+			end
+		end
+		spellCost = cost
+	end
+	return spellCost
+end
+--</state-methods>
diff --git a/OvaleFuture.lua b/OvaleFuture.lua
index 01b6f05..d66579c 100644
--- a/OvaleFuture.lua
+++ b/OvaleFuture.lua
@@ -38,6 +38,7 @@ local API_UnitCastingInfo = UnitCastingInfo
 local API_UnitChannelInfo = UnitChannelInfo
 local API_UnitGUID = UnitGUID
 local API_UnitName = UnitName
+local MAX_COMBO_POINTS = MAX_COMBO_POINTS

 -- Player's GUID.
 local self_guid = nil
@@ -168,16 +169,36 @@ local function AddSpellToQueue(spellId, lineId, startTime, endTime, channeled, a
 		end

 		-- Save the number of combo points used if this spell is a finisher.
-		if si.combo == 0 then
+		if si.combo == "finisher" then
+			-- If a buff is present that removes the combo point cost of the spell,
+			-- then treat it as a maximum combo-point finisher.
+			if si.buff_combo_none then
+				if OvaleAura:GetAura("player", si.buff_combo_none) then
+					spellcast.combo = MAX_COMBO_POINTS
+				end
+			end
 			if OvaleComboPoints.combo > 0 then
 				spellcast.combo = OvaleComboPoints.combo
 			end
 		end

 		-- Save the number of holy power used if this spell is a finisher.
-		if si.holy == 0 then
-			if OvalePower.power.holy > 0 then
-				spellcast.holy = OvalePower.power.holy
+		if si.holy == "finisher" then
+			local max_holy = si.max_holy or 3
+			-- If a buff is present that removes the holy power cost of the spell,
+			-- then treat it as using the maximum amount of holy power.
+			if si.buff_holy_none then
+				if OvaleAura:GetAura("player", si.buff_holy_none) then
+					spellcast.holy = max_holy
+				end
+			end
+			local holy = OvalePower.power.holy
+			if holy > 0 then
+				if holy > max_holy then
+					spellcast.holy = max_holy
+				else
+					spellcast.holy = holy
+				end
 			end
 		end

diff --git a/OvalePower.lua b/OvalePower.lua
index 9a144ce..7225d25 100644
--- a/OvalePower.lua
+++ b/OvalePower.lua
@@ -1,7 +1,7 @@
 --[[--------------------------------------------------------------------
     Ovale Spell Priority
     Copyright (C) 2012 Sidoine
-    Copyright (C) 2012, 2013 Johnny C. Lam
+    Copyright (C) 2012, 2013, 2014 Johnny C. Lam

     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License in the LICENSE
@@ -19,6 +19,7 @@ local OvaleState = nil

 local ceil = math.ceil
 local pairs = pairs
+local type = type
 local API_GetPowerRegen = GetPowerRegen
 local API_GetSpellInfo = GetSpellInfo
 local API_UnitPower = UnitPower
@@ -299,16 +300,7 @@ function OvalePower:ApplySpellAfterCast(state, spellId, targetGUID, startCast, e
 				local cost = state:PowerCost(spellId, powerType)
 				local power = state[powerType] or 0
 				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
-						power = 0
-					else
-						power = power - cost
-					end
+					power = power - cost
 					-- Clamp power to lower and upper limits.
 					local mini = powerInfo.mini or 0
 					local maxi = powerInfo.maxi or self.maxPower[powerType]
@@ -328,49 +320,75 @@ end

 --<state-methods>
 statePrototype.PowerCost = function(state, spellId, powerType)
-	local spellCost = nil
+	local buffParam = "buff_" .. powerType
+	local spellCost = 0
 	local si = OvaleData.spellInfo[spellId]
 	if si and si[powerType] then
-		local cost = si[powerType]
 		--[[
+			cost == 0 means the that spell uses no resources.
 			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).
-
-			Add extra resource generated by presence of a buff.
-			"buff_<powerType>" is the spell ID of the buff that causes extra resources to be generated or used.
-			"buff_<powerType>_amount" is the amount of extra resources generated or used, defaulting to -1
-				(one extra resource generated).
-
-			Some buffs can change the cost of a spell.
-			"buffnocost" is the spell ID of the buff that makes casting the spell resource-free.
-			"buffhalfcost" is the spell ID of the buff that makes casting the spell cost half the resources.
+			cost == "finisher" means that the spell uses all of the resources (zeroes it out).
 		--]]
-		if si.buffnocost and cost > 0 then
-			local aura = state:GetAura("player", si.buffnocost)
-			if state:IsActiveAura(aura) then
-				cost = 0
+		local cost = si[powerType]
+		if cost == "finisher" then
+			-- This spell is a finisher so compute the cost based on the amount of resources consumed.
+			cost = state[powerType]
+			-- Clamp cost between values defined by min_<powerType> and max_<powerType>.
+			local minCostParam = "min_" .. powerType
+			local maxCostParam = "max_" .. powerType
+			local minCost = si[minCostParam] or 1
+			local maxCost = si[maxCostParam]
+			if cost < minCost then
+				cost = minCost
+			end
+			if maxCost and cost > maxCost then
+				cost = maxCost
 			end
 		else
-			local buffParam = "buff_" .. tostring(powerType)
-			local buffAmoumtParam = buffParam .. "_amount"
-			if si[buffParam] then
-				local aura = state:GetAura("player", si[buffParam], nil, true)
+			--[[
+				Add extra resource generated by presence of a buff.
+				"buff_<powerType>" is the spell ID of the buff that causes extra resources to be generated or used.
+				"buff_<powerType>_amount" is the amount of extra resources generated or used, defaulting to -1
+					(one extra resource generated).
+			--]]
+			local buffExtraParam = buffParam
+			local buffAmountParam = buffParam .. "_amount"
+			local buffExtra = si[buffExtraParam]
+			if buffExtra then
+				local aura = state:GetAura("player", buffExtra, nil, true)
 				if state:IsActiveAura(aura) then
 					local buffAmount = si[buffAmountParam] or -1
 					cost = cost + buffAmount
 				end
 			end
-			-- Apply any percent reductions to cost after fixed reductions are applied.
-			-- This seems to be a consistent Blizzard rule for spell costs so that you
-			-- never end up with a negative spell cost.
-			if si.buffhalfcost then
-				local aura = state:GetAura("player", si.buffhalfcost)
-				if state:IsActiveAura(aura) then
-					cost = ceil(cost / 2)
+			if cost > 0 then
+				--[[
+					Apply any percent reductions to cost after fixed reductions are applied.
+					This seems to be a consistent Blizzard rule for spell costs so that you
+					never end up with a negative spell cost.
+				--]]
+				-- "buff_<powerType>_half" is the spell ID of the buff that makes casting the spell cost half the resources.
+				local buffHalfCostParam = buffParam .. "_half"
+				local buffHalfCost = si[buffHalfCostParam]
+				if buffHalfCost then
+					local aura = state:GetAura("player", buffHalfCost)
+					if state:IsActiveAura(aura) then
+						cost = ceil(cost / 2)
+					end
 				end
 			end
 		end
+
+		local buffNoCostParam = buffParam .. "_none"
+		local buffNoCost = si[buffNoCostParam]
+		if buffNoCost then
+			-- "buff_<powerType>_none" is the spell ID of the buff that makes casting the spell resource-free.
+			local aura = state:GetAura("player", buffNoCost)
+			if state:IsActiveAura(aura) then
+				cost = 0
+			end
+		end
 		spellCost = cost
 	else
 		-- Determine cost using information from GetSpellInfo() if there is no SpellInfo() for the spell's cost.