Quantcast

Factor in power regen time for spell "readiness".

Johnny C. Lam [04-25-14 - 20:57]
Factor in power regen time for spell "readiness".

- Add a new state method TimeToPower() for the number of seconds before
  the given resource required is available for a spell.

- If the time to pool resources is longer than the time needed for a spell
  to come off cooldown, then add that additional time to the spell's
  cooldown duration.

These changes allow for "wait Spell(mangle_cat)" to have a time span for
the energy pooling.

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1332 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
OvaleBestAction.lua
OvalePower.lua
conditions/TimeToPowerFor.lua
scripts/ovale_druid.lua
diff --git a/OvaleBestAction.lua b/OvaleBestAction.lua
index 58a4fbf..8461715 100644
--- a/OvaleBestAction.lua
+++ b/OvaleBestAction.lua
@@ -757,7 +757,27 @@ function OvaleBestAction:GetActionInfo(element, state)
 					end
 				end
 			end
+
 			if actionCooldownStart and actionCooldownDuration then
+				-- Get the maximum time before all "primary" resources are ready.
+				local atTime = state.currentTime
+				for powerType in pairs(OvalePower.PRIMARY_POWER) do
+					if si[powerType] then
+						local t = state.currentTime + state:TimeToPower(spellId, powerType)
+						if atTime < t then
+							atTime = t
+						end
+					end
+				end
+				if actionCooldownStart > 0 then
+					if atTime > actionCooldownStart + actionCooldownDuration then
+						actionCooldownDuration = atTime - actionCooldownStart
+					end
+				else
+					actionCooldownStart = state.currentTime
+					actionCooldownDuration = atTime - actionCooldownStart
+				end
+
 				if si.blood or si.frost or si.unholy or si.death then
 					-- Spell requires runes.
 					local runecd = state:GetRunesCooldown(si.blood, si.unholy, si.frost, si.death, false)
diff --git a/OvalePower.lua b/OvalePower.lua
index e6b19d4..5deefa9 100644
--- a/OvalePower.lua
+++ b/OvalePower.lua
@@ -332,6 +332,24 @@ 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]
+	local powerRate = state.powerRate[powerType]
+	local cost = state:PowerCost(spellId, powerType)
+
+	local seconds = 0
+	if power < cost then
+		if powerRate > 0 then
+			seconds = (cost - power) / powerRate
+		else
+			seconds = math.huge
+		end
+	end
+	return seconds
+end
+
+-- Return the amount of the given resource needed to cast the given spell.
 statePrototype.PowerCost = function(state, spellId, powerType)
 	local buffParam = "buff_" .. powerType
 	local spellCost = 0
diff --git a/conditions/TimeToPowerFor.lua b/conditions/TimeToPowerFor.lua
index eba90b0..88b0660 100644
--- a/conditions/TimeToPowerFor.lua
+++ b/conditions/TimeToPowerFor.lua
@@ -19,35 +19,51 @@ do
 	local TestValue = OvaleCondition.TestValue
 	local state = OvaleState.state

-	--- Get the number of seconds before the player has enough primary resources to cast the given spell.
-	-- @name TimeToPowerFor
+	local function TimeToPower(powerType, condition)
+		local spellId, comparator, limit = condition[1], condition[2], condition[3]
+		if not powerType then
+			local _, _, _, _, _, powerToken = API_GetSpellInfo(spellId)
+			powerType = OvalePower.POWER_TYPE[powerToken]
+		end
+		local seconds = state:TimeToPower(spellId, powerType)
+
+		if seconds == 0 then
+			return Compare(0, comparator, limit)
+		elseif seconds < math.huge then
+			return TestValue(0, state.currentTime + seconds, seconds, state.currentTime, -1, comparator, limit)
+		else -- if seconds == math.huge then
+			return Compare(math.huge, comparator, limit)
+		end
+	end
+
+	--- Get the number of seconds before the player has enough energy to cast the given spell.
+	-- @name TimeToEnergyFor
 	-- @paramsig number or boolean
 	-- @param id The spell ID.
 	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
 	-- @param number Optional. The number to compare against.
 	-- @return The number of seconds.
 	-- @return A boolean value for the result of the comparison.
-	-- @see TimeToEnergyFor, TimeToFocusFor, TimeToMaxEnergy
+	-- @see TimeToEnergyFor, TimeToMaxEnergy

-	local function TimeToPowerFor(condition)
-		local spellId, comparator, limit = condition[1], condition[2], condition[3]
-		local _, _, _, cost, _, powerToken = API_GetSpellInfo(spellId)
-		local powerType = OvalePower.POWER_TYPE[powerToken]
-		local currentPower = state[powerType]
-		local powerRate = state.powerRate[powerType]
-		cost = cost or 0
-		if currentPower < cost then
-			if powerRate > 0 then
-				local t = (cost - currentPower)/powerRate
-				return TestValue(0, state.currentTime + t, t, state.currentTime, -1, comparator, limit)
-			else
-				return Compare(math.huge, comparator, limit)
-			end
-		end
-		return Compare(0, comparator, limit)
+	local function TimeToEnergyFor(condition)
+		return TimeToPower("energy", condition)
+	end
+
+	--- Get the number of seconds before the player has enough focus to cast the given spell.
+	-- @name TimeToFocusFor
+	-- @paramsig number or boolean
+	-- @param id The spell ID.
+	-- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+	-- @param number Optional. The number to compare against.
+	-- @return The number of seconds.
+	-- @return A boolean value for the result of the comparison.
+	-- @see TimeToFocusFor
+
+	local function TimeToFocusFor(condition)
+		return TimeToPower("focus", condition)
 	end

