Quantcast

Fix for ticket 195.

Johnny C. Lam [11-30-12 - 03:07]
Fix for ticket 195.

Add a separate module to track the player's combo points.  Deal with the
"combo point delay" from Seal Fate or Primal Fury by pre-adding the extra
combo points before being updated through UNIT_COMBO_POINTS.  This assumes
the delay is less than one GCD.

git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@649 d5049fe3-3747-40f7-a4b5-f36d6801af5f
Filename
Ovale.toc
OvaleComboPoints.lua
OvaleFuture.lua
OvaleState.lua
diff --git a/Ovale.toc b/Ovale.toc
index b552faa..ae4e969 100644
--- a/Ovale.toc
+++ b/Ovale.toc
@@ -27,6 +27,7 @@ Ovale.lua
 OvaleActionBar.lua
 OvaleAura.lua
 OvaleBestAction.lua
+OvaleComboPoints.lua
 OvaleCompile.lua
 OvaleCondition.lua
 OvaleData.lua
diff --git a/OvaleComboPoints.lua b/OvaleComboPoints.lua
new file mode 100644
index 0000000..361e056
--- /dev/null
+++ b/OvaleComboPoints.lua
@@ -0,0 +1,96 @@
+--[[--------------------------------------------------------------------
+    Ovale Spell Priority
+    Copyright (C) 2012 Sidoine, 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
+    file accompanying this program.
+--]]--------------------------------------------------------------------
+
+-- This addon tracks the number of combo points by the player on the current target.
+
+OvaleComboPoints = LibStub("AceAddon-3.0"):NewAddon("OvaleComboPoints", "AceEvent-3.0")
+
+--<private-static-properties>
+local strfind = string.find
+local GetComboPoints = GetComboPoints
+local UnitClass, UnitGUID = UnitClass, UnitGUID
+local MAX_COMBO_POINTS = MAX_COMBO_POINTS
+
+local _, className = UnitClass("player")
+--</private-static-properties>
+
+--<public-static-properties>
+OvaleComboPoints.combo = 0
+OvaleComboPoints.playerGUID = nil
+OvaleComboPoints.targetGUID = nil
+--</public-static-properties>
+
+--<public-static-methods>
+function OvaleComboPoints:OnEnable()
+	self.playerGUID = UnitGUID("player")
+	if className == "ROGUE" or className == "DRUID" then
+		self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+		self:RegisterEvent("PLAYER_ENTERING_WORLD")
+		self:RegisterEvent("PLAYER_TARGET_CHANGED")
+		self:RegisterEvent("UNIT_COMBO_POINTS")
+	end
+end
+
+function OvaleComboPoints:OnDisable()
+	if className == "ROGUE" or className == "DRUID" then
+		self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+		self:UnregisterEvent("PLAYER_ENTERING_WORLD")
+		self:UnregisterEvent("PLAYER_TARGET_CHANGED")
+		self:UnregisterEvent("UNIT_COMBO_POINTS")
+	end
+end
+
+function OvaleComboPoints:Refresh()
+	self.combo = GetComboPoints("player") or 0
+end
+
+--[[
+A rogue's Seal Fate or a druid's Primal Fury are passive abilities that grant an
+extra combo point when a combo-point generator critically strikes the target.
+
+Workaround the "combo point delay" after a generator critically strikes the target
+by catching the critical strike damage event and adding the given number of extra
+combo points.  The delay MUST be less than the GCD.
+
+An ability that generates extra combo points after it critically strikes the target
+should have a "critcombo=N" parameter in its SpellInfo() description, where N is
+the number of extra combo points to add, e.g., critcombo=1.
+--]]
+function OvaleComboPoints:COMBAT_LOG_EVENT_UNFILTERED(event, ...)
+	local _, event, _, sourceGUID, _, _, _,	destGUID = ...
+	if sourceGUID == self.playerGUID and destGUID == self.targetGUID then
+		if event == "SPELL_DAMAGE" then
+			local spellId, _, _, _, _, _, _, _, _, critical = select(12, ...)
+			local si = OvaleData.spellInfo[spellId]
+			if critical and si and si.critcombo then
+				self.combo = self.combo + si.critcombo
+				if self.combo > MAX_COMBO_POINTS then
+					self.combo = MAX_COMBO_POINTS
+				end
+			end
+		end
+	end
+end
+
+function OvaleComboPoints:PLAYER_ENTERING_WORLD(event)
+	self:PLAYER_TARGET_CHANGED(event)
+end
+
+function OvaleComboPoints:PLAYER_TARGET_CHANGED(event)
+	self.targetGUID = UnitGUID("target")
+	self:Refresh()
+end
+
+function OvaleComboPoints:UNIT_COMBO_POINTS(event, ...)
+	local unitId = ...
+	if unitId == "player" then
+		self:Refresh()
+	end
+end
+--</public-static-methods>
diff --git a/OvaleFuture.lua b/OvaleFuture.lua
index 865506e..5a57a7b 100644
--- a/OvaleFuture.lua
+++ b/OvaleFuture.lua
@@ -13,7 +13,7 @@ OvaleFuture = LibStub("AceAddon-3.0"):NewAddon("OvaleFuture", "AceEvent-3.0")

 --<private-static-properties>
 local ipairs, pairs, strfind, tremove = ipairs, pairs, string.find, table.remove
