diff --git a/.gitignore b/.gitignore index 87e8f31..8cc8bf7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,11 @@ DS_Store ## ignore all files in scripts scripts/* +!scripts/Libraries +scripts/Libraries/* !scripts/.gitkeep +!scripts/ExampleModule.lua +!scripts/Libraries/ExampleLibrary.lua ## ignore vscode settings .vscode/* diff --git a/scripts/ExampleModule.lua b/scripts/ExampleModule.lua new file mode 100644 index 0000000..e659bb7 --- /dev/null +++ b/scripts/ExampleModule.lua @@ -0,0 +1,17 @@ +local Tinkr, Bastion = ... +local ExampleModule = Bastion.Module:New('ExampleModule') +local Player = Bastion.UnitManager:Get('player') + +local FlashHeal = Bastion.SpellBook:GetSpell(2061) + +local AdvancedMath = Bastion:GetLibrary('AdvancedMath') + +print(AdvancedMath:Add(1, 2)) + +ExampleModule:Sync(function() + if Player:GetHP() <= 50 then + FlashHeal:Cast(Player) + end +end) + +Bastion:Register(ExampleModule) diff --git a/scripts/Libraries/ExampleLibrary.lua b/scripts/Libraries/ExampleLibrary.lua new file mode 100644 index 0000000..15a4a36 --- /dev/null +++ b/scripts/Libraries/ExampleLibrary.lua @@ -0,0 +1,14 @@ +local Tinkr, Bastion = ... + +local ExampleModule = Bastion.Module:New('ExampleModule') +local Player = Bastion.UnitManager:Get('player') + +local AdvancedMath = {} + +AdvancedMath.__index = AdvancedMath + +function AdvancedMath:Add(a, b) + return a + b +end + +Bastion:RegisterLibrary('AdvancedMath', AdvancedMath) diff --git a/src/APL/APL.lua b/src/APL/APL.lua index d5f4fd2..95d2ebe 100644 --- a/src/APL/APL.lua +++ b/src/APL/APL.lua @@ -206,7 +206,7 @@ end -- Add a spell to the APL ---@param spell Spell ----@param condition fun(...):boolean +---@param condition? fun(...):boolean ---@return APLActor function APL:AddSpell(spell, condition) local castableFunc = spell.CastableIfFunc diff --git a/src/AuraTable/AuraTable.lua b/src/AuraTable/AuraTable.lua index 28239d7..5329d88 100644 --- a/src/AuraTable/AuraTable.lua +++ b/src/AuraTable/AuraTable.lua @@ -275,7 +275,6 @@ function AuraTable:Find(spell) end for k, a in pairs(aurasub) do - print(a) if a ~= nil then if a:IsUp() then -- Handle expired and non refreshed dropoffs not coming in UNIT_AURA return a diff --git a/src/List/List.lua b/src/List/List.lua index f7bb988..421567f 100644 --- a/src/List/List.lua +++ b/src/List/List.lua @@ -90,9 +90,9 @@ function List:each(callback) end ---@param callback fun(value: any): boolean ----@return boolean +---@return List function List:map(callback) - local newList = List.new() + local newList = List:New() for _, v in ipairs(self._list) do newList:push(callback(v)) end @@ -100,9 +100,9 @@ function List:map(callback) end ---@param callback fun(value: any): boolean ----@return boolean +---@return List function List:filter(callback) - local newList = List.new() + local newList = List:New() for _, v in ipairs(self._list) do if callback(v) then newList:push(v) @@ -111,7 +111,7 @@ function List:filter(callback) return newList end ----@param callback fun(value: any): boolean +---@param callback fun(result: any, value: any): boolean ---@param initialValue any ---@return boolean function List:reduce(callback, initialValue) @@ -152,7 +152,7 @@ end ---@return List function List:reverse() - local newList = List.new() + local newList = List:New() for i = #self._list, 1, -1 do newList:push(self._list[i]) end @@ -161,7 +161,7 @@ end ---@return List function List:clone() - local newList = List.new() + local newList = List:New() for _, v in ipairs(self._list) do newList:push(v) end @@ -171,7 +171,7 @@ end ---@param list List ---@return List function List:concat(list) - local newList = List.new() + local newList = List:New() for _, v in ipairs(self._list) do newList:push(v) end diff --git a/src/Sequencer/Sequencer.lua b/src/Sequencer/Sequencer.lua index a44004d..bb688e3 100644 --- a/src/Sequencer/Sequencer.lua +++ b/src/Sequencer/Sequencer.lua @@ -1,6 +1,9 @@ -- Create a sequencer class that takes a table of actions and executes them in order ---@class Sequencer +---@field resetCondition fun(): boolean +---@field abortCondition fun(): boolean +---@field actions fun(sequencer: Sequencer)[] local Sequencer = {} Sequencer.__index = Sequencer diff --git a/src/Unit/Unit.lua b/src/Unit/Unit.lua index 07182b0..400cb9c 100644 --- a/src/Unit/Unit.lua +++ b/src/Unit/Unit.lua @@ -1125,6 +1125,25 @@ function Unit:IsWithinCone(Target, Angle, Distance, rotation) return diff <= Angle and self:GetDistance(Target) <= Distance end +function Unit:GetEmpoweredStage() + local stage = 0 + local _, _, _, startTime, _, _, _, spellID, _, numStages = UnitChannelInfo(self:GetOMToken()) + + if numStages and numStages > 0 then + startTime = startTime / 1000 + local currentTime = GetTime() + local stageDuration = 0 + for i = 1, numStages do + stageDuration = stageDuration + GetUnitEmpowerStageDuration((self:GetOMToken()), i - 1) / 1000 + if startTime + stageDuration > currentTime then + break + end + stage = i + end + end + return stage +end + -- local empowering = {} -- Bastion.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_EMPOWER_START", function(...) diff --git a/src/UnitManager/UnitManager.lua b/src/UnitManager/UnitManager.lua index 8c71176..16743aa 100644 --- a/src/UnitManager/UnitManager.lua +++ b/src/UnitManager/UnitManager.lua @@ -153,7 +153,7 @@ end -- Set a unit by guid ---@param unit Unit ----@return Unit +---@return nil function UnitManager:SetObject(unit) self.objects[unit:GetGUID()] = unit end @@ -224,6 +224,7 @@ function UnitManager:GetNumFriendsWithBuff(spell) if unit:GetAuras():FindMy(spell):IsUp() then count = count + 1 end + return false end) return count end @@ -236,6 +237,7 @@ function UnitManager:GetNumFriendsAlive() if unit:IsAlive() then count = count + 1 end + return false end) return count end @@ -255,6 +257,7 @@ function UnitManager:GetFriendWithMostFriends(radius) if other:IsAlive() and u:GetDistance(other) <= radius then c = c + 1 end + return false end) if c > count then unit = u @@ -264,9 +267,11 @@ function UnitManager:GetFriendWithMostFriends(radius) if other:IsAlive() and u:GetDistance(other) <= radius then table.insert(friends, other) end + return false end) end end + return false end) return unit, friends end @@ -283,6 +288,7 @@ function UnitManager:GetEnemiesWithMostEnemies(radius) if other:IsAlive() and u:GetDistance(other) <= radius then c = c + 1 end + return false end) if c > count then unit = u @@ -292,9 +298,11 @@ function UnitManager:GetEnemiesWithMostEnemies(radius) if other:IsAlive() and u:GetDistance(other) <= radius then table.insert(enemies, other) end + return false end) end end + return false end) return unit, enemies end diff --git a/src/Vector3/Vector3.lua b/src/Vector3/Vector3.lua index 878c888..433cb95 100644 --- a/src/Vector3/Vector3.lua +++ b/src/Vector3/Vector3.lua @@ -1,7 +1,7 @@ -- Create a Vector3 class ---@class Vector3 -local Vector3 = {} +local Vector3 = { } Vector3.__index = Vector3 ---@return string @@ -69,87 +69,129 @@ function Vector3:__index(k) return Vector3[k] end + ---@class Vector3 + ---@field length number if k == "length" then return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z) end + ---@class Vector3 + ---@field normalized Vector3 if k == "normalized" then 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) end + ---@class Vector3 + ---@field magnitude number if k == "magnitude" then return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z) end + ---@class Vector3 + ---@field sqrMagnitude number if k == "sqrMagnitude" then return self.x * self.x + self.y * self.y + self.z * self.z end + ---@class Vector3 + ---@field zero Vector3 if k == "zero" then return Vector3:New(0, 0, 0) end + ---@class Vector3 + ---@field one Vector3 if k == "one" then return Vector3:New(1, 1, 1) end + ---@class Vector3 + ---@field up Vector3 if k == "up" then return Vector3:New(0, 1, 0) end + ---@class Vector3 + ---@field down Vector3 if k == "down" then return Vector3:New(0, -1, 0) end + ---@class Vector3 + ---@field left Vector3 if k == "left" then return Vector3:New(-1, 0, 0) end + ---@class Vector3 + ---@field right Vector3 if k == "right" then return Vector3:New(1, 0, 0) end + ---@class Vector3 + ---@field forward Vector3 if k == "forward" then return Vector3:New(0, 0, 1) end + ---@class Vector3 + ---@field back Vector3 if k == "back" then return Vector3:New(0, 0, -1) end + ---@class Vector3 + ---@field positiveInfinity Vector3 if k == "positiveInfinity" then return Vector3:New(math.huge, math.huge, math.huge) end + ---@class Vector3 + ---@field negativeInfinity Vector3 if k == "negativeInfinity" then return Vector3:New(-math.huge, -math.huge, -math.huge) end + ---@class Vector3 + ---@field nan Vector3 if k == "nan" then return Vector3:New(0 / 0, 0 / 0, 0 / 0) end + ---@class Vector3 + ---@field epsilon number if k == "epsilon" then return 1.401298E-45 end + ---@class Vector3 + ---@field maxValue number if k == "maxValue" then return 3.402823E+38 end + ---@class Vector3 + ---@field minValue number if k == "minValue" then return -3.402823E+38 end + ---@class Vector3 + ---@field x number if k == "x" then return self[1] end + ---@class Vector3 + ---@field y number if k == "y" then return self[2] end + ---@class Vector3 + ---@field z number if k == "z" then return self[3] end @@ -272,7 +314,7 @@ function Vector3:ProjectOnPlane(planeNormal) return self - self:Project(planeNormal) end ----@param inDirection Vector3 +---@param inNormal Vector3 ---@return Vector3 function Vector3:Reflect(inNormal) return -2 * inNormal:Dot(self) * inNormal + self diff --git a/src/_bastion.lua b/src/_bastion.lua index b64c986..4c28181 100644 --- a/src/_bastion.lua +++ b/src/_bastion.lua @@ -7,7 +7,7 @@ local Bastion = { Bastion.__index = Bastion function Bastion.require(class) - return Tinkr:require("scripts/bastion/src/" .. class .. "/" .. class, Bastion) + return require("scripts/bastion/src/" .. class .. "/" .. class, Bastion) end ---@type ClassMagic @@ -34,6 +34,7 @@ Bastion.Unit = Bastion.require("Unit") 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() @@ -61,7 +62,8 @@ Bastion.CombatTimer = Bastion.Timer:New('combat') Bastion.MythicPlusUtils = Bastion.require("MythicPlusUtils"):New() ---@type NotificationsList Bastion.Notifications = Bastion.NotificationsList:New() -Bastion.modules = {} +local LIBRARIES = {} +local MODULES = {} Bastion.Enabled = false Bastion.EventManager:RegisterWoWEvent('UNIT_AURA', function(unit, auras) @@ -89,7 +91,7 @@ end) local pguid = UnitGUID("player") local missed = {} Bastion.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function() - local args = { CombatLogGetCurrentEventInfo() } + local args = {CombatLogGetCurrentEventInfo()} local subEvent = args[2] local sourceGUID = args[4] @@ -131,6 +133,16 @@ Bastion.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function() end end end) + +function Bastion:RegisterLibrary(name, payload) + LIBRARIES[name] = payload + -- Bastion:Print("Registered Library", name) +end + +function Bastion:GetLibrary(name) + return LIBRARIES[name] +end + Bastion.Ticker = C_Timer.NewTicker(0.1, function() if not Bastion.CombatTimer:IsRunning() and UnitAffectingCombat("player") then Bastion.CombatTimer:Start() @@ -140,29 +152,30 @@ Bastion.Ticker = C_Timer.NewTicker(0.1, function() if Bastion.Enabled then Bastion.ObjectManager:Refresh() - for i = 1, #Bastion.modules do - Bastion.modules[i]:Tick() + for i = 1, #MODULES do + MODULES[i]:Tick() end end end) function Bastion:Register(module) - table.insert(Bastion.modules, module) + table.insert(MODULES, module) Bastion:Print("Registered", module) end -- Find a module by name function Bastion:FindModule(name) - for i = 1, #Bastion.modules do - if Bastion.modules[i].name == name then - return Bastion.modules[i] + for i = 1, #MODULES do + if MODULES[i].name == name then + return MODULES[i] end end return nil end + function Bastion:Print(...) - local args = { ... } + local args = {...} local str = "|cFFDF362D[Bastion]|r |cFFFFFFFF" for i = 1, #args do str = str .. tostring(args[i]) .. " " @@ -174,7 +187,7 @@ function Bastion:Debug(...) if not Bastion.DebugMode then return end - local args = { ... } + local args = {...} local str = "|cFFDF6520[Bastion]|r |cFFFFFFFF" for i = 1, #args do str = str .. tostring(args[i]) .. " " @@ -207,13 +220,16 @@ Command:Register('dumpspells', 'Dump spells to a file', function() while true do local spellName, spellSubName = GetSpellBookItemName(i, BOOKTYPE_SPELL) if not spellName then - do break end + do + break + end end -- use spellName and spellSubName here local spellID = select(7, GetSpellInfo(spellName)) if spellID then + spellName = spellName:gsub("[%W%s]", "") WriteFile('bastion-' .. UnitClass('player') .. '-' .. rand .. '.lua', "local " .. spellName .. " = Bastion.SpellBook:GetSpell(" .. spellID .. ")", true) end @@ -261,14 +277,17 @@ Command:Register('missed', 'Dump the list of immune kidney shot spells', functio end end) -local files = ListFiles("scripts/bastion/scripts") - -for i = 1, #files do - local file = files[i] - if file:sub(-4) == ".lua" or file:sub(-5) == '.luac' then +local function Load(dir) + local files = ListFiles(dir) - Tinkr:require("scripts/bastion/scripts/" .. file:sub(1, -5), Bastion) + for i = 1, #files do + local file = files[i] + if file:sub(-4) == ".lua" or file:sub(-5) == '.luac' then + require(dir .. file:sub(1, -5), Bastion) + end end end - +Load("scripts/bastion/scripts/Libraries/") +Load("scripts/bastion/scripts/Modules/") +Load("scripts/bastion/scripts/")