Quantcast

Fix ticket #213 - Issue with Monk Energy Regeneration.

Johnny C. Lam [03-08-13 - 01:31]
Fix ticket #213 - Issue with Monk Energy Regeneration.

This fix has several parts.

Firstly, there was an error in energy regeneration calculations where the
percent haste effect wasn't properly scaled.

Secondly, the Way of the Monk passive effect will increase melee attack
speed by 40% but we have to remove it from the melee haste effect when
computing energy regeneration as that attack speed bonus has no effect.

OvaleEquipement has been extended to cache the weapon types of the
mainhand and offhand slots so that they may be easily checked.

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@736 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
OvaleAura.lua
OvaleBestAction.lua
OvaleCondition.lua
OvaleData.lua
OvaleEquipement.lua
OvalePaperDoll.lua
OvaleState.lua
diff --git a/OvaleAura.lua b/OvaleAura.lua
index 72c4385..efd1e45 100644
--- a/OvaleAura.lua
+++ b/OvaleAura.lua
@@ -57,7 +57,7 @@ function OvaleAura:COMBAT_LOG_EVENT_UNFILTERED(event, ...)
 			if sourceGUID == self.playerGUID and (event == "SPELL_AURA_APPLIED" or event == "SPELL_AURA_REFRESH" or event == "SPELL_AURA_APPLIED_DOSE") then
 				local aura = self:GetAuraByGUID(destGUID, spellId, true)
 				if aura then
-					aura.spellHaste = OvalePaperDoll.spellHaste
+					aura.spellHasteMultiplier = OvalePaperDoll:GetSpellHasteMultiplier()
 				end
 			end
 		end
diff --git a/OvaleBestAction.lua b/OvaleBestAction.lua
index 311675a..a1beba4 100644
--- a/OvaleBestAction.lua
+++ b/OvaleBestAction.lua
@@ -273,7 +273,7 @@ function OvaleBestAction:Compute(element)
 					else
 						--TODO: pas exact, parce que si ce sort est report de par exemple 0,5s par un debuff
 						--a tombera entre deux ticks
-						local ticks = floor(OvalePaperDoll.spellHaste * OvaleData.spellInfo[OvaleState.currentSpellId].canStopChannelling + 0.5)
+						local ticks = floor(OvalePaperDoll:GetSpellHasteMultiplier() * OvaleData.spellInfo[OvaleState.currentSpellId].canStopChannelling + 0.5)
 						local tickLength = (OvaleState.attenteFinCast - OvaleState.startCast) / ticks
 						local tickTime = OvaleState.startCast + tickLength
 						if (Ovale.trace) then
diff --git a/OvaleCondition.lua b/OvaleCondition.lua
index 1e3f506..a599db6 100644
--- a/OvaleCondition.lua
+++ b/OvaleCondition.lua
@@ -83,9 +83,9 @@ local function avecHate(temps, hate)
 	if (not hate) then
 		return temps
 	elseif (hate == "spell") then
-		return temps/(1 + OvalePaperDoll.spellHaste)
+		return temps / OvalePaperDoll:GetSpellHasteMultiplier()
 	elseif (hate == "melee") then
-		return temps/(1 + OvalePaperDoll.meleeHaste)
+		return temps / OvalePaperDoll:GetMeleeHasteMultiplier()
 	else
 		return temps
 	end
@@ -330,7 +330,7 @@ local function getMine(condition)
 end

 -- Recherche un aura sur la cible et récupère sa durée et le nombre de stacks
--- return start, ending, stacks, spellHaste
+-- return start, ending, stacks, spellHasteMultiplier
 local function GetTargetAura(condition, target)
 	if (not target) then
 		target=condition.target
@@ -366,7 +366,7 @@ local function GetTargetAura(condition, target)
 		else
 			ending = aura.ending
 		end
-		return aura.start, ending, aura.stacks, aura.spellHaste
+		return aura.start, ending, aura.stacks, aura.spellHasteMultiplier
 	else
 		return 0,0,0,0
 	end
@@ -1314,13 +1314,8 @@ end
 -- if HasShield() Spell(shield_wall)

 OvaleCondition.conditions.hasshield = function(condition)
-	local _,_,id = strfind(GetInventoryItemLink("player",GetInventorySlotInfo("SecondaryHandSlot")) or "","(item:%d+:%d+:%d+:%d+)")
-	if (not id) then
-		return testbool(false, condition[1])
-	end
-
-	local _,_,_,_,_,_,_,_,itemLoc = GetItemInfo(id)
-	return testbool(itemLoc=="INVTYPE_SHIELD", condition[1])
+	local itemType = OvaleEquipement.offHandWeaponType
+	return testbool(itemType == "INVTYPE_SHIELD", condition[1])
 end

 --- Test if the player has a particular trinket equipped.