-local GetComboPoints, GetMasteryEffect, GetSpellBonusDamage = GetComboPoints, GetMasteryEffect, GetSpellBonusDamage
+local GetMasteryEffect, GetSpellBonusDamage = GetMasteryEffect, GetSpellBonusDamage
 local GetSpellInfo, UnitAttackPower, UnitBuff = GetSpellInfo, UnitAttackPower, UnitBuff
 local UnitGUID = UnitGUID
 --</private-static-properties>
@@ -242,7 +242,8 @@ function OvaleFuture:AddSpellToList(spellId, lineId, startTime, endTime, channel

 	if si then
 		if si.combo == 0 then
-			local comboPoints = GetComboPoints("player")
+			-- This spell is a CP-finisher, so save the number of CPs used.
+			local comboPoints = OvaleComboPoints.combo
 			if comboPoints > 0 then
 				self.lastSpellCombo[spellId] = comboPoints
 			end
@@ -303,7 +304,6 @@ function OvaleFuture:AddSpellToList(spellId, lineId, startTime, endTime, channel
 	Ovale.refreshNeeded["player"] = true
 end

-
 function OvaleFuture:RemoveSpellFromList(spellId, lineId)
 	for i,v in ipairs(self.lastSpell) do
 		if v.lineId == lineId then
diff --git a/OvaleState.lua b/OvaleState.lua
index 9932baf..988100a 100644
--- a/OvaleState.lua
+++ b/OvaleState.lua
@@ -35,9 +35,10 @@ OvaleState.lastSpellId = nil

 --<private-static-properties>
 local floor, pairs, tostring = math.floor, pairs, tostring
-local GetComboPoints, GetRuneCooldown, GetRuneType = GetComboPoints, GetRuneCooldown, GetRuneType
+local GetRuneCooldown, GetRuneType = GetRuneCooldown, GetRuneType
 local GetSpellInfo, UnitGUID, UnitHealth = GetSpellInfo, UnitGUID, UnitHealth
 local UnitHealthMax, UnitPower, UnitPowerMax = UnitHealthMax, UnitPower, UnitPowerMax
+local MAX_COMBO_POINTS = MAX_COMBO_POINTS
 --</private-static-properties>

 --<public-static-methods>
@@ -79,7 +80,7 @@ function OvaleState:Reset()
 	self.currentTime = self.maintenant
 	self.currentSpellId = nil
 	self.attenteFinCast = self.maintenant
-	self.state.combo = GetComboPoints("player")
+	self.state.combo = OvaleComboPoints.combo
 	for k,v in pairs(OvaleData.power) do
 		self.state[k] = UnitPower("player", v.id)
 	end
@@ -192,6 +193,10 @@ function OvaleState:AddSpellToStack(spellId, startCast, endCast, nextCast, nocd,
 				end
 			end

+			--[[
+				This section is not needed since self.state.combo tracks OvaleComboPoints, which updates
+				the number of combo points even before the spell has been "successfully" cast.
+
 			--Points de combo
 			if newSpellInfo.combo then
 				if newSpellInfo.combo == 0 then
@@ -206,10 +211,11 @@ function OvaleState:AddSpellToStack(spellId, startCast, endCast, nextCast, nocd,
 				if self.state.combo < 0 then
 					self.state.combo = 0
 				end
-				if self.state.combo > 5 then
-					self.state.combo = 5
+				if self.state.combo > MAX_COMBO_POINTS then
+					self.state.combo = MAX_COMBO_POINTS
 				end
 			end
+			]]--

 			--Runes
 			if newSpellInfo.frost then