From ac9878a712f0deb078d8639e0409ee4e67c46499 Mon Sep 17 00:00:00 2001 From: "Johnny C. Lam" Date: Sun, 7 Jul 2013 04:42:46 +0000 Subject: [PATCH] Extend tracking of auras cast by others to track all auras. The assumption is that it's not possible for one caster to put more than one aura of a given ID on a target, which should be true. Change GetMyAuraOnAnyTarget to GetAuraOnAnyTarget, which allows for specifying whether to check for only "my" auras or auras cast by anyone. With the associated change to extend aura tracking above, the following script conditions should provide more accurate answers: BuffCount, DebuffCount OtherBuffExpires, OtherDebuffExpires OtherBuffPresent, OtherDebuffPresent OtherBuffRemains, OtherDebuffRemains git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@938 d5049fe3-3747-40f7-a4b5-f36d6801af5f --- OvaleAura.lua | 107 ++++++++++++++++++++++++++-------------------------- OvaleCondition.lua | 19 +++++----- OvaleState.lua | 13 +++++-- 3 files changed, 73 insertions(+), 66 deletions(-) diff --git a/OvaleAura.lua b/OvaleAura.lua index 189aca2..c1197c4 100644 --- a/OvaleAura.lua +++ b/OvaleAura.lua @@ -17,7 +17,6 @@ Ovale.OvaleAura = OvaleAura -- local OvaleData = Ovale.OvaleData local OvaleGUID = Ovale.OvaleGUID -local OvalePaperDoll = Ovale.OvalePaperDoll local OvalePool = Ovale.OvalePool local ipairs = ipairs @@ -32,11 +31,16 @@ local API_UnitAura = UnitAura local self_pool = OvalePool:NewPool("OvaleAura_pool") -- self_aura[guid] pool local self_aura_pool = OvalePool:NewPool("OvaleAura_aura_pool") +-- player's GUID +local self_player_guid = nil -- self_aura[guid][filter][spellId]["mine" or "other"] = { aura properties } +-- self_aura[guid][filter][spellId][casterGUID] = { aura properties } local self_aura = {} -- self_serial[guid] = aura age local self_serial = {} +local OVALE_UNKNOWN_GUID = 0 + local OVALE_AURA_DEBUG = "aura" -- Units for which UNIT_AURA is known to fire. local OVALE_UNIT_AURA_UNITS = {} @@ -91,26 +95,16 @@ local function UnitGainedAura(guid, spellId, filter, casterGUID, icon, count, de self_aura[guid][filter][spellId] = {} end - local mine = (casterGUID == OvaleGUID:GetGUID("player")) + casterGUID = casterGUID or OVALE_UNKNOWN_GUID + local mine = (casterGUID == self_player_guid) local existingAura, aura - if mine then - existingAura = self_aura[guid][filter][spellId].mine - if existingAura then - aura = existingAura - else - aura = self_pool:Get() - aura.gain = Ovale.now - self_aura[guid][filter][spellId].mine = aura - end + existingAura = self_aura[guid][filter][spellId][casterGUID] + if existingAura then + aura = existingAura else - existingAura = self_aura[guid][filter][spellId].other - if existingAura then - aura = existingAura - else - aura = self_pool:Get() - aura.gain = Ovale.now - self_aura[guid][filter][spellId].other = aura - end + aura = self_pool:Get() + aura.gain = Ovale.now + self_aura[guid][filter][spellId][casterGUID] = aura end aura.serial = self_serial[guid] @@ -280,11 +274,11 @@ local function UpdateAuraTick(guid, spellId, timestamp) local serial = self_serial[guid] filter = "HARMFUL" while true do - if self_aura[guid][filter] and self_aura[guid][filter][spellId] and self_aura[guid][filter][spellId].mine then - if RemoveAuraIfExpired(guid, spellId, filter, self_aura[guid][filter][spellId].mine, serial) then - self_aura[guid][filter][spellId].mine = nil + if self_aura[guid][filter] and self_aura[guid][filter][spellId] and self_aura[guid][filter][spellId][self_player_guid] then + if RemoveAuraIfExpired(guid, spellId, filter, self_aura[guid][filter][spellId][self_player_guid], serial) then + self_aura[guid][filter][spellId][self_player_guid] = nil end - aura = self_aura[guid][filter][spellId].mine + aura = self_aura[guid][filter][spellId][self_player_guid] end if aura then break end if filter == "HARMFUL" then @@ -319,6 +313,7 @@ end -- function OvaleAura:OnEnable() + self_player_guid = OvaleGUID:GetGUID("player") self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") self:RegisterEvent("PLAYER_ENTERING_WORLD") self:RegisterEvent("UNIT_AURA") @@ -344,7 +339,7 @@ function OvaleAura:COMBAT_LOG_EVENT_UNFILTERED(event, ...) if unitId and not OVALE_UNIT_AURA_UNITS[unitId] then ScanUnitAuras(event, unitId, destGUID) end - elseif OVALE_CLEU_TICK_EVENTS[event] and sourceGUID == OvaleGUID:GetGUID("player") then + elseif OVALE_CLEU_TICK_EVENTS[event] and sourceGUID == self_player_guid then -- Periodic aura cast by the player. -- Update the latest tick time of the aura. local spellId, spellName, spellSchool = select(12, ...) @@ -403,10 +398,10 @@ function OvaleAura:GetAuraByGUID(guid, spellId, filter, mine, unitId) local whoseTable = auraList[spellId] if whoseTable then if mine then - if RemoveAuraIfExpired(guid, spellId, filter, whoseTable.mine, serial) then - whoseTable.mine = nil + if RemoveAuraIfExpired(guid, spellId, filter, whoseTable[self_player_guid], serial) then + whoseTable[self_player_guid] = nil end - aura = whoseTable.mine + aura = whoseTable[self_player_guid] else for k, v in pairs(whoseTable) do if RemoveAuraIfExpired(guid, spellId, filter, v, serial) then @@ -460,25 +455,27 @@ function OvaleAura:GetStealable(unitId) local start, ending local serial = self_serial[guid] for spellId, whoseTable in pairs(auraList) do - if RemoveAuraIfExpired(guid, spellId, "HELPFUL", whoseTable.other, serial) then - whoseTable.other = nil - end - local aura = whoseTable.other - if aura and aura.stealable then - if aura.start and (not start or aura.start < start) then - start = aura.start + for caster, aura in pairs(whoseTable) do + if RemoveAuraIfExpired(guid, spellId, "HELPFUL", aura, serial) then + whoseTable[caster] = nil end - if aura.ending and (not ending or aura.ending > ending) then - ending = aura.ending + aura = whoseTable[caster] + if aura and aura.stealable then + if aura.start and (not start or aura.start < start) then + start = aura.start + end + if aura.ending and (not ending or aura.ending > ending) then + ending = aura.ending + end end end end return start, ending end --- Look for my aura on any target. +-- Look for an aura on any target, excluding the given GUID. -- Returns the earliest start time, the latest ending time, and the number of auras seen. -function OvaleAura:GetMyAuraOnAnyTarget(spellId, filter, excludingGUID) +function OvaleAura:GetAuraOnAnyTarget(spellId, filter, mine, excludingGUID) local start, ending local count = 0 for guid, auraTable in pairs(self_aura) do @@ -486,19 +483,24 @@ function OvaleAura:GetMyAuraOnAnyTarget(spellId, filter, excludingGUID) local serial = self_serial[guid] for auraFilter, auraList in pairs(auraTable) do if not filter or auraFilter == filter then - if auraList[spellId] then - if RemoveAuraIfExpired(guid, spellId, filter, auraList[spellId].mine, serial) then - auraList[spellId].mine = nil - end - local aura = auraList[spellId].mine - if aura then - if aura.start and (not start or aura.start < start) then - start = aura.start - end - if aura.ending and (not ending or aura.ending > ending) then - ending = aura.ending + local whoseTable = auraList[spellId] + if whoseTable then + for caster, aura in pairs(whoseTable) do + if not mine or caster == self_player_guid then + if RemoveAuraIfExpired(guid, spellId, filter, aura, serial) then + whoseTable[caster] = nil + end + aura = whoseTable[caster] + if aura then + if aura.start and (not start or aura.start < start) then + start = aura.start + end + if aura.ending and (not ending or aura.ending > ending) then + ending = aura.ending + end + count = count + 1 + end end - count = count + 1 end end end @@ -511,9 +513,8 @@ end function OvaleAura:GetDamageMultiplier(spellId) -- Calculate the base damage multiplier for all spells. local damageMultiplier = 1 - local playerGUID = OvaleGUID:GetGUID("player") for auraSpellId, multiplier in pairs(OvaleData.selfDamageBuff) do - local count = select(3, self:GetAuraByGUID(playerGUID, auraSpellId, filter, nil, "player")) + local count = select(3, self:GetAuraByGUID(self_player_guid, auraSpellId, filter, nil, "player")) if count and count > 0 then -- Try to account for a stacking aura. -- multiplier = 1 + (multiplier - 1) * count @@ -527,7 +528,7 @@ function OvaleAura:GetDamageMultiplier(spellId) if si and si.damageAura then for filter, auraList in pairs(si.damageAura) do for auraSpellId, multiplier in pairs(auraList) do - count = select(3, self:GetAuraByGUID(playerGUID, auraSpellId, filter, nil, "player")) + count = select(3, self:GetAuraByGUID(self_player_guid, auraSpellId, filter, nil, "player")) if count and count > 0 then -- Try to account for a stacking aura. -- multiplier = 1 + (multiplier - 1) * count diff --git a/OvaleCondition.lua b/OvaleCondition.lua index 2f96be5..062e2d7 100644 --- a/OvaleCondition.lua +++ b/OvaleCondition.lua @@ -344,11 +344,12 @@ local function GetAura(condition) return start, ending, stacks, tick, value, gain end --- Front-end for OvaleState:GetMyAuraOnAnyTarget() using condition parameters. +-- Front-end for OvaleState:GetAuraOnAnyTarget() using condition parameters. -- return start, ending, count -local function GetMyAuraOnAnyTarget(condition, excludingUnit) +local function GetAuraOnAnyTarget(condition, excludingUnit) local spellId = condition[1] local filter = GetFilter(condition) + local mine = GetMine(condition) if excludingUnit then excludingUnit = OvaleGUID:GetGUID(excludingUnit) end @@ -356,13 +357,13 @@ local function GetMyAuraOnAnyTarget(condition, excludingUnit) Ovale:Log("GetAura: nil spellId") return nil end - local start, ending, count = OvaleState:GetMyAuraOnAnyTarget(spellId, filter, excludingUnit) + local start, ending, count = OvaleState:GetAuraOnAnyTarget(spellId, filter, mine, excludingUnit) if not start then - Ovale:Logf("GetMyAuraOnAnyTarget: aura %s not found, filter=%s excludingUnit=%s", spellId, filter, excludingUnit) + Ovale:Logf("GetAuraOnAnyTarget: aura %s not found, filter=%s mine=%s excludingUnit=%s", spellId, filter, mine, excludingUnit) return nil end - Ovale:Logf("GetMyAuraOnAnyTarget: aura %s found, start=%s ending=%s count=%d", spellId, start, ending, stacks, count) + Ovale:Logf("GetAuraOnAnyTarget: aura %s found, start=%s ending=%s count=%d", spellId, start, ending, stacks, count) return start, ending, count end @@ -558,7 +559,7 @@ end -- @see DebuffCount OvaleCondition.conditions.buffcount = function(condition) - local start, ending, count = GetMyAuraOnAnyTarget(condition) + local start, ending, count = GetAuraOnAnyTarget(condition) return start, ending, count, start, 0 end OvaleCondition.conditions.debuffcount = OvaleCondition.conditions.buffcount @@ -2136,7 +2137,7 @@ end -- Spell(thunder_clap) OvaleCondition.conditions.otherdebuffexpires = function(condition) - local start, ending = GetMyAuraOnAnyTarget(condition, "target") + local start, ending = GetAuraOnAnyTarget(condition, "target") local timeBefore = TimeWithHaste(condition[2], condition.haste) if not start then ending = 0 @@ -2162,7 +2163,7 @@ OvaleCondition.conditions.otherbuffexpires = OvaleCondition.conditions.otherdebu -- Spell(devouring_plague) OvaleCondition.conditions.otherdebuffpresent = function(condition) - local start, ending = GetMyAuraOnAnyTarget(condition, "target") + local start, ending = GetAuraOnAnyTarget(condition, "target") if not start then return nil end @@ -2185,7 +2186,7 @@ OvaleCondition.conditions.otherbuffpresent = OvaleCondition.conditions.otherdebu -- Spell(devouring_plague) OvaleCondition.conditions.otherdebuffremains = function(condition) - local start, ending = GetMyAuraOnAnyTarget(condition, "target") + local start, ending = GetAuraOnAnyTarget(condition, "target") if start and ending and start <= ending then return start, ending, ending - start, start, -1 else diff --git a/OvaleState.lua b/OvaleState.lua index 9fa6e60..6cc2f51 100644 --- a/OvaleState.lua +++ b/OvaleState.lua @@ -565,7 +565,11 @@ function OvaleState:GetAuraByGUID(guid, spellId, filter, mine, unitId) end end if aura then - Ovale:Logf("Found %s aura %s on %s", filter, spellId, guid) + if aura.stacks > 0 then + Ovale:Logf("Found %s aura %s on %s", filter, spellId, guid) + else + Ovale:Logf("Found %s aura %s on %s (removed)", filter, spellId, guid) + end return aura.start, aura.ending, aura.stacks, aura.tick, aura.value, aura.gain else Ovale:Logf("Aura %s not found in state for %s", spellId, guid) @@ -596,10 +600,11 @@ function OvaleState:GetAura(unitId, spellId, filter, mine) end end --- Look for my aura on any target. +-- Look for an aura on any target, excluding the given GUID. -- Returns the earliest start time, the latest ending time, and the number of auras seen. -function OvaleState:GetMyAuraOnAnyTarget(spellId, filter, excludingGUID) - local start, ending, count = OvaleAura:GetMyAuraOnAnyTarget(spellId, filter, excludingGUID) +function OvaleState:GetAuraOnAnyTarget(spellId, filter, mine, excludingGUID) + local start, ending, count = OvaleAura:GetAuraOnAnyTarget(spellId, filter, mine, excludingGUID) + -- TODO: This is broken because it doesn't properly account for removed auras in the current frame. for guid, auraTable in pairs(self.aura) do if guid ~= excludingGUID then for auraFilter, auraList in pairs(auraTable) do -- 1.7.9.5