@@ -1370,12 +1365,8 @@ OvaleCondition.conditions.hasweapon = function(condition)
 	if condition[1] == "offhand" then
 		return testbool(OffhandHasWeapon(), condition[2])
 	elseif condition[1] == "mainhand" then
-		local itemId = GetInventoryItemID("player", GetInventorySlotInfo("MainHandSlot"))
-		if not itemId then
-			return testbool(false, condition[2])
-		end
-		local invType = select(9, GetItemInfo(itemId))
-		return testbool(invType == "INVTYPE_WEAPON" or invType == "INVTYPE_2HWEAPON" or invType == "INVTYPE_WEAPONMAINHAND", condition[2])
+		local itemType = OvaleEquipement.mainHandWeaponType
+		return testbool(itemType == "INVTYPE_WEAPON" or itemType == "INVTYPE_2HWEAPON" or itemType == "INVTYPE_WEAPONMAINHAND", condition[2])
 	else
 		return testbool(false, condition[2])
 	end
@@ -1991,8 +1982,8 @@ end
 -- @see Ticks, TicksRemain, TickTime

 OvaleCondition.conditions.nexttick = function(condition)
-	local start, ending, _, spellHaste = GetTargetAura(condition, getTarget(condition.target))
-	local tickLength = OvaleData:GetTickLength(condition[1], spellHaste)
+	local start, ending, _, spellHasteMultiplier = GetTargetAura(condition, getTarget(condition.target))
+	local tickLength = OvaleData:GetTickLength(condition[1], spellHasteMultiplier)
 	if tickLength then
 		while ending - tickLength > OvaleState.currentTime do
 			ending = ending - tickLength
@@ -2532,7 +2523,7 @@ OvaleCondition.auraConditions.tickvalue = true
 OvaleCondition.conditions.ticks = function(condition)
 	-- TODO: extend to allow checking an existing DoT (how to get DoT duration?)
 	local spellId = condition[1]
-	local duration, tickLength = OvaleData:GetDuration(spellId, OvalePaperDoll.spellHaste, OvaleState.state.combo, OvaleState.state.holy)
+	local duration, tickLength = OvaleData:GetDuration(spellId, OvalePaperDoll:GetSpellHasteMultiplier(), OvaleState.state.combo, OvaleState.state.holy)
 	if tickLength then
 		local numTicks = floor(duration / tickLength + 0.5)
 		return compare(numTicks, condition[2], condition[3])
@@ -2567,8 +2558,8 @@ OvaleCondition.auraConditions.ticksadded = true
 --     Spell(shadow_word_pain)

 OvaleCondition.conditions.ticksremain = function(condition)
-	local start, ending, _, spellHaste = GetTargetAura(condition, getTarget(condition.target))
-	local tickLength = OvaleData:GetTickLength(condition[1], spellHaste)
+	local start, ending, _, spellHasteMultiplier = GetTargetAura(condition, getTarget(condition.target))
+	local tickLength = OvaleData:GetTickLength(condition[1], spellHasteMultiplier)
 	if tickLength then
 		local remain = 1
 		local tickTime = ending
@@ -2596,11 +2587,11 @@ OvaleCondition.auraConditions.ticksremain = true
 -- @see NextTick, Ticks, TicksRemain

 OvaleCondition.conditions.ticktime = function(condition)
-	local start, ending, _, spellHaste = GetTargetAura(condition, getTarget(condition.target))
+	local start, ending, _, spellHasteMultiplier = GetTargetAura(condition, getTarget(condition.target))
 	if not start or not ending or start > OvaleState.currentTime or ending < OvaleState.currentTime then
-		spellHaste = OvalePaperDoll.spellHaste
+		spellHasteMultiplier = OvalePaperDoll:GetSpellHasteMultiplier()
 	end
-	local tickLength = OvaleData:GetTickLength(condition[1], spellHaste)
+	local tickLength = OvaleData:GetTickLength(condition[1], spellHasteMultiplier)
 	if tickLength then
 		return compare(tickLength, condition[2], condition[3])
 	end
diff --git a/OvaleData.lua b/OvaleData.lua
index 1765026..c79530c 100644
--- a/OvaleData.lua
+++ b/OvaleData.lua
@@ -526,7 +526,7 @@ function OvaleData:GetGCD(spellId)
 			if not cd then
 				cd = 1.5
 			end
