@ -1,12 +1,17 @@
---@type Tinkr, Bastion
local Tinkr , Bastion = ...
-- Create a new Unit class
---@class Unit
---@field id boolean | number
---@field ttd_ticker false | cbObject
---@field unit TinkrObjectReference
local Unit = {
---@type Cache
cache = nil ,
---@type AuraTable
aura_table = nil ,
---@type Unit
---@type UnitId | WowGameObject
unit = nil ,
last_shadow_techniques = 0 ,
swings_since_sht = 0 ,
@ -15,13 +20,13 @@ local Unit = {
last_combat_time = 0 ,
ttd_ticker = false ,
ttd = 0 ,
id = false ,
id = false , --[[ @asnumber ]]
}
function Unit : __index ( k )
local response = Bastion.ClassMagic : Resolve ( Unit , k )
if k == ' unit ' then
if k == " unit " then
return rawget ( self , k )
end
@ -40,7 +45,7 @@ end
---@param other Unit
---@return boolean
function Unit : __eq ( other )
return UnitIsUnit ( self : GetOMToken ( ) , other.unit )
return UnitIsUnit ( self : GetOMToken ( ) , other : GetOMToken ( ) )
end
-- tostring
@ -51,11 +56,11 @@ end
---```
---@return string
function Unit : __tostring ( )
return " Bastion.__Unit( " .. tostring ( self : GetOMToken ( ) ) .. " ) " .. " - " .. ( self : GetName ( ) or ' ' )
return " Bastion.__Unit( " .. tostring ( self : GetOMToken ( ) ) .. " ) " .. " - " .. ( self : GetName ( ) or " " )
end
-- Constructor
---@param unit string
---@param unit TinkrObjectReference
---@return Unit
function Unit : New ( unit )
local self = setmetatable ( { } , Unit )
@ -73,9 +78,8 @@ function Unit:IsValid()
end
-- Check if the unit exists
---@return boolean
function Unit : Exists ( )
return Object ( self : GetOMToken ( ) )
return Object ( self : GetOMToken ( ) ) ~= false
end
-- Get the units token
@ -87,11 +91,10 @@ end
-- Get the units name
---@return string
function Unit : GetName ( )
return UnitName ( self : GetOMToken ( ) )
return select ( 1 , UnitName ( self : GetOMToken ( ) ) )
end
-- Get the units GUID
---@return string
function Unit : GetGUID ( )
return ObjectGUID ( self : GetOMToken ( ) )
end
@ -139,9 +142,9 @@ function Unit:GetHealthPercent()
end
-- Get the units power type
---@return number
---@return Enum.PowerType
function Unit : GetPowerType ( )
return UnitPowerType ( self : GetOMToken ( ) )
return select ( 1 , UnitPowerType ( self : GetOMToken ( ) ) )
end
-- Get the units power
@ -226,7 +229,7 @@ end
-- Is the unit a hostile unit
---@return boolean
function Unit : IsHostile ( )
return UnitCanAttack ( self : GetOMToken ( ) , ' player ' )
return UnitCanAttack ( self : GetOMToken ( ) , " player " )
end
-- Is the unit a boss
@ -247,7 +250,7 @@ function Unit:IsBoss()
return false
end
---@return string
---@return UnitId
function Unit : GetOMToken ( )
if not self.unit then
return " none "
@ -341,24 +344,17 @@ local losFlag = bit.bor(0x1, 0x10, 0x100000)
---@param unit Unit
---@return boolean
function Unit : CanSee ( unit )
-- mechagon smoke cloud
-- local mechagonID = 2097
-- local smokecloud = 298602
-- local name, instanceType, difficultyID, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceID, instanceGroupSize, LfgDungeonID =
-- GetInstanceInfo()
-- otherUnit = otherUnit and otherUnit or "player"
-- if instanceID == 2097 then
-- if (self:debuff(smokecloud, unit) and not self:debuff(smokecloud, otherUnit))
-- or (self:debuff(smokecloud, otherUnit) and not self:debuff(smokecloud, unit))
-- then
-- return false
-- end
-- end
local ax , ay , az = ObjectPosition ( self : GetOMToken ( ) )
local ah = ObjectHeight ( self : GetOMToken ( ) )
local attx , atty , attz = GetUnitAttachmentPosition ( unit : GetOMToken ( ) , 34 )
local attx , atty , attz = GetUnitAttachmentPosition ( unit : GetOMToken ( ) , 18 )
local alwaysLos = {
[ 189727 ] = true , -- Khajin the Unyielding
}
--if alwaysLos[unit:GetID()] then
--return true
--end
if not attx or not ax then
return false
@ -391,12 +387,12 @@ function Unit:IsCasting()
end
function Unit : GetTimeCastIsAt ( percent )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId = UnitCastingInfo (
self : GetOMToken ( ) )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId =
UnitCastingInfo ( self : GetOMToken ( ) )
if not name then
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId = UnitChannelInfo ( self
: GetOMToken ( ) )
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId =
UnitChannelInfo ( self : GetOMToken ( ) )
end
if name and startTimeMS and endTimeMS then
@ -413,12 +409,12 @@ end
-- Get Casting or channeling spell
---@return Spell | nil
function Unit : GetCastingOrChannelingSpell ( )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId = UnitCastingInfo (
self : GetOMToken ( ) )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId =
UnitCastingInfo ( self : GetOMToken ( ) )
if not name then
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId = UnitChannelInfo ( self
: GetOMToken ( ) )
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId =
UnitChannelInfo ( self : GetOMToken ( ) )
end
if name then
@ -431,12 +427,12 @@ end
-- Get the end time of the cast or channel
---@return number
function Unit : GetCastingOrChannelingEndTime ( )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId = UnitCastingInfo (
self : GetOMToken ( ) )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId =
UnitCastingInfo ( self : GetOMToken ( ) )
if not name then
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId = UnitChannelInfo ( self
: GetOMToken ( ) )
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId =
UnitChannelInfo ( self : GetOMToken ( ) )
end
if name then
@ -458,6 +454,10 @@ function Unit:IsCastingOrChanneling()
return self : IsCasting ( ) or self : IsChanneling ( )
end
function Unit : IsImmobilized ( )
return bit.band ( self : GetMovementFlag ( ) , 0x400 ) > 0
end
-- Check if the unit can attack the target
---@param unit Unit
---@return boolean
@ -467,12 +467,12 @@ end
---@return number
function Unit : GetChannelOrCastPercentComplete ( )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId = UnitCastingInfo (
self : GetOMToken ( ) )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId =
UnitCastingInfo ( self : GetOMToken ( ) )
if not name then
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId = UnitChannelInfo ( self
: GetOMToken ( ) )
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId =
UnitChannelInfo ( self : GetOMToken ( ) )
end
if name and startTimeMS and endTimeMS then
@ -488,12 +488,12 @@ end
-- Check if unit is interruptible
---@return boolean
function Unit : IsInterruptible ( )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId = UnitCastingInfo (
self : GetOMToken ( ) )
local name , text , texture , startTimeMS , endTimeMS , isTradeSkill , castID , notInterruptible , spellId =
UnitCastingInfo ( self : GetOMToken ( ) )
if not name then
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId = UnitChannelInfo ( self
: GetOMToken ( ) )
name , text , texture , startTimeMS , endTimeMS , isTradeSkill , notInterruptible , spellId =
UnitChannelInfo ( self : GetOMToken ( ) )
end
if name then
@ -534,13 +534,19 @@ function Unit:GetEnemies(range)
local count = 0
Bastion.UnitManager : EnumEnemies ( function ( unit )
if not self : IsUnit ( unit ) and self : IsWithinCombatDistance ( unit , range ) and unit : IsAlive ( ) and self : CanSee ( unit ) and
unit : IsEnemy ( ) then
if
not self : IsUnit ( unit )
and self : IsWithinCombatDistance ( unit , range )
and unit : IsAlive ( )
and self : CanSee ( unit )
and unit : IsEnemy ( )
then
count = count + 1
end
return false
end )
self.cache : Set ( " enemies_ " .. range , count , .5 )
self.cache : Set ( " enemies_ " .. range , count , 0 .5)
return count
end
@ -555,13 +561,13 @@ function Unit:GetMeleeAttackers()
local count = 0
Bastion.UnitManager : EnumEnemies ( function ( unit )
if not self : IsUnit ( unit ) and unit : IsAlive ( ) and self : CanSee ( unit ) and
self : InMelee ( unit ) and unit : IsEnemy ( ) then
if not self : IsUnit ( unit ) and unit : IsAlive ( ) and self : CanSee ( unit ) and self : InMelee ( unit ) and unit : IsEnemy ( ) then
count = count + 1
end
return false
end )
self.cache : Set ( " melee_attackers " , count , .5 )
self.cache : Set ( " melee_attackers " , count , 0 .5)
return count
end
@ -572,10 +578,16 @@ function Unit:GetPartyHPAround(distance, percent)
local count = 0
Bastion.UnitManager : EnumFriends ( function ( unit )
if not self : IsUnit ( unit ) and unit : GetDistance ( self ) <= distance and unit : IsAlive ( ) and self : CanSee ( unit ) and
unit : GetHP ( ) <= percent then
if
not self : IsUnit ( unit )
and unit : GetDistance ( self ) <= distance
and unit : IsAlive ( )
and self : CanSee ( unit )
and unit : GetHP ( ) <= percent
then
count = count + 1
end
return false
end )
return count
@ -587,6 +599,10 @@ function Unit:IsMoving()
return GetUnitSpeed ( self : GetOMToken ( ) ) > 0
end
function Unit : GetMovementFlag ( )
return ObjectMovementFlag ( self : GetOMToken ( ) )
end
-- Is moving at all
---@return boolean
function Unit : IsMovingAtAll ( )
@ -627,15 +643,15 @@ end
---@param unit Unit
---@return boolean
function Unit : IsUnit ( unit )
return UnitIsUnit ( self : GetOMToken ( ) , unit and unit : GetOMToken ( ) or ' none ' )
return UnitIsUnit ( self : GetOMToken ( ) , unit and unit : GetOMToken ( ) or " none " )
end
-- IsTanking
---@param unit Unit
---@return boolean
function Unit : IsTanking ( unit )
local isTanking , status , threatpct , rawthreatpct , threatvalue = UnitDetailedThreatSituation ( self : GetOMToken ( ) ,
unit : GetOMToken ( ) )
local isTanking , status , threatpct , rawthreatpct , threatvalue =
UnitDetailedThreatSituation ( self : GetOMToken ( ) , unit : GetOMToken ( ) )
return isTanking
end
@ -651,6 +667,7 @@ function Unit:IsFacing(unit)
return false
end
---@diagnostic disable-next-line: deprecated
local angle = math.atan2 ( y2 - y , x2 - x ) - rot
angle = math.deg ( angle )
angle = angle % 360
@ -672,7 +689,7 @@ function Unit:IsBehind(unit)
if not x or not x2 then
return false
end
---@diagnostic disable-next-line: deprecated
local angle = math.atan2 ( y2 - y , x2 - x ) - rot
angle = math.deg ( angle )
angle = angle % 360
@ -692,7 +709,16 @@ end
---@return number
function Unit : GetMeleeBoost ( )
if IsPlayerSpell ( 196924 ) then
if IsPlayerSpell ( 197524 ) then
local astralNode = C_Traits.GetNodeInfo ( C_ClassTalents.GetActiveConfigID ( ) or 0 , 82210 )
local currentSpec = select ( 1 , GetSpecializationInfo ( GetSpecialization ( ) ) )
if astralNode then
local currentRank = astralNode.activeRank
if currentRank > 0 then
return ( ( currentSpec == 103 or currentSpec == 104 ) and 1 or 3 ) + ( currentRank == 2 and 2 or 0 )
end
end
elseif IsPlayerSpell ( 196924 ) then
return 3
end
return 0
@ -733,9 +759,11 @@ end
-- Get object id
---@return number
function Unit : GetID ( )
if self.id then return self.id end
if self.id then
return self.id --[[ @as number ]]
end
self.id = ObjectID ( self : GetOMToken ( ) )
return self.id
return self.id --[[ @as number ]]
end
-- In party
@ -836,7 +864,7 @@ end
function Unit : TimeToDie ( )
if self : IsDead ( ) then
self.regression_history = { }
if self.ttd_ticker then
if type ( self.ttd_ticker ) == " table " then
self.ttd_ticker : Cancel ( )
self.ttd_ticker = false
end
@ -854,8 +882,7 @@ function Unit:TimeToDie()
-- if the unit has more than 5 million health but there's not enough data to make a prediction we can assume there's roughly 250000 damage per second and estimate the time to die
if # self.regression_history < 5 and self : GetMaxHealth ( ) > 5000000 then
return self : GetMaxHealth ( ) /
250000 -- 250000 is an estimate of the average damage per second a well geared group will average
return self : GetMaxHealth ( ) / 250000 -- 250000 is an estimate of the average damage per second a well geared group will average
end
if self.ttd ~= self.ttd or self.ttd < 0 or self.ttd == math.huge then
@ -933,7 +960,7 @@ function Unit:IsStealthed()
local Shadowmeld = Bastion.Globals . SpellBook : GetSpell ( 58984 )
local Sepsis = Bastion.Globals . SpellBook : GetSpell ( 328305 )
return self : GetAuras ( ) : FindAny ( Stealth ) or self : GetAuras ( ) : FindAny ( ShadowDance )
return self : GetAuras ( ) : FindAny ( Stealth ) : IsUp ( ) or self : GetAuras ( ) : FindAny ( ShadowDance ) : IsUp ( )
end
-- Get unit swing timers
@ -963,7 +990,7 @@ function Unit:WatchForSwings()
local _ , subtype , _ , sourceGUID , sourceName , _ , _ , destGUID , destName , destFlags , _ , spellID , spellName , _ , amount , interrupt , a , b , c , d , offhand , multistrike =
CombatLogGetCurrentEventInfo ( )
if sourceGUID == self : GetGUID ( ) then
if sourceGUID == self : GetGUID ( ) and subtype then
if subtype == " SPELL_ENERGIZE " and spellID == 196911 then
self.last_shadow_techniques = GetTime ( )
self.swings_since_sht = 0
@ -1036,8 +1063,8 @@ function Unit:GetStaggerPercent()
end
-- Get the units power regen rate
---@return number
function Unit : GetPowerRegen ( )
---@diagnostic disable-next-line: redundant-parameter
return GetPowerRegen ( self : GetOMToken ( ) )
end
@ -1051,7 +1078,7 @@ function Unit:GetStaggeredHealth()
end
-- get the units combat reach
---@return number
---@return number | false
function Unit : GetCombatReach ( )
return ObjectCombatReach ( self : GetOMToken ( ) )
end
@ -1144,6 +1171,27 @@ function Unit:GetEmpoweredStage()
return stage
end
function Unit : IsConnected ( )
return UnitIsConnected ( self : GetOMToken ( ) )
end
function Unit : HasIncomingRessurection ( )
return self : IsDead ( ) and UnitHasIncomingResurrection ( self : GetOMToken ( ) )
end
function Unit : LootTarget ( )
return ObjectLootTarget ( self : GetOMToken ( ) )
end
function Unit : CanLoot ( )
return ObjectLootable ( self : GetOMToken ( ) )
end
function Unit : HasTarget ( )
return ObjectTarget ( self : GetOMToken ( ) ) ~= false
end
function Unit : Target ( )
return self : HasTarget ( ) and Bastion.UnitManager : Get ( ObjectTarget ( self : GetOMToken ( ) ) : unit ( ) )
or Bastion.UnitManager : Get ( " none " )
end
-- local empowering = {}
-- Bastion.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_EMPOWER_START", function(...)