forked from vibe/Bastion
Compare commits
1 Commits
main
...
add_traits
Author | SHA1 | Date |
---|---|---|
![]() |
e4d7894e21 | 6 months ago |
@ -0,0 +1,24 @@ |
|||||||
|
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) |
@ -0,0 +1,21 @@ |
|||||||
|
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 |
||||||
|
} |
||||||
|
})) |
@ -0,0 +1,15 @@ |
|||||||
|
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 |
||||||
|
} |
||||||
|
})) |
@ -0,0 +1,25 @@ |
|||||||
|
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 |
||||||
|
} |
||||||
|
})) |
@ -1,337 +0,0 @@ |
|||||||
local Tinkr, Bastion = ... |
|
||||||
|
|
||||||
local Util = Tinkr.Util |
|
||||||
if UnitClass('player') ~= 'Shaman' then return end |
|
||||||
|
|
||||||
Bastion.Rotation = {} |
|
||||||
local BR = Bastion.Rotation |
|
||||||
BR.Units = { |
|
||||||
Player = Bastion.UnitManager:Get('player'), |
|
||||||
Target = Bastion.UnitManager:Get('target'), |
|
||||||
None = Bastion.UnitManager:Get('none') |
|
||||||
} |
|
||||||
|
|
||||||
local ShamanModule = Bastion.Module:New('Shaman') |
|
||||||
local SpellBook = Bastion.Globals.SpellBook |
|
||||||
|
|
||||||
local Player = BR.Units.Player |
|
||||||
local None = BR.Units.None |
|
||||||
local Target = BR.Units.Target |
|
||||||
|
|
||||||
Tinkr:require("scripts/bastion/scripts/ShamanSettings", Bastion) |
|
||||||
BR.myconf = Tinkr.Util.Config:New('shaman') -- for saving variables |
|
||||||
|
|
||||||
local function _highestrank(spell) |
|
||||||
local name = GetSpellInfo(spell) |
|
||||||
local highrankid = (select(7, GetSpellInfo(name))) |
|
||||||
if not highrankid then |
|
||||||
highrankid = 1 |
|
||||||
end |
|
||||||
return highrankid |
|
||||||
end |
|
||||||
|
|
||||||
local s = { |
|
||||||
-- Basic Attack |
|
||||||
AutoAttack = SpellBook:GetSpell(6603), |
|
||||||
|
|
||||||
-- Shocks |
|
||||||
EarthShock = SpellBook:GetSpell(_highestrank(8042)), |
|
||||||
FrostShock = SpellBook:GetSpell(_highestrank(8056)), |
|
||||||
FlameShock = SpellBook:GetSpell(_highestrank(8050)), |
|
||||||
|
|
||||||
-- Specific Ranks for Utility |
|
||||||
EarthShockRank1 = SpellBook:GetSpell(8042), -- Rank 1 (Interrupt) |
|
||||||
FrostShockRank1 = SpellBook:GetSpell(8056), -- Rank 1 (Slow), |
|
||||||
|
|
||||||
-- Healing Spells |
|
||||||
HealingWave = SpellBook:GetSpell(_highestrank(331)), |
|
||||||
LesserHealingWave = SpellBook:GetSpell(_highestrank(8004)), |
|
||||||
ChainHeal = SpellBook:GetSpell(_highestrank(1064)), |
|
||||||
|
|
||||||
-- Healing Sub Ranks (Healing Wave) |
|
||||||
HealingWaveRank1 = SpellBook:GetSpell(331), -- Rank 1 |
|
||||||
HealingWaveRank2 = SpellBook:GetSpell(332), -- Rank 2 |
|
||||||
HealingWaveRank3 = SpellBook:GetSpell(547), -- Rank 3 |
|
||||||
HealingWaveRank4 = SpellBook:GetSpell(913), -- Rank 4 |
|
||||||
HealingWaveRank5 = SpellBook:GetSpell(939), -- Rank 5 |
|
||||||
HealingWaveRank6 = SpellBook:GetSpell(959), -- Rank 6 |
|
||||||
HealingWaveRank7 = SpellBook:GetSpell(8005), -- Rank 7 |
|
||||||
HealingWaveRank8 = SpellBook:GetSpell(10395), -- Rank 8 |
|
||||||
HealingWaveRank9 = SpellBook:GetSpell(10396), -- Rank 9 (Max Rank) |
|
||||||
|
|
||||||
-- Healing Sub Ranks (Lesser Healing Wave) |
|
||||||
LesserHealingWaveRank1 = SpellBook:GetSpell(8004), -- Rank 1 |
|
||||||
LesserHealingWaveRank2 = SpellBook:GetSpell(8008), -- Rank 2 |
|
||||||
LesserHealingWaveRank3 = SpellBook:GetSpell(8010), -- Rank 3 |
|
||||||
LesserHealingWaveRank4 = SpellBook:GetSpell(10466), -- Rank 4 |
|
||||||
LesserHealingWaveRank5 = SpellBook:GetSpell(10467), -- Rank 5 |
|
||||||
LesserHealingWaveRank6 = SpellBook:GetSpell(10468), -- Rank 6 (Max Rank) |
|
||||||
|
|
||||||
-- Healing Sub Ranks (Chain Heal) |
|
||||||
ChainHealRank1 = SpellBook:GetSpell(1064), -- Rank 1 |
|
||||||
ChainHealRank2 = SpellBook:GetSpell(10622), -- Rank 2 |
|
||||||
ChainHealRank3 = SpellBook:GetSpell(10623), -- Rank 3 |
|
||||||
ChainHealRank4 = SpellBook:GetSpell(25422), -- Rank 4 (Max Rank) |
|
||||||
|
|
||||||
-- Totems |
|
||||||
EarthbindTotem = SpellBook:GetSpell(2484), |
|
||||||
StoneclawTotem = SpellBook:GetSpell(_highestrank(5730)), |
|
||||||
StrengthOfEarthTotem = SpellBook:GetSpell(_highestrank(8075)), |
|
||||||
TremorTotem = SpellBook:GetSpell(_highestrank(8143)), |
|
||||||
SearingTotem = SpellBook:GetSpell(_highestrank(3599)), |
|
||||||
FireNovaTotem = SpellBook:GetSpell(_highestrank(1535)), |
|
||||||
HealingStreamTotem = SpellBook:GetSpell(_highestrank(5394)), |
|
||||||
ManaSpringTotem = SpellBook:GetSpell(_highestrank(5675)), |
|
||||||
WindfuryTotem = SpellBook:GetSpell(_highestrank(8512)), |
|
||||||
GraceOfAirTotem = SpellBook:GetSpell(_highestrank(8835)), |
|
||||||
|
|
||||||
-- Buffs |
|
||||||
LightningShield = SpellBook:GetSpell(_highestrank(324)), |
|
||||||
|
|
||||||
-- Offensive Spells |
|
||||||
LightningBolt = SpellBook:GetSpell(_highestrank(403)), |
|
||||||
ChainLightning = SpellBook:GetSpell(_highestrank(421)), |
|
||||||
|
|
||||||
-- Utility |
|
||||||
Purge = SpellBook:GetSpell(_highestrank(370)), |
|
||||||
CurePoison = SpellBook:GetSpell(526), |
|
||||||
CureDisease = SpellBook:GetSpell(2870), |
|
||||||
GhostWolf = SpellBook:GetSpell(2645), |
|
||||||
WaterWalking = SpellBook:GetSpell(_highestrank(546)), |
|
||||||
WaterBreathing = SpellBook:GetSpell(_highestrank(131)), |
|
||||||
|
|
||||||
-- Weapon Buffs |
|
||||||
FlametongueWeapon = SpellBook:GetSpell(_highestrank(8024)), |
|
||||||
FrostbrandWeapon = SpellBook:GetSpell(_highestrank(8033)), |
|
||||||
WindfuryWeapon = SpellBook:GetSpell(_highestrank(8232)), |
|
||||||
RockbiterWeapon = SpellBook:GetSpell(_highestrank(8017)), |
|
||||||
|
|
||||||
-- Talents |
|
||||||
ElementalMastery = SpellBook:GetSpell(16166), |
|
||||||
NaturesSwiftness = SpellBook:GetSpell(16188), |
|
||||||
ManaTideTotem = SpellBook:GetSpell(_highestrank(16190)), |
|
||||||
|
|
||||||
--Buffs |
|
||||||
refreshment = SpellBook:GetList(430, 431, 432, 1133, 1135, 1137, 10250, 22734, 27089, 433, 434, 435, 1127, 1129, 1131, 5004, 11199, 11200, 22731, 25696) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
-- Create APLs |
|
||||||
local DefaultAPL = Bastion.APL:New('default') |
|
||||||
local HealingAPL = Bastion.APL:New('healing') |
|
||||||
local DamageAPL = Bastion.APL:New('damage') |
|
||||||
local CooldownAPL = Bastion.APL:New('cooldown') |
|
||||||
local DefensiveAPL = Bastion.APL:New('defensive') |
|
||||||
|
|
||||||
-- Default APL |
|
||||||
--DefaultAPL:AddAPL(DefensiveAPL, function() return true end) |
|
||||||
--DefaultAPL:AddAPL(CooldownAPL, function() return true end) |
|
||||||
DefaultAPL:AddAPL(HealingAPL, function() return true end) |
|
||||||
--DefaultAPL:AddAPL(ExecuteAPL, function() return true end) |
|
||||||
--DefaultAPL:AddAPL(DamagePriorityAPL, function() return not HealingNeeded() and AggressiveDamagePhase() end) |
|
||||||
--DefaultAPL:AddAPL(DamageAPL, function() return not HealingNeeded() end) |
|
||||||
|
|
||||||
local DispelTarget = Bastion.UnitManager:CreateCustomUnit('dispel', function(unit) |
|
||||||
local lowest = nil |
|
||||||
local lowestHP = math.huge |
|
||||||
Bastion.UnitManager:EnumFriends(function(unit) |
|
||||||
if unit:IsDead() then return false end |
|
||||||
if not Player:CanSee(unit) then return false end |
|
||||||
if Player:GetDistance(unit) > 40 then return false end |
|
||||||
|
|
||||||
if not unit:IsDead() and Player:CanSee(unit) and (unit:GetAuras():HasAnyDispelableAura(s.CurePoison) or unit:GetAuras():HasAnyDispelableAura(s.CureDisease)) then |
|
||||||
local hp = unit:GetHP() |
|
||||||
if hp < lowestHP then |
|
||||||
lowest = unit |
|
||||||
lowestHP = hp |
|
||||||
end |
|
||||||
end |
|
||||||
end) |
|
||||||
if lowest == nil then |
|
||||||
lowest = None |
|
||||||
end |
|
||||||
return lowest |
|
||||||
end) |
|
||||||
|
|
||||||
local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit) |
|
||||||
local lowest = nil |
|
||||||
local lowestHP = math.huge |
|
||||||
Bastion.UnitManager:EnumFriends(function(unit) |
|
||||||
if unit:IsDead() then return false end |
|
||||||
if Player:GetDistance(unit) > 40 then return false end |
|
||||||
if not Player:CanSee(unit) then return false end |
|
||||||
local hp = unit:GetHP() |
|
||||||
if hp < lowestHP then |
|
||||||
lowest = unit |
|
||||||
lowestHP = hp |
|
||||||
end |
|
||||||
if not lowest then |
|
||||||
lowest = Player |
|
||||||
end |
|
||||||
end) |
|
||||||
if lowest == nil then |
|
||||||
lowest = None |
|
||||||
end |
|
||||||
return lowest |
|
||||||
end) |
|
||||||
|
|
||||||
local InterruptTarget = Bastion.UnitManager:CreateCustomUnit('interrupttarget', function(unit) |
|
||||||
local interrupt = nil |
|
||||||
Bastion.UnitManager:EnumEnemies(function(unit) |
|
||||||
if unit:IsDead() then return false end |
|
||||||
if not Player:CanSee(unit) then return false end |
|
||||||
if Player:GetDistance(unit) > 20 then return false end |
|
||||||
if unit:IsInterruptibleAt(40) and Player:IsFacing(unit) then |
|
||||||
interrupt = unit |
|
||||||
--print(unit) |
|
||||||
return true |
|
||||||
end |
|
||||||
end) |
|
||||||
if interrupt == nil then |
|
||||||
interrupt = None |
|
||||||
end |
|
||||||
return interrupt |
|
||||||
end) |
|
||||||
|
|
||||||
local PurgeTarget = Bastion.UnitManager:CreateCustomUnit('purgetarget', function(unit) |
|
||||||
local purgeTarget = nil |
|
||||||
local highestPriority = 0 |
|
||||||
|
|
||||||
-- List of high-priority buffs to purge |
|
||||||
local highPriorityBuffs = { |
|
||||||
642, -- Divine Shield |
|
||||||
1022, -- Blessing of Protection |
|
||||||
19752, -- Divine Intervention |
|
||||||
1044, -- Blessing of Freedom |
|
||||||
6940, -- Blessing of Sacrifice |
|
||||||
1461, -- Arcane Intellect |
|
||||||
23028, -- Arcane Brilliance |
|
||||||
10157, -- Arcane Intellect (Rank 6) |
|
||||||
27126, -- Arcane Brilliance (Rank 2) |
|
||||||
} |
|
||||||
|
|
||||||
Bastion.UnitManager:EnumEnemies(function(unit) |
|
||||||
-- Basic checks |
|
||||||
if unit:IsDead() then return false end |
|
||||||
if not Player:CanSee(unit) then return false end |
|
||||||
if Player:GetDistance(unit) > 30 then return false end |
|
||||||
if not Player:IsFacing(unit) then return false end |
|
||||||
if not unit:IsAffectingCombat() then return false end |
|
||||||
|
|
||||||
-- Check if unit has purgeable buffs |
|
||||||
if unit:GetAuras():HasPurgeableBuff() then |
|
||||||
local currentPriority = 0 |
|
||||||
|
|
||||||
-- Check if unit has any high priority buffs |
|
||||||
for _, buffId in ipairs(highPriorityBuffs) do |
|
||||||
if unit:GetAuras():Find(buffId):IsUp() then |
|
||||||
currentPriority = 2 |
|
||||||
break |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
-- If no high priority buffs found, but unit has other purgeable buffs |
|
||||||
if currentPriority == 0 then |
|
||||||
currentPriority = 1 |
|
||||||
end |
|
||||||
|
|
||||||
-- Update target if this unit has higher priority |
|
||||||
if currentPriority > highestPriority then |
|
||||||
purgeTarget = unit |
|
||||||
highestPriority = currentPriority |
|
||||||
end |
|
||||||
end |
|
||||||
end) |
|
||||||
|
|
||||||
if purgeTarget == nil then |
|
||||||
purgeTarget = None |
|
||||||
end |
|
||||||
|
|
||||||
return purgeTarget |
|
||||||
end) |
|
||||||
|
|
||||||
-- Utility function to check if healing is needed |
|
||||||
local function HealingNeeded() |
|
||||||
return Lowest:Exists() and Lowest:GetHP() < 90 |
|
||||||
end |
|
||||||
|
|
||||||
-- Utility function to check if emergency healing is needed |
|
||||||
local function EmergencyHealingNeeded() |
|
||||||
return Lowest:Exists() and Lowest:GetHP() < 50 |
|
||||||
end |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local function out_of_combat_function() |
|
||||||
if Player:GetAuras():FindAnyOf(s.refreshment):IsUp() then return end |
|
||||||
|
|
||||||
end |
|
||||||
|
|
||||||
HealingAPL:AddSpell( |
|
||||||
s.LesserHealingWave:CastableIf(function(self) |
|
||||||
if not Lowest:Exists() then return false end |
|
||||||
if Lowest:GetHP() > 20 then return false end |
|
||||||
return self:IsKnownAndUsable() and HealingNeeded() |
|
||||||
end):SetTarget(Lowest) |
|
||||||
) |
|
||||||
|
|
||||||
HealingAPL:AddSpell( |
|
||||||
s.HealingWave:CastableIf(function(self) |
|
||||||
if not Lowest:Exists() then return false end |
|
||||||
if Lowest:GetHP() > 50 or Lowest:GetHP() < 20 then return false end |
|
||||||
return self:IsKnownAndUsable() and HealingNeeded() |
|
||||||
end):SetTarget(Lowest) |
|
||||||
) |
|
||||||
|
|
||||||
HealingAPL:AddSpell( |
|
||||||
s.CurePoison:CastableIf(function(self) |
|
||||||
if not DispelTarget:Exists() then return false end |
|
||||||
return (DispelTarget:GetAuras():HasAnyDispelableAura(s.CurePoison)) and self:IsKnownAndUsable() |
|
||||||
end):SetTarget(DispelTarget) |
|
||||||
) |
|
||||||
|
|
||||||
HealingAPL:AddSpell( |
|
||||||
s.CureDisease:CastableIf(function(self) |
|
||||||
if not DispelTarget:Exists() then return false end |
|
||||||
return (DispelTarget:GetAuras():HasAnyDispelableAura(s.CureDisease)) and self:IsKnownAndUsable() |
|
||||||
end):SetTarget(DispelTarget) |
|
||||||
) |
|
||||||
|
|
||||||
DamageAPL:AddSpell( |
|
||||||
s.Purge:CastableIf(function(self) |
|
||||||
if not PurgeTarget:Exists() then return false end |
|
||||||
return self:IsKnownAndUsable() and PurgeTarget:GetAuras():HasPurgeableBuff() |
|
||||||
end):SetTarget(PurgeTarget) |
|
||||||
) |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ShamanModule:Sync(function() |
|
||||||
if Player:GetAuras():FindAnyOf(s.refreshment):IsUp() then return end |
|
||||||
if Player:IsDead() then return end |
|
||||||
if Player:IsCastingOrChanneling() then return end |
|
||||||
if IsMounted() then return end |
|
||||||
if InterruptTarget:Exists() and s.EarthShockRank1:IsKnownAndUsable() then |
|
||||||
s.EarthShockRank1:Cast(InterruptTarget) |
|
||||||
end |
|
||||||
|
|
||||||
if Player:IsAffectingCombat() then |
|
||||||
|
|
||||||
DefaultAPL:Execute() |
|
||||||
else |
|
||||||
if Player:GetPP() > 5 then |
|
||||||
HealingAPL:Execute() |
|
||||||
end |
|
||||||
out_of_combat_function() |
|
||||||
end |
|
||||||
end) |
|
||||||
|
|
||||||
|
|
||||||
Bastion:Register(ShamanModule) |
|
||||||
ShamanModule:Toggle() |
|
@ -1,124 +0,0 @@ |
|||||||
local Unlocker, Bastion = ... |
|
||||||
--! Creating the initial GUI !-- |
|
||||||
|
|
||||||
Bastion.Settings = Bastion.Interface.Category:New("Shaman") |
|
||||||
|
|
||||||
|
|
||||||
Bastion.Settings:AddSubsection("General") |
|
||||||
|
|
||||||
Bastion.Settings:Slider({ |
|
||||||
category = "bastion", |
|
||||||
var = "tickrate", |
|
||||||
name = "Engine Tickrate (milliseconds)", |
|
||||||
tooltip = "How often the Bastion Engine runs. The lower this number, the more resources Bastion will use.\n\nYou must reload for changes to take effect.", |
|
||||||
default = 100, |
|
||||||
min = 50, |
|
||||||
max = 500, |
|
||||||
step = 50, |
|
||||||
}) |
|
||||||
|
|
||||||
|
|
||||||
Bastion.Settings:Dropdown({ |
|
||||||
category = "bastion", |
|
||||||
var = "pause_key", |
|
||||||
name = "Hold-to-Pause", |
|
||||||
tooltip = "Bastion will not run while this button is held down.", |
|
||||||
default = false, |
|
||||||
options = { |
|
||||||
{ "None", false }, |
|
||||||
{ "Shift", "SHIFT" }, |
|
||||||
{ "Control", "CTRL" }, |
|
||||||
{ "Alt", "ALT" }, |
|
||||||
} |
|
||||||
}) |
|
||||||
|
|
||||||
Bastion.Settings:AddSubsection("Engine Options") |
|
||||||
|
|
||||||
Bastion.Settings:Checkbox({ |
|
||||||
category = "bastion", |
|
||||||
var = "debug", |
|
||||||
name = "Debug Mode", |
|
||||||
tooltip = "Toggles Debug Mode for the Bastion Engine.", |
|
||||||
default = false, |
|
||||||
onClick = function() |
|
||||||
Bastion.DebugMode = not Bastion.DebugMode |
|
||||||
if Bastion.DebugMode then |
|
||||||
Bastion:Debug("Debug Enabled") |
|
||||||
else |
|
||||||
Bastion:Print("Debug Disabled") |
|
||||||
end |
|
||||||
end, |
|
||||||
}) |
|
||||||
|
|
||||||
Bastion.MainBar = Bastion.Interface.Hotbar:New({ |
|
||||||
buttonCount = 3, |
|
||||||
name = "Bastion", |
|
||||||
options = Bastion.Settings |
|
||||||
}) |
|
||||||
|
|
||||||
if Bastion:IsClassic() then |
|
||||||
Bastion.MainBar:AddButton({ |
|
||||||
name = "Toggle", |
|
||||||
texture = "Interface\\ICONS\\Inv_drink_15", |
|
||||||
tooltip = "This button toggle's Bastion on and off.", |
|
||||||
toggle = true, |
|
||||||
onClick = function() |
|
||||||
Bastion.Enabled = not Bastion.Enabled |
|
||||||
if Bastion.Enabled then |
|
||||||
Bastion:Print("Enabled") |
|
||||||
else |
|
||||||
Bastion:Print("Disabled") |
|
||||||
end |
|
||||||
end, |
|
||||||
}) |
|
||||||
Bastion.MainBar:AddButton({ |
|
||||||
name = "Options", |
|
||||||
tooltip = "This button opens the Bastion Options menu.", |
|
||||||
texture = "Interface\\ICONS\\Inv_misc_gear_01", |
|
||||||
toggle = false, |
|
||||||
onClick = function() |
|
||||||
if SettingsPanel and SettingsPanel:IsVisible() then |
|
||||||
HideUIPanel(SettingsPanel) |
|
||||||
HideUIPanel(GameMenuFrame) |
|
||||||
else |
|
||||||
Settings.OpenToCategory(Bastion.MainBar.options.settings:GetID()) |
|
||||||
end |
|
||||||
end, |
|
||||||
}) |
|
||||||
|
|
||||||
else |
|
||||||
Bastion.MainBar:AddButton({ |
|
||||||
name = "Toggle", |
|
||||||
texture = "Interface\\ICONS\\ACHIEVEMENT_GUILDPERK_MRPOPULARITY", |
|
||||||
tooltip = "This button toggle's Bastion on and off.", |
|
||||||
toggle = true, |
|
||||||
onClick = function() |
|
||||||
-- if Bastion.Settings.config:Read("bastion_stimulant", true) then |
|
||||||
-- Bastion.Stimulant:Toggle() |
|
||||||
-- end |
|
||||||
Bastion.Enabled = not Bastion.Enabled |
|
||||||
if Bastion.Enabled then |
|
||||||
Bastion:Print("Enabled") |
|
||||||
else |
|
||||||
Bastion:Print("Disabled") |
|
||||||
end |
|
||||||
end, |
|
||||||
}) |
|
||||||
Bastion.MainBar:AddButton({ |
|
||||||
name = "Options", |
|
||||||
tooltip = "This button opens the Bastion Options menu.", |
|
||||||
texture = "Interface\\ICONS\\INV_Engineering_90_Gizmo", |
|
||||||
toggle = false, |
|
||||||
onClick = function() |
|
||||||
if SettingsPanel and SettingsPanel:IsVisible() then |
|
||||||
HideUIPanel(SettingsPanel) |
|
||||||
HideUIPanel(GameMenuFrame) |
|
||||||
else |
|
||||||
Settings.OpenToCategory(Bastion.MainBar.options.settings:GetID()) |
|
||||||
end |
|
||||||
end, |
|
||||||
}) |
|
||||||
end |
|
||||||
|
|
||||||
|
|
||||||
Bastion.Settings:Register() |
|
@ -1,85 +0,0 @@ |
|||||||
---@type Tinkr |
|
||||||
local Tinkr, |
|
||||||
---@class Bastion |
|
||||||
Bastion = ... |
|
||||||
|
|
||||||
---@class Bastion.Config |
|
||||||
---@field instantiated boolean |
|
||||||
---@field config Tinkr.Util.Config.Instance |
|
||||||
---@field defaults nil | table |
|
||||||
local Config = { |
|
||||||
instantiated = false, |
|
||||||
} |
|
||||||
|
|
||||||
function Config:__index(k) |
|
||||||
local response = Config[k] |
|
||||||
|
|
||||||
if response == nil then |
|
||||||
response = rawget(self, k) |
|
||||||
end |
|
||||||
|
|
||||||
if response == nil and self.instantiated then |
|
||||||
response = self:Read(k) |
|
||||||
end |
|
||||||
|
|
||||||
return response |
|
||||||
end |
|
||||||
|
|
||||||
function Config:__newindex(key, value) |
|
||||||
if self.instantiated then |
|
||||||
self:Write(key, value) |
|
||||||
else |
|
||||||
rawset(self, key, value) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
---@generic D |
|
||||||
---@param name string |
|
||||||
---@param defaults? D |
|
||||||
function Config:New(name, defaults) |
|
||||||
---@type Bastion.Config |
|
||||||
local self = setmetatable({}, Config) |
|
||||||
self.config = Tinkr.Util.Config:New(name) |
|
||||||
self.defaults = type(defaults) == "table" and defaults or {} |
|
||||||
self.instantiated = true |
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
---@generic D |
|
||||||
---@param key string |
|
||||||
---@param default? D |
|
||||||
---@return D |
|
||||||
function Config:Read(key, default) |
|
||||||
if type(default) == "nil" then |
|
||||||
default = self.defaults[key] |
|
||||||
end |
|
||||||
return self.config:Read(key, default) |
|
||||||
end |
|
||||||
|
|
||||||
function Config:Reset() |
|
||||||
if type(self.defaults) == "table" then |
|
||||||
-- Clear all values currently in the config. |
|
||||||
for key, _ in pairs(self.config.data) do |
|
||||||
self:Write(key, nil) |
|
||||||
end |
|
||||||
-- Use default table to write new defaults. |
|
||||||
for key, value in pairs(self.defaults) do |
|
||||||
self:Write(key, value) |
|
||||||
end |
|
||||||
return true |
|
||||||
end |
|
||||||
return false |
|
||||||
end |
|
||||||
|
|
||||||
---@param key string |
|
||||||
---@param value any |
|
||||||
function Config:Write(key, value) |
|
||||||
self.config:Write(key, value) |
|
||||||
end |
|
||||||
|
|
||||||
---@param key string |
|
||||||
function Config:Sync(key) |
|
||||||
self.config:Sync(key) |
|
||||||
end |
|
||||||
|
|
||||||
Bastion.Config = Config |
|
@ -1,268 +0,0 @@ |
|||||||
local Tinkr, Bastion = ... |
|
||||||
local Interface = {} |
|
||||||
|
|
||||||
--[[ |
|
||||||
The current settings is named "Vertical" as it uses the Dragonflight Vertical |
|
||||||
layout, rather than the Canvas layout. Vertical looks better, is easier to |
|
||||||
format and use. Canvas layout allows you to add multi-select dropdowns, text |
|
||||||
inputs, and more. I prefer vertical. Canvas support will be added in the future. |
|
||||||
]]-- |
|
||||||
|
|
||||||
local Hotbar = {} |
|
||||||
Hotbar.__index = Hotbar |
|
||||||
|
|
||||||
Bastion.Hotbars = {} |
|
||||||
|
|
||||||
-- Constructor |
|
||||||
---@return Hotbar |
|
||||||
function Hotbar:New(details) |
|
||||||
local self = setmetatable({}, Hotbar) |
|
||||||
self.button_size = 45 |
|
||||||
self.button_spacing = 5 |
|
||||||
self.button_count = details.buttonCount |
|
||||||
self.name = details.name |
|
||||||
self.options = details.options |
|
||||||
|
|
||||||
local position = self.options.config:Read("bar_location", { "CENTER", 0, -50 }) |
|
||||||
|
|
||||||
|
|
||||||
self.frame = CreateFrame("Frame", nil, UIParent, "SecureHandlerStateTemplate") |
|
||||||
self.frame:SetWidth(self.button_count * (32 + self.button_spacing) - self.button_spacing) -- width = total width of all buttons + total width of all spacings |
|
||||||
self.frame:SetHeight(32 + 20) |
|
||||||
|
|
||||||
|
|
||||||
self.frame:SetPoint(position[1], position[2], position[3]) |
|
||||||
|
|
||||||
self.title = self.frame:CreateFontString(nil, "OVERLAY", "Game15Font") |
|
||||||
|
|
||||||
self.title:SetPoint("BOTTOMLEFT", self.frame, "LEFT", 0, 10) -- adjust these values as necessary |
|
||||||
|
|
||||||
self.title:SetText(self.name) -- replace this with your desired title |
|
||||||
|
|
||||||
self.frame:EnableMouse(true) |
|
||||||
self.frame:SetMovable(true) |
|
||||||
self.frame:SetClampedToScreen(true) |
|
||||||
self.frame:RegisterForDrag("LeftButton") |
|
||||||
self.frame:SetScript("OnDragStart", self.frame.StartMoving) |
|
||||||
self.frame:SetScript("OnDragStop", function() |
|
||||||
self.frame:StopMovingOrSizing() |
|
||||||
local point, _, _, x, y = self.frame:GetPoint() |
|
||||||
self.options.config:Write("bar_location", { point, x, y }) |
|
||||||
end) |
|
||||||
|
|
||||||
if not self.options.config:Read("display_hotbar_" .. self.options.name, true) then |
|
||||||
self.frame:Hide() |
|
||||||
end |
|
||||||
|
|
||||||
self.options:Checkbox({ |
|
||||||
category = "display_hotbar", |
|
||||||
var = self.name, |
|
||||||
name = self.name .. " Hotbar", |
|
||||||
tooltip = "Display the hotbar for " .. self.name, |
|
||||||
default = true |
|
||||||
}) |
|
||||||
|
|
||||||
self.buttons = {} |
|
||||||
|
|
||||||
table.insert(Bastion.Hotbars, self) |
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
-- Needed to ensure hotbars are positioned properly and hidden when a user hides them in settings |
|
||||||
function Hotbar:Refresh() |
|
||||||
if not self.options.config:Read("display_hotbar_" .. self.options.name, true) then |
|
||||||
if self.frame:IsVisible() then |
|
||||||
self.frame:Hide() |
|
||||||
end |
|
||||||
else |
|
||||||
if not self.frame:IsVisible() then |
|
||||||
self.frame:Show() |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
-- Adds a button to the hotbar. |
|
||||||
-- TODO: Make this not a hot mess for classic/retail |
|
||||||
function Hotbar:AddButton(details) |
|
||||||
local button = CreateFrame("CheckButton", nil, self.frame, "UIPanelButtonTemplate") |
|
||||||
button:SetNormalTexture(details.texture) |
|
||||||
button:SetPoint("CENTER") |
|
||||||
button:SetSize(32, 32) |
|
||||||
table.insert(self.buttons, button) |
|
||||||
if details.onClick then |
|
||||||
if details.toggle then |
|
||||||
local toggleAnim = false |
|
||||||
button:SetScript("OnClick", function() |
|
||||||
-- Toggle animation |
|
||||||
if toggleAnim then |
|
||||||
ActionButton_HideOverlayGlow(button) |
|
||||||
toggleAnim = false |
|
||||||
else |
|
||||||
ActionButton_ShowOverlayGlow(button) |
|
||||||
toggleAnim = true |
|
||||||
end |
|
||||||
details.onClick() |
|
||||||
end) |
|
||||||
else |
|
||||||
button:SetScript("OnClick", details.onClick) |
|
||||||
end |
|
||||||
end |
|
||||||
button:SetScript("OnEnter", function(self) |
|
||||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT") |
|
||||||
GameTooltip:AddLine(details.name, 1, 1, 1) -- sets the tooltip as the button's name |
|
||||||
GameTooltip:AddLine(details.tooltip) |
|
||||||
GameTooltip:Show() |
|
||||||
end) |
|
||||||
button:SetScript("OnLeave", function(self) |
|
||||||
GameTooltip:Hide() |
|
||||||
end) |
|
||||||
for i, btn in ipairs(self.buttons) do |
|
||||||
button:SetPoint("BOTTOMLEFT", (i - 1) * (32 + self.button_spacing), 0) -- Position each button |
|
||||||
end |
|
||||||
|
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
local Category = {} |
|
||||||
Category.__index = Category |
|
||||||
|
|
||||||
-- Constructor |
|
||||||
---@param name String |
|
||||||
---@param config Config |
|
||||||
---@return Category |
|
||||||
function Category:New(name, parent) |
|
||||||
local self = setmetatable({}, Category) |
|
||||||
self.name = name |
|
||||||
self.parent = parent or nil |
|
||||||
|
|
||||||
if self.parent then |
|
||||||
self.settings, self.layout = Settings.RegisterVerticalLayoutSubcategory(parent.settings, self.name) |
|
||||||
self.config = self.parent.config |
|
||||||
else |
|
||||||
self.settings, self.layout = Settings.RegisterVerticalLayoutCategory(self.name) |
|
||||||
self.config = Bastion.Config:New(name) |
|
||||||
end |
|
||||||
|
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
function Category:AddSubsection(section_title) |
|
||||||
local section = CreateSettingsListSectionHeaderInitializer(section_title) |
|
||||||
self.layout:AddInitializer(section) |
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
-- Register the Category object with the Blizzard UI |
|
||||||
---@return nil |
|
||||||
function Category:Register() |
|
||||||
Settings.RegisterAddOnCategory(self.settings) |
|
||||||
end |
|
||||||
|
|
||||||
-- Adds a checkbox to the Category |
|
||||||
---@param details Table |
|
||||||
function Category:Checkbox(details) |
|
||||||
local default_value = details.default or false |
|
||||||
local variable_name = details.category .. "_" .. details.var |
|
||||||
|
|
||||||
local setting = Settings.RegisterAddOnSetting(self.settings, details.name, variable_name, type(default_value), self.config:Read(variable_name, default_value)) |
|
||||||
|
|
||||||
Settings.SetOnValueChangedCallback(variable_name, function(event) |
|
||||||
self.config:Write(variable_name, setting:GetValue()) |
|
||||||
end) |
|
||||||
|
|
||||||
local initializer = Settings.CreateCheckBox(self.settings, setting, details.tooltip and ("\n" .. details.tooltip) or "") |
|
||||||
|
|
||||||
if details.disabled then |
|
||||||
initializer:AddModifyPredicate(function() return false end) |
|
||||||
self.config:Write(variable_name, false) |
|
||||||
end |
|
||||||
|
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
-- Adds a checkbox to the Category |
|
||||||
---@param details Table |
|
||||||
function Category:SubCheck(details) |
|
||||||
local default_value = details.default or false |
|
||||||
local variable_name = details.category .. "_" .. details.var |
|
||||||
|
|
||||||
local setting = Settings.RegisterAddOnSetting(self.settings, details.name, variable_name, type(default_value), self.config:Read(variable_name, default_value)) |
|
||||||
|
|
||||||
Settings.SetOnValueChangedCallback(variable_name, function(event) |
|
||||||
print(variable_name, setting:GetValue()) |
|
||||||
self.config:Write(variable_name, setting:GetValue()) |
|
||||||
details.sub:Toggle() |
|
||||||
end) |
|
||||||
|
|
||||||
local initializer = Settings.CreateCheckBox(self.settings, setting, details.tooltip and ("\n" .. details.tooltip) or "") |
|
||||||
|
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
-- Adds a slider to the Category |
|
||||||
---@param details Table |
|
||||||
function Category:Slider(details) |
|
||||||
details = details or {} |
|
||||||
local default_value = details.default or 0 |
|
||||||
local min_value = details.min or 0 |
|
||||||
local max_value = details.max or 100 |
|
||||||
|
|
||||||
local step = details.step or 1 |
|
||||||
local variable_name = details.category .. "_" .. details.var |
|
||||||
|
|
||||||
local setting = Settings.RegisterAddOnSetting(self.settings, details.name, variable_name, type(default_value), tonumber(self.config:Read(variable_name, default_value))) |
|
||||||
|
|
||||||
Settings.SetOnValueChangedCallback(variable_name, function(event) |
|
||||||
self.config:Write(variable_name, setting:GetValue()) |
|
||||||
end) |
|
||||||
|
|
||||||
local options = Settings.CreateSliderOptions(min_value, max_value, step) |
|
||||||
|
|
||||||
options:SetLabelFormatter(MinimalSliderWithSteppersMixin.Label.Right) |
|
||||||
|
|
||||||
local initializer = Settings.CreateSlider(self.settings, setting, options, details.tooltip and ("\n" .. details.tooltip) or "") |
|
||||||
|
|
||||||
-- if details.disabled then |
|
||||||
-- initializer:AddModifyPredicate(function() return false end) |
|
||||||
-- self.config:Write(variable_name, false) |
|
||||||
-- end |
|
||||||
|
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
-- Adds a dropdown to the category |
|
||||||
---@param details Table |
|
||||||
function Category:Dropdown(details) |
|
||||||
local default_value = details.default |
|
||||||
local variable_name = details.category .. "_" .. details.var |
|
||||||
|
|
||||||
local setting = Settings.RegisterAddOnSetting(self.settings, details.name, variable_name, type(default_value), self.config:Read(variable_name, default_value)) |
|
||||||
|
|
||||||
local function GetOptions() |
|
||||||
local container = Settings.CreateControlTextContainer() |
|
||||||
for k, v in ipairs(details.options) do |
|
||||||
container:Add(v[2], v[1]) |
|
||||||
end |
|
||||||
return container:GetData() |
|
||||||
end |
|
||||||
|
|
||||||
Settings.SetOnValueChangedCallback(variable_name, function(event) |
|
||||||
self.config:Write(variable_name, setting:GetValue()) |
|
||||||
end) |
|
||||||
|
|
||||||
local initializer = Settings.CreateDropDown(self.settings, setting, GetOptions, details.tooltip or "") |
|
||||||
|
|
||||||
if details.disabled then |
|
||||||
initializer:AddModifyPredicate(function() return false end) |
|
||||||
self.config:Write(variable_name, false) |
|
||||||
end |
|
||||||
|
|
||||||
return self |
|
||||||
end |
|
||||||
|
|
||||||
Interface.Hotbar = Hotbar |
|
||||||
Interface.Category = Category |
|
||||||
print("Interface Loaded") |
|
||||||
Bastion.Interface = Interface |
|
@ -0,0 +1,23 @@ |
|||||||
|
local Tinkr, Bastion = ... |
||||||
|
|
||||||
|
---@class SpellTrait |
||||||
|
local SpellTrait = {} |
||||||
|
SpellTrait.__index = SpellTrait |
||||||
|
|
||||||
|
-- Constructor |
||||||
|
---@param func function |
||||||
|
---@return SpellTrait |
||||||
|
function SpellTrait:New(func) |
||||||
|
local self = setmetatable({}, SpellTrait) |
||||||
|
self.func = func |
||||||
|
return self |
||||||
|
end |
||||||
|
|
||||||
|
-- Evaluate the trait |
||||||
|
---@param spell Spell |
||||||
|
---@return boolean |
||||||
|
function SpellTrait:Evaluate(spell) |
||||||
|
return self.func(spell) |
||||||
|
end |
||||||
|
|
||||||
|
return SpellTrait |
Loading…
Reference in new issue