Compare commits

...

10 Commits

Author SHA1 Message Date
João Fidalgo 6280196711 feat: add spell traits 4 months ago
4n0n c0c8ab8362 Fix? 6 months ago
4n0n fad3d76d8a 11.0 ItemName 6 months ago
4n0n e6b2b8f42f Merge pull request '11.0' (#27) from 4n0n/Bastion:main into main 6 months ago
4n0n 86e7aeccec 11.0 6 months ago
4n0n f9583a85d8 11.0 6 months ago
4n0n d0cad5746d 11.0 6 months ago
4n0n 010d2b4111 11.0 6 months ago
4n0n 7442498326 11.0 6 months ago
4n0n 83086a9b57 11.0 6 months ago
  1. 34
      src/Aura/Aura.lua
  2. 43
      src/Item/Item.lua
  3. 18
      src/MythicPlusUtils/MythicPlusUtils.lua
  4. 151
      src/Spell/Spell.lua
  5. 10
      src/SpellBook/SpellBook.lua
  6. 589
      src/_bastion.lua

@ -75,6 +75,40 @@ function Aura:New(unit, index, type)
return self
end
if C_UnitAuras.GetAuraDataByIndex then
local unitAuraInfo = C_UnitAuras.GetAuraDataByIndex(unit:GetOMToken(), index, type)
if not unitAuraInfo then
local self = setmetatable({}, Aura)
self.aura = {
name = nil,
icon = nil,
count = 0,
dispelType = nil,
duration = 0,
expirationTime = 0,
source = nil,
isStealable = false,
nameplateShowPersonal = false,
spellId = 0,
canApplyAura = false,
isBossDebuff = false,
castByPlayer = false,
nameplateShowAll = false,
timeMod = 0,
index = nil,
type = nil
}
if self.aura.spellId then
Bastion.Globals.SpellBook:GetSpell(self.aura.spellId)
end
return self
end
return Aura:CreateFromUnitAuraInfo(unitAuraInfo)
end
local name, icon, count, dispelType, duration, expirationTime, source, isStealable, nameplateShowPersonal, spellId,
canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, timeMod = UnitAura(unit:GetOMToken(), index, type)

@ -51,7 +51,13 @@ function Item:New(id)
self.ItemID = id
-- Register spell in spellbook
local name, spellID = GetItemSpell(self:GetID())
local name, spellID
if C_Item.GetItemSpell then
name, spellID = C_Item.GetItemSpell(self:GetID())
else
name, spellID = GetItemSpell(self:GetID())
end
if spellID then
self.spellID = spellID
Bastion.Globals.SpellBook:GetSpell(spellID)
@ -69,18 +75,27 @@ end
-- Get the Items name
---@return string
function Item:GetName()
if C_Item.GetItemInfo then
return C_Item.GetItemInfo(self:GetID())
end
return GetItemInfo(self:GetID())
end
-- Get the Items icon
---@return number
function Item:GetIcon()
if C_Item.GetItemIconByID then
return C_Item.GetItemIconByID(self:GetID())
end
return select(3, GetItemInfo(self:GetID()))
end
-- Get the Items cooldown
---@return number
function Item:GetCooldown()
if C_Item.GetItemCooldown then
return select(2, C_Item.GetItemCooldown(self:GetID()))
end
return select(2, C_Container.GetItemCooldown(self:GetID()))
end
@ -105,6 +120,10 @@ end
-- Get the Items cooldown remaining
---@return number
function Item:GetCooldownRemaining()
if C_Item.GetItemCooldown then
local start, duration = C_Item.GetItemCooldown(self:GetID())
return start + duration - GetTime()
end
local start, duration = C_Container.GetItemCooldown(self:GetID())
return start + duration - GetTime()
end
@ -131,7 +150,11 @@ function Item:Use(unit, condition)
self.wasLooking = IsMouselooking()
-- Use the Item
UseItemByName(self:GetName(), unit:GetOMToken())
if C_Item.UseItemByName then
C_Item.UseItemByName(self:GetName(), unit:GetOMToken())
else
UseItemByName(self:GetName(), unit:GetOMToken())
end
Bastion:Debug("Using", self)
@ -161,18 +184,28 @@ end
-- Check if the Item is known
---@return boolean
function Item:IsEquipped()
if C_Item.IsEquippedItem then
return C_Item.IsEquippedItem(self:GetID())
end
return IsEquippedItem(self:GetID())
end
-- Check if the Item is on cooldown
---@return boolean
function Item:IsOnCooldown()
if C_Item.GetItemCooldown then
return select(2, C_Item.GetItemCooldown(self:GetID())) > 0
end
return select(2, C_Container.GetItemCooldown(self:GetID())) > 0
end
-- Check if the Item is usable
---@return boolean
function Item:IsUsable()
if C_Item.IsUsableItem then
local usable, noMana = C_Item.IsUsableItem(self:GetID())
return usable or usableExcludes[self:GetID()]
end
local usable, noMana = IsUsableItem(self:GetID())
return usable or usableExcludes[self:GetID()]
end
@ -187,6 +220,9 @@ end
-- Is equippable
---@return boolean
function Item:IsEquippable()
if C_Item.IsEquippableItem then
return C_Item.IsEquippableItem(self:GetID())
end
return IsEquippableItem(self:GetID())
end
@ -317,6 +353,9 @@ end
-- Get the Items charges
---@return number
function Item:GetCharges()
if C_Item.GetItemCount then
return C_Item.GetItemCount(self:GetID())
end
return GetItemCharges(self:GetID())
end

@ -462,7 +462,14 @@ function MythicPlusUtils:New()
return
end
local name = GetSpellInfo(spellID)
local name
if C_Spell.GetSpellInfo then
local info = C_Spell.GetSpellInfo(spellID)
name = info and info.name or ''
else
name = GetSpellInfo(spellID)
end
self.loggedCasts[spellID] = true
@ -481,7 +488,14 @@ function MythicPlusUtils:New()
return
end
local name = GetSpellInfo(spellID)
local name
if C_Spell.GetSpellInfo then
local info = C_Spell.GetSpellInfo(spellID)
name = info and info.name or ''
else
name = GetSpellInfo(spellID)
end
self.loggedCasts[spellID] = true

@ -12,7 +12,15 @@ local Spell = {
lastCastAt = false,
conditions = {},
target = false,
release_at = false
release_at = false,
traits = {
ignoreChanneling = false,
ignoreFacing = false,
ignoreLoS = false,
ignoreGCD = false,
ignoreMoving = false,
targeted = false
}
}
local usableExcludes = {
@ -48,12 +56,20 @@ end
-- Constructor
---@param id number
---@param traits? table
---@return Spell
function Spell:New(id)
function Spell:New(id, traits)
local self = setmetatable({}, Spell)
self.spellID = id
if traits == nil then traits = {} end
for k in pairs(traits) do
if self.traits[k] ~= nil and traits[k] ~= nil then
self.traits[k] = traits[k]
end
end
return self
end
@ -80,24 +96,53 @@ end
-- Get the spells name
---@return string
function Spell:GetName()
if C_Spell.GetSpellInfo then
local info = C_Spell.GetSpellInfo(self:GetID())
return info and info.name or nil
end
return GetSpellInfo(self:GetID())
end
-- Get the spells icon
---@return number
function Spell:GetIcon()
if C_Spell.GetSpellInfo then
local info = C_Spell.GetSpellInfo(self:GetID())
return info and info.iconID or nil
end
return select(3, GetSpellInfo(self:GetID()))
end
-- Get the spells cooldown
---@return number
function Spell:GetCooldown()
if C_Spell.GetSpellCooldown then
local info = C_Spell.GetSpellCooldown(self:GetID())
return info and info.duration or nil
end
return select(2, GetSpellCooldown(self:GetID()))
end
-- Get the full cooldown (time until all charges are available)
---@return number
function Spell:GetFullRechargeTime()
if C_Spell.GetSpellCooldown then
local info = C_Spell.GetSpellCooldown(self:GetID())
if info.isEnabled == 0 then
return 0
end
local chargeInfo = C_Spell.GetSpellCharges(self:GetID())
if chargeInfo.currentCharges == chargeInfo.maxCharges then
return 0
end
if chargeInfo.currentCharges == 0 then
return info.startTime + info.duration - GetTime()
end
return chargeInfo.cooldownStartTime + chargeInfo.cooldownDuration - GetTime()
end
local start, duration, enabled = GetSpellCooldown(self:GetID())
if enabled == 0 then
return 0
@ -136,6 +181,10 @@ end
-- Get the spells cooldown remaining
---@return number
function Spell:GetCooldownRemaining()
if C_Spell.GetSpellCooldown then
local info = C_Spell.GetSpellCooldown(self:GetID())
return info and info.startTime + info.duration - GetTime() or nil
end
local start, duration = GetSpellCooldown(self:GetID())
return start + duration - GetTime()
end
@ -143,6 +192,9 @@ end
-- Get the spell count
---@return number
function Spell:GetCount()
if C_Spell.GetSpellCastCount then
return C_Spell.GetSpellCastCount(self:GetID())
end
return GetSpellCount(self:GetID())
end
@ -252,6 +304,8 @@ end
-- Check if the spell is known
---@return boolean
function Spell:IsKnown()
local IsSpellKnown = C_Spell.IsSpellKnown and C_Spell.IsSpellKnown or IsSpellKnown
local IsPlayerSpell = C_Spell.IsPlayerSpell and C_Spell.IsPlayerSpell or IsPlayerSpell
local isKnown = IsSpellKnown(self:GetID())
local isPlayerSpell = IsPlayerSpell(self:GetID())
return isKnown or isPlayerSpell
@ -260,12 +314,20 @@ end
-- Check if the spell is on cooldown
---@return boolean
function Spell:IsOnCooldown()
if C_Spell.GetSpellCooldown then
local info = C_Spell.GetSpellCooldown(self:GetID())
return info and info.duration > 0
end
return select(2, GetSpellCooldown(self:GetID())) > 0
end
-- Check if the spell is usable
---@return boolean
function Spell:IsUsable()
if C_Spell.IsSpellUsable then
local usable, noMana = C_Spell.IsSpellUsable(self:GetID())
return usable or usableExcludes[self:GetID()] and not noMana
end
local usable, noMana = IsUsableSpell(self:GetID())
return usable or usableExcludes[self:GetID()] and not noMana
end
@ -283,7 +345,44 @@ function Spell:Castable()
return self:GetCastableFunction()(self)
end
return self:IsKnownAndUsable()
if not self:IsKnownAndUsable() then return false end
local player = Bastion.UnitManager:Get("player")
if self.traits.targeted then
local target = self:GetTarget()
if not target or
not target:Exists() then return false end
if not self:IsInRange(target) then return false end
if not self.traits.ignoreFacing then
if not player:IsFacing(target) then return false end
end
if not self.traits.ignoreLoS then
if not player:CanSee(target) then return false end
end
end
if not self.traits.ignoreCasting then
if player:IsCasting() then return false end
end
if not self.traits.ignoreChanneling then
if player:IsChanneling() then return false end
end
if not self.traits.ignoreGCD then
if player:GetGCD() > C_Spell.GetSpellQueueWindow() then return false end
end
if not self.traits.ignoreMoving then
if self:GetCastLength() > 0 and player:IsMoving() then return false end
end
return true
end
-- Set a script to check if the spell is castable
@ -350,6 +449,9 @@ end
-- Check if the spell is castable and cast it
---@return boolean
function Spell:HasRange()
if C_Spell.SpellHasRange then
return C_Spell.SpellHasRange(self:GetID())
end
return SpellHasRange(self:GetName())
end
@ -357,6 +459,10 @@ end
---@return number
---@return number
function Spell:GetRange()
if C_Spell.GetSpellInfo then
local info = C_Spell.GetSpellInfo(self:GetID())
return info and info.minRange or nil, info and info.maxRange or nil
end
local name, rank, icon, castTime, minRange, maxRange, spellID, originalIcon = GetSpellInfo(self:GetID())
return maxRange, minRange
end
@ -365,6 +471,7 @@ end
---@param unit Unit
---@return boolean
function Spell:IsInRange(unit)
local IsSpellInRange = C_Spell.IsSpellInRange and C_Spell.IsSpellInRange or IsSpellInRange
local hasRange = self:HasRange()
local inRange = IsSpellInRange(self:GetName(), unit:GetOMToken())
@ -406,20 +513,50 @@ end
-- Get the spells charges
---@return number
function Spell:GetCharges()
if C_Spell.GetSpellCharges then
local info = C_Spell.GetSpellCharges(self:GetID())
return info and info.currentCharges or nil
end
return GetSpellCharges(self:GetID())
end
function Spell:GetMaxCharges()
if C_Spell.GetSpellCharges then
local info = C_Spell.GetSpellCharges(self:GetID())
return info and info.maxCharges or nil
end
return select(2, GetSpellCharges(self:GetID()))
end
function Spell:GetCastLength()
if C_Spell.GetSpellInfo then
local info = C_Spell.GetSpellInfo(self:GetID())
return info and info.castTime or nil
end
return select(4, GetSpellInfo(self:GetID()))
end
-- Get the spells charges
---@return number
function Spell:GetChargesFractional()
if C_Spell.GetSpellCharges then
local info = C_Spell.GetSpellCharges(self:GetID())
if info.currentCharges == info.maxCharges then
return info.maxCharges
end
if info.currentCharges == 0 then
return 0
end
local timeSinceStart = GetTime() - info.cooldownStartTime
local timeLeft = info.cooldownDuration - timeSinceStart
local timePerCharge = info.cooldownDuration / info.maxCharges
local chargesFractional = info.currentCharges + (timeLeft / timePerCharge)
return chargesFractional
end
local charges, maxCharges, start, duration = GetSpellCharges(self:GetID())
if charges == maxCharges then
@ -441,6 +578,10 @@ end
-- Get the spells charges remaining
---@return number
function Spell:GetChargesRemaining()
if C_Spell.GetSpellCharges then
local info = C_Spell.GetSpellCharges(self:GetID())
return info and info.currentCharges or nil
end
local charges, maxCharges, start, duration = GetSpellCharges(self:GetID())
return charges
end
@ -546,6 +687,10 @@ end
-- GetCost
---@return number
function Spell:GetCost()
if C_Spell.GetSpellPowerCost then
local info = C_Spell.GetSpellPowerCost(self:GetID())
return info and info.cost or 0
end
local cost = GetSpellPowerCost(self:GetID())
return cost and cost.cost or 0
end

@ -14,10 +14,12 @@ function SpellBook:New()
end
-- Get a spell from the spellbook
---@param id number
---@param traits? table
---@return Spell
function SpellBook:GetSpell(id)
function SpellBook:GetSpell(id, traits)
if self.spells[id] == nil then
self.spells[id] = Bastion.Spell:New(id)
self.spells[id] = Bastion.Spell:New(id, traits)
end
return self.spells[id]
@ -48,6 +50,10 @@ end
---@param name string
---@return Spell
function SpellBook:GetSpellByName(name)
if C_Spell.GetSpellInfo then
local info = C_Spell.GetSpellInfo(name)
return self:GetSpell(info.spellID)
end
local _, rank, icon, castTime, minRange, maxRange, spellID, originalIcon = GetSpellInfo(name)
return self:GetSpell(spellID)
end

@ -1,9 +1,9 @@
local Tinkr = ...
local Evaulator = Tinkr.Evaluator
---@class Bastion
local Bastion = {
DebugMode = false
}
local Bastion = {DebugMode = false}
Bastion.__index = Bastion
function Bastion:Require(file)
@ -50,348 +50,363 @@ function Bastion.require(class)
return Bastion:Require("~/src/" .. class .. "/" .. class)
end
Bastion.Globals = {}
---@type ClassMagic
Bastion.ClassMagic = Bastion.require("ClassMagic")
---@type List
Bastion.List = Bastion.require("List")
---@type Library
Bastion.Library = Bastion.require("Library")
---@type NotificationsList, Notification
Bastion.NotificationsList, Bastion.Notification = Bastion.require("NotificationsList")
---@type Vector3
Bastion.Vector3 = Bastion.require("Vector3")
---@type Sequencer
Bastion.Sequencer = Bastion.require("Sequencer")
---@type Command
Bastion.Command = Bastion.require("Command")
---@type Cache
Bastion.Cache = Bastion.require("Cache")
---@type Cacheable
Bastion.Cacheable = Bastion.require("Cacheable")
---@type Refreshable
Bastion.Refreshable = Bastion.require("Refreshable")
---@type Unit
Bastion.Unit = Bastion.require("Unit")
---@type Aura
Bastion.Aura = Bastion.require("Aura")
---@type APL, APLActor, APLTrait
Bastion.APL, Bastion.APLActor, Bastion.APLTrait = Bastion.require("APL")
---@type Module
Bastion.Module = Bastion.require("Module")
---@type UnitManager
Bastion.UnitManager = Bastion.require("UnitManager"):New()
---@type ObjectManager
Bastion.ObjectManager = Bastion.require("ObjectManager"):New()
---@type EventManager
Bastion.EventManager = Bastion.require("EventManager")
Bastion.Globals.EventManager = Bastion.EventManager:New()
---@type Spell
Bastion.Spell = Bastion.require("Spell")
---@type SpellBook
Bastion.SpellBook = Bastion.require("SpellBook")
Bastion.Globals.SpellBook = Bastion.SpellBook:New()
---@type Item
Bastion.Item = Bastion.require("Item")
---@type ItemBook
Bastion.ItemBook = Bastion.require("ItemBook")
Bastion.Globals.ItemBook = Bastion.ItemBook:New()
---@type AuraTable
Bastion.AuraTable = Bastion.require("AuraTable")
---@type Class
Bastion.Class = Bastion.require("Class")
---@type Timer
Bastion.Timer = Bastion.require("Timer")
---@type Timer
Bastion.CombatTimer = Bastion.Timer:New('combat')
---@type MythicPlusUtils
Bastion.MythicPlusUtils = Bastion.require("MythicPlusUtils"):New()
---@type NotificationsList
Bastion.Notifications = Bastion.NotificationsList:New()
local LIBRARIES = {}
local MODULES = {}
Bastion.Enabled = false
Bastion.Globals.EventManager:RegisterWoWEvent('UNIT_AURA', function(unit, auras)
local u = Bastion.UnitManager[unit]
if u then
u:GetAuras():OnUpdate(auras)
end
end)
Bastion.Globals.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", function(...)
local unit, castGUID, spellID = ...
local spell = Bastion.Globals.SpellBook:GetIfRegistered(spellID)
if unit == "player" and spell then
spell.lastCastAt = GetTime()
if spell:GetPostCastFunction() then
spell:GetPostCastFunction()(spell)
-- fenv for all required files
function Bastion.Bootstrap()
Bastion.Globals = {}
---@type ClassMagic
Bastion.ClassMagic = Bastion.require("ClassMagic")
---@type List
Bastion.List = Bastion.require("List")
---@type Library
Bastion.Library = Bastion.require("Library")
---@type NotificationsList, Notification
Bastion.NotificationsList, Bastion.Notification = Bastion.require(
"NotificationsList")
---@type Vector3
Bastion.Vector3 = Bastion.require("Vector3")
---@type Sequencer
Bastion.Sequencer = Bastion.require("Sequencer")
---@type Command
Bastion.Command = Bastion.require("Command")
---@type Cache
Bastion.Cache = Bastion.require("Cache")
---@type Cacheable
Bastion.Cacheable = Bastion.require("Cacheable")
---@type Refreshable
Bastion.Refreshable = Bastion.require("Refreshable")
---@type Unit
Bastion.Unit = Bastion.require("Unit")
---@type Aura
Bastion.Aura = Bastion.require("Aura")
---@type APL, APLActor, APLTrait
Bastion.APL, Bastion.APLActor, Bastion.APLTrait = Bastion.require("APL")
---@type Module
Bastion.Module = Bastion.require("Module")
---@type UnitManager
Bastion.UnitManager = Bastion.require("UnitManager"):New()
---@type ObjectManager
Bastion.ObjectManager = Bastion.require("ObjectManager"):New()
---@type EventManager
Bastion.EventManager = Bastion.require("EventManager")
Bastion.Globals.EventManager = Bastion.EventManager:New()
---@type Spell
Bastion.Spell = Bastion.require("Spell")
---@type SpellBook
Bastion.SpellBook = Bastion.require("SpellBook")
Bastion.Globals.SpellBook = Bastion.SpellBook:New()
---@type Item
Bastion.Item = Bastion.require("Item")
---@type ItemBook
Bastion.ItemBook = Bastion.require("ItemBook")
Bastion.Globals.ItemBook = Bastion.ItemBook:New()
---@type AuraTable
Bastion.AuraTable = Bastion.require("AuraTable")
---@type Class
Bastion.Class = Bastion.require("Class")
---@type Timer
Bastion.Timer = Bastion.require("Timer")
---@type Timer
Bastion.CombatTimer = Bastion.Timer:New('combat')
---@type MythicPlusUtils
Bastion.MythicPlusUtils = Bastion.require("MythicPlusUtils"):New()
---@type NotificationsList
Bastion.Notifications = Bastion.NotificationsList:New()
local LIBRARIES = {}
local MODULES = {}
Bastion.Enabled = false
Bastion.Globals.EventManager:RegisterWoWEvent('UNIT_AURA',
function(unit, auras)
local u = Bastion.UnitManager[unit]
if u then u:GetAuras():OnUpdate(auras) end
end)
Bastion.Globals.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED",
function(...)
local unit, castGUID, spellID = ...
local spell = Bastion.Globals.SpellBook:GetIfRegistered(spellID)
if unit == "player" and spell then
spell.lastCastAt = GetTime()
if spell:GetPostCastFunction() then
spell:GetPostCastFunction()(spell)
end
end
end
end)
end)
local pguid = UnitGUID("player")
local missed = {}
local pguid = UnitGUID("player")
local missed = {}
Bastion.Globals.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function()
local args = {CombatLogGetCurrentEventInfo()}
Bastion.Globals.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED",
function()
local args = {CombatLogGetCurrentEventInfo()}
local subEvent = args[2]
local sourceGUID = args[4]
local destGUID = args[8]
local spellID = args[12]
local subEvent = args[2]
local sourceGUID = args[4]
local destGUID = args[8]
local spellID = args[12]
-- if sourceGUID == pguid then
-- local args = { CombatLogGetCurrentEventInfo() }
-- if sourceGUID == pguid then
-- local args = { CombatLogGetCurrentEventInfo() }
-- for i = 1, #args do
-- Log(tostring(args[i]))
-- end
-- end
-- for i = 1, #args do
-- Log(tostring(args[i]))
-- end
-- end
local u = Bastion.UnitManager[sourceGUID]
local u2 = Bastion.UnitManager[destGUID]
local u = Bastion.UnitManager[sourceGUID]
local u2 = Bastion.UnitManager[destGUID]
local t = GetTime()
local t = GetTime()
if u then
u:SetLastCombatTime(t)
end
if u then u:SetLastCombatTime(t) end
if u2 then
u2:SetLastCombatTime(t)
if u2 then
u2:SetLastCombatTime(t)
if subEvent == "SPELL_MISSED" and sourceGUID == pguid and spellID == 408 then
local missType = args[15]
if subEvent == "SPELL_MISSED" and sourceGUID == pguid and spellID ==
408 then
local missType = args[15]
if missType == "IMMUNE" then
local castingSpell = u:GetCastingOrChannelingSpell()
if missType == "IMMUNE" then
local castingSpell = u:GetCastingOrChannelingSpell()
if castingSpell then
if not missed[castingSpell:GetID()] then
missed[castingSpell:GetID()] = true
if castingSpell then
if not missed[castingSpell:GetID()] then
missed[castingSpell:GetID()] = true
end
end
end
end
end
end
end)
end)
Bastion.Ticker = C_Timer.NewTicker(0.1, function()
if not Bastion.CombatTimer:IsRunning() and UnitAffectingCombat("player") then
Bastion.CombatTimer:Start()
elseif Bastion.CombatTimer:IsRunning() and
not UnitAffectingCombat("player") then
Bastion.CombatTimer:Reset()
end
Bastion.Ticker = C_Timer.NewTicker(0.1, function()
if not Bastion.CombatTimer:IsRunning() and UnitAffectingCombat("player") then
Bastion.CombatTimer:Start()
elseif Bastion.CombatTimer:IsRunning() and not UnitAffectingCombat("player") then
Bastion.CombatTimer:Reset()
if Bastion.Enabled then
Bastion.ObjectManager:Refresh()
for i = 1, #MODULES do MODULES[i]:Tick() end
end
end)
function Bastion:Register(module)
table.insert(MODULES, module)
Bastion:Print("Registered", module)
end
if Bastion.Enabled then
Bastion.ObjectManager:Refresh()
-- Find a module by name
function Bastion:FindModule(name)
for i = 1, #MODULES do
MODULES[i]:Tick()
if MODULES[i].name == name then return MODULES[i] end
end
end
end)
function Bastion:Register(module)
table.insert(MODULES, module)
Bastion:Print("Registered", module)
end
-- Find a module by name
function Bastion:FindModule(name)
for i = 1, #MODULES do
if MODULES[i].name == name then
return MODULES[i]
end
return nil
end
return nil
end
function Bastion:Print(...)
local args = {...}
local str = "|cFFDF362D[Bastion]|r |cFFFFFFFF"
for i = 1, #args do
str = str .. tostring(args[i]) .. " "
function Bastion:Print(...)
local args = {...}
local str = "|cFFDF362D[Bastion]|r |cFFFFFFFF"
for i = 1, #args do str = str .. tostring(args[i]) .. " " end
print(str)
end
print(str)
end
function Bastion:Debug(...)
if not Bastion.DebugMode then
return
end
local args = {...}
local str = "|cFFDF6520[Bastion]|r |cFFFFFFFF"
for i = 1, #args do
str = str .. tostring(args[i]) .. " "
function Bastion:Debug(...)
if not Bastion.DebugMode then return end
local args = {...}
local str = "|cFFDF6520[Bastion]|r |cFFFFFFFF"
for i = 1, #args do str = str .. tostring(args[i]) .. " " end
print(str)
end
print(str)
end
local Command = Bastion.Command:New('bastion')
local Command = Bastion.Command:New('bastion')
Command:Register('toggle', 'Toggle bastion on/off', function()
Bastion.Enabled = not Bastion.Enabled
if Bastion.Enabled then
Bastion:Print("Enabled")
else
Bastion:Print("Disabled")
end
end)
Command:Register('toggle', 'Toggle bastion on/off', function()
Bastion.Enabled = not Bastion.Enabled
if Bastion.Enabled then
Bastion:Print("Enabled")
else
Bastion:Print("Disabled")
end
end)
Command:Register('debug', 'Toggle debug mode on/off', function()
Bastion.DebugMode = not Bastion.DebugMode
if Bastion.DebugMode then
Bastion:Print("Debug mode enabled")
else
Bastion:Print("Debug mode disabled")
end
end)
Command:Register('dumpspells', 'Dump spells to a file', function()
local i = 1
local rand = math.random(100000, 999999)
while true do
local spellName, spellSubName = GetSpellBookItemName(i, BOOKTYPE_SPELL)
if not spellName then
do
break
end
Command:Register('debug', 'Toggle debug mode on/off', function()
Bastion.DebugMode = not Bastion.DebugMode
if Bastion.DebugMode then
Bastion:Print("Debug mode enabled")
else
Bastion:Print("Debug mode disabled")
end
end)
Command:Register('dumpspells', 'Dump spells to a file', function()
local i = 1
local rand = math.random(100000, 999999)
local BOOKTYPE_SPELL = BOOKTYPE_SPELL or (Enum.SpellBookSpellBank.Player and Enum.SpellBookSpellBank.Player or 'spell')
while true do
local spellName, spellSubName
if C_SpellBook.GetSpellBookItemName then
spellName, spellSubName = C_SpellBook.GetSpellBookItemName(i, BOOKTYPE_SPELL)
else
spellName, spellSubName = GetSpellBookItemName(i, BOOKTYPE_SPELL)
end
if not spellName then do break end end
-- use spellName and spellSubName here
local spellID = select(7, GetSpellInfo(spellName))
-- use spellName and spellSubName here
local spellID
if spellID then
spellName = spellName:gsub("[%W%s]", "")
WriteFile('bastion-' .. UnitClass('player') .. '-' .. rand .. '.lua',
"local " .. spellName .. " = Bastion.Globals.SpellBook:GetSpell(" .. spellID .. ")\n", true)
if C_Spell.GetSpellInfo then
local info = C_Spell.GetSpellInfo(spellName)
spellID = info.spellID
else
spellID = select(7, GetSpellInfo(spellName))
end
if spellID then
spellName = spellName:gsub("[%W%s]", "")
WriteFile('bastion-' .. UnitClass('player') .. '-' .. rand ..
'.lua',
"local " .. spellName ..
" = Bastion.Globals.SpellBook:GetSpell(" ..
spellID .. ")\n", true)
end
i = i + 1
end
i = i + 1
end
end)
Command:Register('module', 'Toggle a module on/off', function(args)
local module = Bastion:FindModule(args[2])
if module then
module:Toggle()
if module.enabled then
Bastion:Print("Enabled", module.name)
end)
Command:Register('module', 'Toggle a module on/off', function(args)
local module = Bastion:FindModule(args[2])
if module then
module:Toggle()
if module.enabled then
Bastion:Print("Enabled", module.name)
else
Bastion:Print("Disabled", module.name)
end
else
Bastion:Print("Disabled", module.name)
Bastion:Print("Module not found")
end
end)
Command:Register('mplus', 'Toggle m+ module on/off', function(args)
local cmd = args[2]
if cmd == 'debuffs' then
Bastion.MythicPlusUtils:ToggleDebuffLogging()
Bastion:Print("Debuff logging", Bastion.MythicPlusUtils
.debuffLogging and "enabled" or "disabled")
return
end
else
Bastion:Print("Module not found")
end
end)
Command:Register('mplus', 'Toggle m+ module on/off', function(args)
local cmd = args[2]
if cmd == 'debuffs' then
Bastion.MythicPlusUtils:ToggleDebuffLogging()
Bastion:Print("Debuff logging", Bastion.MythicPlusUtils.debuffLogging and "enabled" or "disabled")
return
end
if cmd == 'casts' then
Bastion.MythicPlusUtils:ToggleCastLogging()
Bastion:Print("Cast logging", Bastion.MythicPlusUtils.castLogging and "enabled" or "disabled")
return
end
if cmd == 'casts' then
Bastion.MythicPlusUtils:ToggleCastLogging()
Bastion:Print("Cast logging",
Bastion.MythicPlusUtils.castLogging and "enabled" or
"disabled")
return
end
Bastion:Print("[MythicPlusUtils] Unknown command")
Bastion:Print("Available commands:")
Bastion:Print("debuffs")
Bastion:Print("casts")
end)
Bastion:Print("[MythicPlusUtils] Unknown command")
Bastion:Print("Available commands:")
Bastion:Print("debuffs")
Bastion:Print("casts")
end)
Command:Register('missed', 'Dump the list of immune kidney shot spells', function()
for k, v in pairs(missed) do
Bastion:Print(k)
end
end)
Command:Register('missed', 'Dump the list of immune kidney shot spells',
function()
for k, v in pairs(missed) do Bastion:Print(k) end
end)
---@param library Library
function Bastion:RegisterLibrary(library)
LIBRARIES[library.name] = library
end
---@param library Library
function Bastion:RegisterLibrary(library)
LIBRARIES[library.name] = library
end
function Bastion:CheckLibraryDependencies()
for k, v in pairs(LIBRARIES) do
if v.dependencies then
for i = 1, #v.dependencies do
local dep = v.dependencies[i]
if LIBRARIES[dep] then
if LIBRARIES[dep].dependencies then
for j = 1, #LIBRARIES[dep].dependencies do
if LIBRARIES[dep].dependencies[j] == v.name then
Bastion:Print("Circular dependency detected between " .. v.name .. " and " .. dep)
return false
function Bastion:CheckLibraryDependencies()
for k, v in pairs(LIBRARIES) do
if v.dependencies then
for i = 1, #v.dependencies do
local dep = v.dependencies[i]
if LIBRARIES[dep] then
if LIBRARIES[dep].dependencies then
for j = 1, #LIBRARIES[dep].dependencies do
if LIBRARIES[dep].dependencies[j] == v.name then
Bastion:Print(
"Circular dependency detected between " ..
v.name .. " and " .. dep)
return false
end
end
end
else
Bastion:Print("Library " .. v.name .. " depends on " ..
dep .. " but it's not registered")
return false
end
else
Bastion:Print("Library " .. v.name .. " depends on " .. dep .. " but it's not registered")
return false
end
end
end
return true
end
return true
end
function Bastion:Import(library)
local lib = self:GetLibrary(library)
function Bastion:Import(library)
local lib = self:GetLibrary(library)
if not lib then error("Library " .. library .. " not found") end
if not lib then
error("Library " .. library .. " not found")
return lib:Resolve()
end
return lib:Resolve()
end
function Bastion:GetLibrary(name)
if not LIBRARIES[name] then
error("Library " .. name .. " not found")
end
function Bastion:GetLibrary(name)
if not LIBRARIES[name] then
error("Library " .. name .. " not found")
local library = LIBRARIES[name]
-- if library.dependencies then
-- for i = 1, #library.dependencies do
-- local dep = library.dependencies[i]
-- if LIBRARIES[dep] then
-- if LIBRARIES[dep].dependencies then
-- for j = 1, #LIBRARIES[dep].dependencies do
-- if LIBRARIES[dep].dependencies[j] == library.name then
-- Bastion:Print("Circular dependency detected between " .. library.name .. " and " .. dep)
-- return false
-- end
-- end
-- end
-- else
-- Bastion:Print("Library " .. v.name .. " depends on " .. dep .. " but it's not registered")
-- return false
-- end
-- end
-- end
return library
end
local library = LIBRARIES[name]
-- if library.dependencies then
-- for i = 1, #library.dependencies do
-- local dep = library.dependencies[i]
-- if LIBRARIES[dep] then
-- if LIBRARIES[dep].dependencies then
-- for j = 1, #LIBRARIES[dep].dependencies do
-- if LIBRARIES[dep].dependencies[j] == library.name then
-- Bastion:Print("Circular dependency detected between " .. library.name .. " and " .. dep)
-- return false
-- end
-- end
-- end
-- else
-- Bastion:Print("Library " .. v.name .. " depends on " .. dep .. " but it's not registered")
-- return false
-- end
-- end
-- if not Bastion:CheckLibraryDependencies() then
-- return
-- end
return library
Load("@Libraries/")
Load("@Modules/")
Load("@")
end
-- if not Bastion:CheckLibraryDependencies() then
-- return
-- end
Load("@Libraries/")
Load("@Modules/")
Load("@")
Bastion.Bootstrap()

Loading…
Cancel
Save