forked from Bastion/Bastion
parent
96a1fafa41
commit
b2e94e7d1b
@ -1,24 +0,0 @@ |
||||
local Tinkr, Bastion = ... |
||||
local ExampleModule = Bastion.Module:New('ExampleModule') |
||||
local Player = Bastion.UnitManager:Get('player') |
||||
|
||||
-- Create a local spellbook |
||||
local SpellBook = Bastion.SpellBook:New() |
||||
|
||||
local FlashHeal = SpellBook:GetSpell(2061) |
||||
|
||||
-- Get a global spell (this can collide with other modules, so be careful) |
||||
-- This is useful for caching common spells that you might not actually cast, and to avoid needless spell creation inline |
||||
local FlashHeal = Bastion.Globals.SpellBook:GetSpell(2061) |
||||
|
||||
local AdvancedMath = Bastion:Import('AdvancedMath') |
||||
|
||||
print(AdvancedMath:Add(1, 2)) |
||||
|
||||
ExampleModule:Sync(function() |
||||
if Player:GetHP() <= 50 then |
||||
FlashHeal:Cast(Player) |
||||
end |
||||
end) |
||||
|
||||
Bastion:Register(ExampleModule) |
@ -1,21 +0,0 @@ |
||||
local Tinkr, Bastion = ... |
||||
|
||||
local Player = Bastion.UnitManager:Get('player') |
||||
|
||||
Bastion:RegisterLibrary(Bastion.Library:New({ |
||||
name = 'Dependable', |
||||
exports = { |
||||
default = function() |
||||
local Dependable = {} |
||||
|
||||
Dependable.__index = Dependable |
||||
|
||||
function Dependable:Test(a) |
||||
print(a) |
||||
end |
||||
|
||||
return Dependable |
||||
end, |
||||
Test = 5 |
||||
} |
||||
})) |
@ -1,15 +0,0 @@ |
||||
local Tinkr, Bastion = ... |
||||
|
||||
Bastion:RegisterLibrary(Bastion.Library:New({ |
||||
name = 'Circular', |
||||
exports = { |
||||
default = function(self) |
||||
-- Return default first, and then the remaining exports |
||||
local Math, OtherExports = self:Import('AdvancedMath') |
||||
|
||||
print(Math:Add(1, 2)) |
||||
|
||||
return 'Circular' |
||||
end |
||||
} |
||||
})) |
@ -1,25 +0,0 @@ |
||||
local Tinkr, Bastion = ... |
||||
|
||||
Bastion:RegisterLibrary(Bastion.Library:New({ |
||||
name = 'AdvancedMath', |
||||
exports = { |
||||
default = function(self) -- Function exports are called when the library is loaded |
||||
-- Return default first, and then the remaining exports |
||||
local Dependable, OtherExports = self:Import('Dependable') |
||||
|
||||
local CircularDependency = self:Import('Circular') -- Causes a circular dependency error |
||||
|
||||
Dependable:Test(OtherExports.Test) |
||||
|
||||
local AdvancedMath = {} |
||||
|
||||
AdvancedMath.__index = AdvancedMath |
||||
|
||||
function AdvancedMath:Add(a, b) |
||||
return a + b |
||||
end |
||||
|
||||
return AdvancedMath |
||||
end |
||||
} |
||||
})) |
@ -0,0 +1,333 @@ |
||||
---@type Tinkr |
||||
local Tinkr = ... |
||||
|
||||
---@class Bastion.Globals.SpellName : { [spellId]: string } |
||||
|
||||
---@class Bastion |
||||
local Bastion = { |
||||
Enabled = false, |
||||
Globals = { |
||||
---@type Bastion.Globals.SpellName |
||||
SpellName = {} |
||||
}, |
||||
---@class Bastion.LoadedFiles.Table |
||||
---@field [number] { originalPath: string, loadedPath: string, reloadable: boolean, order: number, newPath: string } |
||||
LoadedFiles = {}, |
||||
LoadThird = true, |
||||
Paths = { |
||||
Scripts = "scripts", |
||||
BastionBase = "scripts/bastion", |
||||
BastionScripts = "scripts/bastion/scripts", |
||||
ThirdParty = "scripts/BastionScripts", |
||||
}, |
||||
Tick = 0, |
||||
} |
||||
|
||||
function Bastion:__index(key) |
||||
if Bastion[key] then |
||||
return Bastion[key] |
||||
end |
||||
return rawget(self, key) |
||||
end |
||||
|
||||
local bastionFiles = { |
||||
"~/src/ClassMagic/ClassMagic", |
||||
"~/src/List/List", |
||||
"~/src/Command/Command", |
||||
"~/src/Util/Util", |
||||
"~/src/Library/Library", |
||||
"~/src/Notification/Notification", |
||||
"~/src/NotificationList/NotificationList", |
||||
"~/src/Vector3/Vector3", |
||||
"~/src/Sequencer/Sequencer", |
||||
"~/src/Cache/Cache", |
||||
"~/src/Cacheable/Cacheable", |
||||
"~/src/Refreshable/Refreshable", |
||||
"~/src/EventManager/EventManager", |
||||
"~/src/Unit/Unit", |
||||
"~/src/Aura/Aura", |
||||
"~/src/APLTrait/APLTrait", |
||||
"~/src/APLActor/APLActor", |
||||
"~/src/APL/APL", |
||||
"~/src/Module/Module", |
||||
"~/src/UnitManager/UnitManager", |
||||
"~/src/ObjectManager/ObjectManager", |
||||
"~/src/Spell/Spell", |
||||
"~/src/SpellBook/SpellBook", |
||||
"~/src/Item/Item", |
||||
"~/src/ItemBook/ItemBook", |
||||
"~/src/AuraTable/AuraTable", |
||||
"~/src/Class/Class", |
||||
"~/src/Timer/Timer", |
||||
"~/src/MythicPlusUtils/MythicPlusUtils", |
||||
"~/src/Config/Config", |
||||
"~/src/TimeToDie/TimeToDie", |
||||
} |
||||
|
||||
---@param filePath string |
||||
function Bastion:CheckIfLoaded(filePath) |
||||
for i, file in ipairs(Bastion.LoadedFiles) do |
||||
if file.loadedPath == filePath or file.originalPath == filePath or file.newPath == filePath then |
||||
return true |
||||
end |
||||
end |
||||
return false |
||||
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 |
||||
exts = extensions |
||||
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, table |
||||
function Bastion:Require(filePath, ...) |
||||
local loadedFile = { |
||||
originalPath = filePath.filePath or filePath, |
||||
newPath = filePath.filePath or filePath, |
||||
loadedPath = filePath.filePath or filePath, |
||||
reloadable = not filePath.reloadable and false or false, |
||||
order = #Bastion.LoadedFiles + 1, |
||||
} |
||||
|
||||
local pathResolutionShortcut = loadedFile.originalPath:sub(1, 1) == "@" and Bastion.Paths.BastionScripts or |
||||
loadedFile.originalPath:sub(1, 1) == "~" and Bastion.Paths.BastionBase or |
||||
loadedFile.originalPath:sub(1, 1) == "!" and Bastion.Paths.Scripts |
||||
|
||||
if pathResolutionShortcut then |
||||
loadedFile.newPath = string.format("%s%s", pathResolutionShortcut, loadedFile.originalPath:sub(2)) |
||||
loadedFile.loadedPath = loadedFile.newPath |
||||
end |
||||
|
||||
if DirectoryExists(loadedFile.newPath) then |
||||
local fileList = ListFiles(loadedFile.newPath) |
||||
if #fileList > 0 then |
||||
local loadResults = {} |
||||
for i = 1, #fileList do |
||||
local file = loadedFile.newPath .. fileList[i] |
||||
local status, returns = Bastion:Require(file, ...) |
||||
table.insert(loadResults, { file = file, status = status, returns = returns }) |
||||
end |
||||
return 1, loadResults |
||||
end |
||||
Log(string.format("Bastion:Require - No files found in directory: %s", loadedFile.newPath)) |
||||
return 0, SafePack(nil) |
||||
end |
||||
|
||||
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 |
||||
|
||||
---@param load? boolean |
||||
---@param folder? string |
||||
local function LoadThird(load, folder) |
||||
load = type(load) == "nil" and Bastion.LoadThird or load |
||||
folder = folder or Bastion.Paths.ThirdParty |
||||
if not load then |
||||
return |
||||
end |
||||
local thirdPartyModulesFolders = ListFolders(folder) |
||||
for i = 1, #thirdPartyModulesFolders do |
||||
local moduleFolder = thirdPartyModulesFolders[i] |
||||
local currentFolderDir = string.format("%s/%s", folder, moduleFolder) |
||||
local loaderFilePath = string.format("%s/%s", currentFolderDir, "loader") |
||||
if FileExists(loaderFilePath .. ".lua") or FileExists(loaderFilePath .. ".luac") then |
||||
Bastion:Require(loaderFilePath, currentFolderDir) |
||||
end |
||||
end |
||||
end |
||||
|
||||
---@param toggle? boolean |
||||
function Bastion:Toggle(toggle) |
||||
Bastion.Enabled = type(toggle) ~= "nil" and toggle or not Bastion.Enabled |
||||
end |
||||
|
||||
local loaded = false |
||||
function Bastion:Load() |
||||
if loaded then |
||||
return self |
||||
end |
||||
|
||||
for i = 1, #bastionFiles do |
||||
self:Require(bastionFiles[i]) |
||||
end |
||||
|
||||
self.Globals.Command:Register('toggle', 'Toggle bastion on/off', function() |
||||
self:Toggle() |
||||
if self.Enabled then |
||||
self.Util:Print("Enabled") |
||||
else |
||||
self.Util:Print("Disabled") |
||||
end |
||||
end) |
||||
|
||||
self.Globals.CombatTimer = self.Timer:New("combat", function() |
||||
return UnitAffectingCombat("player") |
||||
end) |
||||
|
||||
---@param unitTarget UnitId |
||||
self.Globals.EventManager:RegisterWoWEvent("UNIT_HEALTH", function(unitTarget) |
||||
--Bastion.UnitManager:Get(unitTarget):UpdateHealth() |
||||
end) |
||||
|
||||
---@param unit UnitToken |
||||
---@param auras UnitAuraUpdateInfo |
||||
self.Globals.EventManager:RegisterWoWEvent("UNIT_AURA", function(unit, auras) |
||||
---@type Bastion.Unit | nil |
||||
local u = self.UnitManager:Get(unit) |
||||
|
||||
if u then |
||||
u:GetAuras():OnUpdate(auras) |
||||
end |
||||
end) |
||||
|
||||
self.Globals.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", function(...) |
||||
---@type UnitIds, string, spellId |
||||
local unit, castGUID, spellID = ... |
||||
local spell = self.Globals.SpellBook:GetIfRegistered(spellID) |
||||
|
||||
if unit == "player" and spell then |
||||
spell.lastCastAt = GetTime() |
||||
|
||||
if spell:GetPostCastFunction() then |
||||
spell:GetPostCastFunction()(spell) |
||||
end |
||||
end |
||||
end) |
||||
|
||||
local playerGuid = UnitGUID("player") |
||||
local missed = {} |
||||
|
||||
self.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 spellName = args[13] |
||||
|
||||
if subEvent == "SPELL_CAST_SUCCESS" then |
||||
if (not self.Globals.SpellName[spellID] or self.Globals.SpellName[spellID] ~= spellName) then |
||||
self.Globals.SpellName[spellID] = spellName |
||||
end |
||||
end |
||||
|
||||
local u = self.UnitManager[sourceGUID] |
||||
local u2 = self.UnitManager[destGUID] |
||||
local t = GetTime() |
||||
|
||||
if u then |
||||
u:SetLastCombatTime(t) |
||||
end |
||||
|
||||
if u2 then |
||||
u2:SetLastCombatTime(t) |
||||
if subEvent == "SPELL_MISSED" and sourceGUID == playerGuid and spellID == 408 then |
||||
local missType = args[15] |
||||
|
||||
if missType == "IMMUNE" then |
||||
local castingSpell = u:GetCastingOrChannelingSpell() |
||||
|
||||
if castingSpell and type(castingSpell) == "table" then |
||||
if not missed[castingSpell:GetID()] then |
||||
missed[castingSpell:GetID()] = true |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end) |
||||
|
||||
self.Ticker = C_Timer.NewTicker(0.1, function() |
||||
Bastion.Tick = GetGameTick() |
||||
self.Globals.CombatTimer:Check() |
||||
|
||||
if Bastion.Enabled then |
||||
self.ObjectManager:Refresh() |
||||
self.TimeToDie:Refresh() |
||||
self:TickModules() |
||||
end |
||||
end) |
||||
|
||||
self.Globals.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 |
||||
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.Globals.SpellBook:GetSpell(" .. spellID .. ")\n", true) |
||||
end |
||||
i = i + 1 |
||||
end |
||||
end) |
||||
|
||||
self.Globals.Command:Register("missed", "Dump the list of immune kidney shot spells", function() |
||||
for k, v in pairs(missed) do |
||||
self.Util:Print(k) |
||||
end |
||||
end) |
||||
|
||||
self:Require("@/Libraries/") |
||||
self:Require("@/Modules/") |
||||
self:Require("@/") |
||||
LoadThird() |
||||
loaded = true |
||||
|
||||
return self |
||||
end |
||||
|
||||
return Bastion |
@ -1,327 +1,4 @@ |
||||
---@type Tinkr |
||||
local Tinkr = ... |
||||
|
||||
---@class Bastion.Globals.SpellName : { [spellId]: string } |
||||
|
||||
---@class Bastion |
||||
local Bastion = { |
||||
Enabled = false, |
||||
Globals = { |
||||
---@type Bastion.Globals.SpellName |
||||
SpellName = {} |
||||
}, |
||||
Tick = GetGameTick() |
||||
} |
||||
|
||||
Bastion.__index = Bastion |
||||
|
||||
local BastionBase = string.format("%s/%s", "scripts", "bastion") |
||||
local BastionScriptsBase = string.format("%s/%s", BastionBase, "scripts") |
||||
local ThirdPartyModulesBase = string.format("%s/%s", "scripts", "BastionScripts") |
||||
|
||||
---@class Bastion.LoadedFiles.Table |
||||
---@field [number] { originalPath: string, loadedPath: string, reloadable: boolean, order: number, newPath: string } |
||||
Bastion.LoadedFiles = {} |
||||
|
||||
---@param filePath string |
||||
function Bastion:CheckIfLoaded(filePath) |
||||
for i, file in ipairs(Bastion.LoadedFiles) do |
||||
if file.loadedPath == filePath or file.originalPath == filePath or file.newPath == filePath then |
||||
return true |
||||
end |
||||
end |
||||
return false |
||||
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 |
||||
exts = extensions |
||||
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, table |
||||
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) |
||||
local base = filePathModifier == "@" and BastionScriptsBase or filePathModifier == "~" and BastionBase |
||||
if base then |
||||
loadedFile.newPath = string.format("%s%s", base, loadedFile.originalPath:sub(2)) |
||||
loadedFile.loadedPath = loadedFile.newPath |
||||
end |
||||
|
||||
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 |
||||
|
||||
local loadExamples = false |
||||
local exampleNames = { |
||||
"ExampleDependency.lua", |
||||
"ExampleDependencyError.lua", |
||||
"ExampleLibrary.lua", |
||||
"ExampleModule.lua", |
||||
} |
||||
|
||||
---@param dir string |
||||
local function Load(dir) |
||||
if dir:sub(1, 1) == "@" then |
||||
dir = dir:sub(2) |
||||
dir = string.format("%s/%s", BastionScriptsBase, dir) |
||||
end |
||||
|
||||
if dir:sub(1, 1) == "~" then |
||||
dir = dir:sub(2) |
||||
dir = string.format("%s/%s", BastionBase, dir) |
||||
end |
||||
|
||||
local files = ListFiles(dir) |
||||
for i = 1, #files do |
||||
local file = files[i] |
||||
local loadFile = true |
||||
if not loadExamples then |
||||
for j = 1, #exampleNames do |
||||
if file:find(exampleNames[j]) then |
||||
loadFile = false |
||||
break |
||||
end |
||||
end |
||||
end |
||||
if loadFile and (file:sub(-4) == ".lua" or file:sub(-5) == ".luac") then |
||||
Bastion:Require(dir .. file:sub(1, -5)) |
||||
end |
||||
end |
||||
end |
||||
|
||||
local function LoadThird() |
||||
local thirdPartyModulesFolders = ListFolders(ThirdPartyModulesBase) |
||||
for i = 1, #thirdPartyModulesFolders do |
||||
local currentFolderDir = string.format("%s/%s", ThirdPartyModulesBase, thirdPartyModulesFolders[i]) |
||||
local loaderFilePath = string.format("%s/%s", currentFolderDir, "loader") |
||||
if FileExists(loaderFilePath .. ".lua") or FileExists(loaderFilePath .. ".luac") then |
||||
Bastion:Require(loaderFilePath, currentFolderDir) |
||||
end |
||||
end |
||||
end |
||||
|
||||
local bastionFiles = { |
||||
"~/src/ClassMagic/ClassMagic", |
||||
"~/src/List/List", |
||||
"~/src/Command/Command", |
||||
"~/src/Util/Util", |
||||
"~/src/Library/Library", |
||||
"~/src/Notification/Notification", |
||||
"~/src/NotificationList/NotificationList", |
||||
"~/src/Vector3/Vector3", |
||||
"~/src/Sequencer/Sequencer", |
||||
"~/src/Cache/Cache", |
||||
"~/src/Cacheable/Cacheable", |
||||
"~/src/Refreshable/Refreshable", |
||||
"~/src/EventManager/EventManager", |
||||
"~/src/Unit/Unit", |
||||
"~/src/Aura/Aura", |
||||
"~/src/APLTrait/APLTrait", |
||||
"~/src/APLActor/APLActor", |
||||
"~/src/APL/APL", |
||||
"~/src/Module/Module", |
||||
"~/src/UnitManager/UnitManager", |
||||
"~/src/ObjectManager/ObjectManager", |
||||
"~/src/Spell/Spell", |
||||
"~/src/SpellBook/SpellBook", |
||||
"~/src/Item/Item", |
||||
"~/src/ItemBook/ItemBook", |
||||
"~/src/AuraTable/AuraTable", |
||||
"~/src/Class/Class", |
||||
"~/src/Timer/Timer", |
||||
"~/src/MythicPlusUtils/MythicPlusUtils", |
||||
"~/src/Config/Config", |
||||
"~/src/TimeToDie/TimeToDie", |
||||
} |
||||
|
||||
for i = 1, #bastionFiles do |
||||
Bastion:Require(bastionFiles[i]) |
||||
end |
||||
|
||||
---@param toggle? boolean |
||||
function Bastion:Toggle(toggle) |
||||
Bastion.Enabled = type(toggle) ~= "nil" and toggle or not Bastion.Enabled |
||||
end |
||||
|
||||
Bastion.Globals.Command:Register('toggle', 'Toggle bastion on/off', function() |
||||
Bastion:Toggle() |
||||
if Bastion.Enabled then |
||||
Bastion.Util:Print("Enabled") |
||||
else |
||||
Bastion.Util:Print("Disabled") |
||||
end |
||||
end) |
||||
|
||||
Bastion.Globals.CombatTimer = Bastion.Timer:New("combat", function() |
||||
return UnitAffectingCombat("player") |
||||
end) |
||||
|
||||
---@param unitTarget UnitId |
||||
Bastion.Globals.EventManager:RegisterWoWEvent("UNIT_HEALTH", function(unitTarget) |
||||
--Bastion.UnitManager:Get(unitTarget):UpdateHealth() |
||||
end) |
||||
|
||||
---@param unit UnitToken |
||||
---@param auras UnitAuraUpdateInfo |
||||
Bastion.Globals.EventManager:RegisterWoWEvent("UNIT_AURA", function(unit, auras) |
||||
---@type Bastion.Unit | nil |
||||
local u = Bastion.UnitManager:Get(unit) |
||||
|
||||
if u then |
||||
u:GetAuras():OnUpdate(auras) |
||||
end |
||||
end) |
||||
|
||||
Bastion.Globals.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", function(...) |
||||
---@type UnitIds, string, spellId |
||||
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) |
||||
|
||||
local playerGuid = UnitGUID("player") |
||||
local missed = {} |
||||
|
||||
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 spellName = args[13] |
||||
|
||||
if subEvent == "SPELL_CAST_SUCCESS" then |
||||
if (not Bastion.Globals.SpellName[spellID] or Bastion.Globals.SpellName[spellID] ~= spellName) then |
||||
Bastion.Globals.SpellName[spellID] = spellName |
||||
end |
||||
end |
||||
|
||||
local u = Bastion.UnitManager[sourceGUID] |
||||
local u2 = Bastion.UnitManager[destGUID] |
||||
local t = GetTime() |
||||
|
||||
if u then |
||||
u:SetLastCombatTime(t) |
||||
end |
||||
|
||||
if u2 then |
||||
u2:SetLastCombatTime(t) |
||||
if subEvent == "SPELL_MISSED" and sourceGUID == playerGuid and spellID == 408 then |
||||
local missType = args[15] |
||||
|
||||
if missType == "IMMUNE" then |
||||
local castingSpell = u:GetCastingOrChannelingSpell() |
||||
|
||||
if castingSpell and type(castingSpell) == "table" then |
||||
if not missed[castingSpell:GetID()] then |
||||
missed[castingSpell:GetID()] = true |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end) |
||||
|
||||
Bastion.Ticker = C_Timer.NewTicker(0.1, function() |
||||
Bastion.Tick = GetGameTick() |
||||
Bastion.Globals.CombatTimer:Check() |
||||
|
||||
if Bastion.Enabled then |
||||
Bastion.ObjectManager:Refresh() |
||||
Bastion.TimeToDie:Refresh() |
||||
Bastion:TickModules() |
||||
end |
||||
end) |
||||
|
||||
Bastion.Globals.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 |
||||
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.Globals.SpellBook:GetSpell(" .. spellID .. ")\n", true) |
||||
end |
||||
i = i + 1 |
||||
end |
||||
end) |
||||
|
||||
Bastion.Globals.Command:Register("missed", "Dump the list of immune kidney shot spells", function() |
||||
for k, v in pairs(missed) do |
||||
Bastion.Util:Print(k) |
||||
end |
||||
end) |
||||
|
||||
Load("@Libraries/") |
||||
Load("@Modules/") |
||||
Load("@") |
||||
LoadThird() |
||||
require("scripts/bastion/src/Bastion/Bastion"):Load() |
||||
|
Loading…
Reference in new issue