Johnny C. Lam [04-21-14 - 05:02]
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.