Possibly massive improvements to performance in raid, start on notification system

4n0n-patch-1
4n0n 2 years ago
parent de09096a71
commit 1ba0cd7115
  1. 68
      scripts/restodruid.lua
  2. 223
      src/AuraTable/AuraTable.lua
  3. 124
      src/NotificationsList/NotificationsList.lua
  4. 43
      src/Spell/Spell.lua
  5. 52
      src/Unit/Unit.lua
  6. 24
      src/UnitManager/UnitManager.lua
  7. 8
      src/_bastion.lua

@ -139,7 +139,7 @@ local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit)
return lowest
end)
local DispelTarget = Bastion.UnitManager:CreateCustomUnit('rejuv', function(unit)
local DispelTarget = Bastion.UnitManager:CreateCustomUnit('dispel', function(unit)
local lowest = nil
local lowestHP = math.huge
@ -366,7 +366,7 @@ local PLACE_EFFLO = false
RestoCommands:Register('efflo', 'Request the engine to place an Efflorescence', function()
PLACE_EFFLO = true
Bastion:Print('Efflorescence will be placed on next cast')
Bastion.Notifications:AddNotification(Efflorescence:GetIcon(), "Efflorescence requested")
end)
local DefaultAPL = Bastion.APL:New('default')
@ -515,18 +515,6 @@ DefaultAPL:AddSpell(
end):SetTarget(RejuvUnit)
)
DefaultAPL:AddSpell(
Regrowth:CastableIf(function(self)
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Lowest) and
(
not Player:GetAuras():FindMy(Regrowth):IsUp() and Lowest:GetHP() < 70 or
(Lowest:GetHP() <= 85 and Player:GetAuras():FindMy(ClearCasting):IsUp())) and
not Player:GetAuras():FindMy(SoulOfTheForest):IsUp() and
not Player:IsMoving()
end):SetTarget(Lowest)
)
DefaultAPL:AddSpell(
Lifebloom:CastableIf(function(self)
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
@ -547,42 +535,54 @@ DefaultAPL:AddSpell(
end):SetTarget(Tank)
)
DefaultAPL:AddSpell(
Regrowth:CastableIf(function(self)
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Lowest) and
(
not Player:GetAuras():FindMy(Regrowth):IsUp() and Lowest:GetHP() < 70 or
(Lowest:GetHP() <= 85 and Player:GetAuras():FindMy(ClearCasting):IsUp())) and
not Player:GetAuras():FindMy(SoulOfTheForest):IsUp() and
not Player:IsMoving()
end):SetTarget(Lowest)
)
DefaultAPL:AddSpell(
Sunfire:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Target) and
return Bastion.UnitManager['target']:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Bastion.UnitManager['target']) and
(
not Target:GetAuras():FindMy(SunfireAura):IsUp() or
Target:GetAuras():FindMy(SunfireAura):GetRemainingTime() <= 5.4) and Target:IsHostile() and
Target:IsAffectingCombat()
end):SetTarget(Target)
not Bastion.UnitManager['target']:GetAuras():FindMy(SunfireAura):IsUp() or
Bastion.UnitManager['target']:GetAuras():FindMy(SunfireAura):GetRemainingTime() <= 5.4) and Bastion.UnitManager['target']:IsHostile() and
Bastion.UnitManager['target']:IsAffectingCombat()
end):SetTarget(Bastion.UnitManager['target'])
)
DefaultAPL:AddSpell(
Moonfire:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Target) and
return Bastion.UnitManager['target']:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Bastion.UnitManager['target']) and
(
not Target:GetAuras():FindMy(MoonfireAura):IsUp() or
Target:GetAuras():FindMy(MoonfireAura):GetRemainingTime() <= 5.4) and Target:IsHostile() and
Target:IsAffectingCombat()
end):SetTarget(Target)
not Bastion.UnitManager['target']:GetAuras():FindMy(MoonfireAura):IsUp() or
Bastion.UnitManager['target']:GetAuras():FindMy(MoonfireAura):GetRemainingTime() <= 5.4) and Bastion.UnitManager['target']:IsHostile() and
Bastion.UnitManager['target']:IsAffectingCombat()
end):SetTarget(Bastion.UnitManager['target'])
)
DefaultAPL:AddSpell(
Starsurge:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Target) and Target:IsHostile() and
Target:IsAffectingCombat()
end):SetTarget(Target)
return Bastion.UnitManager['target']:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Bastion.UnitManager['target']) and Bastion.UnitManager['target']:IsHostile() and
Bastion.UnitManager['target']:IsAffectingCombat()
end):SetTarget(Bastion.UnitManager['target'])
)
DefaultAPL:AddSpell(
Wrath:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Target) and not Player:IsMoving() and Target:IsHostile() and
Target:IsAffectingCombat()
end):SetTarget(Target)
return Bastion.UnitManager['target']:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:CanSee(Bastion.UnitManager['target']) and not Player:IsMoving() and Bastion.UnitManager['target']:IsHostile() and
Bastion.UnitManager['target']:IsAffectingCombat()
end):SetTarget(Bastion.UnitManager['target'])
)
RestoModule:Sync(function()

@ -17,100 +17,54 @@ function AuraTable:New(unit)
local self = setmetatable({}, AuraTable)
self.unit = unit
self.buffs = {}
self.debuffs = {}
self.auras = {}
-- Our player is usually the most important unit, so we cache the auras for it
self.playerAppliedBuffs = {}
self.playerAppliedDebuffs = {}
self.playerAuras = {}
self.guid = unit:GetGUID()
self.instanceIDLookup = {}
Bastion.EventManager:RegisterWoWEvent('UNIT_AURA', function(unit, auras)
local u = Bastion.UnitManager[unit]
return self
end
if not self.unit:IsUnit(u) then
return
end
function AuraTable:OnUpdate(auras)
local isFullUpdate = auras.isFullUpdate
if isFullUpdate then
self:Update()
return
end
local isFullUpdate = auras.isFullUpdate
local removedAuras = auras.removedAuraInstanceIDs
local addedAuras = auras.addedAuras
local updatedAuras = auras.updatedAuraInstanceIDs
if isFullUpdate then
self:Update()
print("Full update requested for " .. unit)
return
end
-- Add auras
if addedAuras and #addedAuras > 0 then
for i = 1, #addedAuras do
local aura = Bastion.Aura:CreateFromUnitAuraInfo(addedAuras[i])
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
self:AddOrUpdateAuraInstanceID(aura:GetAuraInstanceID(), aura)
end
end
-- Remove auras
if removedAuras and #removedAuras > 0 then
for i = 1, #removedAuras do
self:RemoveInstanceID(removedAuras[i])
-- DevTools_Dump(addedAuras)
if updatedAuras and #updatedAuras > 0 then
for i = 1, #updatedAuras do
local id = updatedAuras[i]
local newAura = C_UnitAuras_GetAuraDataByAuraInstanceID(self.unit.unit, id);
if newAura then
local aura = Bastion.Aura:CreateFromUnitAuraInfo(newAura)
self:AddOrUpdateAuraInstanceID(aura:GetAuraInstanceID(), aura)
end
end
end
-- 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
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
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
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
self.debuffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'debuffs', aura:GetSpell():GetID() }
end
end
end
-- Remove auras
if removedAuras and #removedAuras > 0 then
for i = 1, #removedAuras do
self:RemoveInstanceID(removedAuras[i])
end
end)
return self
end
end
function AuraTable:RemoveInstanceID(instanceID)
@ -118,106 +72,74 @@ function AuraTable:RemoveInstanceID(instanceID)
return
end
local t, id = unpack(self.instanceIDLookup[instanceID])
local id = 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)
if self.playerAuras[id] and self.playerAuras[id][instanceID] then
self.playerAuras[id][instanceID] = nil
self.instanceIDLookup[instanceID] = nil
return
end
self[t][id][instanceID] = nil
self.instanceIDLookup[instanceID] = nil
end
function AuraTable:UpdateInstanceID(instanceID, newAura)
if not self.instanceIDLookup[instanceID] then
if self.auras[id] and self.auras[id][instanceID] then
self.auras[id][instanceID] = nil
self.instanceIDLookup[instanceID] = nil
return
end
end
function AuraTable:AddOrUpdateAuraInstanceID(instanceID, aura)
local spellId = aura:GetSpell():GetID()
self.instanceIDLookup[instanceID] = spellId
local t, id = unpack(self.instanceIDLookup[instanceID])
if Bastion.UnitManager['player']:IsUnit(aura:GetSource()) then
if not self.playerAuras[spellId] then
self.playerAuras[spellId] = {}
end
-- print("Updating aura in table: " .. t .. " " .. id .. " " .. index .. "")
self.playerAuras[spellId][instanceID] = aura
else
if not self.auras[spellId] then
self.auras[spellId] = {}
end
self[t][id][instanceID] = newAura
self.auras[spellId][instanceID] = aura
end
end
-- Get a units buffs
function AuraTable:GetUnitBuffs()
AuraUtil.ForEachAura(self.unit.unit, 'HELPFUL', nil, function(a)
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
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
self.buffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'buffs',
aura:GetSpell():GetID() }
end
self:AddOrUpdateAuraInstanceID(aura:GetAuraInstanceID(), aura)
end
end, true)
end
-- Get a units debuffs
function AuraTable:GetUnitDebuffs()
AuraUtil.ForEachAura(self.unit.unit, 'HARMFUL', nil, function(a)
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
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
self.debuffs[aura:GetSpell():GetID()][aura:GetAuraInstanceID()] = aura
self.instanceIDLookup[aura:GetAuraInstanceID()] = { 'debuffs',
aura:GetSpell():GetID() }
end
self:AddOrUpdateAuraInstanceID(aura:GetAuraInstanceID(), aura)
end
end, true)
end
local function merge(t1, t2)
for k, v in pairs(t2) do
if type(v) == "table" then
if type(t1[k] or false) == "table" then
merge(t1[k] or {}, t2[k] or {})
else
t1[k] = v
end
else
t1[k] = v
end
end
return t1
end
-- Update auras
function AuraTable:Update()
print("Updating auras for " .. tostring(self.unit))
self:Clear()
-- self.lastUpdate = GetTime()
self:GetUnitBuffs()
self:GetUnitDebuffs()
-- self.auras = merge(self.buffs, self.debuffs)
-- self.playerAuras = merge(self.playerAppliedBuffs, self.playerAppliedDebuffs)
-- self.auras = self.auras
-- self.playerAuras = self.playerAuras
end
-- Get a units auras
@ -230,17 +152,17 @@ function AuraTable:GetUnitAuras()
if self.unit:GetGUID() ~= self.guid then
self.guid = self.unit:GetGUID()
self:Update()
return merge(self.buffs, self.debuffs)
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)
-- return self.auras
-- end
-- self:Update()
return merge(self.buffs, self.debuffs)
return self.auras
end
-- Get a units auras
@ -253,26 +175,22 @@ function AuraTable:GetMyUnitAuras()
if self.unit:GetGUID() ~= self.guid then
self.guid = self.unit:GetGUID()
self:Update()
return merge(self.playerAppliedBuffs, self.playerAppliedDebuffs)
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)
-- return self.playerAuras
-- end
-- self:Update()
return merge(self.playerAppliedBuffs, self.playerAppliedDebuffs)
return self.playerAuras
end
-- Clear the aura table
function AuraTable:Clear()
self.buffs = {}
self.debuffs = {}
self.auras = {}
self.playerAppliedBuffs = {}
self.playerAppliedDebuffs = {}
self.playerAuras = {}
self.instanceIDLookup = {}
end
@ -300,8 +218,7 @@ function AuraTable:Find(spell)
end
function AuraTable:FindMy(spell)
local auras = self:GetMyUnitAuras()
local aurasub = auras[spell:GetID()]
local aurasub = self.playerAuras[spell:GetID()]
if not aurasub then
return Bastion.Aura:New()

