main
ck 12 months ago
parent a572688294
commit 031c68009c
  1. 297
      src/APL/APL.lua
  2. 141
      src/APLActor/APLActor.lua
  3. 42
      src/APLTrait/APLTrait.lua
  4. 24
      src/Aura/Aura.lua
  5. 136
      src/AuraTable/AuraTable.lua
  6. 5
      src/Cache/Cache.lua
  7. 23
      src/Cacheable/Cacheable.lua
  8. 8
      src/Class/Class.lua
  9. 2
      src/ClassMagic/ClassMagic.lua
  10. 7
      src/Command/Command.lua
  11. 2
      src/Config/Config.lua
  12. 13
      src/EventManager/EventManager.lua
  13. 48
      src/Item/Item.lua
  14. 8
      src/ItemBook/ItemBook.lua
  15. 10
      src/Library/Library.lua
  16. 45
      src/List/List.lua
  17. 11
      src/Module/Module.lua
  18. 27
      src/MythicPlusUtils/MythicPlusUtils.lua
  19. 69
      src/Notification/Notification.lua
  20. 92
      src/NotificationList/NotificationList.lua
  21. 147
      src/NotificationsList/NotificationsList.lua
  22. 69
      src/ObjectManager/ObjectManager.lua
  23. 4
      src/Refreshable/Refreshable.lua
  24. 6
      src/Sequencer/Sequencer.lua
  25. 165
      src/Spell/Spell.lua
  26. 20
      src/SpellBook/SpellBook.lua
  27. 46
      src/TimeToDie/TimeToDie.lua
  28. 5
      src/Timer/Timer.lua
  29. 75
      src/Unit/Unit.lua
  30. 57
      src/UnitManager/UnitManager.lua
  31. 164
      src/Vector3/Vector3.lua
  32. 183
      src/_bastion.lua