-	OvaleCondition:RegisterCondition("timetoenergyfor", true, TimeToPowerFor)
-	OvaleCondition:RegisterCondition("timetofocusfor", true, TimeToPowerFor)
-	OvaleCondition:RegisterCondition("timetopowerfor", true, TimeToPowerFor)
-end
\ No newline at end of file
+	OvaleCondition:RegisterCondition("timetoenergyfor", true, TimeToEnergyFor)
+	OvaleCondition:RegisterCondition("timetofocusfor", true, TimeToFocusFor)
+end
diff --git a/scripts/ovale_druid.lua b/scripts/ovale_druid.lua
index 96e1627..8db5c53 100644
--- a/scripts/ovale_druid.lua
+++ b/scripts/ovale_druid.lua
@@ -256,7 +256,7 @@ AddFunction FeralBasicActions
 	if target.DebuffRemains(rake_debuff) < 3 or target.Damage(rake_debuff) > target.LastEstimatedDamage(rake_debuff) Spell(rake)
 	#pool_resource,for_next=1
 	#thrash_cat,if=dot.thrash_cat.remains<3&(dot.rip.remains>=8&buff.savage_roar.remains>=12|buff.berserk.up|combo_points>=5)
-	if Energy() >= EnergyCost(thrash_cat) and target.DebuffRemains(thrash_cat_debuff) < 3 and { target.DebuffRemains(rip_debuff) >= 8 and BuffRemains(savage_roar_buff) >= 12 or BuffPresent(berserk_cat_buff) or ComboPoints() >= 5 } wait Spell(thrash_cat)
+	if target.DebuffRemains(thrash_cat_debuff) < 3 and { target.DebuffRemains(rip_debuff) >= 8 and BuffRemains(savage_roar_buff) >= 12 or BuffPresent(berserk_cat_buff) or ComboPoints() >= 5 } wait Spell(thrash_cat)
 	#pool_resource,if=combo_points>=5&!(energy.time_to_max<=1|(buff.berserk.up&energy>=25)|(buff.feral_rage.up&buff.feral_rage.remains<=1))&dot.rip.ticking
 	unless ComboPoints() >= 5 and not { TimeToMaxEnergy() <= 1 or { BuffPresent(berserk_cat_buff) and Energy() >= 25 } or { BuffPresent(feral_rage_buff) and BuffRemains(feral_rage_buff) <= 1 } } and target.DebuffPresent(rip_debuff)
 	{
@@ -306,7 +306,7 @@ AddFunction FeralBasicPredictiveActions
 	if target.DebuffRemains(rake_debuff) < 3 or target.Damage(rake_debuff) > target.LastEstimatedDamage(rake_debuff) Spell(rake)
 	#pool_resource,for_next=1
 	#thrash_cat,if=dot.thrash_cat.remains<3&(dot.rip.remains>=8&buff.savage_roar.remains>=12|buff.berserk.up|combo_points>=5)
-	if Energy() >= EnergyCost(thrash_cat) and target.DebuffRemains(thrash_cat_debuff) < 3 and { target.DebuffRemains(rip_debuff) >= 8 and BuffRemains(savage_roar_buff) >= 12 or BuffPresent(berserk_cat_buff) or ComboPoints() >= 5 } wait Spell(thrash_cat)
+	if target.DebuffRemains(thrash_cat_debuff) < 3 and { target.DebuffRemains(rip_debuff) >= 8 and BuffRemains(savage_roar_buff) >= 12 or BuffPresent(berserk_cat_buff) or ComboPoints() >= 5 } wait Spell(thrash_cat)
 	#pool_resource,if=combo_points>=5&!(energy.time_to_max<=1|(buff.berserk.up&energy>=25)|(buff.feral_rage.up&buff.feral_rage.remains<=1))&dot.rip.ticking
 	unless ComboPoints() >= 5 and not { TimeToMaxEnergy() <= 1 or { BuffPresent(berserk_cat_buff) and Energy() >= 25 } or { BuffPresent(feral_rage_buff) and BuffRemains(feral_rage_buff) <= 1 } } and target.DebuffPresent(rip_debuff)
 	{
@@ -355,10 +355,10 @@ AddFunction FeralAoeActions
 	if BuffPresent(tigers_fury_buff) Spell(berserk_cat)
 	#pool_resource,for_next=1
 	#thrash_cat,if=buff.rune_of_reorigination.up
-	if Energy() >= EnergyCost(thrash_cat) and BuffPresent(rune_of_reorigination_buff) wait Spell(thrash_cat)
+	if BuffPresent(rune_of_reorigination_buff) wait Spell(thrash_cat)
 	#pool_resource,wait=0.1,for_next=1
 	#thrash_cat,if=dot.thrash_cat.remains<3|(buff.tigers_fury.up&dot.thrash_cat.remains<9)
-	if Energy() >= EnergyCost(thrash_cat) and target.DebuffRemains(thrash_cat_debuff) < 3 or { BuffPresent(tigers_fury_buff) and target.DebuffRemains(thrash_cat_debuff) < 9 } wait Spell(thrash_cat)
+	if target.DebuffRemains(thrash_cat_debuff) < 3 or { BuffPresent(tigers_fury_buff) and target.DebuffRemains(thrash_cat_debuff) < 9 } wait Spell(thrash_cat)
 	#savage_roar,if=buff.savage_roar.remains<9&combo_points>=5
 	if BuffRemains(savage_roar_buff) < 9 and ComboPoints() >= 5 SavageRoar()
 	#rip,if=combo_points>=5
@@ -446,7 +446,7 @@ AddFunction FeralAdvancedActions
 		if target.TimeToDie() - target.DebuffRemains(rake_debuff) > 3 and { target.Damage(rake_debuff) > target.LastEstimatedDamage(rake_debuff) or { target.DebuffRemains(rake_debuff) < 3 and target.Damage(rake_debuff) / target.LastEstimatedDamage(rake_debuff) >= 0.75 } } Spell(rake)
 		#pool_resource,for_next=1
 		#thrash_cat,if=target.time_to_die>=6&dot.thrash_cat.remains<3&(dot.rip.remains>=8&buff.savage_roar.remains>=12|buff.berserk.up|combo_points>=5)&dot.rip.ticking
-		if Energy() >= EnergyCost(thrash_cat) and target.TimeToDie() >= 6 and target.DebuffRemains(thrash_cat_debuff) < 3 and { target.DebuffRemains(rip_debuff) >= 8 and BuffRemains(savage_roar_buff) >= 12 or BuffPresent(berserk_cat_buff) or ComboPoints() >= 5 } and target.DebuffPresent(rip_debuff) wait Spell(thrash_cat)
+		if target.TimeToDie() >= 6 and target.DebuffRemains(thrash_cat_debuff) < 3 and { target.DebuffRemains(rip_debuff) >= 8 and BuffRemains(savage_roar_buff) >= 12 or BuffPresent(berserk_cat_buff) or ComboPoints() >= 5 } and target.DebuffPresent(rip_debuff) wait Spell(thrash_cat)
 		#pool_resource,for_next=1
 		#thrash_cat,if=target.time_to_die>=6&dot.thrash_cat.remains<9&buff.rune_of_reorigination.up&buff.rune_of_reorigination.remains<=1.5&dot.rip.ticking
 		if target.TimeToDie() >= 6 and target.DebuffRemains(thrash_cat_debuff) < 9 and BuffPresent(rune_of_reorigination_buff) and BuffRemains(rune_of_reorigination_buff) <= 1.5 and target.DebuffPresent(rip_debuff) wait Spell(thrash_cat)
@@ -519,7 +519,7 @@ AddFunction FeralAdvancedPredictiveActions
 		if target.TimeToDie() - target.DebuffRemains(rake_debuff) > 3 and { target.Damage(rake_debuff) > target.LastEstimatedDamage(rake_debuff) or { target.DebuffRemains(rake_debuff) < 3 and target.Damage(rake_debuff) / target.LastEstimatedDamage(rake_debuff) >= 0.75 } } Spell(rake)
 		#pool_resource,for_next=1
 		#thrash_cat,if=target.time_to_die>=6&dot.thrash_cat.remains<3&(dot.rip.remains>=8&buff.savage_roar.remains>=12|buff.berserk.up|combo_points>=5)&dot.rip.ticking
-		if Energy() >= EnergyCost(thrash_cat) and target.TimeToDie() >= 6 and target.DebuffRemains(thrash_cat_debuff) < 3 and { target.DebuffRemains(rip_debuff) >= 8 and BuffRemains(savage_roar_buff) >= 12 or BuffPresent(berserk_cat_buff) or ComboPoints() >= 5 } and target.DebuffPresent(rip_debuff) wait Spell(thrash_cat)
+		if target.TimeToDie() >= 6 and target.DebuffRemains(thrash_cat_debuff) < 3 and { target.DebuffRemains(rip_debuff) >= 8 and BuffRemains(savage_roar_buff) >= 12 or BuffPresent(berserk_cat_buff) or ComboPoints() >= 5 } and target.DebuffPresent(rip_debuff) wait Spell(thrash_cat)
 		#pool_resource,for_next=1
 		#thrash_cat,if=target.time_to_die>=6&dot.thrash_cat.remains<9&buff.rune_of_reorigination.up&buff.rune_of_reorigination.remains<=1.5&dot.rip.ticking
 		if target.TimeToDie() >= 6 and target.DebuffRemains(thrash_cat_debuff) < 9 and BuffPresent(rune_of_reorigination_buff) and BuffRemains(rune_of_reorigination_buff) <= 1.5 and target.DebuffPresent(rip_debuff) wait Spell(thrash_cat)