@ -0,0 +1,124 @@
-- Create a NotificationsList class
local NotificationsList = {
notifications = {}
}
NotificationsList.__index = NotificationsList
-- Constructor
function NotificationsList:New()
local self = setmetatable({}, NotificationsList)
-- Create a frame for the notifications
self.frame = CreateFrame("Frame", "BastionNotificationsList", UIParent)
self.frame:SetSize(300, 100)
self.frame:SetPoint("TOP", UIParent, "TOP", 0, -100)
self.frame:SetFrameStrata("HIGH")
-- Remove notifications after 5 seconds
C_Timer.NewTicker(0.1, function()
for i, notification in ipairs(self.notifications) do
if GetTime() - notification.addedAt > 2 then
notification:Remove()
table.remove(self.notifications, i)
end
end
end)
return self
end
-- Create a notification class for the notifications list (takes icon and text)
local Notification = {
}
Notification.__index = Notification
-- Constructor
function Notification:New(list, icon, text)
local self = setmetatable({}, Notification)
-- Create a frame for the notification
self.frame = CreateFrame("Frame", nil, list.frame)
self.frame:SetSize(300, 100)
self.frame:SetPoint("TOP", list.frame, "TOP", 0, 0)
self.frame:SetFrameStrata("HIGH")
-- Create a texture for the icon
self.icon = self.frame:CreateTexture(nil, "ARTWORK")
self.icon:SetSize(32, 32)
self.icon:SetPoint("LEFT", self.frame, "LEFT", 0, 0)
self.icon:SetTexture(icon)
-- Create a fontstring for the text
self.text = self.frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
self.text:SetPoint("CENTER", self.frame, "CENTER", 10, 0)
self.text:SetText(text)
self.text:SetFont("Fonts\\FRIZQT__.TTF", 14)
self.addedAt = GetTime()
self.list = list
return self
end
-- Remove notification
function Notification:Remove()
-- Fade out the notification frame and remove it after the fade
UIFrameFadeOut(self.frame, 0.2, 1, 0)
C_Timer.After(0.5, function()
self.frame:Hide()
self.frame:ClearAllPoints()
self.frame:SetParent(nil)
self.frame = nil
self.list:Update()
end)
end
-- Add a notification to the list
function NotificationsList:AddNotification(icon, text)
-- Create a new notification
local notification = Notification:New(self, icon, text)
-- Add the notification to the list
table.insert(self.notifications, notification)
UIFrameFadeIn(notification.frame, 0.2, 0, 1)
-- Update the notifications
self:Update()
end
-- Update the notifications
function NotificationsList:Update()
-- Loop through the notifications
for i, notification in ipairs(self.notifications) do
-- Set the position of the notification
notification.frame:SetPoint("TOP", self.frame, "TOP", 0, -50 * (i - 1))
end
end
-- Remove a notification from the list
function NotificationsList:RemoveNotification(notification)
-- Loop through the notifications
for i, v in ipairs(self.notifications) do
-- Check if the notification is the one we want to remove
if v == notification then
-- Remove the notification from the list
table.remove(self.notifications, i)
notification:Remove()
break
end
end
end
-- Remove all notifications from the list
function NotificationsList:RemoveAllNotifications()
-- Loop through the notifications
for i, v in ipairs(self.notifications) do
-- Remove the notification from the list
table.remove(self.notifications, i)
self.notifications[i]:Remove()
end
end
-- Remove all notifications
return NotificationsList, Notification

