Updated to 4n0n latest - object manager and unit manager updates
main
Ofrex 2 years ago
parent db4ec0ff1c
commit fef75da2a6
  1. 25
      src/Aura/Aura.lua
  2. 134
      src/AuraTable/AuraTable.lua
  3. 19
      src/Item/Item.lua
  4. 21
      src/List/List.lua
  5. 65
      src/ObjectManager/ObjectManager.lua
  6. 10
      src/Refreshable/Refreshable.lua
  7. 16
      src/Spell/Spell.lua
  8. 172
      src/Unit/Unit.lua
  9. 24
      src/UnitManager/UnitManager.lua
  10. 21
      src/_bastion.lua

@ -1,6 +1,7 @@
local Tinkr, Bastion = ...
-- Create a new Aura class
---@class Aura
local Aura = {}
function Aura:__index(k)
@ -17,6 +18,19 @@ function Aura:__index(k)
return response
end
-- Equals
function Aura:__eq(other)
if getmetatable(other) == Aura then
return self:GetSpell():GetID() == other:GetSpell():GetID()
end
if getmetatable(other) == Bastion.Spell then
return self:GetSpell():GetID() == other:GetID()
end
return false
end
function Aura:__tostring()
return "Bastion.__Aura(" .. self:GetSpell():GetID() .. ")" .. " - " .. (self:GetName() or "''")
end
@ -46,12 +60,15 @@ function Aura:New(unit, index, type)
type = nil,
}
Bastion.SpellBook:GetSpell(self.aura.spellId)
if self.aura.spellId then
Bastion.SpellBook:GetSpell(self.aura.spellId)
end
return self
end
local name, icon, count, dispelType, duration, expirationTime, source, isStealable, nameplateShowPersonal,
spellId, canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, timeMod = UnitAura(unit.unit, index, type)
spellId, canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, timeMod = UnitAura(unit:GetOMToken(), index, type)
local self = setmetatable({}, Aura)
self.aura = {
@ -75,7 +92,9 @@ function Aura:New(unit, index, type)
index = index,
type = type,
}
Bastion.SpellBook:GetSpell(self.aura.spellId)
if self.aura.spellId then
Bastion.SpellBook:GetSpell(self.aura.spellId)
end
return self
end