-			cd = cd / (1 + OvalePaperDoll.spellHaste)
+			cd = cd / OvalePaperDoll:GetSpellHasteMultiplier()
 			if (cd<1) then
 				cd = 1
 			end
@@ -544,7 +544,7 @@ function OvaleData:GetGCD(spellId)
 		return 1.0
 	elseif self.className == "MAGE" or self.className == "WARLOCK" or self.className == "PRIEST" or
 			(self.className == "DRUID" and not OvaleStance:IsStance("druid_bear_form")) then
-		local cd = 1.5 / (1 + OvalePaperDoll.spellHaste)
+		local cd = 1.5 / OvalePaperDoll:GetSpellHasteMultiplier()
 		if (cd<1) then
 			cd = 1
 		end
@@ -608,11 +608,11 @@ function OvaleData:GetDamage(spellId, attackpower, spellpower, combo)
 	return damage
 end

-function OvaleData:GetDuration(spellId, spellHaste, combo, holy)
+function OvaleData:GetDuration(spellId, spellHasteMultiplier, combo, holy)
 	local si = self.spellInfo[spellId]
 	if si and si.duration then
 		local duration = si.duration
-		spellHaste = spellHaste or 0
+		spellHasteMultiplier = spellHasteMultiplier or 1
 		combo = combo or 0
 		holy = holy or 1
 		if si.adddurationcp then
@@ -623,7 +623,7 @@ function OvaleData:GetDuration(spellId, spellHaste, combo, holy)
 		end
 		if si.tick then	-- DoT
 			--DoT duration is tickLength * numberOfTicks.
-			local tickLength = self:GetTickLength(spellId, spellHaste)
+			local tickLength = self:GetTickLength(spellId, spellHasteMultiplier)
 			local numTicks = floor(duration / tickLength + 0.5)
 			duration = tickLength * numTicks
 			return duration, tickLength
@@ -634,13 +634,13 @@ function OvaleData:GetDuration(spellId, spellHaste, combo, holy)
 	end
 end

-function OvaleData:GetTickLength(spellId, spellHaste)
+function OvaleData:GetTickLength(spellId, spellHasteMultiplier)
 	local si = self.spellInfo[spellId]
 	if si then
 		local tick = si.tick or 3
-		local haste = spellHaste or 0
+		spellHasteMultiplier = spellHasteMultiplier or 1
 		if si.haste == "spell" then
-			return tick / (1 + haste)
+			return tick / spellHasteMultiplier
 		else
 			return tick
 		end
diff --git a/OvaleEquipement.lua b/OvaleEquipement.lua
index 6472db1..e9e9173 100644
--- a/OvaleEquipement.lua
+++ b/OvaleEquipement.lua
@@ -886,6 +886,30 @@ local armorSet = {
 }
 --</private-static-properties>

+--<public-static-properties>
+-- type of equipped mainhand
+OvaleEquipement.mainHandWeaponType = nil
+-- type of equipped offhand
+OvaleEquipement.offHandWeaponType = nil
+--</public-static-properties>
+
+--<private-static-methods>
+local function GetEquippedWeaponType(slot)
+	local link = GetInventoryItemLink("player", GetInventorySlotInfo(slot))
+	if not link then return nil end
+	local _, _, itemId = strfind(link, "item:(%d+)");
+	local invType = select(9, GetItemInfo(itemId))
+	return invType
+end
+
+local function GetItemId(slot)
+	local link = GetInventoryItemLink("player", GetInventorySlotInfo(slot))
+	if not link then return nil end
+	local a, b, itemId = strfind(link, "item:(%d+)");
+	return tonumber(itemId);
+end
+--</private-static-methods>
+
 --<public-static-methods>
 function OvaleEquipement:OnEnable()
 	self:RegisterEvent("PLAYER_ENTERING_WORLD")
@@ -919,20 +943,18 @@ function OvaleEquipement:Debug()
 	end
 end

-function OvaleEquipement:GetItemId(slot)
-	local link = GetInventoryItemLink("player", GetInventorySlotInfo(slot))
-	if not link then return nil end
-	local a, b, itemId = strfind(link, "item:(%d+)");
-	return tonumber(itemId);
-end
-
 -- slots that can contain pieces from armor sets
 local itemSlots = { "HeadSlot", "ShoulderSlot", "ChestSlot", "HandsSlot", "LegsSlot" }

 function OvaleEquipement:Refresh()
+	-- Update weapon types.
+	self.mainHandWeaponType = GetEquippedWeaponType("MainHandSlot")
+	self.offHandWeaponType = GetEquippedWeaponType("SecondaryHandSlot")
+
+	-- Update armor set counts.
 	wipe(armorSetCount)
 	for i = 1, #itemSlots do