@ -40,6 +40,13 @@ function Spell:New(id)
self.spellID = id
Bastion.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", function(...)
local unit, castGUID, spellID = ...
if unit == "player" and spellID == self:GetID() then
self.lastCastAt = GetTime()
end
end)
return self
end
@ -104,7 +111,7 @@ function Spell:Cast(unit, condition)
-- if unit.unit contains 'nameplate' then we need to use Object wrapper to cast
local u = unit.unit
if string.find(u, 'nameplate') then
if type(u) == "string" and string.find(u, 'nameplate') then
u = Object(u)
end
@ -114,7 +121,7 @@ function Spell:Cast(unit, condition)
Bastion:Debug("Casting", self)
-- Set the last cast time
self.lastCastAt = GetTime()
self.lastCastAttempt = GetTime()
-- Call post cast function
if self:GetOnCastFunction() then
@ -202,36 +209,20 @@ function Spell:Call(unit)
return false
end
function Spell:HasRange()
return SpellHasRange(self:GetName())
end
-- Check if the spell is in range of the unit
function Spell:IsInRange(unit)
local name, rank, icon, castTime, spellmin, spellmax, spellID = GetSpellInfo(self:GetID())
local them = Object(unit.unit)
local tx, ty, tz = ObjectPosition(unit.unit)
local px, py, pz = ObjectPosition('player')
if not them then
return false
end
local hasRange = self:HasRange()
local inRange = IsSpellInRange(self:GetName(), unit.unit)
if tx == 0 and ty == 0 and tz == 0 then
if not hasRange then
return true
end
local combatReach = ObjectCombatReach("player")
local themCombatReach = ObjectCombatReach(unit.unit)
if Bastion.UnitManager['player']:InMelee(unit) and spellmin == 0 then
return true
end
local distance = FastDistance(px, py, pz, tx, ty, tz)
if spellmax
and distance >= spellmin
and distance <= combatReach + themCombatReach + spellmax
then
if hasRange and inRange == 1 then
return true
end