@ -1,174 +1,9 @@
-- Create an APL trait for the APL class ---@type Tinkr, Bastion
---@class APLTrait local Tinkr, Bastion = ...
---@field cb fun(actor?: APLActorTable):boolean
---@field lastcall number
local APLTrait = {}
APLTrait.__index = APLTrait
-- Constructor
---@param cb fun(actor?: APLActorTable):boolean
---@return APLTrait
function APLTrait:New(cb)
local self = setmetatable({}, APLTrait)
self.cb = cb
self.lastcall = 0
return self
end
-- Evaulate the APL trait
---@param actor? APLActorTable
---@return boolean
function APLTrait:Evaluate(actor)
if GetTime() - self.lastcall > 0.1 then
self.lastresult = self.cb(actor)
self.lastcall = GetTime()
return self.lastresult
end
return self.lastresult
end
-- tostring
---@return string
function APLTrait:__tostring()
return "Bastion.__APLTrait"
end
---@class APLActorTableBase
---@field type "spell" | "item" | "apl" | "sequencer" | "variable" | "action"
---@alias APLActorTable APLActorSpellTable | APLActorItemTable | APLActorAPLTable | APLActorSequencerTable | APLActorVariableTable | APLActorActionTable
-- Create an APL actor for the APL class
---@class APLActor
---@field actor APLActorTable
---@field traits APLTrait[]
---@field name string
local APLActor = {}
APLActor.__index = APLActor
-- Constructor
---@param actor APLActorTable
function APLActor:New(actor)
local self = setmetatable({}, APLActor)
if actor.type == "spell" then
self.name = string.format("[%s] `%s`<%s>", "spell", actor.spell:GetName(), actor.spell:GetID())
elseif actor.type == "item" then
self.name = string.format("[%s] `%s`<%s>", "item", actor.item:GetName(), actor.item:GetID())
elseif actor.type == "apl" then
self.name = string.format("[%s] `%s`", "apl", actor.apl.name)
elseif actor.type == "sequencer" then
self.name = string.format("[%s]", "sequencer")
elseif actor.type == "variable" then
self.name = string.format("[%s] `%s`", "variable", actor.variable)
elseif actor.type == "action" then
self.name = string.format("[%s] `%s`", "action", actor.action)
else
self.name = string.format("[%s] Unknown", actor.type)
end
self.actor = actor
self.traits = {}
return self
end
-- Add a trait to the APL actor
---@param ... APLTrait
---@return APLActor
function APLActor:AddTraits(...)
for _, trait in ipairs({ ... }) do
table.insert(self.traits, trait)
end
return self
end
-- Get the actor
---@return APLActorTable
function APLActor:GetActor()
return self.actor
end
-- Evaulate the APL actor
---@return boolean
function APLActor:Evaluate()
for _, trait in ipairs(self.traits) do
if not trait:Evaluate(self:GetActor()) then
return false
end
end
return true
end
-- Execute
function APLActor:Execute()
local actorTable = self:GetActor()
-- If the actor is a sequencer we don't want to continue executing the APL if the sequencer is not finished
if actorTable.type == "sequencer" then
---@cast actorTable APLActorSequencerTable
if actorTable.condition and actorTable.condition() and not actorTable.sequencer:Finished() then
actorTable.sequencer:Execute()
return true
end
if not actorTable.condition and not actorTable.sequencer:Finished() then
actorTable.sequencer:Execute()
return true
end
-- Check if the sequencer can be reset and reset it if it can
if actorTable.sequencer:ShouldReset() then
actorTable.sequencer:Reset()
end
end
if actorTable.type == "apl" then
---@cast actorTable APLActorAPLTable
if actorTable.condition and actorTable.condition() then
-- print("Bastion: APL:Execute: Executing sub APL " .. actorTable.apl.name)
if actorTable.apl:Execute() then
return true
end
end
end
if actorTable.type == "spell" then
---@cast actorTable APLActorSpellTable
return actorTable.spell:CastableIf(actorTable.castableFunc):OnCast(actorTable.onCastFunc):Cast(actorTable.target, actorTable.condition)
end
if actorTable.type == "item" then
---@cast actorTable APLActorItemTable
return actorTable.item:UsableIf(actorTable.usableFunc):Use(actorTable.target, actorTable.condition)
end
if self:GetActor().type == "action" then
---@cast actorTable APLActorActionTable
-- print("Bastion: APL:Execute: Executing action " .. actorTable.action)
self:GetActor().cb()
end
if actorTable.type == "variable" then
---@cast actorTable APLActorVariableTable
-- print("Bastion: APL:Execute: Setting variable " .. actorTable.variable)
actorTable._apl.variables[actorTable.variable] = actorTable.cb(actorTable._apl)
end
return false
end
-- has traits
---@return boolean
function APLActor:HasTraits()
return #self.traits > 0
end
-- tostring
---@return string
function APLActor:__tostring()
return string.format("Bastion.__APLActor(%s)", self.name)
end
-- APL (Attack priority list) class -- APL (Attack priority list) class
---@class APL ---@class Bastion.APL
---@field apl APLActor[] ---@field apl Bastion.APLActor[]
---@field variables table<string, any> ---@field variables table<string, any>
---@field name string ---@field name string
---@field last { successful: { name: string, time: number, index: number }, attempted: { name: string, time: number, index: number } } ---@field last { successful: { name: string, time: number, index: number }, attempted: { name: string, time: number, index: number } }
@ -177,14 +12,25 @@ APL.__index = APL
-- Constructor -- Constructor
---@param name string ---@param name string
---@return APL ---@return Bastion.APL
function APL:New(name) function APL:New(name)
local self = setmetatable({}, APL) local self = setmetatable({}, APL)
self.apl = {} self.apl = {}
self.variables = {} self.variables = {}
self.name = name self.name = name
self.last = {} self.last = {
successful = {
name = "",
time = -1,
index = -1,
},
attempted = {
name = "",
time = -1,
index = -1,
},
}
return self return self
end end
@ -203,17 +49,17 @@ function APL:GetVariable(name)
return self.variables[name] return self.variables[name]
end end
---@class APLActorVariableTable : APLActorTableBase ---@class Bastion.APL.Actor.Variable.Table : Bastion.APLActor.Table.Base
---@field variable string ---@field variable string
---@field cb fun(...):any ---@field cb fun(...):any
---@field _apl APL ---@field _apl Bastion.APL
-- Add variable -- Add variable
---@param name string ---@param name string
---@param cb fun(...):any ---@param cb fun(...):any
---@return APLActor ---@return Bastion.APLActor
function APL:AddVariable(name, cb) function APL:AddVariable(name, cb)
local actor = APLActor:New({ local actor = Bastion.APLActor:New({
type = "variable", type = "variable",
variable = name, variable = name,
cb = cb, cb = cb,
@ -223,16 +69,16 @@ function APL:AddVariable(name, cb)
return actor return actor
end end
---@class APLActorActionTable : APLActorTableBase ---@class Bastion.APL.Actor.Action.Table : Bastion.APLActor.Table.Base
---@field action string ---@field action string
---@field cb fun(...):any ---@field cb fun(...):any
-- Add a manual action to the APL -- Add a manual action to the APL
---@param action string ---@param action string
---@param cb fun(...):any ---@param cb fun(...):any
---@return APLActor ---@return Bastion.APLActor
function APL:AddAction(action, cb) function APL:AddAction(action, cb)
local actor = APLActor:New({ local actor = Bastion.APLActor:New({
type = "action", type = "action",
action = action, action = action,
cb = cb, cb = cb,
@ -241,23 +87,23 @@ function APL:AddAction(action, cb)
return actor return actor
end end
---@class APLActorSpellTable : APLActorTableBase ---@class Bastion.APL.Actor.Spell.Table : Bastion.APLActor.Table.Base
---@field spell Spell ---@field spell Bastion.Spell
---@field condition? string|fun(self: Spell): boolean ---@field condition? string|fun(self: Bastion.Spell): boolean
---@field castableFunc false | fun(self: Spell): boolean ---@field castableFunc false | fun(self: Bastion.Spell): boolean
---@field target Unit | false ---@field target Bastion.Unit | false
---@field onCastFunc false | fun(self: Spell):any ---@field onCastFunc false | fun(self: Bastion.Spell):any
-- Add a spell to the APL -- Add a spell to the APL
---@param spell Spell ---@param spell Bastion.Spell
---@param condition? string|fun(self: Spell):boolean ---@param condition? string|fun(self: Bastion.Spell):boolean
---@return APLActor ---@return Bastion.APLActor
function APL:AddSpell(spell, condition) function APL:AddSpell(spell, condition)
local castableFunc = spell.CastableIfFunc local castableFunc = spell.CastableIfFunc
local onCastFunc = spell.OnCastFunc local onCastFunc = spell.OnCastFunc
local target = spell:GetTarget() local target = spell:GetTarget()
local actor = APLActor:New({ local actor = Bastion.APLActor:New({
type = "spell", type = "spell",
spell = spell, spell = spell,
condition = condition, condition = condition,
@ -271,21 +117,21 @@ function APL:AddSpell(spell, condition)
return actor return actor
end end
---@class APLActorItemTable : APLActorTableBase ---@class Bastion.APL.Actor.Item.Table : Bastion.APLActor.Table.Base
---@field item Item ---@field item Bastion.Item
---@field condition? string | fun(self: Item): boolean ---@field condition? string | fun(self: Bastion.Item): boolean
---@field usableFunc false | fun(...): boolean ---@field usableFunc false | fun(...): boolean
---@field target Unit | nil ---@field target Bastion.Unit | nil
-- Add an item to the APL -- Add an item to the APL
---@param item Item ---@param item Bastion.Item
---@param condition? string | fun(self: Item): boolean ---@param condition? string | fun(self: Bastion.Item): boolean
---@return APLActor ---@return Bastion.APLActor
function APL:AddItem(item, condition) function APL:AddItem(item, condition)
local usableFunc = item.UsableIfFunc local usableFunc = item.UsableIfFunc
local target = item:GetTarget() local target = item:GetTarget()
local actor = APLActor:New({ local actor = Bastion.APLActor:New({
type = "item", type = "item",
item = item, item = item,
condition = condition, condition = condition,
@ -298,19 +144,19 @@ function APL:AddItem(item, condition)
return actor return actor
end end
---@class APLActorAPLTable : APLActorTableBase ---@class Bastion.APL.Actor.APL.Table : Bastion.APLActor.Table.Base
---@field apl APL ---@field apl Bastion.APL
---@field condition? fun(...):boolean ---@field condition? fun(...):boolean
-- Add an APL to the APL (for sub APLs) -- Add an APL to the APL (for sub APLs)
---@param apl APL ---@param apl Bastion.APL
---@param condition fun(...):boolean ---@param condition fun(...):boolean
---@return APLActor ---@return Bastion.APLActor
function APL:AddAPL(apl, condition) function APL:AddAPL(apl, condition)
if not condition then if not condition then
error("Bastion: APL:AddAPL: No condition for APL " .. apl.name) error("Bastion: APL:AddAPL: No condition for APL " .. apl.name)
end end
local actor = APLActor:New({ local actor = Bastion.APLActor:New({
type = "apl", type = "apl",
apl = apl, apl = apl,
condition = condition, condition = condition,
@ -319,35 +165,50 @@ function APL:AddAPL(apl, condition)
return actor return actor
end end
---@param name string
---@param enabled? boolean
function APL:ToggleAPL(name, enabled)
for _, actor in ipairs(self.apl) do
if actor.actor.type == "apl" and actor.name == name then
actor.enabled = type(enabled) == "boolean" and enabled or not actor.enabled
break
end
end
end
function APL:UpdateLastAttempted(name, index)
self.last.attempted.name = name
self.last.attempted.time = GetTime()
self.last.attempted.index = index
end
function APL:UpdateLastSuccessful(name, index)
self.last.successful.name = name
self.last.successful.time = GetTime()
self.last.successful.index = index
end
-- Execute the APL -- Execute the APL
function APL:Execute() function APL:Execute()
for i, actor in ipairs(self.apl) do for i, actor in ipairs(self.apl) do
self.last.attempted = { self:UpdateLastAttempted(actor.name, i)
name = actor.name, if actor.enabled and (not actor:HasTraits() or actor:Evaluate()) and actor:Execute() then
time = GetTime(), self:UpdateLastSuccessful(actor.name, i)
index = i,
}
if (not actor:HasTraits() or actor:Evaluate()) and actor:Execute() then
self.last.successful = {
name = actor.name,
time = GetTime(),
index = i,
}
return true return true
end end
end end
end end
---@class APLActorSequencerTable : APLActorTableBase ---@class Bastion.APL.Actor.Sequencer.Table : Bastion.APLActor.Table.Base
---@field sequencer Sequencer ---@field sequencer Bastion.Sequencer
---@field condition? fun(...):boolean ---@field condition? fun(...):boolean
-- Add a Sequencer to the APL -- Add a Sequencer to the APL
---@param sequencer Sequencer ---@param sequencer Bastion.Sequencer
---@param condition fun(...):boolean ---@param condition fun(...):boolean
---@return APLActor ---@return Bastion.APLActor
function APL:AddSequence(sequencer, condition) function APL:AddSequence(sequencer, condition)
local actor = APLActor:New({ local actor = Bastion.APLActor:New({
type = "sequencer", type = "sequencer",
sequencer = sequencer, sequencer = sequencer,
condition = condition, condition = condition,
@ -362,4 +223,4 @@ function APL:__tostring()
return "Bastion.__APL(" .. self.name .. ")" return "Bastion.__APL(" .. self.name .. ")"
end end
return APL, APLActor, APLTrait return APL

@ -0,0 +1,141 @@
---@type Tinkr, Bastion
local Tinkr, Bastion = ...
---@class Bastion.APLActor.Table.Base
---@field type "spell" | "item" | "apl" | "sequencer" | "variable" | "action"
---@alias Bastion.APLActor.Table Bastion.APL.Actor.Spell.Table | Bastion.APL.Actor.Item.Table | Bastion.APL.Actor.APL.Table | Bastion.APL.Actor.Sequencer.Table | Bastion.APL.Actor.Variable.Table | Bastion.APL.Actor.Action.Table
-- Create an APL actor for the APL class
---@class Bastion.APLActor
---@field actor Bastion.APLActor.Table
---@field enabled boolean
---@field traits Bastion.APLTrait[]
---@field name string
local APLActor = {}
APLActor.__index = APLActor
-- Constructor
---@param actor Bastion.APLActor.Table
function APLActor:New(actor)
local self = setmetatable({}, APLActor)
if actor.type == "spell" then
local name = actor.spell:GetName() or "Unknown"
local id = actor.spell:GetID() or 0
self.name = string.format("[%s] `%s`<%s>", "spell", name, id)
elseif actor.type == "item" then
local name = actor.item:GetName() or "Unknown"
local id = actor.item:GetID() or 0
self.name = string.format("[%s] `%s`<%s>", "item", name, id)
elseif actor.type == "apl" then
self.name = string.format("[%s] `%s`", "apl", actor.apl.name)
elseif actor.type == "sequencer" then
self.name = string.format("[%s]", "sequencer")
elseif actor.type == "variable" then
self.name = string.format("[%s] `%s`", "variable", actor.variable)
elseif actor.type == "action" then
self.name = string.format("[%s] `%s`", "action", actor.action)
else
self.name = string.format("[%s] Unknown", actor.type)
end
self.actor = actor
self.enabled = true
self.traits = {}
return self
end
-- Add a trait to the APL actor
---@param ... Bastion.APLTrait
---@return Bastion.APLActor
function APLActor:AddTraits(...)
for _, trait in ipairs({ ... }) do
table.insert(self.traits, trait)
end
return self
end
-- Get the actor
---@return Bastion.APLActor.Table
function APLActor:GetActor()
return self.actor
end
-- Evaulate the APL actor
---@return boolean
function APLActor:Evaluate()
for _, trait in ipairs(self.traits) do
if not trait:Evaluate(self:GetActor()) then
return false
end
end
return true
end
-- Execute
function APLActor:Execute()
local actorTable = self:GetActor()
-- If the actor is a sequencer we don't want to continue executing the APL if the sequencer is not finished
if actorTable.type == "sequencer" then
---@cast actorTable Bastion.APL.Actor.Sequencer.Table
if actorTable.condition and actorTable.condition() and not actorTable.sequencer:Finished() then
actorTable.sequencer:Execute()
return true
end
if not actorTable.condition and not actorTable.sequencer:Finished() then
actorTable.sequencer:Execute()
return true
end
-- Check if the sequencer can be reset and reset it if it can
if actorTable.sequencer:ShouldReset() then
actorTable.sequencer:Reset()
end
end
if actorTable.type == "apl" then
---@cast actorTable Bastion.APL.Actor.APL.Table
if actorTable.condition and actorTable.condition() then
-- print("Bastion: APL:Execute: Executing sub APL " .. actorTable.apl.name)
if actorTable.apl:Execute() then
return true
end
end
end
if actorTable.type == "spell" then
---@cast actorTable Bastion.APL.Actor.Spell.Table
return actorTable.spell:CastableIf(actorTable.castableFunc):OnCast(actorTable.onCastFunc):Cast(actorTable.target,
actorTable.condition)
end
if actorTable.type == "item" then
---@cast actorTable Bastion.APL.Actor.Item.Table
return actorTable.item:UsableIf(actorTable.usableFunc):Use(actorTable.target, actorTable.condition)
end
if self:GetActor().type == "action" then
---@cast actorTable Bastion.APL.Actor.Action.Table
-- print("Bastion: APL:Execute: Executing action " .. actorTable.action)
self:GetActor().cb()
end
if actorTable.type == "variable" then
---@cast actorTable Bastion.APL.Actor.Variable.Table
-- print("Bastion: APL:Execute: Setting variable " .. actorTable.variable)
actorTable._apl.variables[actorTable.variable] = actorTable.cb(actorTable._apl)
end
return false
end
-- has traits
---@return boolean
function APLActor:HasTraits()
return #self.traits > 0
end
-- tostring
---@return string
function APLActor:__tostring()
return string.format("Bastion.__APLActor(%s)", self.name)
end
return APLActor

@ -0,0 +1,42 @@
---@type Tinkr, Bastion
local Tinkr, Bastion = ...
-- Create an APL trait for the APL class
---@class Bastion.APLTrait
---@field cb fun(actor?: Bastion.APLActor.Table):boolean
---@field lastcall number
local APLTrait = {}
APLTrait.__index = APLTrait
-- Constructor
---@param cb fun(actor?: Bastion.APLActor.Table):boolean
---@return Bastion.APLTrait
function APLTrait:New(cb)
local self = setmetatable({}, APLTrait)
self.cb = cb
self.lastcall = 0
return self
end
-- Evaulate the APL trait
---@param actor? Bastion.APLActor.Table
---@return boolean
function APLTrait:Evaluate(actor)
if GetTime() - self.lastcall > 0.1 then
self.lastresult = self.cb(actor)
self.lastcall = GetTime()
return self.lastresult
end
return self.lastresult
end
-- tostring
---@return string
function APLTrait:__tostring()
return "Bastion.__APLTrait"
end
return APLTrait

@ -2,7 +2,7 @@
---@type Tinkr, Bastion ---@type Tinkr, Bastion
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
---@class AuraAuraData ---@class Bastion.Aura.Aura.Data
---@field auraInstanceID? number ---@field auraInstanceID? number
---@field name? string ---@field name? string
---@field icon? number ---@field icon? number
@ -24,8 +24,8 @@ local Tinkr, Bastion = ...
---@field type? string ---@field type? string
-- Create a new Aura class -- Create a new Aura class
---@class Aura ---@class Bastion.Aura
---@field aura AuraAuraData ---@field aura Bastion.Aura.Aura.Data
local Aura = {} local Aura = {}
function Aura:__index(k) function Aura:__index(k)
@ -43,7 +43,7 @@ function Aura:__index(k)
end end
-- Equals -- Equals
---@param other Aura | Spell ---@param other Bastion.Aura | Bastion.Spell
---@return boolean ---@return boolean
function Aura:__eq(other) function Aura:__eq(other)
if getmetatable(other) == Aura then if getmetatable(other) == Aura then
@ -64,12 +64,12 @@ function Aura:__tostring()
end end
-- Constructor -- Constructor
---@param unit? Unit ---@param unit? Bastion.Unit
---@param index? number ---@param index? number
---@param type? string ---@param type? string
function Aura:New(unit, index, type) function Aura:New(unit, index, type)
if unit == nil or index == nil or type == nil then if unit == nil or index == nil or type == nil then
---@class Aura ---@class Bastion.Aura
local self = setmetatable({}, Aura) local self = setmetatable({}, Aura)
self.aura = { self.aura = {
name = nil, name = nil,
@ -101,7 +101,7 @@ function Aura:New(unit, index, type)
local name, icon, count, dispelType, duration, expirationTime, source, isStealable, nameplateShowPersonal, spellId, canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, timeMod, v1, v2, v3, v4 = local name, icon, count, dispelType, duration, expirationTime, source, isStealable, nameplateShowPersonal, spellId, canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, timeMod, v1, v2, v3, v4 =
UnitAura(unit:GetOMToken(), index, type) UnitAura(unit:GetOMToken(), index, type)
---@class Aura ---@class Bastion.Aura
local self = setmetatable({}, Aura) local self = setmetatable({}, Aura)
self.aura = { self.aura = {
name = name, name = name,
@ -165,9 +165,9 @@ end
-- Constructor -- Constructor
---@param unitAuraInfo AuraData ---@param unitAuraInfo AuraData
---@return Aura ---@return Bastion.Aura
function Aura:CreateFromUnitAuraInfo(unitAuraInfo) function Aura:CreateFromUnitAuraInfo(unitAuraInfo)
---@class Aura ---@class Bastion.Aura
local self = setmetatable({}, Aura) local self = setmetatable({}, Aura)
--[[ --[[
applications applications
@ -298,7 +298,7 @@ function Aura:GetExpirationTime()
end end
-- Get the auras source -- Get the auras source
---@return Unit ---@return Bastion.Unit
function Aura:GetSource() function Aura:GetSource()
return Bastion.UnitManager[self.aura.source] return Bastion.UnitManager[self.aura.source]
end end
@ -316,7 +316,7 @@ function Aura:GetNameplateShowPersonal()
end end
-- Get the auras spell id -- Get the auras spell id
---@return Spell ---@return Bastion.Spell
function Aura:GetSpell() function Aura:GetSpell()
return Bastion.Globals.SpellBook:GetSpell(self.aura.spellId) return Bastion.Globals.SpellBook:GetSpell(self.aura.spellId)
end end
@ -370,7 +370,7 @@ function Aura:GetAuraInstanceID()
end end
-- Check if the aura is dispelable by a spell -- Check if the aura is dispelable by a spell
---@param spell Spell ---@param spell Bastion.Spell
function Aura:IsDispelableBySpell(spell) function Aura:IsDispelableBySpell(spell)
if (self:GetDispelType() == "" or self:GetDispelType() == nil) and self:GetIsStealable() and spell:IsEnrageDispel() then if (self:GetDispelType() == "" or self:GetDispelType() == nil) and self:GetIsStealable() and spell:IsEnrageDispel() then
return true return true

@ -3,20 +3,20 @@ local Tinkr, Bastion = ...
---@alias auraInstanceId integer ---@alias auraInstanceId integer
---@class AuraInstanceTable ---@class Bastion.Aura.Instance.Table
---@field [spellId] { [auraInstanceId]: Aura } ---@field [spellId] { [auraInstanceId]: Bastion.Aura }
-- Create a new AuraTable class -- Create a new AuraTable class
---@class AuraTable ---@class Bastion.AuraTable
---@field unit Unit ---@field unit Bastion.Unit
---@field playerAuras AuraInstanceTable ---@field playerAuras Bastion.Aura.Instance.Table
---@field auras AuraInstanceTable ---@field auras Bastion.Aura.Instance.Table
local AuraTable = {} local AuraTable = {}
AuraTable.__index = AuraTable AuraTable.__index = AuraTable
-- Constructor -- Constructor
---@param unit Unit ---@param unit Bastion.Unit
---@return AuraTable ---@return Bastion.AuraTable
function AuraTable:New(unit) function AuraTable:New(unit)
local self = setmetatable({}, AuraTable) local self = setmetatable({}, AuraTable)
@ -103,7 +103,7 @@ end
-- Update the aura table -- Update the aura table
---@param instanceID number ---@param instanceID number
---@param aura Aura ---@param aura Bastion.Aura
---@return nil ---@return nil
function AuraTable:AddOrUpdateAuraInstanceID(instanceID, aura) function AuraTable:AddOrUpdateAuraInstanceID(instanceID, aura)
local spellId = aura:GetSpell():GetID() local spellId = aura:GetSpell():GetID()
@ -219,7 +219,7 @@ function AuraTable:Update()
end end
-- Get a units auras -- Get a units auras
---@return table<number, table<number, Aura>> ---@return table<number, table<number, Bastion.Aura>>
function AuraTable:GetUnitAuras() function AuraTable:GetUnitAuras()
if not self.did then if not self.did then
self.did = true self.did = true
@ -274,8 +274,8 @@ function AuraTable:Clear()
end end
-- Check if the unit has a specific aura -- Check if the unit has a specific aura
---@param spell Spell ---@param spell Bastion.Spell
---@return Aura ---@return Bastion.Aura
function AuraTable:Find(spell) function AuraTable:Find(spell)
local auras = self:GetUnitAuras() local auras = self:GetUnitAuras()
local aurasub = auras[spell:GetID()] local aurasub = auras[spell:GetID()]
@ -300,8 +300,8 @@ function AuraTable:Find(spell)
end end
-- Check if the unit has a specific aura -- Check if the unit has a specific aura
---@param spell Spell ---@param spell Bastion.Spell
---@return Aura ---@return Bastion.Aura
function AuraTable:FindMy(spell) function AuraTable:FindMy(spell)
local auras = self:GetMyUnitAuras() local auras = self:GetMyUnitAuras()
local aurasub = auras[spell:GetID()] local aurasub = auras[spell:GetID()]
@ -326,9 +326,9 @@ function AuraTable:FindMy(spell)
end end
-- Check if the unit has a specific aura -- Check if the unit has a specific aura
---@param spell Spell ---@param spell Bastion.Spell
---@param source "any" | Unit ---@param source "any" | Bastion.Unit
---@return Aura ---@return Bastion.Aura
function AuraTable:FindFrom(spell, source) function AuraTable:FindFrom(spell, source)
if type(source) == "string" and source == "any" then if type(source) == "string" and source == "any" then
return self:FindAny(spell) return self:FindAny(spell)
@ -359,8 +359,8 @@ function AuraTable:FindFrom(spell, source)
end end
-- Find the aura from the current unit -- Find the aura from the current unit
---@param spell Spell ---@param spell Bastion.Spell
---@return Aura ---@return Bastion.Aura
function AuraTable:FindTheirs(spell) function AuraTable:FindTheirs(spell)
local auras = self:GetUnitAuras() local auras = self:GetUnitAuras()
local aurasub = auras[spell:GetID()] local aurasub = auras[spell:GetID()]
@ -387,8 +387,8 @@ function AuraTable:FindTheirs(spell)
end end
-- Find any -- Find any
---@param spell Spell ---@param spell Bastion.Spell
---@return Aura ---@return Bastion.Aura
function AuraTable:FindAny(spell) function AuraTable:FindAny(spell)
local a = self:Find(spell) local a = self:Find(spell)
if a:IsValid() then if a:IsValid() then
@ -399,8 +399,8 @@ function AuraTable:FindAny(spell)
end end
-- FindAnyOf -- FindAnyOf
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindAnyOf(spells) function AuraTable:FindAnyOf(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindAny(cur) local aura = self:FindAny(cur)
@ -412,8 +412,8 @@ function AuraTable:FindAnyOf(spells)
end end
-- FindAnyOfMy -- FindAnyOfMy
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindAnyOfMy(spells) function AuraTable:FindAnyOfMy(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindMy(cur) local aura = self:FindMy(cur)
@ -425,8 +425,8 @@ function AuraTable:FindAnyOfMy(spells)
end end
-- FindAnyOfTheirs -- FindAnyOfTheirs
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindAnyOfTheirs(spells) function AuraTable:FindAnyOfTheirs(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindTheirs(cur) local aura = self:FindTheirs(cur)
@ -438,9 +438,9 @@ function AuraTable:FindAnyOfTheirs(spells)
end end
-- FindAnyFrom -- FindAnyFrom
---@param spells List ---@param spells Bastion.List
---@param source Unit ---@param source Bastion.Unit
---@return Aura ---@return Bastion.Aura
function AuraTable:FindAnyFrom(spells, source) function AuraTable:FindAnyFrom(spells, source)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindFrom(cur, source) local aura = self:FindFrom(cur, source)
@ -452,8 +452,8 @@ function AuraTable:FindAnyFrom(spells, source)
end end
-- FindLongestOf -- FindLongestOf
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindLongestOf(spells) function AuraTable:FindLongestOf(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:Find(cur) local aura = self:Find(cur)
@ -470,8 +470,8 @@ function AuraTable:FindLongestOf(spells)
end end
-- FindLongestOfMy -- FindLongestOfMy
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindLongestOfMy(spells) function AuraTable:FindLongestOfMy(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindMy(cur) local aura = self:FindMy(cur)
@ -488,8 +488,8 @@ function AuraTable:FindLongestOfMy(spells)
end end
-- FindLongestOfTheirs -- FindLongestOfTheirs
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindLongestOfTheirs(spells) function AuraTable:FindLongestOfTheirs(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindTheirs(cur) local aura = self:FindTheirs(cur)
@ -506,9 +506,9 @@ function AuraTable:FindLongestOfTheirs(spells)
end end
-- FindLongestOfFrom -- FindLongestOfFrom
---@param spells List ---@param spells Bastion.List
---@param source Unit ---@param source Bastion.Unit
---@return Aura ---@return Bastion.Aura
function AuraTable:FindLongestOfFrom(spells, source) function AuraTable:FindLongestOfFrom(spells, source)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindFrom(cur, source) local aura = self:FindFrom(cur, source)
@ -525,8 +525,8 @@ function AuraTable:FindLongestOfFrom(spells, source)
end end
-- FindShortestOf -- FindShortestOf
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindShortestOf(spells) function AuraTable:FindShortestOf(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:Find(cur) local aura = self:Find(cur)
@ -543,8 +543,8 @@ function AuraTable:FindShortestOf(spells)
end end
-- FindShortestOfMy -- FindShortestOfMy
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindShortestOfMy(spells) function AuraTable:FindShortestOfMy(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindMy(cur) local aura = self:FindMy(cur)
@ -561,8 +561,8 @@ function AuraTable:FindShortestOfMy(spells)
end end
-- FindShortestOfTheirs -- FindShortestOfTheirs
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindShortestOfTheirs(spells) function AuraTable:FindShortestOfTheirs(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindTheirs(cur) local aura = self:FindTheirs(cur)
@ -579,9 +579,9 @@ function AuraTable:FindShortestOfTheirs(spells)
end end
-- FindShortestOfFrom -- FindShortestOfFrom
---@param spells List ---@param spells Bastion.List
---@param source Unit ---@param source Bastion.Unit
---@return Aura ---@return Bastion.Aura
function AuraTable:FindShortestOfFrom(spells, source) function AuraTable:FindShortestOfFrom(spells, source)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindFrom(cur, source) local aura = self:FindFrom(cur, source)
@ -598,8 +598,8 @@ function AuraTable:FindShortestOfFrom(spells, source)
end end
-- FindMostOf -- FindMostOf
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindMostOf(spells) function AuraTable:FindMostOf(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:Find(cur) local aura = self:Find(cur)
@ -616,8 +616,8 @@ function AuraTable:FindMostOf(spells)
end end
-- FindMostOfMy -- FindMostOfMy
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindMostOfMy(spells) function AuraTable:FindMostOfMy(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindMy(cur) local aura = self:FindMy(cur)
@ -634,8 +634,8 @@ function AuraTable:FindMostOfMy(spells)
end end
-- FindMostOfTheirs -- FindMostOfTheirs
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindMostOfTheirs(spells) function AuraTable:FindMostOfTheirs(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindTheirs(cur) local aura = self:FindTheirs(cur)
@ -652,9 +652,9 @@ function AuraTable:FindMostOfTheirs(spells)
end end
-- FindMostOfFrom -- FindMostOfFrom
---@param spells List ---@param spells Bastion.List
---@param source Unit ---@param source Bastion.Unit
---@return Aura ---@return Bastion.Aura
function AuraTable:FindMostOfFrom(spells, source) function AuraTable:FindMostOfFrom(spells, source)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindFrom(cur, source) local aura = self:FindFrom(cur, source)
@ -671,8 +671,8 @@ function AuraTable:FindMostOfFrom(spells, source)
end end
-- FindLeastOf -- FindLeastOf
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindLeastOf(spells) function AuraTable:FindLeastOf(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:Find(cur) local aura = self:Find(cur)
@ -689,8 +689,8 @@ function AuraTable:FindLeastOf(spells)
end end
-- FindLeastOfMy -- FindLeastOfMy
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindLeastOfMy(spells) function AuraTable:FindLeastOfMy(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindMy(cur) local aura = self:FindMy(cur)
@ -707,8 +707,8 @@ function AuraTable:FindLeastOfMy(spells)
end end
-- FindLeastOfTheirs -- FindLeastOfTheirs
---@param spells List ---@param spells Bastion.List
---@return Aura ---@return Bastion.Aura
function AuraTable:FindLeastOfTheirs(spells) function AuraTable:FindLeastOfTheirs(spells)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindTheirs(cur) local aura = self:FindTheirs(cur)
@ -725,9 +725,9 @@ function AuraTable:FindLeastOfTheirs(spells)
end end
-- FindLeastOfFrom -- FindLeastOfFrom
---@param spells List ---@param spells Bastion.List
---@param source Unit ---@param source Bastion.Unit
---@return Aura ---@return Bastion.Aura
function AuraTable:FindLeastOfFrom(spells, source) function AuraTable:FindLeastOfFrom(spells, source)
return spells:reduce(function(acc, cur) return spells:reduce(function(acc, cur)
local aura = self:FindFrom(cur, source) local aura = self:FindFrom(cur, source)
@ -744,7 +744,7 @@ function AuraTable:FindLeastOfFrom(spells, source)
end end
-- Has any stealable aura -- Has any stealable aura
---@param spell? Spell ---@param spell? Bastion.Spell
---@return boolean ---@return boolean
function AuraTable:HasAnyStealableAura(spell) function AuraTable:HasAnyStealableAura(spell)
for _, auras in pairs(self:GetUnitAuras()) do for _, auras in pairs(self:GetUnitAuras()) do
@ -781,7 +781,7 @@ function AuraTable:GetStealableAura()
end end
-- Has any dispelable aura -- Has any dispelable aura
---@param spell Spell ---@param spell Bastion.Spell
---@return boolean ---@return boolean
function AuraTable:HasAnyDispelableAura(spell) function AuraTable:HasAnyDispelableAura(spell)
for _, auras in pairs(self:GetUnitAuras()) do for _, auras in pairs(self:GetUnitAuras()) do

@ -1,9 +1,9 @@
---@class Cache ---@class Bastion.Cache
local Cache = {} local Cache = {}
Cache.__index = Cache Cache.__index = Cache
-- Constructor -- Constructor
---@return Cache ---@return Bastion.Cache
function Cache:New() function Cache:New()
local self = setmetatable({}, Cache) local self = setmetatable({}, Cache)
self.cache = {} self.cache = {}
@ -13,7 +13,6 @@ end
---@param key any ---@param key any
---@param value any ---@param value any
---@param duration number ---@param duration number
---@return nil
function Cache:Set(key, value, duration) function Cache:Set(key, value, duration)
self.cache = self.cache or {} self.cache = self.cache or {}
self.cache[key] = { self.cache[key] = {

@ -2,12 +2,13 @@
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
---@class Cacheable ---@class Bastion.Cacheable
---@field cache? Cache ---@field cache? Bastion.Cache
local Cacheable = { local Cacheable = {
cache = nil, cache = nil,
callback = nil, callback = nil,
value = nil, value = nil,
args = nil,
-- __eq = function(self, other) -- __eq = function(self, other)
-- return self.value.__eq(self.value, other) -- return self.value.__eq(self.value, other)
-- end -- end
@ -24,7 +25,7 @@ function Cacheable:__index(k)
end end
if not self.cache:IsCached("self") then if not self.cache:IsCached("self") then
self.value = self.callback() self.value = self.callback(SafeUnpack(self.args))
self.cache:Set("self", self.value, 0.5) self.cache:Set("self", self.value, 0.5)
end end
@ -38,14 +39,17 @@ end
-- Create -- Create
---@generic V ---@generic V
---@generic P
---@param value V ---@param value V
---@param cb fun(): V ---@param cb fun(...:P): V
---@param ... P
---@return V ---@return V
function Cacheable:New(value, cb) function Cacheable:New(value, cb, ...)
local self = setmetatable({}, Cacheable) local self = setmetatable({}, Cacheable)
self.cache = Bastion.Cache:New() self.cache = Bastion.Cache:New()
self.value = value self.value = value
self.args = SafePack(...)
self.callback = cb self.callback = cb
self.cache:Set("self", self.value, 0.5) self.cache:Set("self", self.value, 0.5)
@ -62,7 +66,7 @@ end
-- Update the value -- Update the value
function Cacheable:Update() function Cacheable:Update()
self.value = self.callback() self.value = self.callback(SafeUnpack(self.args))
end end
-- Set a new value -- Set a new value
@ -72,9 +76,12 @@ function Cacheable:Set(value)
end end
-- Set a new callback -- Set a new callback
---@param cb fun():any ---@generic P
function Cacheable:SetCallback(cb) ---@param cb fun(...: P):any
---@param ... P
function Cacheable:SetCallback(cb, ...)
self.callback = cb self.callback = cb
self.args = SafePack(...)
end end
return Cacheable return Cacheable

@ -2,7 +2,8 @@
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
-- Create a new Class class -- Create a new Class class
---@class Class ---@class Bastion.Class
---@field class Class.Class
local Class = {} local Class = {}
function Class:__index(k) function Class:__index(k)
@ -19,10 +20,7 @@ function Class:__index(k)
return response return response
end end
---@class Class ---@class Class.Class
---@field class Class.class
---@class Class.class
---@field locale string ---@field locale string
---@field name string ---@field name string
---@field id number ---@field id number

@ -1,4 +1,4 @@
---@class ClassMagic ---@class Bastion.ClassMagic
local ClassMagic = {} local ClassMagic = {}
ClassMagic.__index = ClassMagic ClassMagic.__index = ClassMagic

@ -1,10 +1,11 @@
-- Create a wow command handler class -- Create a wow command handler class
---@class Command ---@class Bastion.Command
---@field command string ---@field command string
---@field commands Command.commands[] ---@field commands Bastion.Command.Commands[]
---@field prefix string
local Command = {} local Command = {}
---@class Command.commands ---@class Bastion.Command.Commands
---@field helpmsg string ---@field helpmsg string
---@field cb fun(args: table) ---@field cb fun(args: table)

@ -1,7 +1,7 @@
---@type Tinkr, Bastion ---@type Tinkr, Bastion
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
---@class Config ---@class Bastion.Config
---@field instantiated boolean ---@field instantiated boolean
---@field config Tinkr.Util.Config.Instance ---@field config Tinkr.Util.Config.Instance
---@field defaults nil | table ---@field defaults nil | table

@ -2,25 +2,18 @@
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
-- Create an EventManager class -- Create an EventManager class
---@class EventManager ---@class Bastion.EventManager
---@field frame Frame ---@field frame Frame
---@field events table<string, { [number]: fun(...) }> ---@field events table<string, { [number]: fun(...) }>
---@field eventHandlers table<string, { [number]: fun(...) }> ---@field eventHandlers table<string, { [number]: fun(...) }>
---@field wowEventHandlers table<string, { [number]: fun(...) }> ---@field wowEventHandlers table<string, { [number]: fun(...) }>
---@field selfCombatEventHandlers table<string, { [number]: fun(...) }> ---@field selfCombatEventHandlers table<string, { [number]: fun(...) }>
---@field CombatEventHandlers table<string, { [number]: fun(...) }> ---@field CombatEventHandlers table<string, { [number]: fun(...) }>
local EventManager = { local EventManager = {}
events = {},
eventHandlers = {},
wowEventHandlers = {},
selfCombatEventHandlers = {},
CombatEventHandlers = {},
frame = nil,
}
EventManager.__index = EventManager EventManager.__index = EventManager
-- Constructor -- Constructor
---@return EventManager ---@return Bastion.EventManager
function EventManager:New() function EventManager:New()
local self = setmetatable({}, EventManager) local self = setmetatable({}, EventManager)
self.events = {} self.events = {}

@ -2,13 +2,13 @@
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
-- Create a new Item class -- Create a new Item class
---@class Item ---@class Bastion.Item
---@field ItemID number ---@field ItemID number
---@field UsableIfFunc boolean | fun(self:Item):boolean ---@field UsableIfFunc boolean | fun(self:Bastion.Item):boolean
---@field PreUseFunc boolean | fun(self:Item) ---@field PreUseFunc boolean | fun(self:Bastion.Item)
---@field target boolean | Unit ---@field target boolean | Bastion.Unit
---@field conditions table<string, { func: fun(self:Item):boolean }> ---@field conditions table<string, { func: fun(self:Bastion.Item):boolean }>
---@field OnUseFunc boolean | fun(self:Item) ---@field OnUseFunc boolean | fun(self:Bastion.Item)
---@field spellID number | nil ---@field spellID number | nil
local Item = { local Item = {
UsableIfFunc = false, UsableIfFunc = false,
@ -47,7 +47,7 @@ function Item:__index(k)
end end
-- Equals -- Equals
---@param other Item ---@param other Bastion.Item
---@return boolean ---@return boolean
function Item:__eq(other) function Item:__eq(other)
return self:GetID() == other:GetID() return self:GetID() == other:GetID()
@ -126,8 +126,8 @@ function Item:GetCooldownRemaining()
end end
-- Use the Item -- Use the Item
---@param unit Unit ---@param unit Bastion.Unit
---@param condition? string | fun(self:Item):boolean ---@param condition? string | fun(self:Bastion.Item):boolean
---@return boolean ---@return boolean
function Item:Use(unit, condition) function Item:Use(unit, condition)
if condition then if condition then
@ -219,24 +219,24 @@ function Item:Usable()
end end
-- Set a script to check if the Item is Usable -- Set a script to check if the Item is Usable
---@param func fun(self:Item):boolean ---@param func fun(self:Bastion.Item):boolean
---@return Item ---@return Bastion.Item
function Item:UsableIf(func) function Item:UsableIf(func)
self.UsableIfFunc = func self.UsableIfFunc = func
return self return self
end end
-- Set a script to run before the Item has been Use -- Set a script to run before the Item has been Use
---@param func fun(self:Item) ---@param func fun(self:Bastion.Item)
---@return Item ---@return Bastion.Item
function Item:PreUse(func) function Item:PreUse(func)
self.PreUseFunc = func self.PreUseFunc = func
return self return self
end end
-- Set a script to run after the Item has been Use -- Set a script to run after the Item has been Use
---@param func fun(self:Item) ---@param func fun(self:Bastion.Item)
---@return Item ---@return Bastion.Item
function Item:OnUse(func) function Item:OnUse(func)
self.OnUseFunc = func self.OnUseFunc = func
return self return self
@ -269,7 +269,7 @@ function Item:Click(x, y, z)
end end
-- Check if the Item is Usable and Use it -- Check if the Item is Usable and Use it
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Item:Call(unit) function Item:Call(unit)
if self:Usable() then if self:Usable() then
@ -280,7 +280,7 @@ function Item:Call(unit)
end end
-- Check if the Item is in range of the unit -- Check if the Item is in range of the unit
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Item:IsInRange(unit) function Item:IsInRange(unit)
local name, rank, icon, UseTime, Itemmin, Itemmax, ItemID = GetItemInfo(self:GetID()) local name, rank, icon, UseTime, Itemmin, Itemmax, ItemID = GetItemInfo(self:GetID())
@ -343,8 +343,8 @@ end
-- Create a condition for the Item -- Create a condition for the Item
---@param name string ---@param name string
---@param func fun(self:Item) ---@param func fun(self:Bastion.Item)
---@return Item ---@return Bastion.Item
function Item:Condition(name, func) function Item:Condition(name, func)
self.conditions[name] = { self.conditions[name] = {
func = func, func = func,
@ -388,15 +388,15 @@ function Item:HasCondition(name)
end end
-- Set the Items target -- Set the Items target
---@param unit Unit ---@param unit Bastion.Unit
---@return Item ---@return Bastion.Item
function Item:SetTarget(unit) function Item:SetTarget(unit)
self.target = unit self.target = unit
return self return self
end end
-- Get the Items target -- Get the Items target
---@return Unit | boolean ---@return Bastion.Unit | boolean
function Item:GetTarget() function Item:GetTarget()
return self.target return self.target
end end
@ -431,14 +431,14 @@ function Item:IsDiseaseDispel()
return ({})[self:GetID()] return ({})[self:GetID()]
end end
---@param item Item ---@param item Bastion.Item
---@return boolean ---@return boolean
function Item:IsItem(item) function Item:IsItem(item)
return self:GetID() == item:GetID() return self:GetID() == item:GetID()
end end
-- Get the Items spell -- Get the Items spell
---@return Spell | nil ---@return Bastion.Spell | nil
function Item:GetSpell() function Item:GetSpell()
if self.spellID then if self.spellID then
return Bastion.Globals.SpellBook:GetSpell(self.spellID) return Bastion.Globals.SpellBook:GetSpell(self.spellID)

@ -4,13 +4,13 @@ local Tinkr, Bastion = ...
---@alias itemId integer ---@alias itemId integer
-- Create a new ItemBook class -- Create a new ItemBook class
---@class ItemBook ---@class Bastion.ItemBook
---@field items table<itemId, Item> ---@field items table<itemId, Bastion.Item>
local ItemBook = {} local ItemBook = {}
ItemBook.__index = ItemBook ItemBook.__index = ItemBook
-- Constructor -- Constructor
---@return ItemBook ---@return Bastion.ItemBook
function ItemBook:New() function ItemBook:New()
local self = setmetatable({}, ItemBook) local self = setmetatable({}, ItemBook)
self.items = {} self.items = {}
@ -19,7 +19,7 @@ end
-- Get a spell from the ItemBook -- Get a spell from the ItemBook
---@param id number ---@param id number
---@return Item ---@return Bastion.Item
function ItemBook:GetItem(id) function ItemBook:GetItem(id)
if self.items[id] == nil then if self.items[id] == nil then
self.items[id] = Bastion.Item:New(id) self.items[id] = Bastion.Item:New(id)

@ -1,7 +1,7 @@
---@type Tinkr, Bastion ---@type Tinkr, Bastion
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
---@class Library ---@class Bastion.Library
---@field name string | nil ---@field name string | nil
---@field dependencies table ---@field dependencies table
---@field exports table ---@field exports table
@ -19,12 +19,12 @@ local Library = {
Library.__index = Library Library.__index = Library
---@class NewLibrary ---@class Bastion.Library.New
---@field name string ---@field name string
---@field exports? { default: fun(self: Library):any } ---@field exports? { default: fun(self: Bastion.Library):any }
---@param library NewLibrary ---@param library Bastion.Library.New
---@return Library ---@return Bastion.Library
function Library:New(library) function Library:New(library)
local self = { local self = {
name = library.name or nil, name = library.name or nil,

@ -1,20 +1,22 @@
---@class List ---@class Bastion.List<I>: { _list: I[] }
---@operator add(any): List ---@operator add(any): Bastion.List
---@operator sub(any): List ---@operator sub(any): Bastion.List
local List = { local List = {
-- Add overload -- Add overload
---@param self List ---@param self Bastion.List
---@param value any ---@generic I
---@return List ---@param value I
---@return Bastion.List<I>
__add = function(self, value) __add = function(self, value)
self:push(value) self:push(value)
return self return self
end, end,
-- Subtract overload -- Subtract overload
---@param self List ---@param self Bastion.List
---@param value any ---@generic I
---@return List ---@param value I
---@return Bastion.List<I>
__sub = function(self, value) __sub = function(self, value)
self:remove(value) self:remove(value)
return self return self
@ -22,8 +24,9 @@ local List = {
} }
List.__index = List List.__index = List
---@param from table | nil ---@generic I : table
---@return List ---@param from? I[]
---@return Bastion.List<I> | Bastion.List
function List:New(from) function List:New(from)
local self = setmetatable({}, List) local self = setmetatable({}, List)
self._list = from or {} self._list = from or {}
@ -31,7 +34,6 @@ function List:New(from)
end end
---@param value any ---@param value any
---@return nil
function List:push(value) function List:push(value)
table.insert(self._list, value) table.insert(self._list, value)
end end
@ -92,8 +94,8 @@ function List:each(callback)
end end
---@generic I : any ---@generic I : any
---@param callback fun(value: I): boolean ---@param callback fun(value: I): I
---@return List ---@return Bastion.List<I> | Bastion.List
function List:map(callback) function List:map(callback)
local newList = List:New() local newList = List:New()
for _, v in ipairs(self._list) do for _, v in ipairs(self._list) do
@ -104,7 +106,7 @@ end
---@generic I : any ---@generic I : any
---@param callback fun(value: I): boolean ---@param callback fun(value: I): boolean
---@return List ---@return Bastion.List<I> | Bastion.List
function List:filter(callback) function List:filter(callback)
local newList = List:New() local newList = List:New()
for _, v in ipairs(self._list) do for _, v in ipairs(self._list) do
@ -134,7 +136,7 @@ end
---@generic I ---@generic I
---@param callback fun(value: I): boolean ---@param callback fun(value: I): boolean
---@return boolean | nil ---@return I
function List:find(callback) function List:find(callback)
for _, v in ipairs(self._list) do for _, v in ipairs(self._list) do
if callback(v) then if callback(v) then
@ -144,7 +146,8 @@ function List:find(callback)
return nil return nil
end end
---@param callback fun(value: any): boolean ---@generic I
---@param callback fun(value: I): boolean
---@return number | nil ---@return number | nil
function List:findIndex(callback) function List:findIndex(callback)
for i, v in ipairs(self._list) do for i, v in ipairs(self._list) do
@ -155,13 +158,13 @@ function List:findIndex(callback)
return nil return nil
end end
---@param callback fun(...): boolean ---@generic I : any
---@param callback fun(a: I, b: I): boolean
---@return nil ---@return nil
function List:sort(callback) function List:sort(callback)
table.sort(self._list, callback) table.sort(self._list, callback)
end end
---@return List
function List:reverse() function List:reverse()
local newList = List:New() local newList = List:New()
for i = #self._list, 1, -1 do for i = #self._list, 1, -1 do
@ -170,7 +173,6 @@ function List:reverse()
return newList return newList
end end
---@return List
function List:clone() function List:clone()
local newList = List:New() local newList = List:New()
for _, v in ipairs(self._list) do for _, v in ipairs(self._list) do
@ -179,8 +181,7 @@ function List:clone()
return newList return newList
end end
---@param list List ---@param list Bastion.List
---@return List
function List:concat(list) function List:concat(list)
local newList = List:New() local newList = List:New()
for _, v in ipairs(self._list) do for _, v in ipairs(self._list) do

@ -1,6 +1,6 @@
-- Create a module class for a bastion module -- Create a module class for a bastion module
---@class Module ---@class Bastion.Module
---@field name string ---@field name string
---@field enabled boolean ---@field enabled boolean
---@field synced function[] ---@field synced function[]
@ -15,7 +15,7 @@ end
-- Constructor -- Constructor
---@param name string ---@param name string
---@return Module ---@return Bastion.Module
function Module:New(name) function Module:New(name)
local module = {} local module = {}
setmetatable(module, Module) setmetatable(module, Module)
@ -28,13 +28,11 @@ function Module:New(name)
end end
-- Enable the module -- Enable the module
---@return nil
function Module:Enable() function Module:Enable()
self.enabled = true self.enabled = true
end end
-- Disable the module -- Disable the module
---@return nil
function Module:Disable() function Module:Disable()
self.enabled = false self.enabled = false
end end
@ -51,25 +49,22 @@ end
-- Add a function to the sync list -- Add a function to the sync list
---@param func function ---@param func function
---@return nil
function Module:Sync(func) function Module:Sync(func)
table.insert(self.synced, func) table.insert(self.synced, func)
end end
-- Remove a function from the sync list -- Remove a function from the sync list
---@param func function ---@param func function
---@return nil
function Module:Unsync(func) function Module:Unsync(func)
for i = 1, #self.synced do for i = 1, #self.synced do
if self.synced[i] == func then if self.synced[i] == func then
table.remove(self.synced, i) table.remove(self.synced, i)
return break
end end
end end
end end
-- Sync -- Sync
---@return nil
function Module:Tick() function Module:Tick()
if self.enabled then if self.enabled then
for i = 1, #self.synced do for i = 1, #self.synced do

@ -1,20 +1,31 @@
---@type Tinkr, Bastion ---@type Tinkr, Bastion
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
---@class MythicPlusUtils ---@class Bastion.MythicPlusUtils.KickEntry
---@field isKick boolean
---@field isStun boolean
---@field isDisorient boolean
---@class Bastion.MythicPlusUtils
---@field random number
---@field aoeBosses table<number, boolean>
---@field tankBusters table<number, boolean>
---@field debuffLogging boolean
---@field castLogging boolean
---@field loggedCasts table<number, boolean>
---@field loggedDebuffs table<number, boolean>
---@field kickList table<spellId, table<number, boolean[]>>
local MythicPlusUtils = { local MythicPlusUtils = {
debuffLogging = false, debuffLogging = false,
castLogging = false, castLogging = false,
random = "",
loggedCasts = {}, loggedCasts = {},
loggedDebuffs = {}, loggedDebuffs = {},
kickList = {}, kickList = {},
aoeBosses = {},
} }
MythicPlusUtils.__index = MythicPlusUtils MythicPlusUtils.__index = MythicPlusUtils
---@return MythicPlusUtils ---@return Bastion.MythicPlusUtils
function MythicPlusUtils:New() function MythicPlusUtils:New()
local self = setmetatable({}, MythicPlusUtils) local self = setmetatable({}, MythicPlusUtils)
@ -227,7 +238,7 @@ function MythicPlusUtils:New()
false, false,
false, false,
}, },
}, -- Thundering Squall }, -- Thundering Squall
[257899] = { -- Painful Motivation [257899] = { -- Painful Motivation
[0] = { [0] = {
true, true,
@ -1259,7 +1270,7 @@ function MythicPlusUtils:ToggleCastLogging()
self.castLogging = not self.castLogging self.castLogging = not self.castLogging
end end
---@param unit Unit ---@param unit Bastion.Unit
---@param percent? number ---@param percent? number
---@return boolean ---@return boolean
function MythicPlusUtils:CastingCriticalKick(unit, percent) function MythicPlusUtils:CastingCriticalKick(unit, percent)
@ -1288,7 +1299,7 @@ function MythicPlusUtils:CastingCriticalKick(unit, percent)
return false return false
end end
---@param unit Unit ---@param unit Bastion.Unit
---@param percent number ---@param percent number
---@return boolean ---@return boolean
function MythicPlusUtils:CastingCriticalStun(unit, percent) function MythicPlusUtils:CastingCriticalStun(unit, percent)
@ -1317,7 +1328,7 @@ function MythicPlusUtils:CastingCriticalStun(unit, percent)
return false return false
end end
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function MythicPlusUtils:IsAOEBoss(unit) function MythicPlusUtils:IsAOEBoss(unit)
return self.aoeBosses[unit:GetID()] return self.aoeBosses[unit:GetID()]

@ -0,0 +1,69 @@
---@type Tinkr, Bastion
local Tinkr, Bastion = ...
-- Create a notification class for the notifications list (takes icon and text)
---@class Bastion.Notification
---@field icon Texture
---@field text FontString
---@field frame Frame
---@field addedAt number
---@field duration number
---@field list Bastion.NotificationList
local Notification = {
}
Notification.__index = Notification
-- Constructor
---@param list Bastion.NotificationList
---@param icon string
---@param text string
---@param duration number
---@return Bastion.Notification
function Notification:New(list, icon, text, duration)
local self = setmetatable({}, Notification)
if not duration then duration = 2 end
-- Create a frame for the notification
self.frame = CreateFrame("Frame", nil, list.frame)
self.frame:SetSize(5, 5)
self.frame:SetPoint("CENTER", list.frame, "CENTER", 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", "NumberFontNormal")
self.text:SetPoint("LEFT", self.frame, "LEFT", 32 + 16, 0)
self.text:SetText(text)
self.text:SetFont("Fonts\\OpenSans-Bold.ttf", 18, "")
-- set the frame size to the size of the text + icon
self.frame:SetSize(self.text:GetStringWidth() + 32 + 16, 32)
self.addedAt = GetTime()
self.duration = duration
self.list = list
return self
end
-- Remove notification
---@return nil
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
return Notification

@ -0,0 +1,92 @@
---@type Tinkr, Bastion
local Tinkr, Bastion = ...
-- Create a NotificationList class
---@class Bastion.NotificationList
---@field frame Frame
local NotificationList = {
notifications = {}
}
NotificationList.__index = NotificationList
-- Constructor
---@return Bastion.NotificationList
function NotificationList:New()
local self = setmetatable({}, NotificationList)
-- Create a frame for the notifications
self.frame = CreateFrame("Frame", "BastionNotificationList", UIParent)
self.frame:SetSize(600, 60)
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 > notification.duration then
notification:Remove()
table.remove(self.notifications, i)
end
end
end)
return self
end
-- Add a notification to the list
---@param icon string
---@param text string
---@param duration number
---@return nil
function NotificationList:AddNotification(icon, text, duration)
-- Create a new notification
local notification = Bastion.Notification:New(self, icon, text, duration)
-- 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
---@return nil
function NotificationList:Update()
-- Loop through the notifications
for i, notification in ipairs(self.notifications) do
-- Set the position of the notification
notification.frame:SetPoint("CENTER", self.frame, "CENTER", 0, -42 * (i - 1))
end
end
-- Remove a notification from the list
---@param notification Bastion.Notification
---@return nil
function NotificationList: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
---@return nil
function NotificationList: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 NotificationList

@ -1,147 +0,0 @@
-- Create a NotificationsList class
---@class NotificationsList
local NotificationsList = {
notifications = {}
}
NotificationsList.__index = NotificationsList
-- Constructor
---@return NotificationsList
function NotificationsList:New()
local self = setmetatable({}, NotificationsList)
-- Create a frame for the notifications
self.frame = CreateFrame("Frame", "BastionNotificationsList", UIParent)
self.frame:SetSize(600, 60)
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 > notification.duration 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)
---@class Notification
local Notification = {
}
Notification.__index = Notification
-- Constructor
---@param list NotificationsList
---@param icon string
---@param text string
---@param duration number
---@return Notification
function Notification:New(list, icon, text, duration)
local self = setmetatable({}, Notification)
if not duration then duration = 2 end
-- Create a frame for the notification
self.frame = CreateFrame("Frame", nil, list.frame)
self.frame:SetSize(5, 5)
self.frame:SetPoint("CENTER", list.frame, "CENTER", 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", "NumberFontNormal")
self.text:SetPoint("LEFT", self.frame, "LEFT", 32 + 16, 0)
self.text:SetText(text)
self.text:SetFont("Fonts\\OpenSans-Bold.ttf", 18)
-- set the frame size to the size of the text + icon
self.frame:SetSize(self.text:GetStringWidth() + 32 + 16, 32)
self.addedAt = GetTime()
self.duration = duration
self.list = list
return self
end
-- Remove notification
---@return nil
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
---@param icon string
---@param text string
---@param duration number
---@return nil
function NotificationsList:AddNotification(icon, text, duration)
-- Create a new notification
local notification = Notification:New(self, icon, text, duration)
-- 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
---@return nil
function NotificationsList:Update()
-- Loop through the notifications
for i, notification in ipairs(self.notifications) do
-- Set the position of the notification
notification.frame:SetPoint("CENTER", self.frame, "CENTER", 0, -42 * (i - 1))
end
end
-- Remove a notification from the list
---@param notification Notification
---@return nil
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
---@return nil
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

@ -1,14 +1,16 @@
---@type Tinkr, Bastion ---@type Tinkr, Bastion
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
---@class ObjectManager ---@class Bastion.ObjectManager
---@field _lists table<string, { list: List, cb: fun(object: TinkrObjectReference): false | Unit }> ---@field _lists table<string, { list: Bastion.List, cb: fun(object: TinkrObjectReference): false | Bastion.Unit }>
---@field enemies List ---@field afflicted Bastion.List
---@field friends List ---@field enemies Bastion.List
---@field activeEnemies List ---@field critters Bastion.List
---@field explosives List ---@field friends Bastion.List
---@field incorporeal List ---@field activeEnemies Bastion.List
---@field others List ---@field explosives Bastion.List
---@field incorporeal Bastion.List
---@field others Bastion.List
local ObjectManager = {} local ObjectManager = {}
ObjectManager.__index = ObjectManager ObjectManager.__index = ObjectManager
@ -18,10 +20,12 @@ function ObjectManager:New()
self._lists = {} self._lists = {}
self.enemies = Bastion.List:New() self.enemies = Bastion.List:New()
self.critters = Bastion.List:New()
self.friends = Bastion.List:New() self.friends = Bastion.List:New()
self.activeEnemies = Bastion.List:New() self.activeEnemies = Bastion.List:New()
self.explosives = Bastion.List:New() self.explosives = Bastion.List:New()
self.incorporeal = Bastion.List:New() self.incorporeal = Bastion.List:New()
self.afflicted = Bastion.List:New()
self.others = Bastion.List:New() self.others = Bastion.List:New()
return self return self
@ -29,8 +33,8 @@ end
-- Register a custom list with a callback -- Register a custom list with a callback
---@param name string ---@param name string
---@param cb fun(object: TinkrObjectReference): false | Unit ---@param cb fun(object: TinkrObjectReference): false | Bastion.Unit
---@return List | false ---@return Bastion.List | false
function ObjectManager:RegisterList(name, cb) function ObjectManager:RegisterList(name, cb)
if self._lists[name] then if self._lists[name] then
return false return false
@ -66,7 +70,7 @@ end
-- Get a list -- Get a list
---@param name string ---@param name string
---@return List ---@return Bastion.List
function ObjectManager:GetList(name) function ObjectManager:GetList(name)
return self._lists[name].list return self._lists[name].list
end end
@ -74,7 +78,9 @@ end
-- Refresh all lists -- Refresh all lists
---@return nil ---@return nil
function ObjectManager:Refresh() function ObjectManager:Refresh()
self.afflicted:clear()
self.enemies:clear() self.enemies:clear()
self.critters:clear()
self.friends:clear() self.friends:clear()
self.activeEnemies:clear() self.activeEnemies:clear()
self.explosives:clear() self.explosives:clear()
@ -88,25 +94,32 @@ function ObjectManager:Refresh()
self:EnumLists(object) self:EnumLists(object)
if ({ [5] = true, [6] = true, [7] = true })[ObjectType(object)] then if ({ [5] = true, [6] = true, [7] = true })[ObjectType(object)] then
local unit = Bastion.UnitManager:GetObject(ObjectGUID(object)) local objectGUID = ObjectGUID(object)
if not unit then if objectGUID then
unit = Bastion.Unit:New(object) local unit = Bastion.UnitManager:GetObject(objectGUID)
Bastion.UnitManager:SetObject(unit) if not unit then
end unit = Bastion.Unit:New(object)
Bastion.UnitManager:SetObject(unit)
end
if unit:GetID() == 204560 then if ObjectType(object) == 5 and ObjectCreatureType(object) == 8 then
self.incorporeal:push(unit) self.critters:push(unit)
elseif unit:GetID() == 120651 then elseif unit:GetID() == 204560 then
self.explosives:push(unit) self.incorporeal:push(unit)
elseif unit:IsPlayer() and (unit:IsInParty() or unit == Bastion.UnitManager["player"]) then elseif unit:GetID() == 204773 then
self.friends:push(unit) self.afflicted:push(unit)
elseif unit:IsEnemy() then elseif unit:GetID() == 120651 then
self.enemies:push(unit) self.explosives:push(unit)
if unit:InCombatOdds() > 80 then elseif unit:IsPlayer() and (unit:IsInParty() or unit == Bastion.UnitManager["player"]) then
self.activeEnemies:push(unit) self.friends:push(unit)
elseif unit:IsEnemy() then
self.enemies:push(unit)
if unit:InCombatOdds() > 80 or unit:IsAffectingCombat() then
self.activeEnemies:push(unit)
end
else
self.others:push(unit)
end end
else
self.others:push(unit)
end end
end end
end end

@ -2,9 +2,9 @@
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
-- Define a Refreshable class -- Define a Refreshable class
---@class Refreshable ---@class Bastion.Refreshable
---@field cache Bastion.Cache
local Refreshable = { local Refreshable = {
cache = nil,
callback = nil, callback = nil,
value = nil, value = nil,
__eq = function(self, other) __eq = function(self, other)

@ -1,17 +1,17 @@
-- Create a sequencer class that takes a table of actions and executes them in order -- Create a sequencer class that takes a table of actions and executes them in order
---@class Sequencer ---@class Bastion.Sequencer
---@field resetCondition? fun(): boolean ---@field resetCondition? fun(): boolean
---@field abortCondition? fun(): boolean ---@field abortCondition? fun(): boolean
---@field actions SequencerAction[] ---@field actions SequencerAction[]
local Sequencer = {} local Sequencer = {}
Sequencer.__index = Sequencer Sequencer.__index = Sequencer
---@alias SequencerAction fun(sequence: Sequencer):boolean ---@alias SequencerAction fun(sequence: Bastion.Sequencer):boolean
-- Constructor -- Constructor
---@param actions table<number, SequencerAction> ---@param actions table<number, SequencerAction>
---@param resetCondition? fun(): boolean ---@param resetCondition? fun(): boolean
---@return Sequencer ---@return Bastion.Sequencer
function Sequencer:New(actions, resetCondition) function Sequencer:New(actions, resetCondition)
local self = setmetatable({}, Sequencer) local self = setmetatable({}, Sequencer)

@ -1,66 +1,54 @@
---@type Tinkr, Bastion ---@type Tinkr, Bastion
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
---@class Spell.Traits.Cast ---@class Bastion.Spell.Traits.Cast
---@field moving boolean ---@field moving boolean
---@field dead boolean ---@field dead boolean
---@field global boolean ---@field global boolean
---@field casting boolean ---@field casting boolean
---@field channeling boolean ---@field channeling boolean
---@field override boolean ---@field override boolean
---@field talent boolean | spellId
---@class Spell.Traits.Target ---@class Bastion.Spell.Traits.Target
---@field exists boolean ---@field exists boolean
---@field player boolean ---@field player boolean
---@class Spell.Traits ---@class Bastion.Spell.Traits
---@field cast Spell.Traits.Cast ---@field cast Bastion.Spell.Traits.Cast
---@field target Spell.Traits.Target ---@field target Bastion.Spell.Traits.Target
---@class Spell.Traits.Cast.Params : Spell.Traits.Cast, { [string]?: boolean } ---@class Bastion.Spell.Traits.Cast.Params : Bastion.Spell.Traits.Cast, { [string]?: boolean }
---@class Spell.Traits.Target.Params : Spell.Traits.Target, { [string]?: boolean } ---@class Spell.Traits.Target.Params : Bastion.Spell.Traits.Target, { [string]?: boolean }
---@class Spell.Traits.Params ---@class Bastion.Spell.Traits.Params
---@field cast? Spell.Traits.Cast.Params ---@field cast? Bastion.Spell.Traits.Cast.Params
---@field target? Spell.Traits.Target.Params ---@field target? Spell.Traits.Target.Params
---@class Spell.Aura ---@class Bastion.Spell.Aura
---@field spell Spell ---@field spell Bastion.Spell
---@field source? Unit ---@field source? Bastion.Unit
---@field target? Unit ---@field target? Bastion.Unit
---@field lastApplied number ---@field lastApplied number
-- Create a new Spell class -- Create a new Spell class
---@class Spell ---@class Bastion.Spell
---@field auras table<spellId, Spell.Aura> ---@field auras table<spellId, Bastion.Spell.Aura>
---@field CastableIfFunc false | fun(self:Spell):boolean ---@field CastableIfFunc false | fun(self:Bastion.Spell):boolean
---@field damage number ---@field damage number
---@field damageFormula false | fun(self:Spell):number ---@field damageFormula false | fun(self:Bastion.Spell):number
---@field lastCastAt number | false ---@field lastCastAt number | false
---@field lastCastAttempt number | false ---@field lastCastAttempt number | false
---@field OnCastFunc fun(self:Spell) | false ---@field OnCastFunc fun(self:Bastion.Spell) | false
---@field overrides { [spellId]: fun(self: Spell): Spell } ---@field overrides { [spellId]: fun(self: Bastion.Spell): Bastion.Spell }
---@field PostCastFunc fun(self:Spell) | false ---@field PostCastFunc fun(self:Bastion.Spell) | false
---@field PreCastFunc fun(self:Spell) | false ---@field PreCastFunc fun(self:Bastion.Spell) | false
---@field release_at false ---@field release_at false
---@field spellID number ---@field spellID number
---@field target Unit | false ---@field target Bastion.Unit | false
---@field traits Spell.Traits ---@field traits Bastion.Spell.Traits
---@field wasLooking boolean ---@field wasLooking boolean
local Spell = { local Spell = {}
auras = {},
CastableIfFunc = false,
conditions = {},
damage = 0,
damageFormula = false,
lastCastAt = false,
lastCastAttempt = false,
OnCastFunc = false,
overrides = {},
PostCastFunc = false,
PreCastFunc = false,
release_at = false,
}
local usableExcludes = { local usableExcludes = {
[18562] = true, [18562] = true,
@ -81,7 +69,7 @@ function Spell:__index(k)
end end
-- Equals -- Equals
---@param other Spell ---@param other Bastion.Spell
function Spell:__eq(other) function Spell:__eq(other)
return self:GetID() == other:GetID() return self:GetID() == other:GetID()
end end
@ -94,9 +82,17 @@ end
-- Constructor -- Constructor
---@param id number ---@param id number
function Spell:New(id) function Spell:New(id)
---@class Spell ---@class Bastion.Spell
local self = setmetatable({}, Spell) local self = setmetatable({}, Spell)
self.auras = {} self.auras = {}
self.CastableIfFunc = false
self.damage = 0
self.damageFormula = false
self.lastCastAt = false
self.lastCastAttempt = false
self.OnCastFunc = false
self.PostCastFunc = false
self.release_at = false
self.conditions = {} self.conditions = {}
self.overrides = {} self.overrides = {}
self.spellID = id self.spellID = id
@ -108,6 +104,7 @@ function Spell:New(id)
casting = false, casting = false,
channeling = false, channeling = false,
override = false, override = false,
talent = false,
}, },
target = { target = {
exists = true, exists = true,
@ -137,7 +134,7 @@ function Spell:GetID(ignoreOverride)
end end
-- Add post cast func -- Add post cast func
---@param func fun(self:Spell) ---@param func fun(self:Bastion.Spell)
function Spell:PostCast(func) function Spell:PostCast(func)
self.PostCastFunc = func self.PostCastFunc = func
return self return self
@ -202,21 +199,21 @@ function Spell:OnCooldown()
end end
-- Clear castable function -- Clear castable function
---@return Spell ---@return Bastion.Spell
function Spell:ClearCastableFunction() function Spell:ClearCastableFunction()
self.CastableIfFunc = false self.CastableIfFunc = false
return self return self
end end
---@param spell Spell ---@param spell Bastion.Spell
---@param func fun(self: Spell): boolean ---@param func fun(self: Bastion.Spell): boolean
function Spell:AddOverrideSpell(spell, func) function Spell:AddOverrideSpell(spell, func)
self.overrides[spell:GetID()] = func self.overrides[spell:GetID()] = func
end end
-- Cast the spell -- Cast the spell
---@param unit Unit ---@param unit Bastion.Unit
---@param condition? string | fun(self:Spell):boolean ---@param condition? string | fun(self:Bastion.Spell):boolean
---@return boolean ---@return boolean
function Spell:Cast(unit, condition) function Spell:Cast(unit, condition)
if condition then if condition then
@ -237,12 +234,14 @@ function Spell:Cast(unit, condition)
end end
-- Check if the mouse was looking -- Check if the mouse was looking
---@type boolean
self.wasLooking = IsMouselooking() self.wasLooking = IsMouselooking()
-- if unit:GetOMToken() contains 'nameplate' then we need to use Object wrapper to cast -- if unit:GetOMToken() contains 'nameplate' then we need to use Object wrapper to cast
local u = unit and unit:GetOMToken() or self.traits.target.player and "none" or "none" local u = unit and unit:GetOMToken() or self.traits.target.player and "none" or "none"
if type(u) == "string" and string.find(u, "nameplate") then if type(u) == "string" and string.find(u, "nameplate") then
---@diagnostic disable-next-line: cast-local-type
u = Object(u) u = Object(u)
end end
@ -264,7 +263,7 @@ function Spell:Cast(unit, condition)
end end
-- ForceCast the spell -- ForceCast the spell
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Spell:ForceCast(unit) function Spell:ForceCast(unit)
-- Check if the mouse was looking -- Check if the mouse was looking
@ -273,6 +272,7 @@ function Spell:ForceCast(unit)
-- if unit:GetOMToken() contains 'nameplate' then we need to use Object wrapper to cast -- if unit:GetOMToken() contains 'nameplate' then we need to use Object wrapper to cast
local u = unit and unit:GetOMToken() or self.traits.target.player and "none" or "none" local u = unit and unit:GetOMToken() or self.traits.target.player and "none" or "none"
if type(u) == "string" and string.find(u, "nameplate") then if type(u) == "string" and string.find(u, "nameplate") then
---@diagnostic disable-next-line: cast-local-type
u = Object(u) u = Object(u)
end end
@ -338,7 +338,7 @@ function Spell:IsKnownAndUsable(override)
return self:IsKnown(override) and not self:IsOnCooldown() and self:IsUsable(override ~= nil and false or true) return self:IsKnown(override) and not self:IsOnCooldown() and self:IsUsable(override ~= nil and false or true)
end end
---@param traits Spell.Traits.Params ---@param traits Bastion.Spell.Traits.Params
function Spell:SetTraits(traits) function Spell:SetTraits(traits)
for _, trait in pairs({ "cast", "target" }) do for _, trait in pairs({ "cast", "target" }) do
if type(traits[trait]) == "table" then if type(traits[trait]) == "table" then
@ -353,7 +353,7 @@ function Spell:SetTraits(traits)
end end
function Spell:EvaluateTraits() function Spell:EvaluateTraits()
local player = Bastion.UnitManager["player"] local player = Bastion.UnitManager:Get("player")
if not self.traits.cast.global and player:GetGCD() > 0 then if not self.traits.cast.global and player:GetGCD() > 0 then
return false return false
@ -379,6 +379,10 @@ function Spell:EvaluateTraits()
return false return false
end end
if self.traits.cast.talent and not IsPlayerSpell(type(self.traits.cast.talent) == "number" and tonumber(self.traits.cast.talent) or self:GetID()) then
return false
end
return true return true
end end
@ -388,28 +392,29 @@ function Spell:Castable()
return false return false
end end
if self:GetCastableFunction() then if self:GetCastableFunction() then
return self:GetCastableFunction()(self) and self:IsKnownAndUsable(self.traits.cast.override or nil) return self:GetCastableFunction()(self) and
self:IsKnownAndUsable(type(self.traits.cast.override) ~= nil and self.traits.cast.override or nil)
end end
return self:IsKnownAndUsable(self.traits.cast.override or nil) return self:IsKnownAndUsable(type(self.traits.cast.override) ~= nil and self.traits.cast.override or nil)
end end
-- Set a script to check if the spell is castable -- Set a script to check if the spell is castable
---@param func fun(spell:Spell):boolean ---@param func fun(spell:Bastion.Spell):boolean
function Spell:CastableIf(func) function Spell:CastableIf(func)
self.CastableIfFunc = func self.CastableIfFunc = func
return self return self
end end
-- Set a script to run before the spell has been cast -- Set a script to run before the spell has been cast
---@param func fun(spell:Spell) ---@param func fun(spell:Bastion.Spell)
function Spell:PreCast(func) function Spell:PreCast(func)
self.PreCastFunc = func self.PreCastFunc = func
return self return self
end end
-- Set a script to run after the spell has been cast -- Set a script to run after the spell has been cast
---@param func fun(spell:Spell) ---@param func fun(spell:Bastion.Spell)
function Spell:OnCast(func) function Spell:OnCast(func)
self.OnCastFunc = func self.OnCastFunc = func
return self return self
@ -422,7 +427,7 @@ function Spell:GetWasLooking()
end end
-- Click the spell -- Click the spell
---@param x number|Vector3 ---@param x number|Bastion.Vector3
---@param y? number ---@param y? number
---@param z? number ---@param z? number
---@return boolean ---@return boolean
@ -445,18 +450,12 @@ function Spell:Click(x, y, z)
end end
-- Check if the spell is castable and cast it -- Check if the spell is castable and cast it
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean
function Spell:Call(unit) function Spell:Call(unit)
if self:Castable() then return self:Cast(unit)
self:Cast(unit)
return true
end
return false
end end
-- Check if the spell is castable and cast it -- Check if the spell is castable and cast it
---@return boolean
function Spell:HasRange() function Spell:HasRange()
return SpellHasRange(self:GetName()) return SpellHasRange(self:GetName())
end end
@ -470,7 +469,7 @@ function Spell:GetRange()
end end
-- Check if the spell is in range of the unit -- Check if the spell is in range of the unit
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Spell:IsInRange(unit) function Spell:IsInRange(unit)
local hasRange = self:HasRange() local hasRange = self:HasRange()
@ -484,7 +483,7 @@ function Spell:IsInRange(unit)
return true return true
end end
return Bastion.UnitManager["player"]:InMelee(unit) return Bastion.UnitManager:Get("player"):InMelee(unit)
end end
-- Get the last cast time -- Get the last cast time
@ -570,8 +569,8 @@ end
-- Create a condition for the spell -- Create a condition for the spell
---@param name string ---@param name string
---@param func fun(self:Spell):boolean ---@param func fun(self:Bastion.Spell):boolean
---@return Spell ---@return Bastion.Spell
function Spell:Condition(name, func) function Spell:Condition(name, func)
self.conditions[name] = { self.conditions[name] = {
func = func, func = func,
@ -581,7 +580,7 @@ end
-- Get a condition for the spell -- Get a condition for the spell
---@param name string ---@param name string
---@return { func: fun(self: Spell): boolean } | nil ---@return { func: fun(self: Bastion.Spell): boolean } | nil
function Spell:GetCondition(name) function Spell:GetCondition(name)
local condition = self.conditions[name] local condition = self.conditions[name]
if condition then if condition then
@ -616,8 +615,8 @@ function Spell:HasCondition(name)
end end
-- Set the spells target -- Set the spells target
---@param unit Unit ---@param unit Bastion.Unit
---@return Spell ---@return Bastion.Spell
function Spell:SetTarget(unit) function Spell:SetTarget(unit)
self.target = unit self.target = unit
return self return self
@ -671,7 +670,7 @@ function Spell:IsDiseaseDispel()
end end
-- IsSpell -- IsSpell
---@param spell Spell ---@param spell Bastion.Spell
---@return boolean ---@return boolean
function Spell:IsSpell(spell) function Spell:IsSpell(spell)
return self:GetID() == spell:GetID() return self:GetID() == spell:GetID()
@ -690,7 +689,7 @@ function Spell:IsFree()
return self:GetCost() == 0 return self:GetCost() == 0
end end
---@param damageFormula fun(self:Spell): number ---@param damageFormula fun(self:Bastion.Spell): number
function Spell:RegisterDamageFormula(damageFormula) function Spell:RegisterDamageFormula(damageFormula)
self.damageFormula = damageFormula self.damageFormula = damageFormula
end end
@ -704,19 +703,19 @@ function Spell:Damage()
end end
end end
---@param target Unit ---@param target Bastion.Unit
---@param source? "any" | Unit ---@param source? "any" | Bastion.Unit
function Spell:GetAura(target, source) function Spell:GetAura(target, source)
if type(source) == "nil" then if type(source) == "nil" then
source = Bastion.UnitManager["player"] source = Bastion.UnitManager:Get("player")
end end
return target:GetAuras():FindFrom(self, source) return target:GetAuras():FindFrom(self, source)
end end
---@param spell Spell ---@param spell Bastion.Spell
---@param source? Unit ---@param source? Bastion.Unit
---@param target? Unit ---@param target? Bastion.Unit
function Spell:TrackAura(spell, source, target) function Spell:TrackAura(spell, source, target)
self.auras[spell:GetID()] = { self.auras[spell:GetID()] = {
spell = spell, spell = spell,
@ -726,9 +725,9 @@ function Spell:TrackAura(spell, source, target)
} }
end end
---@param aura Spell ---@param aura Bastion.Spell
---@param source? Unit ---@param source? Bastion.Unit
---@param target? Unit ---@param target? Bastion.Unit
function Spell:CheckAuraStatus(aura, source, target) function Spell:CheckAuraStatus(aura, source, target)
for id, trackedAura in pairs(self.auras) do for id, trackedAura in pairs(self.auras) do
if aura:GetID() == id then if aura:GetID() == id then
@ -738,9 +737,9 @@ function Spell:CheckAuraStatus(aura, source, target)
return false return false
end end
---@param spell Spell ---@param spell Bastion.Spell
---@param source? Unit ---@param source? Bastion.Unit
---@param target? Unit ---@param target? Bastion.Unit
function Spell:UpdateAura(spell, source, target) function Spell:UpdateAura(spell, source, target)
if not self.auras[spell:GetID()] then if not self.auras[spell:GetID()] then
self:TrackAura(spell, source, target) self:TrackAura(spell, source, target)

@ -2,14 +2,14 @@
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
-- Create a new SpellBook class -- Create a new SpellBook class
---@class SpellBook ---@class Bastion.SpellBook
---@field spells table<number, Spell> ---@field spells table<number, Bastion.Spell>
---@field auras { [spellId]: { [spellId]: { spell: Spell, source?: Unit, target?: Unit, lastApplied: number } } } ---@field auras { [spellId]: { [spellId]: { spell: Bastion.Spell, source?: Bastion.Unit, target?: Bastion.Unit, lastApplied: number } } }
local SpellBook = {} local SpellBook = {}
SpellBook.__index = SpellBook SpellBook.__index = SpellBook
-- Constructor -- Constructor
---@return SpellBook ---@return Bastion.SpellBook
function SpellBook:New() function SpellBook:New()
local self = setmetatable({}, SpellBook) local self = setmetatable({}, SpellBook)
self.spells = {} self.spells = {}
@ -28,7 +28,7 @@ end ]]
-- Get a spell from the spellbook -- Get a spell from the spellbook
---@param id integer ---@param id integer
---@return Spell ---@return Bastion.Spell
function SpellBook:GetSpell(id) function SpellBook:GetSpell(id)
local override = FindSpellOverrideByID(id) local override = FindSpellOverrideByID(id)
if self.spells[id] == nil then if self.spells[id] == nil then
@ -45,7 +45,7 @@ function SpellBook:GetSpell(id)
end end
---@param ... integer ---@param ... integer
---@return Spell, ... Spell ---@return Bastion.Spell, ... Spell
function SpellBook:GetSpells(...) function SpellBook:GetSpells(...)
local spells = {} local spells = {}
for _, id in ipairs({ ... }) do for _, id in ipairs({ ... }) do
@ -55,8 +55,8 @@ function SpellBook:GetSpells(...)
return unpack(spells) return unpack(spells)
end end
---@param aura Spell ---@param aura Bastion.Spell
---@return Spell[] ---@return Bastion.Spell[]
function SpellBook:GetAuraSpells(aura) function SpellBook:GetAuraSpells(aura)
local spells = {} local spells = {}
for _, spell in pairs(self.spells) do for _, spell in pairs(self.spells) do
@ -69,7 +69,7 @@ function SpellBook:GetAuraSpells(aura)
end end
---@param ... integer ---@param ... integer
---@return List ---@return Bastion.List
function SpellBook:GetList(...) function SpellBook:GetList(...)
local spells = {} local spells = {}
for _, id in ipairs({ ... }) do for _, id in ipairs({ ... }) do
@ -80,7 +80,7 @@ function SpellBook:GetList(...)
end end
---@param name string ---@param name string
---@return Spell ---@return Bastion.Spell
function SpellBook:GetSpellByName(name) function SpellBook:GetSpellByName(name)
local _, rank, icon, castTime, minRange, maxRange, spellID, originalIcon = GetSpellInfo(name) local _, rank, icon, castTime, minRange, maxRange, spellID, originalIcon = GetSpellInfo(name)
return self:GetSpell(spellID) return self:GetSpell(spellID)

@ -10,7 +10,7 @@ end
local Cache = Bastion.Globals.UnitInfo local Cache = Bastion.Globals.UnitInfo
--- An attempt to integrate HeroLib TTD timers. --- An attempt to integrate HeroLib TTD timers.
---@class TimeToDie ---@class Bastion.TimeToDie
local TimeToDie = { local TimeToDie = {
Settings = { Settings = {
-- Refresh time (seconds) : min=0.1, max=2, default = 0.1 -- Refresh time (seconds) : min=0.1, max=2, default = 0.1
@ -29,8 +29,7 @@ local TimeToDie = {
} }
function TimeToDie:IterableUnits() function TimeToDie:IterableUnits()
return Bastion.List:New():concat(Bastion.ObjectManager.enemies):concat(Bastion.ObjectManager.explosives):concat( return Bastion.ObjectManager.enemies
Bastion.ObjectManager.incorporeal)
end end
function TimeToDie:Refresh() function TimeToDie:Refresh()
@ -38,24 +37,22 @@ function TimeToDie:Refresh()
local historyCount = TimeToDie.Settings.HistoryCount local historyCount = TimeToDie.Settings.HistoryCount
local historyTime = TimeToDie.Settings.HistoryTime local historyTime = TimeToDie.Settings.HistoryTime
local ttdCache = TimeToDie.Cache local ttdCache = TimeToDie.Cache
local iterableUnits = TimeToDie:IterableUnits() local iterableUnits = Bastion.ObjectManager.enemies
local units = TimeToDie.Units local units = TimeToDie.Units
local existingUnits = TimeToDie.ExistingUnits local existingUnits = TimeToDie.ExistingUnits
wipe(existingUnits) wipe(existingUnits)
local thisUnit ---@param unit Bastion.Unit
---@param unit Unit
iterableUnits:each(function(unit) iterableUnits:each(function(unit)
thisUnit = unit if unit:Exists() then
if thisUnit:Exists() then local unitGUID = unit:GetGUID()
local unitGUID = thisUnit:GetGUID()
-- Check if we didn't already scanned this unit. -- Check if we didn't already scanned this unit.
if unitGUID and not existingUnits[unitGUID] then if unitGUID and not existingUnits[unitGUID] then
existingUnits[unitGUID] = true existingUnits[unitGUID] = true
local healthPercentage = thisUnit:GetHealthPercent() local healthPercentage = unit:GetHealthPercent()
-- Check if it's a valid unit -- Check if it's a valid unit
if Player:CanAttack(thisUnit) and healthPercentage < 100 then if healthPercentage < 100 then
local unitTable = units[unitGUID] local unitTable = units[unitGUID]
-- Check if we have seen one time this unit, if we don't then initialize it. -- Check if we have seen one time this unit, if we don't then initialize it.
if not unitTable or healthPercentage > unitTable[1][1][2] then if not unitTable or healthPercentage > unitTable[1][1][2] then
@ -123,33 +120,33 @@ TimeToDie.specialTTDPercentageData = {
----- Castle Nathria ----- ----- Castle Nathria -----
--- Stone Legion Generals --- Stone Legion Generals
-- General Kaal leaves the fight at 50% if General Grashaal has not fight yet. We take 49% as check value since it get -95% dmg reduction at 50% until intermission is over. -- General Kaal leaves the fight at 50% if General Grashaal has not fight yet. We take 49% as check value since it get -95% dmg reduction at 50% until intermission is over.
---@param self Unit ---@param self Bastion.Unit
[168112] = function(self) return (not self:CheckHPFromBossList(168113, 99) and 49) or 0 end, [168112] = function(self) return (not self:CheckHPFromBossList(168113, 99) and 49) or 0 end,
--- Sun King's Salvation --- Sun King's Salvation
-- Shade of Kael'thas fight is 60% -> 45% and then 10% -> 0%. -- Shade of Kael'thas fight is 60% -> 45% and then 10% -> 0%.
---@param self Unit ---@param self Bastion.Unit
[165805] = function(self) return (self:GetHealthPercent() > 20 and 45) or 0 end, [165805] = function(self) return (self:GetHealthPercent() > 20 and 45) or 0 end,
----- Sanctum of Domination ----- ----- Sanctum of Domination -----
--- Eye of the Jailer leaves at 66% and 33% --- Eye of the Jailer leaves at 66% and 33%
---@param self Unit ---@param self Bastion.Unit
[180018] = function(self) [180018] = function(self)
return (self:GetHealthPercent() > 66 and 66) or return (self:GetHealthPercent() > 66 and 66) or
(self:GetHealthPercent() <= 66 and self:GetHealthPercent() > 33 and 33) or 0 (self:GetHealthPercent() <= 66 and self:GetHealthPercent() > 33 and 33) or 0
end, end,
--- Painsmith Raznal leaves at 70% and 40% --- Painsmith Raznal leaves at 70% and 40%
---@param self Unit ---@param self Bastion.Unit
[176523] = function(self) [176523] = function(self)
return (self:GetHealthPercent() > 70 and 70) or return (self:GetHealthPercent() > 70 and 70) or
(self:GetHealthPercent() <= 70 and self:GetHealthPercent() > 40 and 40) or 0 (self:GetHealthPercent() <= 70 and self:GetHealthPercent() > 40 and 40) or 0
end, end,
--- Fatescribe Roh-Kalo phases at 70% and 40% --- Fatescribe Roh-Kalo phases at 70% and 40%
---@param self Unit ---@param self Bastion.Unit
[179390] = function(self) [179390] = function(self)
return (self:GetHealthPercent() > 70 and 70) or return (self:GetHealthPercent() > 70 and 70) or
(self:GetHealthPercent() <= 70 and self:GetHealthPercent() > 40 and 40) or 0 (self:GetHealthPercent() <= 70 and self:GetHealthPercent() > 40 and 40) or 0
end, end,
--- Sylvanas Windrunner intermission at 83% and "dies" at 50% (45% in MM) --- Sylvanas Windrunner intermission at 83% and "dies" at 50% (45% in MM)
---@param self Unit ---@param self Bastion.Unit
[180828] = function(self) [180828] = function(self)
local _, _, difficultyId = GetInstanceInfo() local _, _, difficultyId = GetInstanceInfo()
return (self:GetHealthPercent() > 83 and 83) or return (self:GetHealthPercent() > 83 and 83) or
@ -166,7 +163,7 @@ TimeToDie.specialTTDPercentageData = {
-- Hymdall leaves the fight at 10%. -- Hymdall leaves the fight at 10%.
[94960] = 10, [94960] = 10,
-- Fenryr leaves the fight at 60%. We take 50% as check value since it doesn't get immune at 60%. -- Fenryr leaves the fight at 60%. We take 50% as check value since it doesn't get immune at 60%.
---@param self Unit ---@param self Bastion.Unit
[95674] = function(self) return (self:GetHealthPercent() > 50 and 60) or 0 end, [95674] = function(self) return (self:GetHealthPercent() > 50 and 60) or 0 end,
-- Odyn leaves the fight at 80%. -- Odyn leaves the fight at 80%.
[95676] = 80, [95676] = 80,
@ -176,14 +173,15 @@ TimeToDie.specialTTDPercentageData = {
----- Trial of Valor ----- ----- Trial of Valor -----
--- Odyn --- Odyn
-- Hyrja & Hymdall leaves the fight at 25% during first stage and 85%/90% during second stage (HM/MM). -- Hyrja & Hymdall leaves the fight at 25% during first stage and 85%/90% during second stage (HM/MM).
---@param self Unit ---@param self Bastion.Unit
[114360] = function(self) [114360] = function(self)
local _, _, difficultyId = GetInstanceInfo() local _, _, difficultyId = GetInstanceInfo()
return (not self:CheckHPFromBossList(114263, 99) and 25) or return (not self:CheckHPFromBossList(114263, 99) and 25) or
(difficultyId == 16 and 85) or 90 (difficultyId == 16 and 85) or 90
end, end,
---@param self Unit ---@param self Bastion.Unit
[114361] = function(self) [114361] = function(self)
local _, _, difficultyId = GetInstanceInfo()
return (not self:CheckHPFromBossList(114263, 99) and 25) or return (not self:CheckHPFromBossList(114263, 99) and 25) or
(difficultyId == 16 and 85) or 90 (difficultyId == 16 and 85) or 90
end, end,
@ -191,7 +189,7 @@ TimeToDie.specialTTDPercentageData = {
[114263] = 10, [114263] = 10,
----- Nighthold ----- ----- Nighthold -----
--- Elisande leaves the fight two times at 10% then normally dies. She looses 50% power per stage (100 -> 50 -> 0). --- Elisande leaves the fight two times at 10% then normally dies. She looses 50% power per stage (100 -> 50 -> 0).
---@param self Unit ---@param self Bastion.Unit
[106643] = function(self) return (self:GetPower() > 0 and 10) or 0 end, [106643] = function(self) return (self:GetPower() > 0 and 10) or 0 end,
--- Warlord of Draenor (WoD) --- Warlord of Draenor (WoD)
@ -215,7 +213,7 @@ TimeToDie.specialTTDPercentageData = {
} }
-- Returns the max fight length of boss units, or the current selected target if no boss units -- Returns the max fight length of boss units, or the current selected target if no boss units
---@param enemies? List ---@param enemies? Bastion.List
---@param bossOnly? boolean ---@param bossOnly? boolean
function TimeToDie.FightRemains(enemies, bossOnly) function TimeToDie.FightRemains(enemies, bossOnly)
local bossExists, maxTimeToDie local bossExists, maxTimeToDie
@ -236,7 +234,7 @@ function TimeToDie.FightRemains(enemies, bossOnly)
-- If we specify an AoE range, iterate through all the targets in the specified range -- If we specify an AoE range, iterate through all the targets in the specified range
if enemies then if enemies then
---@param enemy Unit ---@param enemy Bastion.Unit
enemies:each(function(enemy) enemies:each(function(enemy)
if (enemy:InCombatOdds() > 80 or enemy:IsDummy()) and enemy:TimeToDieIsNotValid() then if (enemy:InCombatOdds() > 80 or enemy:IsDummy()) and enemy:TimeToDieIsNotValid() then
maxTimeToDie = math.max(maxTimeToDie or 0, enemy:TimeToDie2()) maxTimeToDie = math.max(maxTimeToDie or 0, enemy:TimeToDie2())
@ -262,7 +260,7 @@ function TimeToDie.BossFightRemainsIsNotValid()
end end
-- Returns if the current fight length meets the requirements. -- Returns if the current fight length meets the requirements.
---@param enemies? List ---@param enemies? Bastion.List
---@param operator CompareThisTable ---@param operator CompareThisTable
---@param value number ---@param value number
---@param checkIfValid boolean ---@param checkIfValid boolean

@ -2,7 +2,8 @@
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
-- Create a new Timer class -- Create a new Timer class
---@class Timer ---@class Bastion.Timer
---@field type string
local Timer = { local Timer = {
startTime = nil, startTime = nil,
resetAfterCombat = false, resetAfterCombat = false,
@ -11,7 +12,7 @@ Timer.__index = Timer
-- Constructor -- Constructor
---@param type string ---@param type string
---@return Timer ---@return Bastion.Timer
function Timer:New(type) function Timer:New(type)
local self = setmetatable({}, Timer) local self = setmetatable({}, Timer)
self.startTime = nil self.startTime = nil

@ -2,22 +2,17 @@
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
-- Create a new Unit class -- Create a new Unit class
---@class Unit ---@class Bastion.Unit
---@field id boolean | number ---@field id boolean | number
---@field ttd_ticker false | cbObject ---@field ttd_ticker false | cbObject
---@field unit TinkrObjectReference ---@field unit? TinkrObjectReference
---@field aura_table AuraTable | nil ---@field aura_table Bastion.AuraTable | nil
local Unit = { local Unit = {
---@type Cache ---@type Bastion.Cache
cache = nil, cache = nil,
aura_table = nil, aura_table = nil,
---@type UnitId | WowGameObject ---@type UnitId | WowGameObject
unit = nil, unit = nil,
last_shadow_techniques = 0,
swings_since_sht = 0,
last_off_attack = 0,
last_main_attack = 0,
last_combat_time = 0,
ttd_ticker = false, ttd_ticker = false,
ttd = 0, ttd = 0,
id = false, --[[ @asnumber ]] id = false, --[[ @asnumber ]]
@ -42,7 +37,7 @@ function Unit:__index(k)
end end
-- Equals -- Equals
---@param other Unit ---@param other Bastion.Unit
---@return boolean ---@return boolean
function Unit:__eq(other) function Unit:__eq(other)
return UnitIsUnit(self:GetOMToken(), other:GetOMToken()) return UnitIsUnit(self:GetOMToken(), other:GetOMToken())
@ -61,10 +56,15 @@ end
-- Constructor -- Constructor
---@param unit? TinkrObjectReference ---@param unit? TinkrObjectReference
---@return Unit
function Unit:New(unit) function Unit:New(unit)
---@class Bastion.Unit
local self = setmetatable({}, Unit) local self = setmetatable({}, Unit)
self.unit = unit self.unit = unit
self.last_shadow_techniques = 0
self.swings_since_sht = 0
self.last_off_attack = 0
self.last_main_attack = 0
self.last_combat_time = 0
self.cache = Bastion.Cache:New() self.cache = Bastion.Cache:New()
self.aura_table = Bastion.AuraTable:New(self) self.aura_table = Bastion.AuraTable:New(self)
self.regression_history = {} self.regression_history = {}
@ -89,7 +89,6 @@ function Unit:Token()
end end
-- Get the units name -- Get the units name
---@return string?
function Unit:GetName() function Unit:GetName()
local unitName, realm = UnitName(self:GetOMToken()) local unitName, realm = UnitName(self:GetOMToken())
return unitName return unitName
@ -181,14 +180,14 @@ function Unit:GetPowerDeficit(powerType)
end end
-- Get the units position -- Get the units position
---@return Vector3 ---@return Bastion.Vector3
function Unit:GetPosition() function Unit:GetPosition()
local x, y, z = ObjectPosition(self:GetOMToken()) local x, y, z = ObjectPosition(self:GetOMToken())
return Bastion.Vector3:New(x, y, z) return Bastion.Vector3:New(x, y, z)
end end
-- Get the units distance from another unit -- Get the units distance from another unit
---@param unit Unit ---@param unit Bastion.Unit
---@return number ---@return number
function Unit:GetDistance(unit) function Unit:GetDistance(unit)
local pself = self:GetPosition() local pself = self:GetPosition()
@ -244,8 +243,7 @@ function Unit:IsHostile()
return UnitCanAttack(self:GetOMToken(), "player") return UnitCanAttack(self:GetOMToken(), "player")
end end
---@param unit Unit ---@param unit Bastion.Unit
---@return number
function Unit:GetReaction(unit) function Unit:GetReaction(unit)
return UnitReaction(unit:GetOMToken(), self:GetOMToken()) return UnitReaction(unit:GetOMToken(), self:GetOMToken())
end end
@ -354,14 +352,14 @@ function Unit:IsAffectingCombat()
end end
-- Get the units class id -- Get the units class id
---@return Class ---@return Bastion.Class
function Unit:GetClass() function Unit:GetClass()
local locale, class, classID = UnitClass(self:GetOMToken()) local locale, class, classID = UnitClass(self:GetOMToken())
return Bastion.Class:New(locale, class, classID) return Bastion.Class:New(locale, class, classID)
end end
-- Get the units auras -- Get the units auras
---@return AuraTable ---@return Bastion.AuraTable
function Unit:GetAuras() function Unit:GetAuras()
return self.aura_table return self.aura_table
end end
@ -382,7 +380,7 @@ local isClassicWow = select(4, GetBuildInfo()) < 40000
local losFlag = bit.bor(0x1, 0x10) local losFlag = bit.bor(0x1, 0x10)
-- Check if the unit can see another unit -- Check if the unit can see another unit
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Unit:CanSee(unit) function Unit:CanSee(unit)
-- mechagon smoke cloud -- mechagon smoke cloud
@ -455,7 +453,7 @@ function Unit:GetTimeCastIsAt(percent)
end end
-- Get Casting or channeling spell -- Get Casting or channeling spell
---@return Spell | nil ---@return Bastion.Spell | nil
function Unit:GetCastingOrChannelingSpell() function Unit:GetCastingOrChannelingSpell()
local name, text, texture, startTimeMS, endTimeMS, isTradeSkill, castID, notInterruptible, spellId = UnitCastingInfo( local name, text, texture, startTimeMS, endTimeMS, isTradeSkill, castID, notInterruptible, spellId = UnitCastingInfo(
self:GetOMToken()) self:GetOMToken())
@ -503,10 +501,12 @@ function Unit:IsCastingOrChanneling()
end end
function Unit:CastTarget() function Unit:CastTarget()
return self:IsCastingOrChanneling() and Bastion.UnitManager:Get(ObjectCastingTarget(self:GetOMToken())) ---@diagnostic disable-next-line: param-type-mismatch
return self:IsCastingOrChanneling() and Bastion.UnitManager:Get(ObjectCastingTarget(self:GetOMToken())) or
Bastion.UnitManager:Get("none")
end end
---@param unit Unit ---@param unit Bastion.Unit
function Unit:CastTargetIsUnit(unit) function Unit:CastTargetIsUnit(unit)
return self:IsCastingOrChanneling() and self:CastTarget():IsUnit(unit) return self:IsCastingOrChanneling() and self:CastTarget():IsUnit(unit)
end end
@ -516,7 +516,7 @@ function Unit:IsImmobilized()
end end
-- Check if the unit can attack the target -- Check if the unit can attack the target
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Unit:CanAttack(unit) function Unit:CanAttack(unit)
return UnitCanAttack(self:GetOMToken(), unit:GetOMToken()) return UnitCanAttack(self:GetOMToken(), unit:GetOMToken())
@ -655,7 +655,7 @@ function Unit:IsMovingAtAll()
return ObjectMovementFlag(self:GetOMToken()) ~= 0 return ObjectMovementFlag(self:GetOMToken()) ~= 0
end end
---@param unit? Unit ---@param unit? Bastion.Unit
---@return number ---@return number
function Unit:GetComboPoints(unit) function Unit:GetComboPoints(unit)
if Tinkr.classic or Tinkr.era then if Tinkr.classic or Tinkr.era then
@ -676,7 +676,7 @@ function Unit:GetComboPointsMax()
end end
-- Get combopoints deficit -- Get combopoints deficit
---@param unit Unit | nil ---@param unit Bastion.Unit | nil
---@return number ---@return number
function Unit:GetComboPointsDeficit(unit) function Unit:GetComboPointsDeficit(unit)
if Tinkr.classic or Tinkr.era then if Tinkr.classic or Tinkr.era then
@ -686,14 +686,14 @@ function Unit:GetComboPointsDeficit(unit)
end end
-- IsUnit -- IsUnit
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Unit:IsUnit(unit) 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 end
-- IsTanking -- IsTanking
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Unit:IsTanking(unit) function Unit:IsTanking(unit)
local isTanking, status, threatpct, rawthreatpct, threatvalue = UnitDetailedThreatSituation(self:GetOMToken(), local isTanking, status, threatpct, rawthreatpct, threatvalue = UnitDetailedThreatSituation(self:GetOMToken(),
@ -702,7 +702,7 @@ function Unit:IsTanking(unit)
end end
-- IsFacing -- IsFacing
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Unit:IsFacing(unit) function Unit:IsFacing(unit)
local rot = ObjectRotation(self:GetOMToken()) local rot = ObjectRotation(self:GetOMToken())
@ -725,7 +725,7 @@ function Unit:IsFacing(unit)
end end
-- IsBehind -- IsBehind
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Unit:IsBehind(unit) function Unit:IsBehind(unit)
local rot = ObjectRotation(unit:GetOMToken()) local rot = ObjectRotation(unit:GetOMToken())
@ -747,7 +747,7 @@ function Unit:IsBehind(unit)
end end
-- IsInfront -- IsInfront
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Unit:IsInfront(unit) function Unit:IsInfront(unit)
return not self:IsBehind(unit) return not self:IsBehind(unit)
@ -783,7 +783,7 @@ end
-- return ((myPos.x - targetPos.x) * (myPos.x - targetPos.x)) + ((myPos.y - targetPos.y) * (myPos.y - targetPos.y)) + ((myPos.z - targetPos.z) * (myPos.z - targetPos.z)) <= (float)(fMaxDist * fMaxDist); -- return ((myPos.x - targetPos.x) * (myPos.x - targetPos.x)) + ((myPos.y - targetPos.y) * (myPos.y - targetPos.y)) + ((myPos.z - targetPos.z) * (myPos.z - targetPos.z)) <= (float)(fMaxDist * fMaxDist);
-- InMelee -- InMelee
---@param unit Unit ---@param unit Bastion.Unit
---@return boolean ---@return boolean
function Unit:InMelee(unit) function Unit:InMelee(unit)
local x, y, z = ObjectPosition(self.unit) local x, y, z = ObjectPosition(self.unit)
@ -809,10 +809,12 @@ end
-- Get object id -- Get object id
function Unit:GetID() function Unit:GetID()
if self.id then if self.id ~= false then
---@type number
return self.id return self.id
end end
self.id = ObjectID(self:GetOMToken()) self.id = ObjectID(self:GetOMToken())
---@type number
return self.id or 0 return self.id or 0
end end
@ -970,6 +972,7 @@ end
---@return number ---@return number
function Unit:InCombatOdds() function Unit:InCombatOdds()
local time = self:GetCombatTime() local time = self:GetCombatTime()
local percent = 1 - (time / 60) local percent = 1 - (time / 60)
return percent * 100 return percent * 100
@ -1162,7 +1165,7 @@ end
-- Is the unit within distance of the target (combat reach + distance) -- Is the unit within distance of the target (combat reach + distance)
--- If the target is within 8 combat yards (8 + combat reach) of the unit --- If the target is within 8 combat yards (8 + combat reach) of the unit
---@param Target Unit ---@param Target Bastion.Unit
---@param Distance number ---@param Distance number
---@return boolean ---@return boolean
function Unit:IsWithinCombatDistance(Target, Distance) function Unit:IsWithinCombatDistance(Target, Distance)
@ -1173,7 +1176,7 @@ function Unit:IsWithinCombatDistance(Target, Distance)
end end
-- Check if the unit is within X yards (consider combat reach) -- Check if the unit is within X yards (consider combat reach)
---@param Target Unit ---@param Target Bastion.Unit
---@param Distance number ---@param Distance number
---@return boolean ---@return boolean
function Unit:IsWithinDistance(Target, Distance) function Unit:IsWithinDistance(Target, Distance)
@ -1181,7 +1184,7 @@ function Unit:IsWithinDistance(Target, Distance)
end end
-- Get the angle between the unit and the target in raidans -- Get the angle between the unit and the target in raidans
---@param Target Unit ---@param Target Bastion.Unit
---@return number ---@return number
function Unit:GetAngle(Target) function Unit:GetAngle(Target)
if not Target:Exists() then if not Target:Exists() then
@ -1201,7 +1204,7 @@ function Unit:GetFacing()
end end
-- Check if target is within a arc around the unit (angle, distance) accounting for a rotation of self -- Check if target is within a arc around the unit (angle, distance) accounting for a rotation of self
---@param Target Unit ---@param Target Bastion.Unit
---@param Angle number ---@param Angle number
---@param Distance number ---@param Distance number
---@param rotation? number ---@param rotation? number

@ -1,20 +1,18 @@
---@type Tinkr, Bastion ---@type Tinkr, Bastion
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
local ObjectManager = Tinkr.Util.ObjectManager
local Unit = Bastion.Unit local Unit = Bastion.Unit
---@class UnitManager.CustomUnit ---@class Bastion.UnitManager.CustomUnit
---@field unit Cacheable | Unit ---@field unit Bastion.Cacheable | Bastion.Unit
---@field cb fun(): Unit ---@field cb fun(): Bastion.Unit
-- Create a new UnitManager class -- Create a new UnitManager class
---@class UnitManager : { [UnitId]: Unit } ---@class Bastion.UnitManager
---@field units table<string, Unit> ---@field units table<string, Bastion.Unit>
---@field customUnits table<string, UnitManager.CustomUnit> ---@field customUnits table<string, Bastion.UnitManager.CustomUnit>
---@field objects table<string, Unit> ---@field objects table<string, Bastion.Unit>
---@field cache Cache ---@field cache Bastion.Cache
local UnitManager = { local UnitManager = {
units = {}, units = {},
customUnits = {}, customUnits = {},
@ -27,7 +25,6 @@ function UnitManager:__index(k)
if k == "none" then if k == "none" then
return self:Get("none") return self:Get("none")
end end
if UnitManager[k] then if UnitManager[k] then
return UnitManager[k] return UnitManager[k]
end end
@ -66,9 +63,9 @@ function UnitManager:__index(k)
end end
-- Constructor -- Constructor
---@return UnitManager ---@return Bastion.UnitManager
function UnitManager:New() function UnitManager:New()
---@class UnitManager ---@class Bastion.UnitManager
local self = setmetatable({}, UnitManager) local self = setmetatable({}, UnitManager)
self.units = {} self.units = {}
self.customUnits = {} self.customUnits = {}
@ -78,7 +75,7 @@ end
-- Get or create a unit -- Get or create a unit
---@param token UnitId ---@param token UnitId
---@return Unit ---@return Bastion.Unit
function UnitManager:Get(token) function UnitManager:Get(token)
-- if not Validate(token) then -- if not Validate(token) then
-- error("UnitManager:Get - Invalid token: " .. token) -- error("UnitManager:Get - Invalid token: " .. token)
@ -90,6 +87,7 @@ function UnitManager:Get(token)
if token == "none" then if token == "none" then
self.objects["none"] = Unit:New() self.objects["none"] = Unit:New()
else else
---@diagnostic disable-next-line: param-type-mismatch
self.objects[tguid] = Unit:New(Object(tguid)) self.objects[tguid] = Unit:New(Object(tguid))
end end
end end
@ -101,6 +99,7 @@ function UnitManager:Get(token)
if token == "none" then if token == "none" then
self.objects["none"] = Unit:New() self.objects["none"] = Unit:New()
else else
---@diagnostic disable-next-line: param-type-mismatch
self.objects[tguid] = Unit:New(Object(tguid)) self.objects[tguid] = Unit:New(Object(tguid))
end end
end end
@ -110,21 +109,21 @@ end
-- Get a unit by guid -- Get a unit by guid
---@param guid string | WowGameObject ---@param guid string | WowGameObject
---@return Unit ---@return Bastion.Unit
function UnitManager:GetObject(guid) function UnitManager:GetObject(guid)
return self.objects[guid] return self.objects[guid]
end end
-- Set a unit by guid -- Set a unit by guid
---@param unit Unit ---@param unit Bastion.Unit
function UnitManager:SetObject(unit) function UnitManager:SetObject(unit)
self.objects[unit:GetGUID()] = unit self.objects[unit:GetGUID()] = unit
end end
-- Create a custom unit and cache it for .5 seconds -- Create a custom unit and cache it for .5 seconds
---@generic V :Unit ---@generic V :Bastion.Unit
---@param token string ---@param token string
---@param cb fun(): Unit ---@param cb fun(): Bastion.Unit
function UnitManager:CreateCustomUnit(token, cb) function UnitManager:CreateCustomUnit(token, cb)
local unit = cb() local unit = cb()
local cachedUnit = Bastion.Cacheable:New(unit, cb) local cachedUnit = Bastion.Cacheable:New(unit, cb)
@ -143,7 +142,7 @@ function UnitManager:CreateCustomUnit(token, cb)
end end
---@description Enumerates all friendly units in the battlefield ---@description Enumerates all friendly units in the battlefield
---@param cb fun(unit: Unit):boolean ---@param cb fun(unit: Bastion.Unit):boolean
---@return nil ---@return nil
function UnitManager:EnumFriends(cb) function UnitManager:EnumFriends(cb)
Bastion.ObjectManager.friends:each(function(unit) Bastion.ObjectManager.friends:each(function(unit)
@ -155,7 +154,7 @@ function UnitManager:EnumFriends(cb)
end end
-- Enum Enemies (object manager) -- Enum Enemies (object manager)
---@param cb fun(unit: Unit):boolean ---@param cb fun(unit: Bastion.Unit):boolean
---@return nil ---@return nil
function UnitManager:EnumEnemies(cb) function UnitManager:EnumEnemies(cb)
Bastion.ObjectManager.activeEnemies:each(function(unit) Bastion.ObjectManager.activeEnemies:each(function(unit)
@ -167,7 +166,7 @@ function UnitManager:EnumEnemies(cb)
end end
-- Enum Units (object manager) -- Enum Units (object manager)
---@param cb fun(unit: Unit):boolean ---@param cb fun(unit: Bastion.Unit):boolean
---@return nil ---@return nil
function UnitManager:EnumUnits(cb) function UnitManager:EnumUnits(cb)
Bastion.ObjectManager.enemies:each(function(unit) Bastion.ObjectManager.enemies:each(function(unit)
@ -179,7 +178,7 @@ function UnitManager:EnumUnits(cb)
end end
-- Enum Incorporeal (object manager) -- Enum Incorporeal (object manager)
---@param cb fun(unit: Unit):boolean ---@param cb fun(unit: Bastion.Unit):boolean
---@return nil ---@return nil
function UnitManager:EnumIncorporeal(cb) function UnitManager:EnumIncorporeal(cb)
Bastion.ObjectManager.incorporeal:each(function(unit) Bastion.ObjectManager.incorporeal:each(function(unit)
@ -191,7 +190,7 @@ function UnitManager:EnumIncorporeal(cb)
end end
-- Get the number of enemies with a debuff -- Get the number of enemies with a debuff
---@param spell Spell ---@param spell Bastion.Spell
---@param range? number ---@param range? number
---@return number ---@return number
function UnitManager:GetNumEnemiesWithDebuff(spell, range) function UnitManager:GetNumEnemiesWithDebuff(spell, range)
@ -209,7 +208,7 @@ function UnitManager:GetNumEnemiesWithDebuff(spell, range)
end end
-- Get the number of friends with a buff (party/raid members) -- Get the number of friends with a buff (party/raid members)
---@param spell Spell ---@param spell Bastion.Spell
---@return number ---@return number
function UnitManager:GetNumFriendsWithBuff(spell) function UnitManager:GetNumFriendsWithBuff(spell)
local count = 0 local count = 0
@ -237,8 +236,8 @@ end
-- Get the friend with the most friends within a given radius (party/raid members) -- Get the friend with the most friends within a given radius (party/raid members)
---@param radius number ---@param radius number
---@return Unit | nil ---@return Bastion.Unit | nil
---@return Unit[] ---@return Bastion.Unit[]
function UnitManager:GetFriendWithMostFriends(radius) function UnitManager:GetFriendWithMostFriends(radius)
local unit = nil local unit = nil
local count = 0 local count = 0
@ -270,7 +269,7 @@ function UnitManager:GetFriendWithMostFriends(radius)
end end
-- Get the enemy with the most enemies within a given radius -- Get the enemy with the most enemies within a given radius
---@return Unit|nil, Unit[] ---@return Bastion.Unit|nil, Bastion.Unit[]
function UnitManager:GetEnemiesWithMostEnemies(radius) function UnitManager:GetEnemiesWithMostEnemies(radius)
local unit = nil local unit = nil
local count = 0 local count = 0
@ -304,7 +303,7 @@ end
-- Find the centroid of the most dense area of friends (party/raid members) of a given radius within a given range -- Find the centroid of the most dense area of friends (party/raid members) of a given radius within a given range
---@param radius number ---@param radius number
---@param range number ---@param range number
---@return Vector3 | nil ---@return Bastion.Vector3 | nil
function UnitManager:FindFriendsCentroid(radius, range) function UnitManager:FindFriendsCentroid(radius, range)
local unit, friends = self:GetFriendWithMostFriends(radius) local unit, friends = self:GetFriendWithMostFriends(radius)
if unit == nil then if unit == nil then
@ -335,7 +334,7 @@ end
-- Find the centroid of the most dense area of enemies of a given radius within a given range -- Find the centroid of the most dense area of enemies of a given radius within a given range
---@param radius number ---@param radius number
---@param range number ---@param range number
---@return Vector3 | nil ---@return Bastion.Vector3 | nil
function UnitManager:FindEnemiesCentroid(radius, range) function UnitManager:FindEnemiesCentroid(radius, range)
local unit, enemies = self:GetEnemiesWithMostEnemies(radius) local unit, enemies = self:GetEnemiesWithMostEnemies(radius)
if unit == nil then if unit == nil then

@ -1,11 +1,32 @@
-- Create a Vector3 class -- Create a Vector3 class
---@class Vector3 ---@class Bastion.Vector3
---@operator add(Vector3): Vector3 ---@field length number
---@operator sub(Vector3|number): Vector3 ---@field normalized Bastion.Vector3
---@operator mul(number): Vector3 ---@field magnitude number
---@operator div(number): Vector3 ---@field sqrMagnitude number
---@operator unm(): Vector3 ---@field zero Bastion.Vector3
---@field one Bastion.Vector3
---@field up Bastion.Vector3
---@field down Bastion.Vector3
---@field left Bastion.Vector3
---@field right Bastion.Vector3
---@field forward Bastion.Vector3
---@field back Bastion.Vector3
---@field positiveInfinity Bastion.Vector3
---@field negativeInfinity Bastion.Vector3
---@field nan Bastion.Vector3
---@field epsilon number
---@field maxValue number
---@field minValue number
---@field x number
---@field y number
---@field z number
---@operator add(Bastion.Vector3): Bastion.Vector3
---@operator sub(Bastion.Vector3|number): Bastion.Vector3
---@operator mul(number): Bastion.Vector3
---@operator div(number): Bastion.Vector3
---@operator unm(): Bastion.Vector3
---@operator len(): number ---@operator len(): number
local Vector3 = {} local Vector3 = {}
Vector3.__index = Vector3 Vector3.__index = Vector3
@ -15,14 +36,14 @@ function Vector3:__tostring()
return "Vector3(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ")" return "Vector3(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ")"
end end
---@param other Vector3 ---@param other Bastion.Vector3
---@return Vector3 ---@return Bastion.Vector3
function Vector3:__add(other) function Vector3:__add(other)
return Vector3:New(self.x + other.x, self.y + other.y, self.z + other.z) return Vector3:New(self.x + other.x, self.y + other.y, self.z + other.z)
end end
---@param other Vector3 | number ---@param other Bastion.Vector3 | number
---@return Vector3 ---@return Bastion.Vector3
function Vector3:__sub(other) function Vector3:__sub(other)
if type(other) == "number" then if type(other) == "number" then
return Vector3:New(self.x - other, self.y - other, self.z - other) return Vector3:New(self.x - other, self.y - other, self.z - other)
@ -31,36 +52,36 @@ function Vector3:__sub(other)
end end
---@param other number ---@param other number
---@return Vector3 ---@return Bastion.Vector3
function Vector3:__mul(other) function Vector3:__mul(other)
return Vector3:New(self.x * other, self.y * other, self.z * other) return Vector3:New(self.x * other, self.y * other, self.z * other)
end end
---@param other number ---@param other number
---@return Vector3 ---@return Bastion.Vector3
function Vector3:__div(other) function Vector3:__div(other)
return Vector3:New(self.x / other, self.y / other, self.z / other) return Vector3:New(self.x / other, self.y / other, self.z / other)
end end
---@param other Vector3 ---@param other Bastion.Vector3
---@return boolean ---@return boolean
function Vector3:__eq(other) function Vector3:__eq(other)
return self.x == other.x and self.y == other.y and self.z == other.z return self.x == other.x and self.y == other.y and self.z == other.z
end end
---@param other Vector3 ---@param other Bastion.Vector3
---@return boolean ---@return boolean
function Vector3:__lt(other) function Vector3:__lt(other)
return self.x < other.x and self.y < other.y and self.z < other.z return self.x < other.x and self.y < other.y and self.z < other.z
end end
---@param other Vector3 ---@param other Bastion.Vector3
---@return boolean ---@return boolean
function Vector3:__le(other) function Vector3:__le(other)
return self.x <= other.x and self.y <= other.y and self.z <= other.z return self.x <= other.x and self.y <= other.y and self.z <= other.z
end end
---@return Vector3 ---@return Bastion.Vector3
function Vector3:__unm() function Vector3:__unm()
return Vector3:New(-self.x, -self.y, -self.z) return Vector3:New(-self.x, -self.y, -self.z)
end end
@ -70,134 +91,114 @@ function Vector3:__len()
return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z) return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
end end
---@param k string
function Vector3:__index(k) function Vector3:__index(k)
if Vector3[k] then if Vector3[k] then
return Vector3[k] return Vector3[k]
end end
---@class Vector3
---@field length number
if k == "length" then if k == "length" then
return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z) return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
end end
---@class Vector3
---@field normalized Vector3
if k == "normalized" then if k == "normalized" then
local length = math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z) local length = math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
return Vector3:New(self.x / length, self.y / length, self.z / length) return Vector3:New(self.x / length, self.y / length, self.z / length)
end end
---@class Vector3
---@field magnitude number
if k == "magnitude" then if k == "magnitude" then
return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z) return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
end end
---@class Vector3
---@field sqrMagnitude number
if k == "sqrMagnitude" then if k == "sqrMagnitude" then
return self.x * self.x + self.y * self.y + self.z * self.z return self.x * self.x + self.y * self.y + self.z * self.z
end end
---@class Vector3
---@field zero Vector3
if k == "zero" then if k == "zero" then
return Vector3:New(0, 0, 0) return Vector3:New(0, 0, 0)
end end
---@class Vector3
---@field one Vector3
if k == "one" then if k == "one" then
return Vector3:New(1, 1, 1) return Vector3:New(1, 1, 1)
end end
---@class Vector3
---@field up Vector3
if k == "up" then if k == "up" then
return Vector3:New(0, 1, 0) return Vector3:New(0, 1, 0)
end end
---@class Vector3
---@field down Vector3
if k == "down" then if k == "down" then
return Vector3:New(0, -1, 0) return Vector3:New(0, -1, 0)
end end
---@class Vector3
---@field left Vector3
if k == "left" then if k == "left" then
return Vector3:New(-1, 0, 0) return Vector3:New(-1, 0, 0)
end end
---@class Vector3
---@field right Vector3
if k == "right" then if k == "right" then
return Vector3:New(1, 0, 0) return Vector3:New(1, 0, 0)
end end
---@class Vector3
---@field forward Vector3
if k == "forward" then if k == "forward" then
return Vector3:New(0, 0, 1) return Vector3:New(0, 0, 1)
end end
---@class Vector3
---@field back Vector3
if k == "back" then if k == "back" then
return Vector3:New(0, 0, -1) return Vector3:New(0, 0, -1)
end end
---@class Vector3
---@field positiveInfinity Vector3
if k == "positiveInfinity" then if k == "positiveInfinity" then
return Vector3:New(math.huge, math.huge, math.huge) return Vector3:New(math.huge, math.huge, math.huge)
end end
---@class Vector3
---@field negativeInfinity Vector3
if k == "negativeInfinity" then if k == "negativeInfinity" then
return Vector3:New(-math.huge, -math.huge, -math.huge) return Vector3:New(-math.huge, -math.huge, -math.huge)
end end
---@class Vector3
---@field nan Vector3
if k == "nan" then if k == "nan" then
return Vector3:New(0 / 0, 0 / 0, 0 / 0) return Vector3:New(0 / 0, 0 / 0, 0 / 0)
end end
---@class Vector3
---@field epsilon number
if k == "epsilon" then if k == "epsilon" then
return 1.401298E-45 return 1.401298E-45
end end
---@class Vector3
---@field maxValue number
if k == "maxValue" then if k == "maxValue" then
return 3.402823E+38 return 3.402823E+38
end end
---@class Vector3
---@field minValue number
if k == "minValue" then if k == "minValue" then
return -3.402823E+38 return -3.402823E+38
end end
---@class Vector3
---@field x number
if k == "x" then if k == "x" then
return self[1] return self[1]
end end
---@class Vector3
---@field y number
if k == "y" then if k == "y" then
return self[2] return self[2]
end end
---@class Vector3
---@field z number
if k == "z" then if k == "z" then
return self[3] return self[3]
end end
@ -220,7 +221,7 @@ end
---@param x number ---@param x number
---@param y number ---@param y number
---@param z number ---@param z number
---@return Vector3 ---@return Bastion.Vector3
function Vector3:New(x, y, z) function Vector3:New(x, y, z)
if x == false then if x == false then
return Vector3:New(0, 0, 0) return Vector3:New(0, 0, 0)
@ -230,37 +231,38 @@ function Vector3:New(x, y, z)
return self return self
end end
---@param rhs Vector3 ---@param rhs Bastion.Vector3
---@return number ---@return number
function Vector3:Dot(rhs) function Vector3:Dot(rhs)
return self.x * rhs.x + self.y * rhs.y + self.z * rhs.z return self.x * rhs.x + self.y * rhs.y + self.z * rhs.z
end end
---@param rhs Vector3 ---@param rhs Bastion.Vector3
---@return Vector3 ---@return Bastion.Vector3
function Vector3:Cross(rhs) function Vector3:Cross(rhs)
return Vector3:New(self.y * rhs.z - self.z * rhs.y, self.z * rhs.x - self.x * rhs.z, self.x * rhs.y - self.y * rhs.x) return Vector3:New(self.y * rhs.z - self.z * rhs.y, self.z * rhs.x - self.x * rhs.z, self.x * rhs.y - self.y * rhs.x)
end end
---@param b Vector3 ---@param b Bastion.Vector3
---@return number ---@return number
function Vector3:Distance(b) function Vector3:Distance(b)
return FastDistance(self.x, self.y, self.z, b.x, b.y, b.z) return FastDistance(self.x, self.y, self.z, b.x, b.y, b.z)
end end
---@param to Vector3 ---@param to Bastion.Vector3
function Vector3:GetAbsoluteAngle(to) function Vector3:GetAbsoluteAngle(to)
return self:NormalizeOrientation(math.atan2(to.y - self.y, to.x - self.x)) return self:NormalizeOrientation(math.atan2(to.y - self.y, to.x - self.x))
end end
---@param to Vector3 ---@param to Bastion.Vector3
---@return number ---@return number
function Vector3:Angle(to) function Vector3:Angle(to)
return math.acos(self:Dot(to) / (math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z) * math.sqrt(to.x * to.x + to.y * to.y + to.z * to.z))) return math.acos(self:Dot(to) /
(math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z) * math.sqrt(to.x * to.x + to.y * to.y + to.z * to.z)))
end end
---@param maxLength number ---@param maxLength number
---@return Vector3 ---@return Bastion.Vector3
function Vector3:ClampMagnitude(maxLength) function Vector3:ClampMagnitude(maxLength)
if self:Dot(self) > maxLength * maxLength then if self:Dot(self) > maxLength * maxLength then
return self.normalized * maxLength return self.normalized * maxLength
@ -269,7 +271,7 @@ function Vector3:ClampMagnitude(maxLength)
return self return self
end end
---@return Vector3 ---@return Bastion.Vector3
function Vector3:directionOrZero() function Vector3:directionOrZero()
local mag = self.magnitude local mag = self.magnitude
if mag < 0.0000001 then if mag < 0.0000001 then
@ -290,17 +292,17 @@ local function clamp(x, min, max)
return x < min and min or (x > max and max or x) return x < min and min or (x > max and max or x)
end end
---@param b Vector3 ---@param b Bastion.Vector3
---@param t number ---@param t number
---@return Vector3 ---@return Bastion.Vector3
function Vector3:Lerp(b, t) function Vector3:Lerp(b, t)
t = clamp(t, 0, 1) t = clamp(t, 0, 1)
return Vector3:New(self.x + (b.x - self.x) * t, self.y + (b.y - self.y) * t, self.z + (b.z - self.z) * t) return Vector3:New(self.x + (b.x - self.x) * t, self.y + (b.y - self.y) * t, self.z + (b.z - self.z) * t)
end end
---@param target Vector3 ---@param target Bastion.Vector3
---@param maxDistanceDelta number ---@param maxDistanceDelta number
---@return Vector3 ---@return Bastion.Vector3
function Vector3:MoveTowards(target, maxDistanceDelta) function Vector3:MoveTowards(target, maxDistanceDelta)
local toVector = target - self local toVector = target - self
local distance = toVector.magnitude local distance = toVector.magnitude
@ -311,14 +313,14 @@ function Vector3:MoveTowards(target, maxDistanceDelta)
return self + toVector / distance * maxDistanceDelta return self + toVector / distance * maxDistanceDelta
end end
---@param b Vector3 ---@param b Bastion.Vector3
---@return Vector3 ---@return Bastion.Vector3
function Vector3:Scale(b) function Vector3:Scale(b)
return Vector3:New(self.x * b.x, self.y * b.y, self.z * b.z) return Vector3:New(self.x * b.x, self.y * b.y, self.z * b.z)
end end
---@param onNormal Vector3 ---@param onNormal Bastion.Vector3
---@return Vector3 ---@return Bastion.Vector3
function Vector3:Project(onNormal) function Vector3:Project(onNormal)
local num = onNormal:Dot(onNormal) local num = onNormal:Dot(onNormal)
if num < 1.401298E-45 then if num < 1.401298E-45 then
@ -328,19 +330,19 @@ function Vector3:Project(onNormal)
return onNormal * self:Dot(onNormal) / num return onNormal * self:Dot(onNormal) / num
end end
---@param planeNormal Vector3 ---@param planeNormal Bastion.Vector3
---@return Vector3 ---@return Bastion.Vector3
function Vector3:ProjectOnPlane(planeNormal) function Vector3:ProjectOnPlane(planeNormal)
return self - self:Project(planeNormal) return self - self:Project(planeNormal)
end end
---@param inNormal Vector3 ---@param inNormal Bastion.Vector3
---@return Vector3 ---@return Bastion.Vector3
function Vector3:Reflect(inNormal) function Vector3:Reflect(inNormal)
return -2 * inNormal:Dot(self) * inNormal + self return -2 * inNormal:Dot(self) * inNormal + self
end end
---@return Vector3 ---@return Bastion.Vector3
function Vector3:Normalize() function Vector3:Normalize()
local num = self:Dot(self) local num = self:Dot(self)
if num > 1E-05 then if num > 1E-05 then

@ -13,23 +13,94 @@ local ThirdPartyModulesBase = string.format("%s/%s", TinkrScriptsBase, "BastionS
Bastion.__index = Bastion Bastion.__index = Bastion
---@param file string ---@class Bastion.LoadedFiles.Table
---@param ... any ---@field [number] { originalPath: string, loadedPath: string, reloadable: boolean, order: number, newPath: string }
---@return any ... Bastion.LoadedFiles = {}
function Bastion:Require(file, ...)
-- If require starts with an @ then we require from the scripts/bastion/scripts folder ---@param filePath string
if file:sub(1, 1) == "@" then function Bastion:CheckIfLoaded(filePath)
file = file:sub(2) for i, file in ipairs(Bastion.LoadedFiles) do
-- print('1') if file.loadedPath == filePath or file.originalPath == filePath or file.newPath == filePath then
return require(string.format("%s%s", BastionScriptsBase, file), Bastion, ...) return true
elseif file:sub(1, 1) == "~" then end
file = file:sub(2) end
-- print("2") return false
return require(string.format("%s%s", BastionBase, file), Bastion, ...) end
---@param path string
---@param extension string
---@return string
local function AppendExtension(path, extension)
return string.format("%s.%s", path, extension)
end
---@param path string
---@param extensions string|string[]
local function CheckFileExtensions(path, extensions)
local exts = {}
if type(extensions) == "string" then
exts = { extensions }
else else
-- print("Normal req") exts = extensions
return require(file, Bastion, ...)
end end
for i, extension in ipairs(exts) do
local newPath = path
if newPath:sub(extension:len() * -1) ~= extension then
newPath = AppendExtension(newPath, extension)
end
if FileExists(newPath) then
return newPath:sub(1, (extension:len() + 2) * -1), true
end
end
return path, false
end
--- 0 = Failed, 1 = Success, 2 = Already Loaded
---@param filePath string | { filePath: string, reloadable: boolean }
---@param ... any
---@return 0|1|2, ...
function Bastion:Require(filePath, ...)
local loadedFile = {
originalPath = type(filePath) == "table" and filePath.filePath or tostring(filePath),
newPath = type(filePath) == "table" and filePath.filePath or tostring(filePath),
loadedPath = type(filePath) == "table" and filePath.filePath or tostring(filePath),
reloadable = type(filePath) == "table" and filePath.reloadable or false,
order = #Bastion.LoadedFiles + 1,
}
local filePathModifier = loadedFile.originalPath:sub(1, 1)
if filePathModifier == "@" then
-- If require starts with an @ then we require from the scripts/bastion/scripts folder
loadedFile.newPath = string.format("%s%s", BastionScriptsBase, loadedFile.originalPath:sub(2))
loadedFile.loadedPath = loadedFile.newPath
elseif filePathModifier == "~" then
-- If file path starts with a ~ then we require from the scripts/bastion folder
loadedFile.newPath = string.format("%s%s", BastionBase, loadedFile.originalPath:sub(2))
loadedFile.loadedPath = loadedFile.newPath
end
loadedFile.loadedPath = loadedFile.newPath
local found = false
-- Check if file path has a .lua or .luac extension. If not, try to add one and check if the file exists
loadedFile.loadedPath, found = CheckFileExtensions(loadedFile.newPath, { "lua", "luac" })
if not found then
Log(string.format("Bastion:Require - Not Found: %s (%s)", loadedFile.newPath, loadedFile.originalPath))
return 0, SafePack(nil)
end
if not loadedFile.reloadable then
if Bastion:CheckIfLoaded(loadedFile.loadedPath) then
--Log(string.format("Bastion:Require - Already loaded: %s (%s)", loadedFile.newPath, loadedFile.originalPath))
return 2, SafePack(nil)
end
end
table.insert(Bastion.LoadedFiles, loadedFile)
return 1, SafePack(require(loadedFile.loadedPath, Bastion, ...))
end end
local loadExamples = false local loadExamples = false
@ -82,50 +153,57 @@ local function LoadThird()
end end
end end
---@generic V ---@generic V : string
---@param class `V` ---@param class `V`
---@return V ... ---@return V ...
function Bastion.require(class) function Bastion.require(class)
---@cast class string
local newClass = class:gsub("Bastion%.", "")
-- return require("scripts/bastion/src/" .. class .. "/" .. class, Bastion) -- return require("scripts/bastion/src/" .. class .. "/" .. class, Bastion)
return Bastion:Require("~/src/" .. class .. "/" .. class) local success, result = Bastion:Require("~/src/" .. newClass .. "/" .. newClass)
if success == 0 then
Log("Bastion.require - Failed to load " .. class .. ": " .. result)
end
return SafeUnpack(result)
end end
Bastion.Globals = {} Bastion.Globals = {}
Bastion.ClassMagic = Bastion.require("ClassMagic") Bastion.ClassMagic = Bastion.require("Bastion.ClassMagic")
Bastion.List = Bastion.require("List") Bastion.List = Bastion.require("Bastion.List")
Bastion.Library = Bastion.require("Library") Bastion.Library = Bastion.require("Bastion.Library")
---@type NotificationsList, Notification Bastion.Notification = Bastion.require("Bastion.Notification")
Bastion.NotificationsList, Bastion.Notification = Bastion.require("NotificationsList") Bastion.NotificationList = Bastion.require("Bastion.NotificationList")
Bastion.Vector3 = Bastion.require("Vector3") Bastion.Vector3 = Bastion.require("Bastion.Vector3")
Bastion.Sequencer = Bastion.require("Sequencer") Bastion.Sequencer = Bastion.require("Bastion.Sequencer")
Bastion.Command = Bastion.require("Command") Bastion.Command = Bastion.require("Bastion.Command")
Bastion.Cache = Bastion.require("Cache") Bastion.Cache = Bastion.require("Bastion.Cache")
Bastion.Cacheable = Bastion.require("Cacheable") Bastion.Cacheable = Bastion.require("Bastion.Cacheable")
Bastion.Refreshable = Bastion.require("Refreshable") Bastion.Refreshable = Bastion.require("Bastion.Refreshable")
Bastion.Unit = Bastion.require("Unit") Bastion.Unit = Bastion.require("Bastion.Unit")
Bastion.Aura = Bastion.require("Aura") Bastion.Aura = Bastion.require("Bastion.Aura")
---@type APL, APLActor, APLTrait Bastion.APLTrait = Bastion.require("Bastion.APLTrait")
Bastion.APL, Bastion.APLActor, Bastion.APLTrait = Bastion.require("APL") Bastion.APLActor = Bastion.require("Bastion.APLActor")
Bastion.Module = Bastion.require("Module") Bastion.APL = Bastion.require("Bastion.APL")
Bastion.UnitManager = Bastion.require("UnitManager"):New() Bastion.Module = Bastion.require("Bastion.Module")
Bastion.ObjectManager = Bastion.require("ObjectManager"):New() Bastion.UnitManager = Bastion.require("Bastion.UnitManager"):New()
Bastion.EventManager = Bastion.require("EventManager") Bastion.ObjectManager = Bastion.require("Bastion.ObjectManager"):New()
Bastion.EventManager = Bastion.require("Bastion.EventManager")
Bastion.Globals.EventManager = Bastion.EventManager:New() Bastion.Globals.EventManager = Bastion.EventManager:New()
Bastion.Spell = Bastion.require("Spell") Bastion.Spell = Bastion.require("Bastion.Spell")
Bastion.SpellBook = Bastion.require("SpellBook") Bastion.SpellBook = Bastion.require("Bastion.SpellBook")
Bastion.Globals.SpellBook = Bastion.SpellBook:New() Bastion.Globals.SpellBook = Bastion.SpellBook:New()
Bastion.Item = Bastion.require("Item") Bastion.Item = Bastion.require("Bastion.Item")
Bastion.ItemBook = Bastion.require("ItemBook") Bastion.ItemBook = Bastion.require("Bastion.ItemBook")
Bastion.Globals.ItemBook = Bastion.ItemBook:New() Bastion.Globals.ItemBook = Bastion.ItemBook:New()
Bastion.AuraTable = Bastion.require("AuraTable") Bastion.AuraTable = Bastion.require("Bastion.AuraTable")
Bastion.Class = Bastion.require("Class") Bastion.Class = Bastion.require("Bastion.Class")
Bastion.Timer = Bastion.require("Timer") Bastion.Timer = Bastion.require("Bastion.Timer")
Bastion.CombatTimer = Bastion.Timer:New("combat") Bastion.CombatTimer = Bastion.Timer:New("combat")
Bastion.MythicPlusUtils = Bastion.require("MythicPlusUtils"):New() Bastion.MythicPlusUtils = Bastion.require("Bastion.MythicPlusUtils"):New()
Bastion.Notifications = Bastion.NotificationsList:New() Bastion.Notifications = Bastion.NotificationList:New()
Bastion.Config = Bastion.require("Config") Bastion.Config = Bastion.require("Bastion.Config")
Bastion.TimeToDie = Bastion.require("TimeToDie") Bastion.TimeToDie = Bastion.require("Bastion.TimeToDie")
---@enum (key) CompareThisTable ---@enum (key) CompareThisTable
@ -150,14 +228,14 @@ Bastion.Utils = {
} }
local LIBRARIES = {} local LIBRARIES = {}
---@type Module[] ---@type Bastion.Module[]
local MODULES = {} local MODULES = {}
Bastion.Enabled = false Bastion.Enabled = false
Bastion.Globals.EventManager:RegisterWoWEvent("UNIT_AURA", function(unit, auras) Bastion.Globals.EventManager:RegisterWoWEvent("UNIT_AURA", function(unit, auras)
---@type Unit | nil ---@type Bastion.Unit | nil
local u = Bastion.UnitManager[unit] local u = Bastion.UnitManager:Get(unit)
if u then if u then
u:GetAuras():OnUpdate(auras) u:GetAuras():OnUpdate(auras)
@ -211,6 +289,8 @@ Bastion.Globals.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", fun
-- Log(tostring(args[i])) -- Log(tostring(args[i]))
-- end -- end
-- end -- end
--Bastion.UnitManager:SetCombatTime(sourceGUID)
--Bastion.UnitManager:SetCombatTime(destGUID)
local u = Bastion.UnitManager[sourceGUID] local u = Bastion.UnitManager[sourceGUID]
local u2 = Bastion.UnitManager[destGUID] local u2 = Bastion.UnitManager[destGUID]
@ -223,7 +303,6 @@ Bastion.Globals.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", fun
if u2 then if u2 then
u2:SetLastCombatTime(t) u2:SetLastCombatTime(t)
if subEvent == "SPELL_MISSED" and sourceGUID == pguid and spellID == 408 then if subEvent == "SPELL_MISSED" and sourceGUID == pguid and spellID == 408 then
local missType = args[15] local missType = args[15]
@ -385,7 +464,7 @@ Command:Register("missed", "Dump the list of immune kidney shot spells", functio
end end
end) end)
---@param library Library ---@param library Bastion.Library
function Bastion:RegisterLibrary(library) function Bastion:RegisterLibrary(library)
LIBRARIES[library.name] = library LIBRARIES[library.name] = library
end end

Loading…
Cancel
Save