From d05232c63d318514fcd06cf4fec8ad843cf2c332 Mon Sep 17 00:00:00 2001 From: "Johnny C. Lam" Date: Sun, 17 Nov 2013 16:29:28 +0000 Subject: [PATCH] Use reference-counted table pool to manage snapshots instead of a queue. git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1187 d5049fe3-3747-40f7-a4b5-f36d6801af5f --- Ovale.lua | 9 -- OvaleAura.lua | 25 ++-- OvaleFuture.lua | 78 +++++++--- OvalePaperDoll.lua | 271 ++++++++++++++++------------------- OvaleState.lua | 8 +- conditions/BuffAmount.lua | 65 +++++++++ conditions/BuffComboPoints.lua | 48 +++++++ conditions/BuffDamageMultiplier.lua | 8 +- conditions/BuffSnapshot.lua | 78 ++-------- conditions/Damage.lua | 10 +- conditions/DamageMultiplier.lua | 2 +- conditions/LastComboPoints.lua | 46 ++++++ conditions/LastEstimatedDamage.lua | 2 +- conditions/LastSnapshot.lua | 23 --- conditions/PaperDoll.lua | 4 +- conditions/WeaponDamage.lua | 6 +- conditions/conditions.xml | 3 + 17 files changed, 396 insertions(+), 290 deletions(-) create mode 100644 conditions/BuffAmount.lua create mode 100644 conditions/BuffComboPoints.lua create mode 100644 conditions/LastComboPoints.lua diff --git a/Ovale.lua b/Ovale.lua index 5220106..20147f3 100644 --- a/Ovale.lua +++ b/Ovale.lua @@ -33,8 +33,6 @@ local OVALE_TRUE_STRING = tostring(true) -- Ovale.L = L --- The most recent spell cast. -Ovale.lastSpellcast = {} --The table of check boxes definition Ovale.casesACocher = {} --the frame with the icons @@ -123,13 +121,6 @@ function Ovale:ToggleOptions() self.frame:ToggleOptions() end -function Ovale:UpdateLastSpellcast(spellcast) - wipe(self.lastSpellcast) - for k, v in pairs(spellcast) do - self.lastSpellcast[k] = v - end -end - function Ovale:UpdateVisibility() local visible = true local profile = OvaleOptions:GetProfile() diff --git a/OvaleAura.lua b/OvaleAura.lua index dc9fe00..5cb6bc1 100644 --- a/OvaleAura.lua +++ b/OvaleAura.lua @@ -17,6 +17,7 @@ Ovale.OvaleAura = OvaleAura -- local OvaleData = Ovale.OvaleData +local OvaleFuture = nil -- forward declaration local OvaleGUID = Ovale.OvaleGUID local OvalePaperDoll = Ovale.OvalePaperDoll local OvalePool = Ovale.OvalePool @@ -34,6 +35,14 @@ local API_UnitAura = UnitAura -- aura pool local self_pool = OvalePool("OvaleAura_pool") +do + self_pool.Clean = function(self, aura) + -- Release reference-counted snapshot before wiping. + if aura.snapshot then + aura.snapshot:ReleaseReference() + end + end +end -- self_aura[guid] pool local self_aura_pool = OvalePool("OvaleAura_aura_pool") -- player's GUID @@ -145,14 +154,13 @@ local function UnitGainedAura(guid, spellId, filter, casterGUID, icon, count, de aura.tick = self:GetTickLength(spellId) end -- Determine whether to snapshot player stats for the aura or to keep the existing stats. - local lastSpellcast = Ovale.lastSpellcast + local lastSpellcast = OvaleFuture.lastSpellcast local lastSpellId = lastSpellcast and lastSpellcast.spellId if lastSpellId and OvaleData:NeedNewSnapshot(spellId, lastSpellId) then Ovale:DebugPrintf(OVALE_AURA_DEBUG, " Snapshot stats for %s %s (%s) on %s from %f, now=%f, aura.serial=%d", filter, name, spellId, guid, lastSpellcast.snapshotTime, now, aura.serial) - OvalePaperDoll:SnapshotStats(aura, Ovale.lastSpellcast) - -- TODO: This isn't correct if lastSpellId doesn't directly apply the DoT. - aura.damageMultiplier = Ovale.lastSpellcast.damageMultiplier + -- TODO: damageMultiplier isn't correct if lastSpellId spreads the DoT. + OvaleFuture:UpdateFromSpellcast(aura, lastSpellcast) end end end @@ -322,6 +330,7 @@ end -- function OvaleAura:OnEnable() + OvaleFuture = Ovale.OvaleFuture -- resolve forward declaration self_guid = OvaleGUID:GetGUID("player") self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") self:RegisterEvent("PLAYER_ENTERING_WORLD") @@ -719,9 +728,7 @@ do newAura.ending = (ending - tick * remainingTicks) + duration newAura.tick = OvaleAura:GetTickLength(auraId) -- Re-snapshot stats for the DoT. - -- XXX This is not quite right because it uses the current player stats instead of the simulator's state. - OvalePaperDoll:SnapshotStats(newAura, spellcast) - newAura.damageMultiplier = state:GetDamageMultiplier(auraId) + OvaleFuture:UpdateFromSpellcast(newAura, spellcast) else newAura.ending = atTime + duration end @@ -745,9 +752,7 @@ do if isDoT then newAura.tick = OvaleAura:GetTickLength(auraId) -- Snapshot stats for the DoT. - -- XXX This is not quite right because it uses the current player stats instead of the simulator's state. - OvalePaperDoll:SnapshotStats(newAura, spellcast) - newAura.damageMultiplier = state:GetDamageMultiplier(auraId) + OvaleFuture:UpdateFromSpellcast(newAura, spellcast) end end end diff --git a/OvaleFuture.lua b/OvaleFuture.lua index 3e22902..3d7249d 100644 --- a/OvaleFuture.lua +++ b/OvaleFuture.lua @@ -21,6 +21,7 @@ local OvaleData = Ovale.OvaleData local OvaleGUID = Ovale.OvaleGUID local OvalePaperDoll = Ovale.OvalePaperDoll local OvalePool = Ovale.OvalePool +local OvalePower = Ovale.OvalePower local OvaleScore = Ovale.OvaleScore local OvaleSpellBook = Ovale.OvaleSpellBook local OvaleState = Ovale.OvaleState @@ -37,13 +38,22 @@ local API_UnitChannelInfo = UnitChannelInfo local API_UnitGUID = UnitGUID local API_UnitName = UnitName -local self_playerName = nil +-- Player's GUID. +local self_guid = nil -- The spells that the player is casting or has cast but are still in-flight toward their targets. local self_activeSpellcast = {} -- self_lastSpellcast[targetGUID][spellId] is the most recent spell that has landed successfully on the target. local self_lastSpellcast = {} local self_pool = OvalePool("OvaleFuture_pool") +do + self_pool.Clean = function(self, spellcast) + -- Release reference-counted snapshot before wiping. + if spellcast.snapshot then + spellcast.snapshot:ReleaseReference() + end + end +end -- Used to track the most recent spellcast started with UNIT_SPELLCAST_SENT. local self_lastLineID = nil @@ -69,6 +79,8 @@ local OVALE_CLEU_SPELLCAST_RESULTS = { -- --spell counter (see Counter function) OvaleFuture.counter = {} +-- Most recent spellcast. +OvaleFuture.lastSpellcast = nil -- Debugging: spells to trace OvaleFuture.traceSpellList = nil -- @@ -134,7 +146,7 @@ local function AddSpellToQueue(spellId, lineId, startTime, endTime, channeled, a spellName, spellId, lineId, startTime, endTime, spellcast.target) -- Snapshot the current stats for the spellcast. - OvalePaperDoll:SnapshotStats(spellcast) + spellcast.snapshot = OvalePaperDoll:GetSnapshot() spellcast.damageMultiplier = GetDamageMultiplier(spellId) local si = OvaleData.spellInfo[spellId] @@ -143,9 +155,15 @@ local function AddSpellToQueue(spellId, lineId, startTime, endTime, channeled, a -- Save the number of combo points used if this spell is a finisher. if si.combo == 0 then - local comboPoints = OvaleComboPoints.combo - if comboPoints > 0 then - spellcast.comboPoints = comboPoints + 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 end end @@ -198,11 +216,12 @@ local function RemoveSpellFromQueue(spellId, lineId) Ovale.refreshNeeded["player"] = true end --- UpdateLastSpellInfo() is called at the end of the event handler for OVALE_CLEU_SPELLCAST_RESULTS[]. +-- UpdateLastSpellcast() is called at the end of the event handler for OVALE_CLEU_SPELLCAST_RESULTS[]. -- It saves the given spellcast as the most recent one on its target and ensures that the spellcast -- snapshot values are correctly adjusted for buffs that are added or cleared simultaneously with the -- spellcast. -local function UpdateLastSpellInfo(spellcast) +local function UpdateLastSpellcast(spellcast) + local self = OvaleFuture local targetGUID = spellcast.target local spellId = spellcast.spellId if targetGUID and spellId then @@ -214,6 +233,7 @@ local function UpdateLastSpellInfo(spellcast) self_pool:Release(oldSpellcast) end self_lastSpellcast[targetGUID][spellId] = spellcast + self.lastSpellcast = spellcast --[[ If any auras have been added between the start of the spellcast and this event, @@ -221,25 +241,22 @@ local function UpdateLastSpellInfo(spellcast) This is needed to see any auras that were applied at the same time as the spellcast, e.g., potions or other on-use abilities or items. - ]]-- + --]] if self_timeAuraAdded then if self_timeAuraAdded >= spellcast.start and self_timeAuraAdded - spellcast.stop < 1 then - OvalePaperDoll:SnapshotStats(spellcast) + OvalePaperDoll:UpdateSnapshot(spellcast.snapshot) spellcast.damageMultiplier = GetDamageMultiplier(spellId) TracePrintf(spellId, " Updated spell info for %s (%d) to snapshot from %f.", - OvaleSpellBook:GetSpellName(spellId), spellId, spellcast.snapshotTime) + OvaleSpellBook:GetSpellName(spellId), spellId, spellcast.snapshot.snapshotTime) end end - - -- Save this most recent spellcast. - Ovale:UpdateLastSpellcast(spellcast) end end -- -- function OvaleFuture:OnEnable() - self_playerName = API_UnitName("player") + self_guid = OvaleGUID:GetGUID("player") self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") self:RegisterEvent("PLAYER_ENTERING_WORLD") self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START") @@ -275,7 +292,7 @@ function OvaleFuture:PLAYER_ENTERING_WORLD(event) end function OvaleFuture:Ovale_AuraAdded(event, timestamp, guid, spellId, caster) - if guid == OvaleGUID:GetGUID("player") then + if guid == self_guid then self_timeAuraAdded = timestamp end end @@ -367,7 +384,10 @@ function OvaleFuture:UNIT_SPELLCAST_SUCCEEDED(event, unit, name, rank, lineId, s if spellcast.lineId == lineId then spellcast.allowRemove = true -- Take a more recent snapshot of the player stats for this cast-time spell. - OvalePaperDoll:SnapshotStats(spellcast) + if spellcast.snapshot then + OvalePaperDoll:ReleaseSnapshot(spellcast.snapshot) + end + spellcast.snapshot = OvalePaperDoll:GetSnapshot() spellcast.damageMultiplier = GetDamageMultiplier(spellId) return end @@ -439,7 +459,7 @@ function OvaleFuture:COMBAT_LOG_EVENT_UNFILTERED(event, ...) if not spellcast.channeled and (spellcast.removeOnSuccess or event ~= "SPELL_CAST_SUCCESS") then TracePrintf(spellId, " Spell finished: %s (%d)", spellName, spellId) tremove(self_activeSpellcast, index) - UpdateLastSpellInfo(spellcast) + UpdateLastSpellcast(spellcast) Ovale.refreshNeeded["player"] = true end break @@ -471,9 +491,31 @@ function OvaleFuture:ApplyInFlightSpells() end end +function OvaleFuture:UpdateFromSpellcast(dest, spellcast) + if dest.snapshot then + dest.snapshot:ReleaseReference() + end + if spellcast.snapshot then + dest.snapshot = spellcast.snapshot:GetReference() + end + if spellcast.damageMultiplier then + dest.damageMultiplier = spellcast.damageMultiplier + end + if spellcast.combo then + dest.combo = spellcast.combo + end + if spellcast.holy then + dest.holy = spellcast.holy + end +end + function OvaleFuture:GetLastSpellInfo(guid, spellId, statName) if self_lastSpellcast[guid] and self_lastSpellcast[guid][spellId] then - return self_lastSpellcast[guid][spellId][statName] + if OvalePaperDoll.SNAPSHOT_STATS[statName] then + return self_lastSpellcast[guid][spellId].snapshot[statName] + else + return self_lastSpellcast[guid][spellId][statName] + end end end diff --git a/OvalePaperDoll.lua b/OvalePaperDoll.lua index 9a86b85..db8c5d7 100644 --- a/OvalePaperDoll.lua +++ b/OvalePaperDoll.lua @@ -15,8 +15,7 @@ Ovale.OvalePaperDoll = OvalePaperDoll -- local OvaleEquipement = Ovale.OvaleEquipement -local OvalePool = Ovale.OvalePool -local OvaleQueue = Ovale.OvaleQueue +local OvalePoolRefCount = Ovale.OvalePoolRefCount local OvaleStance = Ovale.OvaleStance local select = select @@ -43,13 +42,9 @@ local API_UnitStat = UnitStat -- Player's class. local self_class = select(2, API_UnitClass("player")) -- Snapshot table pool. -local self_pool = OvalePool("OvalePaperDoll_pool") --- Snapshot queue: new snapshots are inserted at the front of the queue. -local self_snapshot = OvaleQueue:NewDeque("OvalePaperDoll_snapshot") +local self_pool = OvalePoolRefCount("OvalePaperDoll_pool") -- Total number of snapshots taken. local self_snapshotCount = 0 --- Time window (past number of seconds) for which snapshots are stored. -local SNAPSHOT_WINDOW = 5 local OVALE_PAPERDOLL_DEBUG = "paper_doll" local OVALE_SNAPSHOT_DEBUG = "snapshot" @@ -82,12 +77,10 @@ OvalePaperDoll.level = API_UnitLevel("player") -- Player's current specialization. OvalePaperDoll.specialization = nil -- Most recent snapshot. -OvalePaperDoll.stat = nil +OvalePaperDoll.snapshot = nil -- Maps field names to default value & descriptions for player's stats. OvalePaperDoll.SNAPSHOT_STATS = { - snapshotTime = { default = 0, description = "snapshot time" } - -- primary stats agility = { default = 0, description = "agility" }, intellect = { default = 0, description = "intellect" }, @@ -119,38 +112,35 @@ OvalePaperDoll.SNAPSHOT_STATS = { -- -- --- Return stat table for most recent snapshot no older than the given time. -local function GetSnapshot(t) +-- Return table for most recent snapshot to be updated through events. +local function UpdateCurrentSnapshot() local self = OvalePaperDoll - self:RemoveOldSnapshots() - local stat = self_snapshot:Front() local now = API_GetTime() - if not stat then - local newStat = self_pool:Get() - do - -- Initialize stat table. - for k, info in pairs(self.SNAPSHOT_STATS) do - newStat[k] = info.default - end - end - newStat.snapshotTime = now - self_snapshot:InsertFront(newStat) - stat = self_snapshot:Front() - elseif stat.snapshotTime < t then - local newStat = self_pool:Get() - self:SnapshotStats(newStat, stat) - newStat.snapshotTime = now - self_snapshot:InsertFront(newStat) - stat = self_snapshot:Front() + if self.snapshot.snapshotTime < now then Ovale:DebugPrintf(OVALE_SNAPSHOT_DEBUG, true, "New snapshot.") self_snapshotCount = self_snapshotCount + 1 + local snapshot = self_pool:Get() + -- Pre-populate snapshot with the most recent previously-captured stats. + for k in pairs(self.SNAPSHOT_STATS) do + snapshot[k] = self.snapshot[k] + end + snapshot.snapshotTime = now + self_pool:Release(self.snapshot) + self.snapshot = snapshot end - return stat + return self.snapshot end -- -- function OvalePaperDoll:OnEnable() + -- Initialize latest snapshot table. + self.snapshot = self_pool:Get() + for k, info in pairs(self.SNAPSHOT_STATS) do + self.snapshot[k] = info.default + end + self.snapshot.snapshotTime = 0 + self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED", "UpdateStats") self:RegisterEvent("COMBAT_RATING_UPDATE") self:RegisterEvent("MASTERY_UPDATE") @@ -170,9 +160,6 @@ function OvalePaperDoll:OnEnable() self:RegisterEvent("UNIT_STATS") self:RegisterMessage("Ovale_EquipmentChanged", "UpdateDamage") self:RegisterMessage("Ovale_StanceChanged", "UpdateDamage") - - local now = API_GetTime() - self.stat = GetSnapshot(now) end function OvalePaperDoll:OnDisable() @@ -198,26 +185,24 @@ function OvalePaperDoll:OnDisable() end function OvalePaperDoll:COMBAT_RATING_UPDATE(event) - local now = API_GetTime() - self.stat = GetSnapshot(now) - self.stat.meleeCrit = API_GetCritChance() - self.stat.rangedCrit = API_GetRangedCritChance() - self.stat.spellCrit = API_GetSpellCritChance(OVALE_SPELLDAMAGE_SCHOOL[self_class]) + local snapshot = UpdateCurrentSnapshot() + snapshot.meleeCrit = API_GetCritChance() + snapshot.rangedCrit = API_GetRangedCritChance() + snapshot.spellCrit = API_GetSpellCritChance(OVALE_SPELLDAMAGE_SCHOOL[self_class]) Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s", event) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["meleeCrit"].description, self.stat.meleeCrit) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["rangedCrit"].description, self.stat.rangedCrit) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["spellCrit"].description, self.stat.spellCrit) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["meleeCrit"].description, snapshot.meleeCrit) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["rangedCrit"].description, snapshot.rangedCrit) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["spellCrit"].description, snapshot.spellCrit) end function OvalePaperDoll:MASTERY_UPDATE(event) - local now = API_GetTime() - self.stat = GetSnapshot(now) + local snapshot = UpdateCurrentSnapshot() if self.level < 80 then - self.stat.masteryEffect = 0 + snapshot.masteryEffect = 0 else - self.stat.masteryEffect = API_GetMasteryEffect() + snapshot.masteryEffect = API_GetMasteryEffect() Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s: %s = %f%%", - event, self.SNAPSHOT_STATS["masteryEffect"].description, self.stat.masteryEffect) + event, self.SNAPSHOT_STATS["masteryEffect"].description, snapshot.masteryEffect) end end @@ -227,11 +212,10 @@ function OvalePaperDoll:PLAYER_LEVEL_UP(event, level, ...) end function OvalePaperDoll:PLAYER_DAMAGE_DONE_MODS(event, unitId) - local now = API_GetTime() - self.stat = GetSnapshot(now) - self.stat.spellBonusHealing = API_GetSpellBonusHealing() + local snapshot = UpdateCurrentSnapshot() + snapshot.spellBonusHealing = API_GetSpellBonusHealing() Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s: %s = %d", - event, self.SNAPSHOT_STATS["spellBonusHealing"].description, self.stat.spellBonusHealing) + event, self.SNAPSHOT_STATS["spellBonusHealing"].description, snapshot.spellBonusHealing) end function OvalePaperDoll:PLAYER_REGEN_DISABLED(event) @@ -248,21 +232,19 @@ function OvalePaperDoll:PLAYER_REGEN_ENABLED(event) end function OvalePaperDoll:SPELL_POWER_CHANGED(event) - local now = API_GetTime() - self.stat = GetSnapshot(now) - self.stat.spellBonusDamage = API_GetSpellBonusDamage(OVALE_SPELLDAMAGE_SCHOOL[self_class]) + local snapshot = UpdateCurrentSnapshot() + snapshot.spellBonusDamage = API_GetSpellBonusDamage(OVALE_SPELLDAMAGE_SCHOOL[self_class]) Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s: %s = %d", - event, self.SNAPSHOT_STATS["spellBonusDamage"].description, self.stat.spellBonusDamage) + event, self.SNAPSHOT_STATS["spellBonusDamage"].description, snapshot.spellBonusDamage) end function OvalePaperDoll:UNIT_ATTACK_POWER(event, unitId) if unitId == "player" then - local now = API_GetTime() - self.stat = GetSnapshot(now) + local snapshot = UpdateCurrentSnapshot() local base, posBuff, negBuff = API_UnitAttackPower(unitId) - self.stat.attackPower = base + posBuff + negBuff + snapshot.attackPower = base + posBuff + negBuff Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s: %s = %d", - event, self.SNAPSHOT_STATS["attackPower"].description, self.stat.attackPower) + event, self.SNAPSHOT_STATS["attackPower"].description, snapshot.attackPower) self:UpdateDamage(event) end end @@ -276,53 +258,49 @@ end function OvalePaperDoll:UNIT_RANGEDDAMAGE(event, unitId) if unitId == "player" then - local now = API_GetTime() - self.stat = GetSnapshot(now) - self.stat.rangedHaste = API_GetRangedHaste() + local snapshot = UpdateCurrentSnapshot() + snapshot.rangedHaste = API_GetRangedHaste() Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s: %s = %f%%", - event, self.SNAPSHOT_STATS["rangedHaste"].description, self.stat.rangedHaste) + event, self.SNAPSHOT_STATS["rangedHaste"].description, snapshot.rangedHaste) end end function OvalePaperDoll:UNIT_RANGED_ATTACK_POWER(event, unitId) if unitId == "player" then local base, posBuff, negBuff = API_UnitRangedAttackPower(unitId) - local now = API_GetTime() - self.stat = GetSnapshot(now) - self.stat.rangedAttackPower = base + posBuff + negBuff + local snapshot = UpdateCurrentSnapshot() + snapshot.rangedAttackPower = base + posBuff + negBuff Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s: %s = %d", - event, self.SNAPSHOT_STATS["rangedAttackPower"].description, self.stat.rangedAttackPower) + event, self.SNAPSHOT_STATS["rangedAttackPower"].description, snapshot.rangedAttackPower) end end function OvalePaperDoll:UNIT_SPELL_HASTE(event, unitId) if unitId == "player" then - local now = API_GetTime() - self.stat = GetSnapshot(now) - self.stat.meleeHaste = API_GetMeleeHaste() - self.stat.spellHaste = API_UnitSpellHaste(unitId) + local snapshot = UpdateCurrentSnapshot() + snapshot.meleeHaste = API_GetMeleeHaste() + snapshot.spellHaste = API_UnitSpellHaste(unitId) Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s", event) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["meleeHaste"].description, self.stat.meleeHaste) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["spellHaste"].description, self.stat.spellHaste) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["meleeHaste"].description, snapshot.meleeHaste) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f%%", self.SNAPSHOT_STATS["spellHaste"].description, snapshot.spellHaste) self:UpdateDamage(event) end end function OvalePaperDoll:UNIT_STATS(event, unitId) if unitId == "player" then - local now = API_GetTime() - self.stat = GetSnapshot(now) - self.stat.strength = API_UnitStat(unitId, 1) - self.stat.agility = API_UnitStat(unitId, 2) - self.stat.stamina = API_UnitStat(unitId, 3) - self.stat.intellect = API_UnitStat(unitId, 4) - self.stat.spirit = API_UnitStat(unitId, 5) + local snapshot = UpdateCurrentSnapshot() + snapshot.strength = API_UnitStat(unitId, 1) + snapshot.agility = API_UnitStat(unitId, 2) + snapshot.stamina = API_UnitStat(unitId, 3) + snapshot.intellect = API_UnitStat(unitId, 4) + snapshot.spirit = API_UnitStat(unitId, 5) Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s", event) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["agility"].description, self.stat.agility) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["intellect"].description, self.stat.intellect) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["spirit"].description, self.stat.spirit) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["stamina"].description, self.stat.stamina) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["strength"].description, self.stat.strength) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["agility"].description, snapshot.agility) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["intellect"].description, snapshot.intellect) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["spirit"].description, snapshot.spirit) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["stamina"].description, snapshot.stamina) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %d", self.SNAPSHOT_STATS["strength"].description, snapshot.strength) self:COMBAT_RATING_UPDATE(event) end end @@ -331,9 +309,8 @@ function OvalePaperDoll:UpdateDamage(event) local minDamage, maxDamage, minOffHandDamage, maxOffHandDamage, _, _, damageMultiplier = API_UnitDamage("player") local mainHandAttackSpeed, offHandAttackSpeed = API_UnitAttackSpeed("player") - local now = API_GetTime() - self.stat = GetSnapshot(now) - self.stat.baseDamageMultiplier = damageMultiplier + local snapshot = UpdateCurrentSnapshot() + snapshot.baseDamageMultiplier = damageMultiplier if self_class == "DRUID" and OvaleStance:IsStance("druid_cat_form") then -- Cat Form: 100% increased auto-attack damage. damageMultiplier = damageMultiplier * 2 @@ -354,7 +331,7 @@ function OvalePaperDoll:UpdateDamage(event) normalizedMainHandWeaponSpeed = 2.5 end end - self.stat.mainHandWeaponDamage = avgDamage / mainHandWeaponSpeed * normalizedMainHandWeaponSpeed + snapshot.mainHandWeaponDamage = avgDamage / mainHandWeaponSpeed * normalizedMainHandWeaponSpeed --Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " MH weapon damage = ((%f + %f) / 2 / %f) / %f * %f", -- minDamage, maxDamage, damageMultiplier, mainHandWeaponSpeed, normalizedMainHandWeaponSpeed) @@ -371,17 +348,17 @@ function OvalePaperDoll:UpdateDamage(event) normalizedOffHandWeaponSpeed = 2.5 end end - self.stat.offHandWeaponDamage = avgOffHandDamage / offHandWeaponSpeed * normalizedOffHandWeaponSpeed + snapshot.offHandWeaponDamage = avgOffHandDamage / offHandWeaponSpeed * normalizedOffHandWeaponSpeed --Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " OH weapon damage = ((%f + %f) / 2 / %f) / %f * %f", -- minOffHandDamage, maxOffHandDamage, damageMultiplier, offHandWeaponSpeed, normalizedOffHandWeaponSpeed) else - self.stat.offHandWeaponDamage = 0 + snapshot.offHandWeaponDamage = 0 end Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, true, "%s", event) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f", self.SNAPSHOT_STATS["baseDamageMultiplier"].description, self.stat.baseDamageMultiplier) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f", self.SNAPSHOT_STATS["mainHandWeaponDamage"].description, self.stat.mainHandWeaponDamage) - Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f", self.SNAPSHOT_STATS["offHandWeaponDamage"].description, self.stat.offHandWeaponDamage) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f", self.SNAPSHOT_STATS["baseDamageMultiplier"].description, snapshot.baseDamageMultiplier) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f", self.SNAPSHOT_STATS["mainHandWeaponDamage"].description, snapshot.mainHandWeaponDamage) + Ovale:DebugPrintf(OVALE_PAPERDOLL_DEBUG, " %s = %f", self.SNAPSHOT_STATS["offHandWeaponDamage"].description, snapshot.offHandWeaponDamage) end function OvalePaperDoll:UpdateSpecialization(event) @@ -407,77 +384,79 @@ function OvalePaperDoll:UpdateStats(event) end function OvalePaperDoll:GetMasteryMultiplier() - return 1 + self.stat.masteryEffect / 100 + local snapshot = self:CurrentSnapshot() + return 1 + snapshot.masteryEffect / 100 end function OvalePaperDoll:GetMeleeHasteMultiplier() - return 1 + self.stat.meleeHaste / 100 + local snapshot = self:CurrentSnapshot() + return 1 + snapshot.meleeHaste / 100 end function OvalePaperDoll:GetRangedHasteMultiplier() - return 1 + self.stat.rangedHaste / 100 + local snapshot = self:CurrentSnapshot() + return 1 + snapshot.rangedHaste / 100 end function OvalePaperDoll:GetSpellHasteMultiplier() - return 1 + self.stat.spellHaste / 100 + local snapshot = self:CurrentSnapshot() + return 1 + snapshot.spellHaste / 100 end --- Snapshot the stats into the given table using the same keynames as SNAPSHOT_STATS. --- If source is nil, then use the most recent player stats; otherwise, use the given stat table. -function OvalePaperDoll:SnapshotStats(t, source) - if not source then - self:UpdateStats("SnapshotStats") - source = self_snapshot:Front() - end +-- Copy the current snapshot into the given snapshot table. +function OvalePaperDoll:UpdateSnapshot(snapshot) + local snapshot = self:CurrentSnapshot() for k in pairs(self.SNAPSHOT_STATS) do - if source[k] then - t[k] = source[k] - end - end - -- Copy other properties that might be present that are relevant for auras. - -- TODO: Holy power? - if source.comboPoints then - t.comboPoints = source.comboPoints + snapshot[k] = self.snapshot[k] end + return snapshot end --- Remove snapshots older than SNAPSHOT_WINDOW seconds from now, but always leave most recent snapshot. -function OvalePaperDoll:RemoveOldSnapshots() +-- Return a raw reference to the current snapshot. +function OvalePaperDoll:CurrentSnapshot() local now = API_GetTime() - while self_snapshot:Size() > 1 do - local stat = self_snapshot:Back() - if stat then - if now - stat.snapshotTime < SNAPSHOT_WINDOW then break end - self_snapshot:RemoveBack() - self_pool:Release(stat) - end + if self.snapshot.snapshotTime < now then + self:UpdateStats("CurrentSnapshot") end + return self.snapshot end -function OvalePaperDoll:Debug(stat) - stat = stat or self.stat +-- Get a new reference to the current snapshot. +function OvalePaperDoll:GetSnapshot() + local snapshot = self:CurrentSnapshot() + return snapshot:GetReference() +end + +-- Release a reference to the given snapshot. +function OvalePaperDoll:ReleaseSnapshot(snapshot) + return snapshot:ReleaseReference() +end + +function OvalePaperDoll:Debug(snapshot) + snapshot = snapshot or self.snapshot + self_pool:Debug() + Ovale:FormatPrint("Total snapshots: %d", self_snapshotCount) Ovale:FormatPrint("Level: %d", self.level) Ovale:FormatPrint("Specialization: %s", self.specialization) - Ovale:FormatPrint("Total snapshots: %d", self_snapshotCount) - Ovale:FormatPrint("Snapshot time: %f", stat.snapshotTime) - Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["agility"].description, stat.agility) - Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["intellect"].description, stat.intellect) - Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["spirit"].description, stat.spirit) - Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["stamina"].description, stat.stamina) - Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["strength"].description, stat.strength) - Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["attackPower"].description, stat.attackPower) - Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["rangedAttackPower"].description, stat.rangedAttackPower) - Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["spellBonusDamage"].description, stat.spellBonusDamage) - Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["spellBonusHealing"].description, stat.spellBonusHealing) - Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["spellCrit"].description, stat.spellCrit) - Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["spellHaste"].description, stat.spellHaste) - Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["meleeCrit"].description, stat.meleeCrit) - Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["meleeHaste"].description, stat.meleeHaste) - Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["rangedCrit"].description, stat.rangedCrit) - Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["rangedHaste"].description, stat.rangedHaste) - Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["masteryEffect"].description, stat.masteryEffect) - Ovale:FormatPrint("%s: %f", self.SNAPSHOT_STATS["baseDamageMultiplier"].description, stat.baseDamageMultiplier) - Ovale:FormatPrint("%s: %f", self.SNAPSHOT_STATS["mainHandWeaponDamage"].description, stat.mainHandWeaponDamage) - Ovale:FormatPrint("%s: %f", self.SNAPSHOT_STATS["offHandWeaponDamage"].description, stat.offHandWeaponDamage) + Ovale:FormatPrint("Snapshot time: %f", snapshot.snapshotTime) + Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["agility"].description, snapshot.agility) + Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["intellect"].description, snapshot.intellect) + Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["spirit"].description, snapshot.spirit) + Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["stamina"].description, snapshot.stamina) + Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["strength"].description, snapshot.strength) + Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["attackPower"].description, snapshot.attackPower) + Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["rangedAttackPower"].description, snapshot.rangedAttackPower) + Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["spellBonusDamage"].description, snapshot.spellBonusDamage) + Ovale:FormatPrint("%s: %d", self.SNAPSHOT_STATS["spellBonusHealing"].description, snapshot.spellBonusHealing) + Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["spellCrit"].description, snapshot.spellCrit) + Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["spellHaste"].description, snapshot.spellHaste) + Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["meleeCrit"].description, snapshot.meleeCrit) + Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["meleeHaste"].description, snapshot.meleeHaste) + Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["rangedCrit"].description, snapshot.rangedCrit) + Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["rangedHaste"].description, snapshot.rangedHaste) + Ovale:FormatPrint("%s: %f%%", self.SNAPSHOT_STATS["masteryEffect"].description, snapshot.masteryEffect) + Ovale:FormatPrint("%s: %f", self.SNAPSHOT_STATS["baseDamageMultiplier"].description, snapshot.baseDamageMultiplier) + Ovale:FormatPrint("%s: %f", self.SNAPSHOT_STATS["mainHandWeaponDamage"].description, snapshot.mainHandWeaponDamage) + Ovale:FormatPrint("%s: %f", self.SNAPSHOT_STATS["offHandWeaponDamage"].description, snapshot.offHandWeaponDamage) end -- diff --git a/OvaleState.lua b/OvaleState.lua index e199c27..4f87ed2 100644 --- a/OvaleState.lua +++ b/OvaleState.lua @@ -18,6 +18,7 @@ Ovale.OvaleState = OvaleState -- local OvaleData = Ovale.OvaleData +local OvaleFuture = nil -- forward declaration local OvaleQueue = Ovale.OvaleQueue local pairs = pairs @@ -50,6 +51,11 @@ OvaleState.state = { -- -- +function OvaleState:OnInitialize() + -- Resolve module dependencies. + OvaleFuture = Ovale.OvaleFuture +end + function OvaleState:RegisterState(addon, statePrototype) self_stateModules:Insert(addon) self_statePrototype[addon] = statePrototype @@ -103,7 +109,7 @@ function OvaleState:Reset() state.currentTime = self.now Ovale:Logf("Reset state with current time = %f", state.currentTime) - self.lastSpellId = Ovale.lastSpellcast and Ovale.lastSpellcast.spellId + self.lastSpellId = OvaleFuture.lastSpellcast and OvaleFuture.lastSpellcast.spellId self.currentSpellId = nil self.isChanneling = false self.nextCast = self.now diff --git a/conditions/BuffAmount.lua b/conditions/BuffAmount.lua new file mode 100644 index 0000000..71a1b16 --- /dev/null +++ b/conditions/BuffAmount.lua @@ -0,0 +1,65 @@ +--[[-------------------------------------------------------------------- + Ovale Spell Priority + Copyright (C) 2013 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. +--]]-------------------------------------------------------------------- + +local _, Ovale = ... + +do + local OvaleCondition = Ovale.OvaleCondition + local OvaleState = Ovale.OvaleState + + local ParseCondition = OvaleCondition.ParseCondition + local TestValue = OvaleCondition.TestValue + + local auraFound = {} + + --- Get the value of a buff as a number. Not all buffs return an amount. + -- @name BuffAmount + -- @paramsig number + -- @param id The spell ID of the aura or the name of a spell list. + -- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more. + -- @param number Optional. The number to compare against. + -- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition. + -- Defaults to target=player. + -- Valid values: player, target, focus, pet. + -- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1. + -- Defaults to any=0. + -- Valid values: 0, 1. + -- @param value Optional. Sets which aura value to return from UnitAura(). + -- Defaults to value=1. + -- Valid values: 1, 2, 3. + -- @return The value of the buff as a number. + -- @see DebuffAmount + -- @see TickValue + -- @usage + -- if DebuffAmount(stagger) >10000 Spell(purifying_brew) + -- if DebuffAmount(stagger more 10000) Spell(purifying_brew) + + local function BuffAmount(condition) + local auraId, comparator, limit = condition[1], condition[2], condition[3] + local target, filter, mine = ParseCondition(condition) + local value = condition.value or 1 + local state = OvaleState.state + local statName = "value1" + if value == 1 then + statName = "value1" + elseif value == 2 then + statName = "value2" + elseif value == 3 then + statName = "value3" + end + auraFound[statName] = nil + local start, ending = state:GetAura(target, auraId, filter, mine, auraFound) + local value = auraFound[statName] or 0 + return TestValue(start, ending, value, start, 0, comparator, limit) + end + + OvaleCondition:RegisterCondition("buffamount", false, BuffAmount) + OvaleCondition:RegisterCondition("debuffamount", false, BuffAmount) + OvaleCondition:RegisterCondition("tickvalue", false, BuffAmount) +end diff --git a/conditions/BuffComboPoints.lua b/conditions/BuffComboPoints.lua new file mode 100644 index 0000000..534013b --- /dev/null +++ b/conditions/BuffComboPoints.lua @@ -0,0 +1,48 @@ +--[[-------------------------------------------------------------------- + Ovale Spell Priority + Copyright (C) 2013 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. +--]]-------------------------------------------------------------------- + +local _, Ovale = ... + +do + local OvaleCondition = Ovale.OvaleCondition + local OvaleState = Ovale.OvaleState + + local ParseCondition = OvaleCondition.ParseCondition + local TestValue = OvaleCondition.TestValue + + local auraFound = {} + + --- Get the player's combo points for the given aura at the time the aura was applied on the target. + -- @name BuffComboPoints + -- @paramsig number or boolean + -- @param id The aura spell ID. + -- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more. + -- @param number Optional. The number to compare against. + -- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition. + -- Defaults to target=player. + -- Valid values: player, target, focus, pet. + -- @return The number of combo points. + -- @return A boolean value for the result of the comparison. + -- @see DebuffComboPoints + -- @usage + -- if target.DebuffComboPoints(rip) <5 Spell(rip) + + local function BuffComboPoints(condition) + local auraId, comparator, limit = condition[1], condition[2], condition[3] + local target, filter, mine = ParseCondition(condition) + local state = OvaleState.state + auraFound.combo = nil + local start, ending = state:GetAura(target, auraId, filter, mine, auraFound) + local value = auraFound.combo or 1 + return TestValue(start, ending, value, start, 0, comparator, limit) + end + + OvaleCondition:RegisterCondition("buffcombopoints", false, BuffComboPoints) + OvaleCondition:RegisterCondition("debuffcombopoints", false, BuffComboPoints) +end diff --git a/conditions/BuffDamageMultiplier.lua b/conditions/BuffDamageMultiplier.lua index ad2b1b8..5f7985b 100644 --- a/conditions/BuffDamageMultiplier.lua +++ b/conditions/BuffDamageMultiplier.lua @@ -37,9 +37,13 @@ do local auraId, comparator, limit = condition[1], condition[2], condition[3] local target, filter, mine = ParseCondition(condition) local state = OvaleState.state - auraFound.comboPoints = nil + auraFound.snapshot = nil + auraFound.damageMultiplier = nil local start, ending = state:GetAura(target, auraId, filter, mine, auraFound) - local baseDamageMultiplier = auraFound.baseDamageMultiplier or 1 + local baseDamageMultiplier = 1 + if auraFound.snapshot and auraFound.snapshot.baseDamageMultiplier then + baseDamageMultiplier = auraFound.snapshot.baseDamageMultiplier + end local damageMultiplier = auraFound.damageMultiplier or 1 local value = baseDamageMultiplier * damageMultiplier return TestValue(start, ending, value, start, 0, comparator, limit) diff --git a/conditions/BuffSnapshot.lua b/conditions/BuffSnapshot.lua index ec86406..3347347 100644 --- a/conditions/BuffSnapshot.lua +++ b/conditions/BuffSnapshot.lua @@ -23,10 +23,12 @@ do local auraId, comparator, limit = condition[1], condition[2], condition[3] local target, filter, mine = ParseCondition(condition) local state = OvaleState.state - auraFound[statName] = nil + auraFound.snapshot = nil local start, ending = state:GetAura(target, auraId, filter, mine, auraFound) - local value = auraFound[statName] - value = value or defaultValue + local value = defaultValue + if auraFound.snapshot and auraFound.snapshot[statName] then + value = auraFound.snapshot[statName] + end return TestValue(start, ending, value, start, 0, comparator, limit) end @@ -37,55 +39,16 @@ do local state = OvaleState.state auraFound[statName] = nil local start, ending = state:GetAura(target, auraId, filter, mine, auraFound) - local value = auraFound[statName] - value = value or defaultValue + local value = defaultValue + if auraFound.snapshot and auraFound.snapshot[statName] then + value = auraFound.snapshot[statName] + end if condition.unlimited ~= 1 and value > 100 then value = 100 end return TestValue(start, ending, value, start, 0, comparator, limit) end - --- Get the value of a buff as a number. Not all buffs return an amount. - -- @name BuffAmount - -- @paramsig number - -- @param id The spell ID of the aura or the name of a spell list. - -- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more. - -- @param number Optional. The number to compare against. - -- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition. - -- Defaults to target=player. - -- Valid values: player, target, focus, pet. - -- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1. - -- Defaults to any=0. - -- Valid values: 0, 1. - -- @param value Optional. Sets which aura value to return from UnitAura(). - -- Defaults to value=1. - -- Valid values: 1, 2, 3. - -- @return The value of the buff as a number. - -- @see DebuffAmount - -- @see TickValue - -- @usage - -- if DebuffAmount(stagger) >10000 Spell(purifying_brew) - -- if DebuffAmount(stagger more 10000) Spell(purifying_brew) - - local function BuffAmount(condition) - local value = condition.value or 1 - local statName - if value == 1 then - statName = "value1" - elseif value == 2 then - statName = "value2" - elseif value == 3 then - statName = "value3" - else - statName = "value1" - end - return BuffSnapshot(statName, 0, condition) - end - - OvaleCondition:RegisterCondition("buffamount", false, BuffAmount) - OvaleCondition:RegisterCondition("debuffamount", false, BuffAmount) - OvaleCondition:RegisterCondition("tickvalue", false, BuffAmount) - --- Get the player's attack power at the time the given aura was applied on the target. -- @name BuffAttackPower -- @paramsig number or boolean @@ -108,29 +71,6 @@ do OvaleCondition:RegisterCondition("buffattackpower", false, BuffAttackPower) OvaleCondition:RegisterCondition("debuffattackpower", false, BuffAttackPower) - --- Get the player's combo points for the given aura at the time the aura was applied on the target. - -- @name BuffComboPoints - -- @paramsig number or boolean - -- @param id The aura spell ID. - -- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more. - -- @param number Optional. The number to compare against. - -- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition. - -- Defaults to target=player. - -- Valid values: player, target, focus, pet. - -- @return The number of combo points. - -- @return A boolean value for the result of the comparison. - -- @see DebuffComboPoints - -- @usage - -- if target.DebuffComboPoints(rip) <5 Spell(rip) - - local function BuffComboPoints(condition) - -- If the buff is presetnt, then it had at least one combo point. - return BuffSnapshot("comboPoints", 1, condition) - end - - OvaleCondition:RegisterCondition("buffcombopoints", false, BuffComboPoints) - OvaleCondition:RegisterCondition("debuffcombopoints", false, BuffComboPoints) - --- Get the player's mastery effect at the time the given aura was applied on the target. -- @name BuffMasteryEffect -- @paramsig number or boolean diff --git a/conditions/Damage.lua b/conditions/Damage.lua index 9613ad6..8049f83 100644 --- a/conditions/Damage.lua +++ b/conditions/Damage.lua @@ -21,11 +21,11 @@ do local function GetDamage(spellId) local state = OvaleState.state -- TODO: Use target's debuffs in this calculation. - local ap = OvalePaperDoll.stat.attackPower or 0 - local sp = OvalePaperDoll.stat.spellBonusDamage or 0 - local mh = OvalePaperDoll.stat.mainHandWeaponDamage or 0 - local oh = OvalePaperDoll.stat.offHandWeaponDamage or 0 - local bdm = OvalePaperDoll.stat.baseDamageMultiplier or 1 + local ap = OvalePaperDoll.snapshot.attackPower or 0 + local sp = OvalePaperDoll.snapshot.spellBonusDamage or 0 + local mh = OvalePaperDoll.snapshot.mainHandWeaponDamage or 0 + local oh = OvalePaperDoll.snapshot.offHandWeaponDamage or 0 + local bdm = OvalePaperDoll.snapshot.baseDamageMultiplier or 1 local dm = state:GetDamageMultiplier(spellId) or 1 local combo = state.combo or 0 return OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm diff --git a/conditions/DamageMultiplier.lua b/conditions/DamageMultiplier.lua index 7a1ad37..e49fceb 100644 --- a/conditions/DamageMultiplier.lua +++ b/conditions/DamageMultiplier.lua @@ -33,7 +33,7 @@ do local function DamageMultiplier(condition) local spellId, comparator, limit = condition[1], condition[2], condition[3] local state = OvaleState.state - local bdm = OvalePaperDoll.stat.baseDamageMultiplier + local bdm = OvalePaperDoll.snapshot.baseDamageMultiplier local dm = state:GetDamageMultiplier(spellId) local value = bdm * dm return Compare(value, comparator, limit) diff --git a/conditions/LastComboPoints.lua b/conditions/LastComboPoints.lua new file mode 100644 index 0000000..d09d85d --- /dev/null +++ b/conditions/LastComboPoints.lua @@ -0,0 +1,46 @@ +--[[-------------------------------------------------------------------- + Ovale Spell Priority + Copyright (C) 2013 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. +--]]-------------------------------------------------------------------- + +local _, Ovale = ... + +do + local OvaleCondition = Ovale.OvaleCondition + local OvaleGUID = Ovale.OvaleGUID + local OvaleFuture = Ovale.OvaleFuture + + local Compare = OvaleCondition.Compare + local ParseCondition = OvaleCondition.ParseCondition + + --- Get the number of combo points consumed by the most recent cast of a spell on the target for a feral druid or a rogue. + -- @name LastComboPoints + -- @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. + -- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition. + -- Defaults to target=target. + -- Valid values: player, target, focus, pet. + -- @return The number of combo points. + -- @return A boolean value for the result of the comparison. + -- @see ComboPoints + -- @usage + -- if ComboPoints() >3 and target.LastComboPoints(rip) <3 + -- Spell(rip) + + local function LastComboPoints(condition) + local spellId, comparator, limit = condition[1], condition[2], condition[3] + local target = ParseCondition(condition, "target") + local guid = OvaleGUID:GetGUID(target) + local value = OvaleFuture:GetLastSpellInfo(guid, spellId, "combo") or 0 + return Compare(value, comparator, limit) + end + + OvaleCondition:RegisterCondition("lastcombopoints", false, LastComboPoints) + OvaleCondition:RegisterCondition("lastspellcombopoints", false, LastComboPoints) +end diff --git a/conditions/LastEstimatedDamage.lua b/conditions/LastEstimatedDamage.lua index b83281d..8a10b03 100644 --- a/conditions/LastEstimatedDamage.lua +++ b/conditions/LastEstimatedDamage.lua @@ -47,7 +47,7 @@ do local sp = OvaleFuture:GetLastSpellInfo(guid, spellId, "spellBonusDamage") or 0 local mh = OvaleFuture:GetLastSpellInfo(guid, spellId, "mainHandWeaponDamage") or 0 local oh = OvaleFuture:GetLastSpellInfo(guid, spellId, "offHandWeaponDamage") or 0 - local combo = OvaleFuture:GetLastSpellInfo(guid, spellId, "comboPoints") or 0 + local combo = OvaleFuture:GetLastSpellInfo(guid, spellId, "combo") or 0 local bdm = OvaleFuture:GetLastSpellInfo(guid, spellId, "baseDamageMultiplier") or 1 local dm = OvaleFuture:GetLastSpellInfo(guid, spellId, "damageMultiplier") or 1 local value = OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm diff --git a/conditions/LastSnapshot.lua b/conditions/LastSnapshot.lua index de68eae..21d371b 100644 --- a/conditions/LastSnapshot.lua +++ b/conditions/LastSnapshot.lua @@ -63,29 +63,6 @@ do OvaleCondition:RegisterCondition("lastattackpower", false, LastAttackPower) OvaleCondition:RegisterCondition("lastspellattackpower", false, LastAttackPower) - --- Get the number of combo points consumed by the most recent cast of a spell on the target for a feral druid or a rogue. - -- @name LastComboPoints - -- @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. - -- @param target Optional. Sets the target to check. The target may also be given as a prefix to the condition. - -- Defaults to target=target. - -- Valid values: player, target, focus, pet. - -- @return The number of combo points. - -- @return A boolean value for the result of the comparison. - -- @see ComboPoints - -- @usage - -- if ComboPoints() >3 and target.LastComboPoints(rip) <3 - -- Spell(rip) - - local function LastComboPoints(condition) - return LastSnapshot("comboPoints", 0, condition) - end - - OvaleCondition:RegisterCondition("lastcombopoints", false, LastComboPoints) - OvaleCondition:RegisterCondition("lastspellcombopoints", false, LastComboPoints) - --- Get the mastery effect of the player during the most recent cast of a spell on the target. -- Mastery effect is the effect of the player's mastery, typically a percent-increase to damage -- or a percent-increase to chance to trigger some effect. diff --git a/conditions/PaperDoll.lua b/conditions/PaperDoll.lua index 9db4f3d..43e655f 100644 --- a/conditions/PaperDoll.lua +++ b/conditions/PaperDoll.lua @@ -18,7 +18,7 @@ do -- Returns the value of the given paper-doll stat. local function PaperDoll(statName, defaultValue, condition) local comparator, limit = condition[1], condition[2] - local value = OvalePaperDoll.stat[statName] + local value = OvalePaperDoll.snapshot[statName] value = value or defaultValue return Compare(value, comparator, limit) end @@ -26,7 +26,7 @@ do -- Returns the critical strike chance of the given paper-doll stat. local function PaperDollCritChance(statName, defaultValue, condition) local comparator, limit = condition[1], condition[2] - local value = OvalePaperDoll.stat[statName] + local value = OvalePaperDoll.snapshot[statName] value = value or defaultValue if condition.unlimited ~= 1 and value > 100 then value = 100 diff --git a/conditions/WeaponDamage.lua b/conditions/WeaponDamage.lua index 65c728f..94b0dcd 100644 --- a/conditions/WeaponDamage.lua +++ b/conditions/WeaponDamage.lua @@ -36,13 +36,13 @@ do local value = 0 if hand == "offhand" or hand == "off" then comparator, limit = condition[2], condition[3] - value = OvalePaperDoll.stat.offHandWeaponDamage + value = OvalePaperDoll.snapshot.offHandWeaponDamage elseif hand == "mainhand" or hand == "main" then comparator, limit = condition[2], condition[3] - value = OvalePaperDoll.stat.mainHandWeaponDamage + value = OvalePaperDoll.snapshot.mainHandWeaponDamage else comparator, limit = condition[1], condition[2] - value = OvalePaperDoll.stat.mainHandWeaponDamage + value = OvalePaperDoll.snapshot.mainHandWeaponDamage end return Compare(value, comparator, limit) end diff --git a/conditions/conditions.xml b/conditions/conditions.xml index 59af71f..c6a80dc 100644 --- a/conditions/conditions.xml +++ b/conditions/conditions.xml @@ -1,6 +1,8 @@