@ -23,11 +23,15 @@ end
-- tostring
function Unit:__tostring()
return "Bastion.__Unit(" .. self.unit .. ")" .. " - " .. (self:GetName() or '')
return "Bastion.__Unit(" .. tostring(self.unit) .. ")" .. " - " .. (self:GetName() or '')
end
-- Constructor
function Unit:New(unit)
if UnitIsUnit(unit, "player") then
print("Created unit for player")
end
local self = setmetatable({}, Unit)
self.unit = unit
self.cache = Bastion.Cache:New()
@ -144,7 +148,7 @@ end
-- Is the unit a hostile unit
function Unit:IsHostile()
return UnitIsEnemy("player", self.unit)
return UnitCanAttack(self.unit, 'player')
end
-- Is the unit a boss
@ -217,15 +221,7 @@ local isClassicWow = select(4, GetBuildInfo()) < 40000
-- Check if two units are in melee
function Unit:InMelee(unit)
local combatReach = ObjectCombatReach(self.unit)
local themCombatReach = ObjectCombatReach(unit.unit)
if not combatReach or not themCombatReach then
return false
end
return self:GetDistance(unit)
< math.max(combatReach + 1.3333 + themCombatReach, 5)
return UnitInMelee(self.unit, unit.unit)
end
local losFlag = bit.bor(0x1, 0x10, 0x100000)
@ -317,27 +313,31 @@ function Unit:GetEnemies(range)
end
local count = 0
local objs = Objects()
local numobjs = #objs
for i = 1, numobjs do
local object = objs[i]
-- unit types 5,6,7
if ObjectType(object) == 5 or ObjectType(object) == 6 then
local unit = Unit:New(object)
if Bastion.UnitManager['player']:CanAttack(unit) and unit:IsAffectingCombat() and unit:IsAlive() and
unit:CanSee(self)
and
self:GetDistance(unit) <= range then
count = count + 1
end
Bastion.UnitManager:EnumNameplates(function(unit)
if not self:IsUnit(unit) and unit:GetDistance(self) <= range and unit:IsAlive() and self:CanSee(unit) then
count = count + 1
end
end
end)
self.cache:Set("enemies_" .. range, count, .5)
return count
end
-- Get the number of melee attackers
function Unit:GetMeleeAttackers()
local count = 0
Bastion.UnitManager:EnumNameplates(function(unit)
if not self:IsUnit(unit) and unit:IsAlive() and self:CanSee(unit) and
self:InMelee(unit) and unit:IsAffectingCombat() and not unit:IsFriendly(self) then
count = count + 1
end
end)
return count
end
function Unit:GetPartyHPAround(distance, percent)
local count = 0

