|
|
|
@ -4,6 +4,14 @@ local Tinkr, Bastion = ... |
|
|
|
|
local AuraTable = {} |
|
|
|
|
AuraTable.__index = AuraTable |
|
|
|
|
|
|
|
|
|
local function tsize(t) |
|
|
|
|
local keys = {} |
|
|
|
|
for k, v in pairs(t) do |
|
|
|
|
table.insert(keys, k) |
|
|
|
|
end |
|
|
|
|
return keys[#keys] |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Constructor |
|
|
|
|
function AuraTable:New(unit) |
|
|
|
|
local self = setmetatable({}, AuraTable) |
|
|
|
@ -18,42 +26,84 @@ function AuraTable:New(unit) |
|
|
|
|
self.playerAppliedDebuffs = {} |
|
|
|
|
self.playerAuras = {} |
|
|
|
|
self.guid = unit:GetGUID() |
|
|
|
|
self.instanceIDLookup = {} |
|
|
|
|
|
|
|
|
|
Bastion.EventManager:RegisterWoWEvent('UNIT_AURA', function(unit, auras) |
|
|
|
|
local u = Bastion.UnitManager[unit] |
|
|
|
|
|
|
|
|
|
if not self.unit:IsUnit(unit) then |
|
|
|
|
if not self.unit:IsUnit(u) then |
|
|
|
|
return |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local isFullUpdate = auras.isFullUpdate |
|
|
|
|
|
|
|
|
|
if isFullUpdate then |
|
|
|
|
self:Update() |
|
|
|
|
print("Full update requested for " .. unit) |
|
|
|
|
return |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local addedAuras = auras.addedAuras |
|
|
|
|
local removedAuras = auras.removedAuraInstanceIDs |
|
|
|
|
local updatedAuras = auras.updatedAuraInstanceIDs |
|
|
|
|
|
|
|
|
|
-- DevTools_Dump(addedAuras) |
|
|
|
|
if updatedAuras and #updatedAuras > 0 then |
|
|
|
|
for i = 1, #updatedAuras do |
|
|
|
|
local id = updatedAuras[i] |
|
|
|
|
local newAura = C_UnitAuras.GetAuraDataByAuraInstanceID(unit, id); |
|
|
|
|
if newAura then |
|
|
|
|
local aura = Bastion.Aura:CreateFromUnitAuraInfo(newAura) |
|
|
|
|
self:UpdateInstanceID(id, aura) |
|
|
|
|
else |
|
|
|
|
print("Instance ID " .. id .. " not found" .. " for unit " .. unit) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Remove auras |
|
|
|
|
if removedAuras and #removedAuras > 0 then |
|
|
|
|
for i = 1, #removedAuras do |
|
|
|
|
self:RemoveInstanceID(removedAuras[i]) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if #addedAuras > 0 then |
|
|
|
|
-- Add auras |
|
|
|
|
if addedAuras and #addedAuras > 0 then |
|
|
|
|
for i = 1, #addedAuras do |
|
|
|
|
local aura = Bastion.Aura:CreateFromUnitAuraInfo(addedAuras[i]) |
|
|
|
|
|
|
|
|
|
if aura:IsBuff() then |
|
|
|
|
if aura:GetSource():Exists() and aura:GetSource():IsUnit(Bastion.UnitManager['player']) then |
|
|
|
|
if not self.playerAppliedBuffs[aura:GetSpell():GetID()] then |
|
|
|
|
self.playerAppliedBuffs[aura:GetSpell():GetID()] = {} |
|
|
|
|
end |
|
|
|
|
table.insert(self.playerAppliedBuffs[aura:GetSpell():GetID()], aura) |
|
|
|
|
self.playerAppliedBuffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura |
|
|
|
|
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'playerAppliedBuffs', |
|
|
|
|
aura:GetSpell():GetID() } |
|
|
|
|
else |
|
|
|
|
if not self.buffs[aura:GetSpell():GetID()] then |
|
|
|
|
self.buffs[aura:GetSpell():GetID()] = {} |
|
|
|
|
end |
|
|
|
|
table.insert(self.buffs[aura:GetSpell():GetID()], aura) |
|
|
|
|
self.buffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura |
|
|
|
|
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'buffs', |
|
|
|
|
aura:GetSpell():GetID() } |
|
|
|
|
end |
|
|
|
|
else |
|
|
|
|
if aura:GetSource():Exists() and aura:GetSource():IsUnit(Bastion.UnitManager['player']) then |
|
|
|
|
if not self.playerAppliedDebuffs[aura:GetSpell():GetID()] then |
|
|
|
|
self.playerAppliedDebuffs[aura:GetSpell():GetID()] = {} |
|
|
|
|
end |
|
|
|
|
table.insert(self.playerAppliedDebuffs[aura:GetSpell():GetID()], aura) |
|
|
|
|
self.playerAppliedDebuffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura |
|
|
|
|
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'playerAppliedDebuffs', |
|
|
|
|
aura:GetSpell():GetID() } |
|
|
|
|
else |
|
|
|
|
if not self.debuffs[aura:GetSpell():GetID()] then |
|
|
|
|
self.debuffs[aura:GetSpell():GetID()] = {} |
|
|
|
|
end |
|
|
|
|
table.insert(self.debuffs[aura:GetSpell():GetID()], aura) |
|
|
|
|
self.debuffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura |
|
|
|
|
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'debuffs', aura:GetSpell():GetID() } |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
@ -63,44 +113,84 @@ function AuraTable:New(unit) |
|
|
|
|
return self |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function AuraTable:RemoveInstanceID(instanceID) |
|
|
|
|
if not self.instanceIDLookup[instanceID] then |
|
|
|
|
return |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local t, id = unpack(self.instanceIDLookup[instanceID]) |
|
|
|
|
|
|
|
|
|
-- print("Removing aura from table: " .. t .. " " .. id .. " " .. index .. "") |
|
|
|
|
local a = self[t][id][instanceID] |
|
|
|
|
|
|
|
|
|
if a:GetAuraInstanceID() ~= instanceID then |
|
|
|
|
print("Instance ID mismatch: " .. a:GetAuraInstanceID() .. " " .. instanceID) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
self[t][id][instanceID] = nil |
|
|
|
|
self.instanceIDLookup[instanceID] = nil |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function AuraTable:UpdateInstanceID(instanceID, newAura) |
|
|
|
|
if not self.instanceIDLookup[instanceID] then |
|
|
|
|
return |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local t, id = unpack(self.instanceIDLookup[instanceID]) |
|
|
|
|
|
|
|
|
|
-- print("Updating aura in table: " .. t .. " " .. id .. " " .. index .. "") |
|
|
|
|
|
|
|
|
|
self[t][id][instanceID] = newAura |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Get a units buffs |
|
|
|
|
function AuraTable:GetUnitBuffs() |
|
|
|
|
for i = 1, 40 do |
|
|
|
|
local aura = Bastion.Aura:New(self.unit, i, 'HELPFUL') |
|
|
|
|
AuraUtil.ForEachAura(self.unit.unit, 'HELPFUL', nil, function(a) |
|
|
|
|
local aura = Bastion.Aura:CreateFromUnitAuraInfo(a) |
|
|
|
|
|
|
|
|
|
if aura:IsValid() then |
|
|
|
|
if aura:GetSource():Exists() and aura:GetSource():IsUnit(Bastion.UnitManager['player']) then |
|
|
|
|
if not self.playerAppliedBuffs[aura:GetSpell():GetID()] then |
|
|
|
|
self.playerAppliedBuffs[aura:GetSpell():GetID()] = {} |
|
|
|
|
end |
|
|
|
|
table.insert(self.playerAppliedBuffs[aura:GetSpell():GetID()], aura) |
|
|
|
|
self.playerAppliedBuffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura |
|
|
|
|
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'playerAppliedBuffs', |
|
|
|
|
aura:GetSpell():GetID() } |
|
|
|
|
else |
|
|
|
|
if not self.buffs[aura:GetSpell():GetID()] then |
|
|
|
|
self.buffs[aura:GetSpell():GetID()] = {} |
|
|
|
|
end |
|
|
|
|
table.insert(self.buffs[aura:GetSpell():GetID()], aura) |
|
|
|
|
end |
|
|
|
|
self.buffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura |
|
|
|
|
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'buffs', |
|
|
|
|
aura:GetSpell():GetID() } |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end, true) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Get a units debuffs |
|
|
|
|
function AuraTable:GetUnitDebuffs() |
|
|
|
|
for i = 1, 40 do |
|
|
|
|
local aura = Bastion.Aura:New(self.unit, i, 'HARMFUL') |
|
|
|
|
AuraUtil.ForEachAura(self.unit.unit, 'HARMFUL', nil, function(a) |
|
|
|
|
local aura = Bastion.Aura:CreateFromUnitAuraInfo(a) |
|
|
|
|
|
|
|
|
|
if aura:IsValid() then |
|
|
|
|
if aura:GetSource():Exists() and aura:GetSource():IsUnit(Bastion.UnitManager['player']) then |
|
|
|
|
if not self.playerAppliedDebuffs[aura:GetSpell():GetID()] then |
|
|
|
|
self.playerAppliedDebuffs[aura:GetSpell():GetID()] = {} |
|
|
|
|
end |
|
|
|
|
table.insert(self.playerAppliedDebuffs[aura:GetSpell():GetID()], aura) |
|
|
|
|
self.playerAppliedDebuffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura |
|
|
|
|
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'playerAppliedDebuffs', |
|
|
|
|
aura:GetSpell():GetID() } |
|
|
|
|
else |
|
|
|
|
if not self.debuffs[aura:GetSpell():GetID()] then |
|
|
|
|
self.debuffs[aura:GetSpell():GetID()] = {} |
|
|
|
|
end |
|
|
|
|
table.insert(self.debuffs[aura:GetSpell():GetID()], aura) |
|
|
|
|
end |
|
|
|
|
self.debuffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura |
|
|
|
|
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'debuffs', |
|
|
|
|
aura:GetSpell():GetID() } |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end, true) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function merge(t1, t2) |
|
|
|
@ -121,50 +211,59 @@ end |
|
|
|
|
-- Update auras |
|
|
|
|
function AuraTable:Update() |
|
|
|
|
self:Clear() |
|
|
|
|
self.lastUpdate = GetTime() |
|
|
|
|
-- self.lastUpdate = GetTime() |
|
|
|
|
|
|
|
|
|
self:GetUnitBuffs() |
|
|
|
|
self:GetUnitDebuffs() |
|
|
|
|
self.auras = merge(self.buffs, self.debuffs) |
|
|
|
|
self.playerAuras = merge(self.playerAppliedBuffs, self.playerAppliedDebuffs) |
|
|
|
|
|
|
|
|
|
-- self.auras = merge(self.buffs, self.debuffs) |
|
|
|
|
-- self.playerAuras = merge(self.playerAppliedBuffs, self.playerAppliedDebuffs) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Get a units auras |
|
|
|
|
function AuraTable:GetUnitAuras() |
|
|
|
|
if not self.did then |
|
|
|
|
self.did = true |
|
|
|
|
self:Update() |
|
|
|
|
end |
|
|
|
|
-- For token units, we need to check if the GUID has changed |
|
|
|
|
if self.unit:GetGUID() ~= self.guid then |
|
|
|
|
self.guid = self.unit:GetGUID() |
|
|
|
|
self:Update() |
|
|
|
|
return self.auras |
|
|
|
|
return merge(self.buffs, self.debuffs) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Cache the auras for the unit so we don't have to query the API every time we want to check if the unit has a specific aura or not |
|
|
|
|
-- If it's less than .4 seconds since the last time we queried the API, return the cached auras |
|
|
|
|
if self.lastUpdate and GetTime() - self.lastUpdate < 0.5 then |
|
|
|
|
return self.auras |
|
|
|
|
end |
|
|
|
|
-- -- Cache the auras for the unit so we don't have to query the API every time we want to check if the unit has a specific aura or not |
|
|
|
|
-- -- If it's less than .4 seconds since the last time we queried the API, return the cached auras |
|
|
|
|
-- if self.lastUpdate and GetTime() - self.lastUpdate < 0.5 then |
|
|
|
|
-- return merge(self.buffs, self.debuffs) |
|
|
|
|
-- end |
|
|
|
|
|
|
|
|
|
self:Update() |
|
|
|
|
return self.auras |
|
|
|
|
-- self:Update() |
|
|
|
|
return merge(self.buffs, self.debuffs) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Get a units auras |
|
|
|
|
function AuraTable:GetMyUnitAuras() |
|
|
|
|
if not self.did then |
|
|
|
|
self.did = true |
|
|
|
|
self:Update() |
|
|
|
|
end |
|
|
|
|
-- For token units, we need to check if the GUID has changed |
|
|
|
|
if self.unit:GetGUID() ~= self.guid then |
|
|
|
|
self.guid = self.unit:GetGUID() |
|
|
|
|
self:Update() |
|
|
|
|
return self.playerAuras |
|
|
|
|
return merge(self.playerAppliedBuffs, self.playerAppliedDebuffs) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Cache the auras for the unit so we don't have to query the API every time we want to check if the unit has a specific aura or not |
|
|
|
|
-- If it's less than .4 seconds since the last time we queried the API, return the cached auras |
|
|
|
|
if self.lastUpdate and GetTime() - self.lastUpdate < 0.5 then |
|
|
|
|
return self.playerAuras |
|
|
|
|
end |
|
|
|
|
-- -- Cache the auras for the unit so we don't have to query the API every time we want to check if the unit has a specific aura or not |
|
|
|
|
-- -- If it's less than .4 seconds since the last time we queried the API, return the cached auras |
|
|
|
|
-- if self.lastUpdate and GetTime() - self.lastUpdate < 0.5 then |
|
|
|
|
-- return merge(self.playerAppliedBuffs, self.playerAppliedDebuffs) |
|
|
|
|
-- end |
|
|
|
|
|
|
|
|
|
self:Update() |
|
|
|
|
return self.playerAuras |
|
|
|
|
-- self:Update() |
|
|
|
|
return merge(self.playerAppliedBuffs, self.playerAppliedDebuffs) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Clear the aura table |
|
|
|
@ -175,15 +274,26 @@ function AuraTable:Clear() |
|
|
|
|
self.playerAppliedBuffs = {} |
|
|
|
|
self.playerAppliedDebuffs = {} |
|
|
|
|
self.playerAuras = {} |
|
|
|
|
self.instanceIDLookup = {} |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Check if the unit has a specific aura |
|
|
|
|
function AuraTable:Find(spell) |
|
|
|
|
local auras = self:GetUnitAuras() |
|
|
|
|
local aura = auras[spell:GetID()] |
|
|
|
|
local aurasub = auras[spell:GetID()] |
|
|
|
|
|
|
|
|
|
if aura then |
|
|
|
|
return aura[1] |
|
|
|
|
if not aurasub then |
|
|
|
|
return Bastion.Aura:New() |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
for k, a in pairs(aurasub) do |
|
|
|
|
if a ~= nil then |
|
|
|
|
if a:IsUp() then -- Handle expired and non refreshed dropoffs not coming in UNIT_AURA |
|
|
|
|
return a |
|
|
|
|
else |
|
|
|
|
self:RemoveInstanceID(a:GetAuraInstanceID()) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
return Bastion.Aura:New() |
|
|
|
@ -191,10 +301,20 @@ end |
|
|
|
|
|
|
|
|
|
function AuraTable:FindMy(spell) |
|
|
|
|
local auras = self:GetMyUnitAuras() |
|
|
|
|
local aura = auras[spell:GetID()] |
|
|
|
|
local aurasub = auras[spell:GetID()] |
|
|
|
|
|
|
|
|
|
if aura then |
|
|
|
|
return aura[1] |
|
|
|
|
if not aurasub then |
|
|
|
|
return Bastion.Aura:New() |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
for k, a in pairs(aurasub) do |
|
|
|
|
if a ~= nil then |
|
|
|
|
if a:IsUp() then -- Handle expired and non refreshed dropoffs not coming in UNIT_AURA |
|
|
|
|
return a |
|
|
|
|
else |
|
|
|
|
self:RemoveInstanceID(a:GetAuraInstanceID()) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
return Bastion.Aura:New() |
|
|
|
@ -204,9 +324,13 @@ end |
|
|
|
|
function AuraTable:HasAnyStealableAura() |
|
|
|
|
for _, auras in pairs(self:GetUnitAuras()) do |
|
|
|
|
for _, aura in pairs(auras) do |
|
|
|
|
if aura:IsUp() then -- Handle expired and non refreshed dropoffs not coming in UNIT_AURA |
|
|
|
|
if aura:GetIsStealable() then |
|
|
|
|
return true |
|
|
|
|
end |
|
|
|
|
else |
|
|
|
|
self:RemoveInstanceID(aura:GetAuraInstanceID()) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
@ -217,9 +341,13 @@ end |
|
|
|
|
function AuraTable:HasAnyDispelableAura(spell) |
|
|
|
|
for _, auras in pairs(self:GetUnitAuras()) do |
|
|
|
|
for _, aura in pairs(auras) do |
|
|
|
|
if aura:IsUp() then -- Handle expired and non refreshed dropoffs not coming in UNIT_AURA |
|
|
|
|
if aura:IsDebuff() and aura:IsDispelableBySpell(spell) then |
|
|
|
|
return true |
|
|
|
|
end |
|
|
|
|
else |
|
|
|
|
self:RemoveInstanceID(aura:GetAuraInstanceID()) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|