-		local itemId = self:GetItemId(itemSlots[i])
+		local itemId = GetItemId(itemSlots[i])
 		if itemId then
 			local name = armorSet[itemId]
 			if name then
diff --git a/OvalePaperDoll.lua b/OvalePaperDoll.lua
index 3dd8822..07a3444 100644
--- a/OvalePaperDoll.lua
+++ b/OvalePaperDoll.lua
@@ -143,6 +143,18 @@ function OvalePaperDoll:UNIT_STATS(event, unitId)
 	self.spirit = UnitStat(unitId, 5)
 end

+function OvalePaperDoll:GetSpellHasteMultiplier()
+	return 1 + self.spellHaste / 100
+end
+
+function OvalePaperDoll:GetMeleeHasteMultiplier()
+	return 1 + self.meleeHaste / 100
+end
+
+function OvalePaperDoll:GetMasteryMultiplier()
+	return 1 + self.masteryEffect / 100
+end
+
 function OvalePaperDoll:Debug()
 	Ovale:Print("Agility: " ..self.agility)
 	Ovale:Print("Intellect: " ..self.intellect)
diff --git a/OvaleState.lua b/OvaleState.lua
index 5700dd6..a10221f 100644
--- a/OvaleState.lua
+++ b/OvaleState.lua
@@ -53,9 +53,15 @@ function OvaleState:UpdatePowerRates()
 		self.powerRate[k] = 0
 	end

-	self.powerRate.energy = 10 * OvalePaperDoll.meleeHaste
+	self.powerRate.energy = 10 * OvalePaperDoll:GetMeleeHasteMultiplier()

 	if OvaleData.className == "MONK" then
+		-- Way of the Monk (monk)
+		if OvaleEquipement.mainHandWeaponType == "INVTYPE_2HWEAPON" then
+			-- Strip off 40% melee attack speed bonus for two-handed weapon.
+			self.powerRate.energy = self.powerRate.energy / 1.4
+		end
+
 		-- Ascension (monk)
 		if OvaleData:GetTalentPoints(8) > 0 then
 			self.powerRate.energy = self.powerRate.energy * 1.15
@@ -84,7 +90,7 @@ function OvaleState:UpdatePowerRates()
 		end
 	end

-	self.powerRate.focus = 4 * OvalePaperDoll.meleeHaste
+	self.powerRate.focus = 4 * OvalePaperDoll:GetMeleeHasteMultiplier()
 end

 function OvaleState:Reset()
@@ -336,7 +342,7 @@ function OvaleState:AddSpellToStack(spellId, startCast, endCast, nextCast, nocd,

 							-- Set the duration to the proper length if it's a DoT.
 							if auraSpellInfo and auraSpellInfo.duration then
-								duration = OvaleData:GetDuration(auraSpellId, OvalePaperDoll.spellHaste, self.state.combo, self.state.holy)
+								duration = OvaleData:GetDuration(auraSpellId, OvalePaperDoll:GetSpellHasteMultiplier(), self.state.combo, self.state.holy)
 							end

 							-- If aura is specified with a duration, then assume stacks == 1.
@@ -365,10 +371,10 @@ function OvaleState:AddSpellToStack(spellId, startCast, endCast, nextCast, nocd,
 									newAura.start = previousAura.start
 									if isDoT and previousAura.ending > newAura.start then
 										-- TODO: check that refreshed DoTs take a new snapshot of player stats.
-										local tickLength = OvaleData:GetTickLength(auraSpellId, previousAura.spellHaste)
+										local tickLength = OvaleData:GetTickLength(auraSpellId, previousAura.spellHasteMultiplier)
 										local k = floor((previousAura.ending - endCast) / tickLength)
 										newAura.ending = previousAura.ending - tickLength * k + duration
-										newAura.spellHaste = OvalePaperDoll.spellHaste
+										newAura.spellHasteMultiplier = OvalePaperDoll:GetSpellHasteMultiplier()
 									else
 										newAura.ending = endCast + duration
 									end
@@ -393,7 +399,7 @@ function OvaleState:AddSpellToStack(spellId, startCast, endCast, nextCast, nocd,
 								newAura.start = endCast
 								newAura.ending = endCast + duration
 								if isDoT then
-									newAura.spellHaste = OvalePaperDoll.spellHaste
+									newAura.spellHasteMultiplier = OvalePaperDoll:GetSpellHasteMultiplier()
 								end
 							end
 						end