@ -69,25 +69,25 @@ function UnitManager:__index(k)
self.cache:Set(k, self.customUnits[k].unit, 0.5)
end
return self.customUnits[k].unit
end
if self.objects[k] then
return self.objects[k]
local kguid = ObjectGUID(k)
if kguid and self.objects[kguid] then
return self.objects[kguid]
end
-- if not Validate(k) then
-- error("UnitManager:Get - Invalid token: " .. k)
-- end
if self.units[k] == nil then
self.units[k] = Unit:New(k)
if self.objects[kguid] == nil then
local unit = Unit:New(Object(k))
self:SetObject(unit)
end
return self.units[k]
return self.objects[kguid]
end
-- Constructor
@ -109,11 +109,13 @@ function UnitManager:Get(token)
-- error("UnitManager:Get - Invalid token: " .. token)
-- end
if self.units[token] == nil then
self.units[token] = Unit:New(token)
local tguid = ObjectGUID(token)
if self.objects[tguid] == nil then
self.objects[tguid] = Unit:New(Object(tguid))
end
return self.units[token]
return self.objects[tguid]
end
function UnitManager:GetObject(guid)

@ -15,6 +15,7 @@ function Bastion.require(class)
end
Bastion.ClassMagic = Bastion.require("ClassMagic")
Bastion.NotificationsList, Bastion.Notification = Bastion.require("NotificationsList")
Bastion.Vector3 = Bastion.require("Vector3")
Bastion.Commmand = Bastion.require("Command")
Bastion.Cache = Bastion.require("Cache")
@ -34,10 +35,17 @@ Bastion.Class = Bastion.require("Class")
Bastion.Timer = Bastion.require("Timer")
Bastion.CombatTimer = Bastion.Timer:New('combat')
Bastion.MythicPlusUtils = Bastion.require("MythicPlusUtils"):New()
Bastion.Notifications = Bastion.NotificationsList:New()
Bastion.modules = {}
Bastion.Enabled = false
Bastion.EventManager:RegisterWoWEvent('UNIT_AURA', function(unit, auras)
local u = Bastion.UnitManager[unit]
u:GetAuras():OnUpdate(auras)
end)
Bastion.Ticker = C_Timer.NewTicker(0.1, function()
if not Bastion.CombatTimer:IsRunning() and UnitAffectingCombat("player") then
Bastion.CombatTimer:Start()

Loading…
Cancel
Save