@ -1,6 +1,7 @@
local Tinkr, Bastion = ...
-- Create a new AuraTable class
---@class AuraTable
local AuraTable = {}
AuraTable.__index = AuraTable
@ -17,9 +18,10 @@ function AuraTable:New(unit)
local self = setmetatable({}, AuraTable)
self.unit = unit
self.auras = {}
self.auras = {}
self.playerAuras = {}
self.guid = unit:GetGUID()
self.instanceIDLookup = {}
@ -27,6 +29,10 @@ function AuraTable:New(unit)
end
function AuraTable:OnUpdate(auras)
if not auras then
self:Update()
return
end
local isFullUpdate = auras.isFullUpdate
if isFullUpdate then
@ -51,7 +57,7 @@ function AuraTable:OnUpdate(auras)
if updatedAuras and #updatedAuras > 0 then
for i = 1, #updatedAuras do
local id = updatedAuras[i]
local newAura = C_UnitAuras_GetAuraDataByAuraInstanceID(self.unit.unit, id);
local newAura = C_UnitAuras_GetAuraDataByAuraInstanceID(self.unit:GetOMToken(), id);
if newAura then
local aura = Bastion.Aura:CreateFromUnitAuraInfo(newAura)
self:AddOrUpdateAuraInstanceID(aura:GetAuraInstanceID(), aura)
@ -109,7 +115,34 @@ end
-- Get a units buffs
function AuraTable:GetUnitBuffs()
AuraUtil_ForEachAura(self.unit.unit, 'HELPFUL', nil, function(a)
if Tinkr.classic then
for i = 1, 40 do
local aura = Bastion.Aura:New(self.unit, i, 'HELPFUL')
if not aura:IsValid() then
break
end
local spellId = aura:GetSpell():GetID()
if Bastion.UnitManager['player']:IsUnit(aura:GetSource()) then
if not self.playerAuras[spellId] then
self.playerAuras[spellId] = {}
end
table.insert(self.playerAuras[spellId], aura)
else
if not self.auras[spellId] then
self.auras[spellId] = {}
end
table.insert(self.auras[spellId], aura)
end
end
return
end
AuraUtil_ForEachAura(self.unit:GetOMToken(), 'HELPFUL', nil, function(a)
local aura = Bastion.Aura:CreateFromUnitAuraInfo(a)
if aura:IsValid() then
@ -120,7 +153,34 @@ end
-- Get a units debuffs
function AuraTable:GetUnitDebuffs()
AuraUtil_ForEachAura(self.unit.unit, 'HARMFUL', nil, function(a)
if Tinkr.classic then
for i = 1, 40 do
local aura = Bastion.Aura:New(self.unit, i, 'HARMFUL')
if not aura:IsValid() then
break
end
local spellId = aura:GetSpell():GetID()
if Bastion.UnitManager['player']:IsUnit(aura:GetSource()) then
if not self.playerAuras[spellId] then
self.playerAuras[spellId] = {}
end
table.insert(self.playerAuras[spellId], aura)
else
if not self.auras[spellId] then
self.auras[spellId] = {}
end
table.insert(self.auras[spellId], aura)
end
end
return
end
AuraUtil_ForEachAura(self.unit:GetOMToken(), 'HARMFUL', nil, function(a)
local aura = Bastion.Aura:CreateFromUnitAuraInfo(a)
if aura:IsValid() then
@ -196,6 +256,7 @@ function AuraTable:Clear()
end
-- Check if the unit has a specific aura
---@return Aura
function AuraTable:Find(spell)
local auras = self:GetUnitAuras()
local aurasub = auras[spell:GetID()]
@ -205,11 +266,14 @@ function AuraTable:Find(spell)
end
for k, a in pairs(aurasub) do
print(a)
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())
if not Tinkr.classic then
self:RemoveInstanceID(a:GetAuraInstanceID())
end
end
end
end
@ -217,8 +281,10 @@ function AuraTable:Find(spell)
return Bastion.Aura:New()
end
---@return Aura
function AuraTable:FindMy(spell)
local aurasub = self.playerAuras[spell:GetID()]
local auras = self:GetMyUnitAuras()
local aurasub = auras[spell:GetID()]
if not aurasub then
return Bastion.Aura:New()
@ -229,7 +295,60 @@ function AuraTable:FindMy(spell)
if a:IsUp() then -- Handle expired and non refreshed dropoffs not coming in UNIT_AURA
return a
else
self:RemoveInstanceID(a:GetAuraInstanceID())
if not Tinkr.classic then
self:RemoveInstanceID(a:GetAuraInstanceID())
end
end
end
end
return Bastion.Aura:New()
end
function AuraTable:FindFrom(spell, source)
local auras = self:GetUnitAuras()
local aurasub = auras[spell:GetID()]
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
if a:GetSource() == source then
return a
end
else
if not Tinkr.classic then
self:RemoveInstanceID(a:GetAuraInstanceID())
end
end
end
end
return Bastion.Aura:New()
end
-- Find the aura from the current unit
function AuraTable:FindTheirs(spell)
local auras = self:GetUnitAuras()
local aurasub = auras[spell:GetID()]
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
if self.unit:IsUnit(a:GetSource()) then
return a
end
else
if not Tinkr.classic then
self:RemoveInstanceID(a:GetAuraInstanceID())
end
end
end
end
@ -238,6 +357,7 @@ function AuraTable:FindMy(spell)
end
-- Find any
---@return Aura
function AuraTable:FindAny(spell)
local a = self:Find(spell)
if a:IsValid() then

@ -1,6 +1,7 @@
local Tinkr, Bastion = ...
-- Create a new Item class
---@class Item
local Item = {
UsableIfFunc = false,
PreUseFunc = false,
@ -29,6 +30,11 @@ function Item:__index(k)
return response
end
-- Equals
function Item:__eq(other)
return self:GetID() == other:GetID()
end
-- tostring
function Item:__tostring()
return "Bastion.__Item(" .. self:GetID() .. ")" .. " - " .. self:GetName()
@ -110,7 +116,7 @@ function Item:Use(unit, condition)
self.wasLooking = IsMouselooking()
-- Use the Item
UseItemByName(self:GetName(), unit.unit)
UseItemByName(self:GetName(), unit:GetOMToken())
Bastion:Debug("Using", self)
@ -170,18 +176,21 @@ function Item:Usable()
end
-- Set a script to check if the Item is Usable
---@param func fun(self:Item):boolean
function Item:UsableIf(func)
self.UsableIfFunc = func
return self
end
-- Set a script to run before the Item has been Use
---@param func fun(self:Item)
function Item:PreUse(func)
self.PreUseFunc = func
return self
end
-- Set a script to run after the Item has been Use
---@param func fun(self:Item)
function Item:OnUse(func)
self.OnUseFunc = func
return self
@ -221,9 +230,9 @@ end
function Item:IsInRange(unit)
local name, rank, icon, UseTime, Itemmin, Itemmax, ItemID = GetItemInfo(self:GetID())
local them = Object(unit.unit)
local them = Object(unit:GetOMToken())
local tx, ty, tz = ObjectPosition(unit.unit)
local tx, ty, tz = ObjectPosition(unit:GetOMToken())
local px, py, pz = ObjectPosition('player')
if not them then
@ -235,7 +244,7 @@ function Item:IsInRange(unit)
end
local combatReach = ObjectCombatReach("player")
local themCombatReach = ObjectCombatReach(unit.unit)
local themCombatReach = ObjectCombatReach(unit:GetOMToken())
if Bastion.UnitManager['player']:InMelee(unit) and Itemmin == 0 then
return true
@ -278,6 +287,8 @@ function Item:GetChargesRemaining()
end
-- Create a condition for the Item
---@param name string
---@param func fun(self:Item)
function Item:Condition(name, func)
self.conditions[name] = {
func = func

@ -1,6 +1,25 @@
local Tinkr, Bastion = ...
local List = {}
---@class List
local List = {
-- Add overload
---@param self List
---@param value any
---@return List
__add = function(self, value)
self:push(value)
return self
end,
-- Subtract overload
---@param self List
---@param value any
---@return List
__sub = function(self, value)
self:remove(value)
return self
end,
}
List.__index = List
function List:New(from)

@ -1,12 +1,13 @@
local Tinkr, Bastion = ...
---@class ObjectManager
local ObjectManager = {}
ObjectManager.__index = ObjectManager
function ObjectManager:New()
local self = setmetatable({}, ObjectManager)
self._objects = {}
self._lists = {}
self.enemies = Bastion.List:New()
self.friends = Bastion.List:New()
@ -16,15 +17,54 @@ function ObjectManager:New()
return self
end
-- Register a custom list with a callback
function ObjectManager:RegisterList(name, cb)
if self._lists[name] then
return false
end
self._lists[name] = {
list = Bastion.List:New(),
cb = cb
}
return self._lists[name].list
end
-- reset custom lists
function ObjectManager:ResetLists()
for _, list in pairs(self._lists) do
list.list:clear()
end
end
-- Refresh custom lists
function ObjectManager:EnumLists(object)
for _, list in pairs(self._lists) do
local r = list.cb(object)
if r then
list.list:push(r)
end
end
end
-- Get a list
function ObjectManager:GetList(name)
return self._lists[name].list
end
function ObjectManager:Refresh()
self.enemies:clear()
self.friends:clear()
self.activeEnemies:clear()
self.explosives:clear()
self:ResetLists()
local objects = Objects()
for _, object in pairs(objects) do
self:EnumLists(object)
if ObjectType(object) == 5 or ObjectType(object) == 6 then
local unit = Bastion.UnitManager:GetObject(ObjectGUID(object))
if not unit then
@ -39,7 +79,7 @@ function ObjectManager:Refresh()
elseif unit:IsEnemy() then
self.enemies:push(unit)
if unit:IsAffectingCombat() then
if unit:InCombatOdds() > 80 then
self.activeEnemies:push(unit)
end
end
@ -48,3 +88,24 @@ function ObjectManager:Refresh()
end
return ObjectManager
-- -- Register a list of objects that are training dummies
-- local dummies = Bastion.ObjectManager:RegisterList('dummies', function(object)
-- if ObjectType(object) == 5 or ObjectType(object) == 6 then
-- local unit = Bastion.UnitManager:GetObject(ObjectGUID(object))
-- if not unit then
-- unit = Bastion.Unit:New(object)
-- Bastion.UnitManager:SetObject(unit)
-- end
-- if unit:GetID() == 198594 then
-- return unit
-- end
-- end
-- end)
-- dummies:each(function(dummy)
-- print(dummy:GetName())
-- end)

@ -1,10 +1,14 @@
local Tinkr, Bastion = ...
-- Define a Refreshable class
---@class Refreshable
local Refreshable = {
cache = nil,
callback = nil,
value = nil
value = nil,
__eq = function(self, other)
return self.value.__eq(rawget(self, 'value'), other)
end
}
-- On index check the cache to be valid and return the value or reconstruct the value and return it
@ -19,7 +23,7 @@ end
-- When the object is accessed return the value
function Refreshable:__tostring()
return "Bastion.__Refreshable(" .. tostring(self.value) .. ")"
return "Bastion.__Refreshable(" .. tostring(rawget(self, 'value')) .. ")"
end
-- Create
@ -30,7 +34,7 @@ function Refreshable:New(value, cb)
self.value = value
self.callback = cb
self.cache:Set('self', self.value, 0.5)
self.cache:Set('self', rawget(self, 'value'), 0.5)
return self
end

@ -1,6 +1,7 @@
local Tinkr, Bastion = ...
-- Create a new Spell class
---@class Spell
local Spell = {
CastableIfFunc = false,
PreCastFunc = false,
@ -30,6 +31,11 @@ function Spell:__index(k)
return response
end
-- Equals
function Spell:__eq(other)
return self:GetID() == other:GetID()
end
-- tostring
function Spell:__tostring()
return "Bastion.__Spell(" .. self:GetID() .. ")" .. " - " .. self:GetName()
@ -50,6 +56,7 @@ function Spell:GetID()
end
-- Add post cast func
---@param func fun(self:Spell)
function Spell:PostCast(func)
self.PostCastFunc = func
return self
@ -114,8 +121,8 @@ function Spell:Cast(unit, condition)
-- Check if the mouse was looking
self.wasLooking = IsMouselooking()
-- if unit.unit contains 'nameplate' then we need to use Object wrapper to cast
local u = unit.unit
-- if unit:GetOMToken() contains 'nameplate' then we need to use Object wrapper to cast
local u = unit:GetOMToken()
if type(u) == "string" and string.find(u, 'nameplate') then
u = Object(u)
end
@ -173,18 +180,21 @@ function Spell:Castable()
end
-- Set a script to check if the spell is castable
---@param func fun(spell:Spell):boolean
function Spell:CastableIf(func)
self.CastableIfFunc = func
return self
end
-- Set a script to run before the spell has been cast
---@param func fun(spell:Spell)
function Spell:PreCast(func)
self.PreCastFunc = func
return self
end
-- Set a script to run after the spell has been cast
---@param func fun(spell:Spell)
function Spell:OnCast(func)
self.OnCastFunc = func
return self
@ -227,7 +237,7 @@ end
-- Check if the spell is in range of the unit
function Spell:IsInRange(unit)
local hasRange = self:HasRange()
local inRange = IsSpellInRange(self:GetName(), unit.unit)
local inRange = IsSpellInRange(self:GetName(), unit:GetOMToken())
if hasRange == false then
return true

@ -1,19 +1,27 @@
local Tinkr, Bastion = ...
-- Create a new Unit class
---@class Unit
local Unit = {
cache = nil,
---@type AuraTable
aura_table = nil,
---@type Unit
unit = nil,
last_shadow_techniques = 0,
swings_since_sht = 0,
last_off_attack = 0,
last_main_attack = 0,
last_combat_time = 0,
}
function Unit:__index(k)
local response = Bastion.ClassMagic:Resolve(Unit, k)
if k == 'unit' then
return rawget(self, k)
end
if response == nil then
response = rawget(self, k)
end
@ -25,9 +33,14 @@ function Unit:__index(k)
return response
end
-- Equals
function Unit:__eq(other)
return UnitIsUnit(self:GetOMToken(), other.unit)
end
-- tostring
function Unit:__tostring()
return "Bastion.__Unit(" .. tostring(self.unit) .. ")" .. " - " .. (self:GetName() or '')
return "Bastion.__Unit(" .. tostring(self:GetOMToken()) .. ")" .. " - " .. (self:GetName() or '')
end
-- Constructor
@ -42,37 +55,37 @@ end
-- Check if the unit is valid
function Unit:IsValid()
return self.unit ~= nil and self:Exists()
return self:GetOMToken() ~= nil and self:Exists()
end
-- Check if the unit exists
function Unit:Exists()
return Object(self.unit)
return Object(self:GetOMToken())
end
-- Get the units token
function Unit:Token()
return self.unit
return self:GetOMToken()
end
-- Get the units name
function Unit:GetName()
return UnitName(self.unit)
return UnitName(self:GetOMToken())
end
-- Get the units GUID
function Unit:GetGUID()
return ObjectGUID(self.unit)
return ObjectGUID(self:GetOMToken())
end
-- Get the units health
function Unit:GetHealth()
return UnitHealth(self.unit)
return UnitHealth(self:GetOMToken())
end
-- Get the units max health
function Unit:GetMaxHealth()
return UnitHealthMax(self.unit)
return UnitHealthMax(self:GetOMToken())
end
-- Get the units health percentage
@ -86,19 +99,19 @@ end
-- Get the units power type
function Unit:GetPowerType()
return UnitPowerType(self.unit)
return UnitPowerType(self:GetOMToken())
end
-- Get the units power
function Unit:GetPower(powerType)
local powerType = powerType or self:GetPowerType()
return UnitPower(self.unit, powerType)
return UnitPower(self:GetOMToken(), powerType)
end
-- Get the units max power
function Unit:GetMaxPower(powerType)
local powerType = powerType or self:GetPowerType()
return UnitPowerMax(self.unit, powerType)
return UnitPowerMax(self:GetOMToken(), powerType)
end
-- Get the units power percentage
@ -115,7 +128,7 @@ end
-- Get the units position
function Unit:GetPosition()
local x, y, z = ObjectPosition(self.unit)
local x, y, z = ObjectPosition(self:GetOMToken())
return Bastion.Vector3:New(x, y, z)
end
@ -129,37 +142,37 @@ end
-- Is the unit dead
function Unit:IsDead()
return UnitIsDeadOrGhost(self.unit)
return UnitIsDeadOrGhost(self:GetOMToken())
end
-- Is the unit alive
function Unit:IsAlive()
return not UnitIsDeadOrGhost(self.unit)
return not UnitIsDeadOrGhost(self:GetOMToken())
end
-- Is the unit a pet
function Unit:IsPet()
return UnitIsUnit(self.unit, "pet")
return UnitIsUnit(self:GetOMToken(), "pet")
end
-- Is the unit a friendly unit
function Unit:IsFriendly()
return UnitIsFriend("player", self.unit)
return UnitIsFriend("player", self:GetOMToken())
end
-- IsEnemy
function Unit:IsEnemy()
return UnitCanAttack("player", self.unit)
return UnitCanAttack("player", self:GetOMToken())
end
-- Is the unit a hostile unit
function Unit:IsHostile()
return UnitCanAttack(self.unit, 'player')
return UnitCanAttack(self:GetOMToken(), 'player')
end
-- Is the unit a boss
function Unit:IsBoss()
if UnitClassification(self.unit) == "worldboss" then
if UnitClassification(self:GetOMToken()) == "worldboss" then
return true
end
@ -174,77 +187,80 @@ function Unit:IsBoss()
return false
end
function Unit:GetOMToken()
if not self.unit then
return "none"
end
return self.unit:unit()
end
-- Is the unit a target
function Unit:IsTarget()
return UnitIsUnit(self.unit, "target")
return UnitIsUnit(self:GetOMToken(), "target")
end
-- Is the unit a focus
function Unit:IsFocus()
return UnitIsUnit(self.unit, "focus")
return UnitIsUnit(self:GetOMToken(), "focus")
end
-- Is the unit a mouseover
function Unit:IsMouseover()
return UnitIsUnit(self.unit, "mouseover")
return UnitIsUnit(self:GetOMToken(), "mouseover")
end
-- Is the unit a tank
function Unit:IsTank()
return UnitGroupRolesAssigned(self.unit) == "TANK"
return UnitGroupRolesAssigned(self:GetOMToken()) == "TANK"
end
-- Is the unit a healer
function Unit:IsHealer()
return UnitGroupRolesAssigned(self.unit) == "HEALER"
return UnitGroupRolesAssigned(self:GetOMToken()) == "HEALER"
end
-- Is the unit a damage dealer
function Unit:IsDamage()
return UnitGroupRolesAssigned(self.unit) == "DAMAGER"
return UnitGroupRolesAssigned(self:GetOMToken()) == "DAMAGER"
end
-- Is the unit a player
function Unit:IsPlayer()
return UnitIsPlayer(self.unit)
return UnitIsPlayer(self:GetOMToken())
end
-- Is the unit a player controlled unit
function Unit:IsPCU()
return UnitPlayerControlled(self.unit)
return UnitPlayerControlled(self:GetOMToken())
end
-- Get if the unit is affecting combat
function Unit:IsAffectingCombat()
return UnitAffectingCombat('player', self.unit)
end
-- Is the unit indoors
function Unit:IsIndoors()
return IsIndoors()
return UnitAffectingCombat(self:GetOMToken())
end
-- Get the units class id
function Unit:GetClass()
local locale, class, classID = UnitClass(self.unit)
local locale, class, classID = UnitClass(self:GetOMToken())
return Bastion.Class:New(locale, class, classID)
end
-- Get the units auras
---@return AuraTable
function Unit:GetAuras()
return self.aura_table
end
-- Get the raw unit
function Unit:GetRawUnit()
return self.unit
return self:GetOMToken()
end
local isClassicWow = select(4, GetBuildInfo()) < 40000
-- Check if two units are in melee
-- function Unit:InMelee(unit)
-- return UnitInMelee(self.unit, unit.unit)
-- return UnitInMelee(self:GetOMToken(), unit.unit)
-- end
local losFlag = bit.bor(0x1, 0x10, 0x100000)
@ -266,8 +282,8 @@ function Unit:CanSee(unit)
-- return false
-- end
-- end
local ax, ay, az = ObjectPosition(self.unit)
local ah = ObjectHeight(self.unit)
local ax, ay, az = ObjectPosition(self:GetOMToken())
local ah = ObjectHeight(self:GetOMToken())
local attx, atty, attz = GetUnitAttachmentPosition(unit.unit, 34)
if (ax == 0 and ay == 0 and az == 0) or (attx == 0 and atty == 0 and attz == 0) then
@ -288,7 +304,7 @@ end
-- Check if the unit is casting a spell
function Unit:IsCasting()
return UnitCastingInfo(self.unit) ~= nil
return UnitCastingInfo(self:GetOMToken()) ~= nil
end
-- Get Casting or channeling spell
@ -297,7 +313,8 @@ function Unit:GetCastingOrChannelingSpell()
.unit)
if not name then
name, text, texture, startTimeMS, endTimeMS, isTradeSkill, notInterruptible, spellId = UnitChannelInfo(self.unit)
name, text, texture, startTimeMS, endTimeMS, isTradeSkill, notInterruptible, spellId = UnitChannelInfo(self.unit
:unit())
end
if name then
@ -309,7 +326,7 @@ end
-- Check if the unit is channeling a spell
function Unit:IsChanneling()
return UnitChannelInfo(self.unit) ~= nil
return UnitChannelInfo(self:GetOMToken()) ~= nil
end
-- Check if the unit is casting or channeling a spell
@ -319,7 +336,7 @@ end
-- Check if the unit can attack the target
function Unit:CanAttack(unit)
return UnitCanAttack(self.unit, unit.unit)
return UnitCanAttack(self:GetOMToken(), unit.unit)
end
function Unit:GetChannelOrCastPercentComplete()
@ -327,7 +344,8 @@ function Unit:GetChannelOrCastPercentComplete()
.unit)
if not name then
name, text, texture, startTimeMS, endTimeMS, isTradeSkill, notInterruptible, spellId = UnitChannelInfo(self.unit)
name, text, texture, startTimeMS, endTimeMS, isTradeSkill, notInterruptible, spellId = UnitChannelInfo(self.unit
:unit())
end
if name and startTimeMS and endTimeMS then
@ -345,7 +363,8 @@ function Unit:IsInterruptible()
.unit)
if not name then
name, text, texture, startTimeMS, endTimeMS, isTradeSkill, notInterruptible, spellId = UnitChannelInfo(self.unit)
name, text, texture, startTimeMS, endTimeMS, isTradeSkill, notInterruptible, spellId = UnitChannelInfo(self.unit
:unit())
end
if name then
@ -382,7 +401,7 @@ function Unit:GetEnemies(range)
Bastion.UnitManager:EnumEnemies(function(unit)
if not self:IsUnit(unit) and unit:GetDistance(self) <= range and unit:IsAlive() and self:CanSee(unit) and
unit:IsEnemy() and unit:IsAffectingCombat() then
unit:IsEnemy() then
count = count + 1
end
end)
@ -402,7 +421,7 @@ function Unit:GetMeleeAttackers()
Bastion.UnitManager:EnumEnemies(function(unit)
if not self:IsUnit(unit) and unit:IsAlive() and self:CanSee(unit) and
self:InMelee(unit) and unit:IsEnemy() and unit:IsAffectingCombat() then
self:InMelee(unit) and unit:IsEnemy() and unit:InCombatOdds() > 80 then
count = count + 1
end
end)
@ -426,19 +445,19 @@ end
-- Is moving
function Unit:IsMoving()
return GetUnitSpeed(self.unit) > 0
return GetUnitSpeed(self:GetOMToken()) > 0
end
function Unit:IsMovingAtAll()
return ObjectMovementFlag(self.unit) ~= 0
return ObjectMovementFlag(self:GetOMToken()) ~= 0
end
function Unit:GetComboPoints()
return UnitPower(self.unit, 4)
return UnitPower(self:GetOMToken(), 4)
end
function Unit:GetComboPointsMax()
return UnitPowerMax(self.unit, 4)
return UnitPowerMax(self:GetOMToken(), 4)
end
-- Get combopoints deficit
@ -448,19 +467,20 @@ end
-- IsUnit
function Unit:IsUnit(unit)
return UnitIsUnit(self.unit, unit.unit)
return UnitIsUnit(self:GetOMToken(), unit and unit:GetOMToken() or 'none')
end
-- IsTanking
function Unit:IsTanking(unit)
local isTanking, status, threatpct, rawthreatpct, threatvalue = UnitDetailedThreatSituation(self.unit, unit.unit)
local isTanking, status, threatpct, rawthreatpct, threatvalue = UnitDetailedThreatSituation(self:GetOMToken(),
unit.unit)
return isTanking
end
-- IsFacing
function Unit:IsFacing(unit)
local rot = ObjectRotation(self.unit)
local x, y, z = ObjectPosition(self.unit)
local rot = ObjectRotation(self:GetOMToken())
local x, y, z = ObjectPosition(self:GetOMToken())
local x2, y2, z2 = ObjectPosition(unit.unit)
if not x or not x2 then
@ -481,7 +501,7 @@ end
function Unit:IsBehind(unit)
local rot = ObjectRotation(unit.unit)
local x, y, z = ObjectPosition(unit.unit)
local x2, y2, z2 = ObjectPosition(self.unit)
local x2, y2, z2 = ObjectPosition(self:GetOMToken())
if not x or not x2 then
return false
@ -513,7 +533,7 @@ end
-- InMelee
function Unit:InMelee(unit)
local x, y, z = ObjectPosition(self.unit)
local x, y, z = ObjectPosition(self:GetOMToken())
local x2, y2, z2 = ObjectPosition(unit.unit)
if not x or not x2 then
@ -521,7 +541,7 @@ function Unit:InMelee(unit)
end
local dist = math.sqrt((x - x2) ^ 2 + (y - y2) ^ 2 + (z - z2) ^ 2)
local maxDist = math.max((ObjectCombatReach(self.unit) + 1.3333) + ObjectCombatReach(unit.unit), 5.0)
local maxDist = math.max((ObjectCombatReach(self:GetOMToken()) + 1.3333) + ObjectCombatReach(unit.unit), 5.0)
maxDist = maxDist + 1.0 + self:GetMeleeBoost()
return dist <= maxDist
@ -529,12 +549,12 @@ end
-- Get object id
function Unit:GetID()
return ObjectID(self.unit)
return ObjectID(self:GetOMToken())
end
-- In party
function Unit:IsInParty()
return UnitInParty(self.unit)
return UnitInParty(self:GetOMToken())
end
-- Linear regression between time and percent to something
@ -623,17 +643,20 @@ end
-- Set combat time if affecting combat and return the difference between now and the last time
function Unit:GetCombatTime()
if self:IsAffectingCombat() then
self.last_combat_time = GetTime()
elseif not self:IsAffectingCombat() and self.last_combat_time then
self.last_combat_time = nil
end
return GetTime() - self.last_combat_time
end
if not self.last_combat_time then
return 0
end
function Unit:SetLastCombatTime(time)
self.last_combat_time = time
end
return GetTime() - self.last_combat_time
-- Get combat odds (if the last combat time is less than 1 minute ago return 1 / time, else return 0)
-- the closer to 0 the more likely the unit is to be in combat (0 = 100%) 60 = 0%
function Unit:InCombatOdds()
local time = self:GetCombatTime()
local percent = 1 - (time / 60)
return percent * 100
end
-- Get units gcd time
@ -656,7 +679,7 @@ More than 50% Haste will drop a spell below 1 second
]]
function Unit:GetMaxGCD()
local haste = UnitSpellHaste(self.unit)
local haste = UnitSpellHaste(self:GetOMToken())
if haste > 50 then
haste = 50
end
@ -674,12 +697,12 @@ function Unit:IsStealthed()
local Sepsis = Bastion.SpellBook:GetSpell(328305)
return self:GetAuras():FindAny(Stealth) or self:GetAuras():FindAny(ShadowDance)
return self:GetAuras():FindAny(Stealth) or self:GetAuras():FindAny(ShadowDance)
end
-- Get unit swing timers
function Unit:GetSwingTimers()
local main_speed, off_speed = UnitAttackSpeed(self.unit)
local main_speed, off_speed = UnitAttackSpeed(self:GetOMToken())
local main_speed = main_speed or 2
local off_speed = off_speed or 2
@ -833,4 +856,9 @@ function Unit:GetTimeToShurikenTornado(n)
end
end
return Unit
-- Is the unit indoors
function Unit:IsIndoors()
return IsIndoors()
end
return Unit

@ -48,6 +48,7 @@ local function Validate(token)
end
-- Create a new UnitManager class
---@class UnitManager
local UnitManager = {
units = {},
customUnits = {},
@ -87,11 +88,14 @@ function UnitManager:__index(k)
-- end
if self.objects[kguid] == nil then
local unit = Unit:New(Object(k))
self:SetObject(unit)
local o = Object(k)
if o then
local unit = Unit:New(Object(k))
self:SetObject(unit)
end
end
return self.objects[kguid]
return self.objects['none']
end
-- Constructor
@ -108,6 +112,7 @@ function UnitManager:Validate(token)
end
-- Get or create a unit
---@return Unit
function UnitManager:Get(token)
-- if not Validate(token) then
-- error("UnitManager:Get - Invalid token: " .. token)
@ -115,19 +120,20 @@ function UnitManager:Get(token)
local tguid = ObjectGUID(token)
if self.objects[tguid] == nil then
if tguid and self.objects[tguid] == nil then
if token == 'none' then
self.objects[tguid] = Unit:New(token)
self.objects['none'] = Unit:New()
else
self.objects[tguid] = Unit:New(Object(tguid))
end
end
return Bastion.Refreshable:New(self.objects[tguid], function()
local tguid = ObjectGUID(token)
local tguid = ObjectGUID(token) or "none"
if self.objects[tguid] == nil then
if token == 'none' then
self.objects[tguid] = Unit:New(token)
self.objects['none'] = Unit:New()
else
self.objects[tguid] = Unit:New(Object(tguid))
end
@ -145,6 +151,9 @@ function UnitManager:SetObject(unit)
end
-- Create a custom unit and cache it for .5 seconds
---@param token string
---@param cb fun():Unit
---@return Unit
function UnitManager:CreateCustomUnit(token, cb)
local unit = cb()
local cachedUnit = Bastion.Cacheable:New(unit, cb)
@ -175,6 +184,7 @@ function UnitManager:EnumFriends(cb)
end
-- Enum Enemies (object manager)
---@param cb fun(unit: Unit):boolean
function UnitManager:EnumEnemies(cb)
Bastion.ObjectManager.activeEnemies:each(function(unit)
if cb(unit) then

@ -42,7 +42,9 @@ Bastion.Enabled = false
Bastion.EventManager:RegisterWoWEvent('UNIT_AURA', function(unit, auras)
local u = Bastion.UnitManager[unit]
u:GetAuras():OnUpdate(auras)
if u then
u:GetAuras():OnUpdate(auras)
end
end)
Bastion.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", function(...)
@ -59,6 +61,23 @@ Bastion.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", function(...)
end
end)
Bastion.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function()
local _, subtype, _, sourceGUID, sourceName, _, _, destGUID, destName, destFlags, _, spellID, spellName, _, amount, interrupt, a, b, c, d, offhand, multistrike = CombatLogGetCurrentEventInfo()
local u = Bastion.UnitManager[sourceGUID]
local u2 = Bastion.UnitManager[destGUID]
local t = GetTime()
if u then
u:SetLastCombatTime(t)
end
if u2 then
u2:SetLastCombatTime(t)
end
end)
Bastion.Ticker = C_Timer.NewTicker(0.1, function()
if not Bastion.CombatTimer:IsRunning() and UnitAffectingCombat("player") then
Bastion.CombatTimer:Start()

Loading…
Cancel
Save