forked from Bastion/Bastion
Compare commits
68 Commits
@ -1,188 +0,0 @@ |
||||
local Tinkr, _Bastion = ... |
||||
|
||||
---@type Bastion |
||||
local Bastion = _Bastion |
||||
|
||||
local BrewModule = Bastion.Module:New('brewmaster') |
||||
local Player = Bastion.UnitManager:Get('player') |
||||
local Target = Bastion.UnitManager:Get('target') |
||||
local None = Bastion.UnitManager:Get('none') |
||||
|
||||
local PurifyingBrew = Bastion.SpellBook:GetSpell(119582) |
||||
local CelestialBrew = Bastion.SpellBook:GetSpell(322507) |
||||
local PurifiedChi = Bastion.SpellBook:GetSpell(325092) |
||||
local AutoAttack = Bastion.SpellBook:GetSpell(6603) |
||||
local ImpCelestialBrew = Bastion.SpellBook:GetSpell(322510) |
||||
local ChiWave = Bastion.SpellBook:GetSpell(115098) |
||||
local RushingJadeWind = Bastion.SpellBook:GetSpell(116847) |
||||
local BreathOfFire = Bastion.SpellBook:GetSpell(115181) |
||||
local KegSmash = Bastion.SpellBook:GetSpell(121253) |
||||
local WeaponsOfOrder = Bastion.SpellBook:GetSpell(387184) |
||||
local BlackoutKick = Bastion.SpellBook:GetSpell(205523) |
||||
local RisingSunKick = Bastion.SpellBook:GetSpell(107428) |
||||
local TigerPalm = Bastion.SpellBook:GetSpell(100780) |
||||
local SpinningCraneKick = Bastion.SpellBook:GetSpell(322729) |
||||
local ExpelHarm = Bastion.SpellBook:GetSpell(322101) |
||||
local GiftOfTheOx = Bastion.SpellBook:GetSpell(124502) |
||||
|
||||
local CDsEnabled = false |
||||
|
||||
local Command = Bastion.Command:New('brewmaster') |
||||
|
||||
Command:Register('cooldowns', 'Toggle Brewmaster CDs', function() |
||||
CDsEnabled = not CDsEnabled |
||||
Bastion:Print('Brewmaster Cooldowns ' .. (CDsEnabled and 'enabled' or 'disabled')) |
||||
end) |
||||
|
||||
---@return number | nil |
||||
local function GetExpelHarmHealAmount() |
||||
-- Gift of the Ox orbs |
||||
local OrbCount = GetSpellCount(ExpelHarm:GetID()) or 0 |
||||
local OrbHeal = tonumber((GetSpellDescription(GiftOfTheOx:GetID()):match("%d+%S+%d"):gsub("%D",""))) |
||||
|
||||
print(GetSpellDescription(GiftOfTheOx:GetID()):match("%d+%S+%d")) |
||||
|
||||
-- expel harm |
||||
local ExpelHeal = tonumber((GetSpellDescription(ExpelHarm:GetID()):match("%d+%S+%d"):gsub("%D",""))) |
||||
|
||||
return ExpelHeal + (OrbHeal * OrbCount) |
||||
end |
||||
|
||||
---@return boolean |
||||
local function CombatRotation() |
||||
local isAoe = Player:GetEnemies(8) > 1 |
||||
|
||||
-- Attack the target is auto attack isnt active. |
||||
if AutoAttack:IsKnownAndUsable() and not IsCurrentSpell(AutoAttack:GetID()) and Player:InMelee(Target) and not Target:IsDead() then |
||||
AutoAttack:Cast(Target) |
||||
end |
||||
|
||||
local Stagger = UnitStagger("player") |
||||
|
||||
if Stagger > 10000 and PurifyingBrew:IsKnownAndUsable() and PurifyingBrew:GetChargesRemaining() > 1 or (PurifyingBrew:GetNextChargeCooldown() <= 2.5 and PurifyingBrew:GetChargesRemaining() == 1) then |
||||
PurifyingBrew:Cast(Player) |
||||
end |
||||
|
||||
if CelestialBrew:IsKnownAndUsable() and (not ImpCelestialBrew:IsKnown() or (ImpCelestialBrew:IsKnown() and Player:GetAuras():FindMy(PurifiedChi):IsUp())) then |
||||
return CelestialBrew:Cast(Player) |
||||
end |
||||
|
||||
local ExpelHarmHeal = GetExpelHarmHealAmount() |
||||
|
||||
if not Player:InMelee(Target) then |
||||
if not Player:GetAuras():FindMy(RushingJadeWind):IsUp() and RushingJadeWind:IsKnownAndUsable() then |
||||
return RushingJadeWind:Cast(Player) |
||||
end |
||||
if ChiWave:IsKnownAndUsable() and Target:Exists() and ChiWave:IsInRange(Target) and Player:IsFacing(Target) then |
||||
return ChiWave:Cast(Target) |
||||
end |
||||
end |
||||
|
||||
if BreathOfFire:IsKnownAndUsable() and BreathOfFire:IsInRange(Target) and Player:IsFacing(Target) then |
||||
return BreathOfFire:Cast(Player) |
||||
end |
||||
|
||||
if KegSmash:IsKnownAndUsable() and Target:Exists() and KegSmash:IsInRange(Target) and Player:IsFacing(Target) then |
||||
if KegSmash:GetChargesRemaining() == KegSmash:GetMaxCharges() then |
||||
return KegSmash:Cast(Target) |
||||
end |
||||
if KegSmash:GetChargesRemaining() == KegSmash:GetMaxCharges() - 1 and KegSmash:GetNextChargeCooldown() <= 3 then |
||||
return KegSmash:Cast(Target) |
||||
end |
||||
end |
||||
|
||||
if WeaponsOfOrder:IsKnownAndUsable() and CDsEnabled then |
||||
return WeaponsOfOrder:Cast(Player) |
||||
end |
||||
|
||||
-- Exploding Keg in AOE here |
||||
-- Rising Sun Kick In AOE here |
||||
|
||||
if BlackoutKick:IsKnownAndUsable() and Target:Exists() and BlackoutKick:IsInRange(Target) and Player:IsFacing(Target) then |
||||
return BlackoutKick:Cast(Target) |
||||
end |
||||
|
||||
if RisingSunKick:IsKnownAndUsable() and Target:Exists() and RisingSunKick:IsInRange(Target) and Player:IsFacing(Target) then |
||||
return RisingSunKick:Cast(Target) |
||||
end |
||||
|
||||
-- Exploding Keg in ST here |
||||
|
||||
if ChiWave:IsKnownAndUsable() and Target:Exists() and ChiWave:IsInRange(Target) then |
||||
return ChiWave:Cast(Target) |
||||
end |
||||
|
||||
if RushingJadeWind:IsKnownAndUsable() and (not Player:GetAuras():FindMy(RushingJadeWind):IsUp() or Player:GetAuras():FindMy(RushingJadeWind):GetRemainingTime() <= 2) then |
||||
return RushingJadeWind:Cast(Player) |
||||
end |
||||
|
||||
if not isAoe and TigerPalm:IsKnownAndUsable() and Target:Exists() and TigerPalm:IsInRange(Target) and Player:IsFacing(Target) then |
||||
if not KegSmash:IsKnown() then |
||||
return TigerPalm:Cast(Target) |
||||
else |
||||
local TigerPalmCost = GetSpellPowerCost(TigerPalm:GetID())[1]['cost'] |
||||
local KegSmashCost = GetSpellPowerCost(KegSmash:GetID())[1]['cost'] |
||||
local CurrentEnergy = Player:GetPower(Enum.PowerType.Energy) |
||||
|
||||
local CanKegSmash = KegSmash:GetChargesRemaining() > 0 or KegSmash:GetNextChargeCooldown() >= 2.5 |
||||
|
||||
if CanKegSmash then |
||||
if (CurrentEnergy - KegSmashCost) >= TigerPalmCost then |
||||
return TigerPalm:Cast(Target) |
||||
end |
||||
else |
||||
return TigerPalm:Cast(Target) |
||||
end |
||||
end |
||||
end |
||||
|
||||
if isAoe and SpinningCraneKick:IsKnownAndUsable() then |
||||
if not KegSmash:IsKnown() then |
||||
return SpinningCraneKick:Cast(Player) |
||||
else |
||||
local SpinningCraneKickCost = GetSpellPowerCost(SpinningCraneKick:GetID())[1]['cost'] |
||||
local KegSmashCost = GetSpellPowerCost(KegSmash:GetID())[1]['cost'] |
||||
local CurrentEnergy = Player:GetPower(Enum.PowerType.Energy) |
||||
|
||||
local CanKegSmash = KegSmash:GetChargesRemaining() > 0 or KegSmash:GetNextChargeCooldown() >= 2.5 |
||||
|
||||
if CanKegSmash then |
||||
if (CurrentEnergy - KegSmashCost) >= SpinningCraneKickCost then |
||||
return SpinningCraneKick:Cast(Player) |
||||
end |
||||
else |
||||
return SpinningCraneKick:Cast(Player) |
||||
end |
||||
end |
||||
end |
||||
|
||||
return false |
||||
end |
||||
|
||||
---@return boolean |
||||
local function OutOfCombatRotation() |
||||
return false |
||||
end |
||||
|
||||
local isRunning = false |
||||
|
||||
BrewModule:Sync(function() |
||||
if not isRunning then |
||||
Bastion:Print('Brewmaster Started') |
||||
isRunning = true |
||||
end |
||||
|
||||
if not Player:IsAlive() or Player:IsMounted() then |
||||
return false |
||||
end |
||||
|
||||
if Player:IsAffectingCombat() or IsCurrentSpell(AutoAttack:GetID()) then |
||||
-- Combat Rotation |
||||
return CombatRotation() |
||||
else |
||||
-- Out Of Combat Rotation |
||||
return OutOfCombatRotation() |
||||
end |
||||
end) |
||||
|
||||
Bastion:Register(BrewModule) |
@ -1,954 +0,0 @@ |
||||
-- local Tinkr, Bastion = ... |
||||
|
||||
-- local OutlawModule = Bastion.Module:New('outlaw') |
||||
-- local Evaluator = Tinkr.Util.Evaluator |
||||
-- local Player = Bastion.UnitManager:Get('player') |
||||
-- local None = Bastion.UnitManager:Get('none') |
||||
-- local Target = Bastion.UnitManager:Get('target') |
||||
|
||||
-- local Stealth = Bastion.SpellBook:GetSpell(115191) |
||||
-- local Kick = Bastion.SpellBook:GetSpell(1766) |
||||
-- local CountTheOdds = Bastion.SpellBook:GetSpell(381982) |
||||
-- local Shadowmeld = Bastion.SpellBook:GetSpell(58984) |
||||
-- local ShadowDance = Bastion.SpellBook:GetSpell(185313) |
||||
-- local ShadowDanceAura = Bastion.SpellBook:GetSpell(185422) |
||||
-- local HiddenOpportunity = Bastion.SpellBook:GetSpell(383281) |
||||
-- local RollTheBones = Bastion.SpellBook:GetSpell(315508) |
||||
-- local FanTheHammer = Bastion.SpellBook:GetSpell(381846) |
||||
-- local ImprovedAmbush = Bastion.SpellBook:GetSpell(381620) |
||||
-- local SummarilyDispatched = Bastion.SpellBook:GetSpell(381990) |
||||
-- local BladeFlurry = Bastion.SpellBook:GetSpell(13877) |
||||
-- local KillingSpree = Bastion.SpellBook:GetSpell(51690) |
||||
-- local ArcaneTorrent = Bastion.SpellBook:GetSpell(25046) |
||||
-- local ArcanePulse = Bastion.SpellBook:GetSpell(260364) |
||||
-- local LightsJudgment = Bastion.SpellBook:GetSpell(255647) |
||||
-- local BagOfTricks = Bastion.SpellBook:GetSpell(312411) |
||||
-- local Sepsis = Bastion.SpellBook:GetSpell(385408) |
||||
-- local BetweenTheEyes = Bastion.SpellBook:GetSpell(315341) |
||||
-- local GhostlyStrike = Bastion.SpellBook:GetSpell(196937) |
||||
-- local Dreadblades = Bastion.SpellBook:GetSpell(343142) |
||||
-- local Subterfuge = Bastion.SpellBook:GetSpell(108208) |
||||
-- local EchoingReprimand = Bastion.SpellBook:GetSpell(385616) |
||||
-- local Ambush = Bastion.SpellBook:GetSpell(8676) |
||||
-- local KeepItRolling = Bastion.SpellBook:GetSpell(381989) |
||||
-- local Audacity = Bastion.SpellBook:GetSpell(381845) |
||||
-- local FindWeakness = Bastion.SpellBook:GetSpell(91023) |
||||
-- local PistolShot = Bastion.SpellBook:GetSpell(185763) |
||||
-- local Opportunity = Bastion.SpellBook:GetSpell(279876) |
||||
-- local OpportunityAura = Bastion.SpellBook:GetSpell(195627) |
||||
-- local GreenskinsWickers = Bastion.SpellBook:GetSpell(386823) |
||||
-- local QuickDraw = Bastion.SpellBook:GetSpell(196938) |
||||
-- local Weaponmaster = Bastion.SpellBook:GetSpell(200733) |
||||
-- local SinisterStrike = Bastion.SpellBook:GetSpell(193315) |
||||
-- local AdrenalineRush = Bastion.SpellBook:GetSpell(13750) |
||||
-- local ImprovedAdrenalineRush = Bastion.SpellBook:GetSpell(395422) |
||||
-- local BladeRush = Bastion.SpellBook:GetSpell(271877) |
||||
-- local MarkedForDeath = Bastion.SpellBook:GetSpell(137619) |
||||
-- local ThistleTea = Bastion.SpellBook:GetSpell(381623) |
||||
-- local PotionOfUnbridledFury = Bastion.SpellBook:GetSpell(169299) |
||||
-- local Bloodlust = Bastion.SpellBook:GetSpell(2825) |
||||
-- local BloodFury = Bastion.SpellBook:GetSpell(20572) |
||||
-- local Berserking = Bastion.SpellBook:GetSpell(26297) |
||||
-- local Fireblood = Bastion.SpellBook:GetSpell(265221) |
||||
-- local AncestralCall = Bastion.SpellBook:GetSpell(274738) |
||||
-- local SliceAndDice = Bastion.SpellBook:GetSpell(315496) |
||||
-- local SwiftSlasher = Bastion.SpellBook:GetSpell(381988) |
||||
-- local ColdBlood = Bastion.SpellBook:GetSpell(382245) |
||||
-- local Dispatch = Bastion.SpellBook:GetSpell(2098) |
||||
-- local Vanish = Bastion.SpellBook:GetSpell(1856) |
||||
|
||||
-- local Broadside = Bastion.SpellBook:GetSpell(193356) |
||||
-- local GrandMelee = Bastion.SpellBook:GetSpell(193358) |
||||
-- local SkullAndCrossbones = Bastion.SpellBook:GetSpell(199603) |
||||
-- local TrueBearing = Bastion.SpellBook:GetSpell(193359) |
||||
-- local LoadedDice = Bastion.SpellBook:GetSpell(256171) |
||||
-- local BuriedTreasure = Bastion.SpellBook:GetSpell(199600) |
||||
-- local RuthlessPrecision = Bastion.SpellBook:GetSpell(193357) |
||||
|
||||
-- local PurgeTarget = Bastion.UnitManager:CreateCustomUnit('purge', function(unit) |
||||
-- local purge = 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) > 40 then |
||||
-- return false |
||||
-- end |
||||
|
||||
-- if unit:GetAuras():HasAnyStealableAura() then |
||||
-- purge = unit |
||||
-- return true |
||||
-- end |
||||
-- end) |
||||
|
||||
-- if purge == nil then |
||||
-- purge = None |
||||
-- end |
||||
|
||||
-- return purge |
||||
-- end) |
||||
|
||||
-- local KickTarget = Bastion.UnitManager:CreateCustomUnit('kick', function(unit) |
||||
-- local purge = 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) > 40 then |
||||
-- return false |
||||
-- end |
||||
|
||||
-- if Player:InMelee(unit) and unit:IsInterruptible(5) and Player:IsFacing(unit) then |
||||
-- purge = unit |
||||
-- return true |
||||
-- end |
||||
-- end) |
||||
|
||||
-- if purge == nil then |
||||
-- purge = None |
||||
-- end |
||||
|
||||
-- return purge |
||||
-- end) |
||||
|
||||
-- local Tank = Bastion.UnitManager:CreateCustomUnit('tank', function(unit) |
||||
-- local tank = nil |
||||
|
||||
-- Bastion.UnitManager:EnumFriends(function(unit) |
||||
-- if Player:GetDistance(unit) > 40 then |
||||
-- return false |
||||
-- end |
||||
|
||||
-- if not Player:CanSee(unit) then |
||||
-- return false |
||||
-- end |
||||
|
||||
-- if unit:IsDead() then |
||||
-- return false |
||||
-- end |
||||
|
||||
-- if unit:IsTank() then |
||||
-- tank = unit |
||||
-- return true |
||||
-- end |
||||
|
||||
-- return false |
||||
-- end) |
||||
|
||||
-- if tank == nil then |
||||
-- tank = None |
||||
-- end |
||||
|
||||
-- return tank |
||||
-- end) |
||||
|
||||
-- local Explosive = Bastion.UnitManager:CreateCustomUnit('explosive', function(unit) |
||||
-- local explosive = 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) > 40 then |
||||
-- return false |
||||
-- end |
||||
|
||||
-- if Player:InMelee(unit) and unit:GetID() == 120651 and Player:IsFacing(unit) then |
||||
|
||||
-- explosive = unit |
||||
-- return true |
||||
-- end |
||||
-- end) |
||||
|
||||
-- if explosive == nil then |
||||
-- explosive = None |
||||
-- end |
||||
|
||||
-- return explosive |
||||
-- end) |
||||
|
||||
-- local DefaultAPL = Bastion.APL:New('default') |
||||
-- local StealthAPL = Bastion.APL:New('stealth') |
||||
-- local CDsAPL = Bastion.APL:New('cds') |
||||
-- local FinishAPL = Bastion.APL:New('finish') |
||||
-- local BuildAPL = Bastion.APL:New('build') |
||||
-- local StealthCDsAPL = Bastion.APL:New('stealthcds') |
||||
|
||||
-- -- # Executed every time the actor is available. |
||||
-- -- # Restealth if possible (no vulnerable enemies in combat) |
||||
-- -- actions=stealth |
||||
|
||||
-- DefaultAPL:AddSpell( |
||||
-- Stealth:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and not Player:GetAuras():FindMy(Stealth):IsUp() and |
||||
-- not Player:IsAffectingCombat() and not IsMounted() |
||||
-- end |
||||
-- ):SetTarget(Player) |
||||
-- ) |
||||
|
||||
-- -- # Interrupt on cooldown to allow simming interactions with that |
||||
-- -- actions+=/kick |
||||
-- DefaultAPL:AddSpell( |
||||
-- Kick:CastableIf(function(self) |
||||
-- return self:IsKnownAndUsable() and KickTarget:Exists() and self:IsInRange(KickTarget) and |
||||
-- self:IsKnownAndUsable() and |
||||
-- not Player:IsCastingOrChanneling() and Player:IsFacing(Target) |
||||
-- end):SetTarget(KickTarget) |
||||
-- ) |
||||
-- -- # Checks if we are in an appropriate Stealth state for triggering the Count the Odds bonus |
||||
-- -- actions+=/variable,name=stealthed_cto,value=talent.count_the_odds&(stealthed.basic|buff.shadowmeld.up|buff.shadow_dance.up) |
||||
-- DefaultAPL:AddVariable( |
||||
-- 'stealthed_cto', |
||||
-- function() |
||||
-- return CountTheOdds:IsKnown() and (Player:GetAuras():FindMy(Stealth):IsUp() or |
||||
-- Player:GetAuras():FindMy(Shadowmeld):IsUp() or |
||||
-- Player:GetAuras():FindMy(ShadowDanceAura):IsUp()) |
||||
-- end |
||||
-- ) |
||||
|
||||
-- local function GetRTBCount() |
||||
-- local count = 0 |
||||
|
||||
-- if Player:GetAuras():FindMy(Broadside):IsUp() then |
||||
-- count = count + 1 |
||||
-- end |
||||
|
||||
-- if Player:GetAuras():FindMy(GrandMelee):IsUp() then |
||||
-- count = count + 1 |
||||
-- end |
||||
|
||||
-- if Player:GetAuras():FindMy(SkullAndCrossbones):IsUp() then |
||||
-- count = count + 1 |
||||
-- end |
||||
|
||||
-- if Player:GetAuras():FindMy(TrueBearing):IsUp() then |
||||
-- count = count + 1 |
||||
-- end |
||||
|
||||
-- if Player:GetAuras():FindMy(LoadedDice):IsUp() then |
||||
-- count = count + 1 |
||||
-- end |
||||
|
||||
-- if Player:GetAuras():FindMy(BuriedTreasure):IsUp() then |
||||
-- count = count + 1 |
||||
-- end |
||||
|
||||
-- if Player:GetAuras():FindMy(RuthlessPrecision):IsUp() then |
||||
-- count = count + 1 |
||||
-- end |
||||
|
||||
-- return count |
||||
-- end |
||||
|
||||
-- -- # Roll the Bones Reroll Conditions |
||||
-- -- actions+=/variable,name=rtb_reroll,if=!talent.hidden_opportunity,value=rtb_buffs<2&(!buff.broadside.up&(!talent.fan_the_hammer|!buff.skull_and_crossbones.up)&!buff.true_bearing.up|buff.loaded_dice.up)|rtb_buffs=2&(buff.buried_treasure.up&buff.grand_melee.up|!buff.broadside.up&!buff.true_bearing.up&buff.loaded_dice.up) |
||||
-- DefaultAPL:AddVariable( |
||||
-- 'rtb_reroll', |
||||
-- function() |
||||
-- if not HiddenOpportunity:IsKnown() then |
||||
-- return GetRTBCount() < 2 and |
||||
-- (not Player:GetAuras():FindMy(Broadside):IsUp() and |
||||
-- (not FanTheHammer:IsKnown() or |
||||
-- not Player:GetAuras():FindMy(SkullAndCrossbones):IsUp()) and |
||||
-- not Player:GetAuras():FindMy(TrueBearing):IsUp() or |
||||
-- Player:GetAuras():FindMy(LoadedDice):IsUp()) or |
||||
-- GetRTBCount() == 2 and |
||||
-- (Player:GetAuras():FindMy(BuriedTreasure):IsUp() and |
||||
-- Player:GetAuras():FindMy(GrandMelee):IsUp() or |
||||
-- not Player:GetAuras():FindMy(Broadside):IsUp() and |
||||
-- not Player:GetAuras():FindMy(TrueBearing):IsUp() and |
||||
-- Player:GetAuras():FindMy(LoadedDice):IsUp()) |
||||
-- end |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- # Additional Reroll Conditions for Keep it Rolling or Count the Odds |
||||
-- -- actions+=/variable,name=rtb_reroll,if=!talent.hidden_opportunity&(talent.keep_it_rolling|talent.count_the_odds),value=variable.rtb_reroll|((rtb_buffs.normal=0&rtb_buffs.longer>=1)&!(buff.broadside.up&buff.true_bearing.up&buff.skull_and_crossbones.up)&!(buff.broadside.remains>39|buff.true_bearing.remains>39|buff.ruthless_precision.remains>39|buff.skull_and_crossbones.remains>39)) |
||||
-- DefaultAPL:AddVariable( |
||||
-- 'rtb_reroll', |
||||
-- function() |
||||
-- if not HiddenOpportunity:IsKnown() then |
||||
-- return GetRTBCount() < 2 and |
||||
-- (not Player:GetAuras():FindMy(Broadside):IsUp() and |
||||
-- (not FanTheHammer:IsKnown() or |
||||
-- not Player:GetAuras():FindMy(SkullAndCrossbones):IsUp()) and |
||||
-- not Player:GetAuras():FindMy(TrueBearing):IsUp() or |
||||
-- Player:GetAuras():FindMy(LoadedDice):IsUp()) or |
||||
-- GetRTBCount() == 2 and |
||||
-- (Player:GetAuras():FindMy(BuriedTreasure):IsUp() and |
||||
-- Player:GetAuras():FindMy(GrandMelee):IsUp() or |
||||
-- not Player:GetAuras():FindMy(Broadside):IsUp() and |
||||
-- not Player:GetAuras():FindMy(TrueBearing):IsUp() and |
||||
-- Player:GetAuras():FindMy(LoadedDice):IsUp()) |
||||
-- end |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- # With Hidden Opportunity, prioritize rerolling for Skull and Crossbones over everything else |
||||
-- -- actions+=/variable,name=rtb_reroll,if=talent.hidden_opportunity,value=!rtb_buffs.will_lose.skull_and_crossbones&(rtb_buffs.will_lose-rtb_buffs.will_lose.grand_melee)<2+buff.loaded_dice.up |
||||
-- DefaultAPL:AddVariable( |
||||
-- 'rtb_reroll', |
||||
-- function() |
||||
-- if HiddenOpportunity:IsKnown() then |
||||
-- return not Player:GetAuras():FindMy(SkullAndCrossbones):IsUp() and |
||||
-- ((Player:GetAuras():FindMy(SkullAndCrossbones):IsUp() and 1 or 0) - |
||||
-- (Player:GetAuras():FindMy(GrandMelee):IsUp() and 1 or 0)) < |
||||
-- 2 + (Player:GetAuras():FindMy(LoadedDice):IsUp() and 1 or 0) |
||||
-- end |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- # Avoid rerolls when we will not have time remaining on the fight or add wave to recoup the opportunity cost of the global |
||||
-- -- actions+=/variable,name=rtb_reroll,op=reset,if=!(raid_event.adds.remains>12|raid_event.adds.up&(raid_event.adds.in-raid_event.adds.remains)<6|target.time_to_die>12)|fight_remains<12 |
||||
-- DefaultAPL:AddVariable( |
||||
-- 'rtb_reroll', |
||||
-- function() |
||||
-- if not HiddenOpportunity:IsKnown() then |
||||
-- return GetRTBCount() < 2 and |
||||
-- (not Player:GetAuras():FindMy(Broadside):IsUp() and |
||||
-- (not FanTheHammer:IsKnown() or |
||||
-- not Player:GetAuras():FindMy(SkullAndCrossbones):IsUp()) and |
||||
-- not Player:GetAuras():FindMy(TrueBearing):IsUp() or |
||||
-- Player:GetAuras():FindMy(LoadedDice):IsUp()) or |
||||
-- GetRTBCount() == 2 and |
||||
-- (Player:GetAuras():FindMy(BuriedTreasure):IsUp() and |
||||
-- Player:GetAuras():FindMy(GrandMelee):IsUp() or |
||||
-- not Player:GetAuras():FindMy(Broadside):IsUp() and |
||||
-- not Player:GetAuras():FindMy(TrueBearing):IsUp() and |
||||
-- Player:GetAuras():FindMy(LoadedDice):IsUp()) |
||||
-- end |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- # Ensure we get full Ambush CP gains and aren't rerolling Count the Odds buffs away |
||||
-- -- actions+=/variable,name=ambush_condition,value=combo_points.deficit>=2+talent.improved_ambush+buff.broadside.up&energy>=50&(!talent.count_the_odds|buff.roll_the_bones.remains>=10) |
||||
-- DefaultAPL:AddVariable( |
||||
-- 'ambush_condition', |
||||
-- function() |
||||
-- return Player:GetComboPointsDeficit() >= 2 + (ImprovedAmbush:IsKnown() and 1 or 0) + |
||||
-- (Player:GetAuras():FindMy(Broadside):IsUp() and 1 or 0) and |
||||
-- Player:GetPower() >= 50 and |
||||
-- (not CountTheOdds:IsKnown() or |
||||
-- Player:GetAuras():FindMy(RollTheBones):GetRemainingTime() >= 10) |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- # Finish at 6 (5 with Summarily Dispatched talented) CP or CP Max-1, whichever is greater of the two |
||||
-- -- actions+=/variable,name=finish_condition,value=combo_points>=((cp_max_spend-1)<?(6-talent.summarily_dispatched))|effective_combo_points>=cp_max_spend |
||||
-- DefaultAPL:AddVariable( |
||||
-- 'finish_condition', |
||||
-- function() |
||||
-- return Player:GetComboPoints() >= |
||||
-- math.min(Player:GetComboPointsMax() - 1, 6 - (SummarilyDispatched:IsKnown() and 1 or 0)) or |
||||
-- Player:GetComboPoints() >= Player:GetComboPointsMax() |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- # With multiple targets, this variable is checked to decide whether some CDs should be synced with Blade Flurry |
||||
-- -- actions+=/variable,name=blade_flurry_sync,value=spell_targets.blade_flurry<2&raid_event.adds.in>20|buff.blade_flurry.remains>1+talent.killing_spree.enabled |
||||
-- DefaultAPL:AddVariable( |
||||
-- 'blade_flurry_sync', |
||||
-- function() |
||||
-- return Player:GetMeleeAttackers() < 2 and |
||||
-- (not Player:GetAuras():FindMy(BladeFlurry):IsUp() or |
||||
-- Player:GetAuras():FindMy(BladeFlurry):GetRemainingTime() > 1 + |
||||
-- (KillingSpree:IsKnown() and 1 or 0)) |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- # Higher priority Stealth list for Count the Odds or true Stealth/Vanish that will break in a single global |
||||
-- -- actions+=/call_action_list,name=stealth,if=stealthed.basic|buff.shadowmeld.up |
||||
-- DefaultAPL:AddAPL( |
||||
-- StealthAPL, |
||||
-- function() |
||||
-- return Player:IsStealthed() or Player:GetAuras():FindMy(Shadowmeld):IsUp() |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- actions+=/call_action_list,name=cds |
||||
-- DefaultAPL:AddAPL( |
||||
-- CDsAPL, |
||||
-- function() |
||||
-- return true |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- # Lower priority Stealth list for Shadow Dance |
||||
-- -- actions+=/call_action_list,name=stealth,if=variable.stealthed_cto |
||||
-- DefaultAPL:AddAPL( |
||||
-- StealthAPL, |
||||
-- function() |
||||
-- return DefaultAPL:GetVariable('stealthed_cto') |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- actions+=/run_action_list,name=finish,if=variable.finish_condition |
||||
-- DefaultAPL:AddAPL( |
||||
-- FinishAPL, |
||||
-- function() |
||||
-- return DefaultAPL:GetVariable('finish_condition') |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- actions+=/call_action_list,name=build |
||||
-- DefaultAPL:AddAPL( |
||||
-- BuildAPL, |
||||
-- function() |
||||
-- return true |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- actions+=/arcane_torrent,if=energy.base_deficit>=15+energy.regen |
||||
-- DefaultAPL:AddSpell( |
||||
-- ArcaneTorrent:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and Player:GetPowerDeficit() >= 15 + Player:GetPowerRegen() |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
|
||||
-- ) |
||||
|
||||
-- -- actions+=/arcane_pulse |
||||
-- DefaultAPL:AddSpell( |
||||
-- ArcanePulse:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions+=/lights_judgment |
||||
-- DefaultAPL:AddSpell( |
||||
-- LightsJudgment:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions+=/bag_of_tricks |
||||
-- DefaultAPL:AddSpell( |
||||
-- BagOfTricks:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # Builders |
||||
-- -- actions.build=sepsis,target_if=max:target.time_to_die*debuff.between_the_eyes.up,if=target.time_to_die>11&debuff.between_the_eyes.up|fight_remains<11 |
||||
-- BuildAPL:AddSpell( |
||||
-- Sepsis:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and ((Target:TimeToDie() > 11 and |
||||
-- Target:GetAuras():FindMy(BetweenTheEyes):IsUp()) or |
||||
-- Player:TimeToDie() < 11) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.build+=/ghostly_strike,if=debuff.ghostly_strike.remains<=3&(spell_targets.blade_flurry<=2|buff.dreadblades.up)&!buff.subterfuge.up&target.time_to_die>=5 |
||||
-- BuildAPL:AddSpell( |
||||
-- GhostlyStrike:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and Target:GetAuras():FindMy(GhostlyStrike):GetRemainingTime() <= 3 and |
||||
-- (Player:GetMeleeAttackers() <= 2 or Player:GetAuras():FindMy(Dreadblades):IsUp()) and |
||||
-- not Player:GetAuras():FindMy(Subterfuge):IsUp() and Target:TimeToDie() >= 5 |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.build+=/echoing_reprimand,if=!buff.dreadblades.up |
||||
-- BuildAPL:AddSpell( |
||||
-- EchoingReprimand:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and not Player:GetAuras():FindMy(Dreadblades):IsUp() |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # High priority Ambush line to apply Find Weakness or consume Audacity/Sepsis buff before Pistol Shot |
||||
-- -- actions.build+=/ambush,if=(talent.hidden_opportunity|talent.keep_it_rolling)&(buff.audacity.up|buff.sepsis_buff.up|buff.subterfuge.up&cooldown.keep_it_rolling.ready)|talent.find_weakness&debuff.find_weakness.down |
||||
-- BuildAPL:AddSpell( |
||||
-- Ambush:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and ((HiddenOpportunity:IsKnown() or KeepItRolling:IsKnown()) and |
||||
-- (Player:GetAuras():FindMy(Audacity):IsUp() or Player:GetAuras():FindMy(Sepsis):IsUp() or |
||||
-- (Player:GetAuras():FindMy(Subterfuge):IsUp() and KeepItRolling:OnCooldown())) or |
||||
-- (FindWeakness:IsKnown() and Target:GetAuras():FindMy(FindWeakness):IsDown())) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # With Audacity + Hidden Opportunity + Fan the Hammer, use Pistol Shot to proc Audacity any time Ambush is not available |
||||
-- -- actions.build+=/pistol_shot,if=talent.fan_the_hammer&talent.audacity&talent.hidden_opportunity&buff.opportunity.up&!buff.audacity.up&!buff.subterfuge.up&!buff.shadow_dance.up |
||||
-- BuildAPL:AddSpell( |
||||
-- PistolShot:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and FanTheHammer:IsKnown() and Audacity:IsKnown() and |
||||
-- HiddenOpportunity:IsKnown() and |
||||
-- Player:GetAuras():FindMy(OpportunityAura):IsUp() and not Player:GetAuras():FindMy(Audacity):IsUp() and |
||||
-- not Player:GetAuras():FindMy(Subterfuge):IsUp() and not Player:GetAuras():FindMy(ShadowDance):IsUp() |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # Use Greenskins Wickers buff immediately with Opportunity unless running Fan the Hammer |
||||
-- -- actions.build+=/pistol_shot,if=buff.greenskins_wickers.up&(!talent.fan_the_hammer&buff.opportunity.up|buff.greenskins_wickers.remains<1.5) |
||||
-- BuildAPL:AddSpell( |
||||
-- PistolShot:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and Player:GetAuras():FindMy(GreenskinsWickers):IsUp() and |
||||
-- (not FanTheHammer:IsKnown() and Player:GetAuras():FindMy(OpportunityAura):IsUp() or |
||||
-- Player:GetAuras():FindMy(GreenskinsWickers):GetRemainingTime() < 1.5) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- const int stacks = 1 + as<int>( p()->talent.outlaw.fan_the_hammer->effectN( 1 ).base_value() ); |
||||
-- local function MaxOpportunity() |
||||
-- return 1 + (FanTheHammer:IsKnown() and 1 or 0) |
||||
-- end |
||||
|
||||
-- -- # With Fan the Hammer, consume Opportunity at max stacks or if we will get max 4+ CP and Dreadblades is not up |
||||
-- -- actions.build+=/pistol_shot,if=talent.fan_the_hammer&buff.opportunity.up&(buff.opportunity.stack>=buff.opportunity.max_stack|buff.opportunity.remains<2) |
||||
-- BuildAPL:AddSpell( |
||||
-- PistolShot:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and FanTheHammer:IsKnown() and |
||||
-- Player:GetAuras():FindMy(OpportunityAura):IsUp() and |
||||
-- ( |
||||
-- Player:GetAuras():FindMy(OpportunityAura):GetCount() >= |
||||
-- MaxOpportunity() |
||||
-- or |
||||
-- Player:GetAuras():FindMy(OpportunityAura):GetRemainingTime() < 2) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.build+=/pistol_shot,if=talent.fan_the_hammer&buff.opportunity.up&combo_points.deficit>((1+talent.quick_draw)*talent.fan_the_hammer.rank)&!buff.dreadblades.up&(!talent.hidden_opportunity|!buff.subterfuge.up&!buff.shadow_dance.up) |
||||
-- BuildAPL:AddSpell( |
||||
-- PistolShot:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and FanTheHammer:IsKnown() and |
||||
-- Player:GetAuras():FindMy(OpportunityAura):IsUp() and |
||||
-- Player:GetComboPointsDeficit() > ((1 + (QuickDraw:IsKnown() and 1 or 0)) * 1) and |
||||
-- not Player:GetAuras():FindMy(Dreadblades):IsUp() and |
||||
-- (not HiddenOpportunity:IsKnown() or not Player:GetAuras():FindMy(Subterfuge):IsUp() and |
||||
-- not Player:GetAuras():FindMy(ShadowDance):IsUp()) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.build+=/pool_resource,for_next=1 |
||||
-- -- actions.build+=/ambush,if=talent.hidden_opportunity|talent.find_weakness&debuff.find_weakness.down |
||||
-- BuildAPL:AddSpell( |
||||
-- Ambush:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and (HiddenOpportunity:IsKnown() or |
||||
-- (FindWeakness:IsKnown() and Target:GetAuras():FindMy(FindWeakness):IsDown())) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # Use Pistol Shot with Opportunity if Combat Potency won't overcap energy, when it will exactly cap CP, or when using Quick Draw |
||||
-- -- actions.build+=/pistol_shot,if=!talent.fan_the_hammer&buff.opportunity.up&(energy.base_deficit>energy.regen*1.5|!talent.weaponmaster&combo_points.deficit<=1+buff.broadside.up|talent.quick_draw.enabled|talent.audacity.enabled&!buff.audacity.up) |
||||
-- BuildAPL:AddSpell( |
||||
-- PistolShot:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and not FanTheHammer:IsKnown() and |
||||
-- Player:GetAuras():FindMy(OpportunityAura):IsUp() and |
||||
-- (Player:GetPowerDeficit() > Player:GetPowerRegen() * 1.5 or |
||||
-- (not Weaponmaster:IsKnown() and |
||||
-- Player:GetComboPointsDeficit() <= 1 + (Player:GetAuras():FindMy(Broadside):IsUp() and 1 or 0)) or |
||||
-- QuickDraw:IsKnown() or |
||||
-- (Audacity:IsKnown() and not Player:GetAuras():FindMy(Audacity):IsUp())) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
|
||||
-- -- actions.build+=/sinister_strike |
||||
-- BuildAPL:AddSpell( |
||||
-- SinisterStrike:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # Cooldowns |
||||
-- -- actions.cds=adrenaline_rush,if=!buff.adrenaline_rush.up&(!talent.improved_adrenaline_rush|combo_points<=2) |
||||
-- CDsAPL:AddSpell( |
||||
-- AdrenalineRush:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and not Player:GetAuras():FindMy(AdrenalineRush):IsUp() and |
||||
-- (not ImprovedAdrenalineRush:IsKnown() or Player:GetComboPoints() <= 2) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/blade_flurry,if=spell_targets>=2&buff.blade_flurry.remains<gcd |
||||
-- CDsAPL:AddSpell( |
||||
-- BladeFlurry:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and Target:GetMeleeAttackers() >= 2 and |
||||
-- Player:GetAuras():FindMy(BladeFlurry):GetRemainingTime() < Player:GetGCD() |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/roll_the_bones,if=buff.dreadblades.down&(rtb_buffs.total=0|variable.rtb_reroll) |
||||
-- CDsAPL:AddSpell( |
||||
-- RollTheBones:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and Player:GetAuras():FindMy(Dreadblades):IsDown() and |
||||
-- (GetRTBCount() == 0 or |
||||
-- DefaultAPL:GetVariable("rtb_reroll")) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/keep_it_rolling,if=!variable.rtb_reroll&(buff.broadside.up+buff.true_bearing.up+buff.skull_and_crossbones.up+buff.ruthless_precision.up)>2&(buff.shadow_dance.down|rtb_buffs>=6) |
||||
-- CDsAPL:AddSpell( |
||||
-- RollTheBones:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and not DefaultAPL:GetVariable("rtb_reroll") and |
||||
-- ((Player:GetAuras():FindMy(Broadside):IsUp() and 1 or 0) + |
||||
-- (Player:GetAuras():FindMy(TrueBearing):IsUp() and 1 or 0) + |
||||
-- (Player:GetAuras():FindMy(SkullAndCrossbones):IsUp() and 1 or 0) + |
||||
-- (Player:GetAuras():FindMy(RuthlessPrecision):IsUp() and 1 or 0)) > 2 and |
||||
-- (Player:GetAuras():FindMy(ShadowDance):IsDown() or |
||||
-- GetRTBCount() >= 6) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/blade_rush,if=variable.blade_flurry_sync&!buff.dreadblades.up&(energy.base_time_to_max>4+stealthed.rogue-spell_targets%3) |
||||
-- CDsAPL:AddSpell( |
||||
-- BladeRush:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and DefaultAPL:GetVariable("blade_flurry_sync") and |
||||
-- not Player:GetAuras():FindMy(Dreadblades):IsUp() and |
||||
-- (Player:GetTimeToPowerPercent() > 4 + (Player:GetAuras():FindMy(Subterfuge):IsUp() and 1 or 0) + |
||||
-- (Player:GetAuras():FindMy(ShadowDance):IsUp() and 1 or 0) - Target:GetMeleeAttackers() % 3) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/call_action_list,name=stealth_cds,if=!stealthed.all|talent.count_the_odds&!variable.stealthed_cto |
||||
-- CDsAPL:AddAPL( |
||||
-- StealthCDsAPL, |
||||
-- function() |
||||
-- return not Player:GetAuras():FindMy(Stealth):IsUp() or |
||||
-- (CountTheOdds:IsKnown() and not DefaultAPL:GetVariable("stealthed_cto")) |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/dreadblades,if=!(variable.stealthed_cto|stealthed.basic|talent.hidden_opportunity&stealthed.rogue)&combo_points<=2&(!talent.marked_for_death|!cooldown.marked_for_death.ready)&target.time_to_die>=10 |
||||
-- CDsAPL:AddSpell( |
||||
-- Dreadblades:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and |
||||
-- not (DefaultAPL:GetVariable("stealthed_cto") or Player:GetAuras():FindMy(Stealth):IsUp() or |
||||
-- (HiddenOpportunity:IsKnown() and Player:GetAuras():FindMy(Subterfuge):IsUp())) and |
||||
-- Player:GetComboPoints() <= 2 and |
||||
-- (not MarkedForDeath:IsKnown() or not MarkedForDeath:CooldownUp()) and |
||||
-- Target:TimeToDie() >= 10 |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # If adds are up, snipe the one with lowest TTD. Use when dying faster than CP deficit or without any CP. |
||||
-- -- actions.cds+=/marked_for_death,line_cd=1.5,target_if=min:target.time_to_die,if=raid_event.adds.up&(target.time_to_die<combo_points.deficit|combo_points.deficit>=cp_max_spend-1)&!buff.dreadblades.up |
||||
|
||||
-- -- # If no adds will die within the next 30s, use MfD on boss without any CP. |
||||
-- -- actions.cds+=/marked_for_death,if=raid_event.adds.in>30-raid_event.adds.duration&combo_points.deficit>=cp_max_spend-1&!buff.dreadblades.up |
||||
|
||||
-- -- actions.cds+=/thistle_tea,if=!buff.thistle_tea.up&(energy.base_deficit>=100|fight_remains<charges*6) |
||||
-- CDsAPL:AddSpell( |
||||
-- ThistleTea:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and Player:GetAuras():FindMy(ThistleTea):IsDown() and |
||||
-- (Player:GetPowerDeficit() >= 100 or Target:TimeToDie() < ThistleTea:Charges() * 6) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/killing_spree,if=variable.blade_flurry_sync&!stealthed.rogue&debuff.between_the_eyes.up&energy.base_time_to_max>4 |
||||
-- CDsAPL:AddSpell( |
||||
-- KillingSpree:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and DefaultAPL:GetVariable("blade_flurry_sync") and |
||||
-- not Player:GetAuras():FindMy(Subterfuge):IsUp() and |
||||
-- Target:GetAuras():FindMy(BetweenTheEyes):IsUp() and |
||||
-- Player:GetTimeToPowerPercent() > 4 |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/shadowmeld,if=!stealthed.all&(talent.count_the_odds&variable.finish_condition|!talent.weaponmaster.enabled&variable.ambush_condition) |
||||
-- CDsAPL:AddSpell( |
||||
-- Shadowmeld:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and not Player:GetAuras():FindMy(Stealth):IsUp() and |
||||
-- (CountTheOdds:IsKnown() and DefaultAPL:GetVariable("finish_condition") or |
||||
-- not Weaponmaster:IsKnown() and DefaultAPL:GetVariable("ambush_condition")) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/potion,if=buff.bloodlust.react|fight_remains<30|buff.adrenaline_rush.up |
||||
-- -- CDsAPL:AddItem( |
||||
-- -- PotionOfUnbridledFury:CastableIf( |
||||
-- -- function(self) |
||||
-- -- return self:IsKnownAndUsable() and Player:GetAuras():FindMy(Bloodlust):IsUp() or Target:TimeToDie() < 30 or |
||||
-- -- Player:GetAuras():FindMy(AdrenalineRush):IsUp() |
||||
-- -- end |
||||
-- -- ):SetTarget(Target) |
||||
-- -- ) |
||||
|
||||
-- -- actions.cds+=/blood_fury |
||||
-- CDsAPL:AddSpell( |
||||
-- BloodFury:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/berserking |
||||
-- CDsAPL:AddSpell( |
||||
-- Berserking:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/fireblood |
||||
-- CDsAPL:AddSpell( |
||||
-- Fireblood:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.cds+=/ancestral_call |
||||
-- CDsAPL:AddSpell( |
||||
-- AncestralCall:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # Default conditions for usable items. |
||||
-- -- actions.cds+=/use_item,name=manic_grieftorch,if=!stealthed.all&!buff.adrenaline_rush.up|fight_remains<5 |
||||
-- -- actions.cds+=/use_item,name=stormeaters_boon,if=spell_targets.blade_flurry>desired_targets|raid_event.adds.in>60|fight_remains<10 |
||||
-- -- actions.cds+=/use_item,name=windscar_whetstone,if=spell_targets.blade_flurry>desired_targets|raid_event.adds.in>60|fight_remains<7 |
||||
-- -- actions.cds+=/use_items,slots=trinket1,if=debuff.between_the_eyes.up|trinket.1.has_stat.any_dps|fight_remains<=20 |
||||
-- -- actions.cds+=/use_items,slots=trinket2,if=debuff.between_the_eyes.up|trinket.2.has_stat.any_dps|fight_remains<=20 |
||||
|
||||
-- -- # Finishers BtE to keep the Crit debuff up, if RP is up, or for Greenskins, unless the target is about to die. |
||||
-- -- actions.finish=between_the_eyes,if=target.time_to_die>3&(debuff.between_the_eyes.remains<4|talent.greenskins_wickers&!buff.greenskins_wickers.up|!talent.greenskins_wickers&buff.ruthless_precision.up) |
||||
-- FinishAPL:AddSpell( |
||||
-- BetweenTheEyes:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and Target:TimeToDie() > 3 and |
||||
-- (Target:GetAuras():FindMy(BetweenTheEyes):GetRemainingTime() < 4 or |
||||
-- GreenskinsWickers:IsKnown() and Player:GetAuras():FindMy(GreenskinsWickers):IsDown() or |
||||
-- not GreenskinsWickers:IsKnown() and Player:GetAuras():FindMy(RuthlessPrecision):IsUp()) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.finish+=/slice_and_dice,if=buff.slice_and_dice.remains<fight_remains&refreshable&(!talent.swift_slasher|combo_points>=cp_max_spend) |
||||
-- FinishAPL:AddSpell( |
||||
-- SliceAndDice:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and |
||||
-- Player:GetAuras():FindMy(SliceAndDice):GetRemainingTime() < Target:TimeToDie() and |
||||
-- Player:GetAuras():FindMy(SliceAndDice):GetRemainingTime() < 6 and |
||||
-- (not SwiftSlasher:IsKnown() or Player:GetComboPoints() >= Player:GetComboPointsMax()) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.finish+=/cold_blood |
||||
-- FinishAPL:AddSpell( |
||||
-- ColdBlood:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.finish+=/dispatch |
||||
-- FinishAPL:AddSpell( |
||||
-- Dispatch:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and true |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # Stealth |
||||
-- -- actions.stealth=blade_flurry,if=talent.subterfuge&talent.hidden_opportunity&spell_targets>=2&!buff.blade_flurry.up |
||||
-- StealthAPL:AddSpell( |
||||
-- BladeFlurry:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and Subterfuge:IsKnown() and HiddenOpportunity:IsKnown() and |
||||
-- Target:GetMeleeAttackers() >= 2 and |
||||
-- not Player:GetAuras():FindMy(BladeFlurry):IsUp() |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.stealth+=/cold_blood,if=variable.finish_condition |
||||
-- StealthAPL:AddSpell( |
||||
-- ColdBlood:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and DefaultAPL:GetVariable('finish_condition') |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.stealth+=/dispatch,if=variable.finish_condition |
||||
-- StealthAPL:AddSpell( |
||||
-- Dispatch:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and DefaultAPL:GetVariable('finish_condition') |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.stealth+=/ambush,if=variable.stealthed_cto|stealthed.basic&talent.find_weakness&!debuff.find_weakness.up|talent.hidden_opportunity |
||||
-- StealthAPL:AddSpell( |
||||
-- Ambush:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and (DefaultAPL:GetVariable('stealthed_cto') or |
||||
-- Player:IsStealthed() and FindWeakness:IsKnown() and not Target:GetAuras():FindMy(FindWeakness):IsUp() or |
||||
-- HiddenOpportunity:IsKnown()) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- # Stealth Cooldowns |
||||
-- -- actions.stealth_cds=variable,name=vanish_condition,value=talent.hidden_opportunity|!talent.shadow_dance|!cooldown.shadow_dance.ready |
||||
-- StealthAPL:AddVariable( |
||||
-- 'vanish_condition', |
||||
-- function() |
||||
-- return HiddenOpportunity:IsKnown() or not ShadowDance:IsKnown() or not ShadowDance:CooldownUp() |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- actions.stealth_cds+=/variable,name=vanish_opportunity_condition,value=!talent.shadow_dance&talent.fan_the_hammer.rank+talent.quick_draw+talent.audacity<talent.count_the_odds+talent.keep_it_rolling |
||||
-- StealthAPL:AddVariable( |
||||
-- 'vanish_opportunity_condition', |
||||
-- function() |
||||
-- return not ShadowDance:IsKnown() and |
||||
-- (FanTheHammer:IsKnown() and 1 or 0) + (QuickDraw:IsKnown() and 1 or 0) + (Audacity:IsKnown() and 1 or 0) < |
||||
-- (CountTheOdds:IsKnown() and 1 or 0) + (KeepItRolling:IsKnown() and 1 or 0) |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- actions.stealth_cds+=/vanish,if=talent.find_weakness&!talent.audacity&debuff.find_weakness.down&variable.ambush_condition&variable.vanish_condition |
||||
-- StealthAPL:AddSpell( |
||||
-- Vanish:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and FindWeakness:IsKnown() and not Audacity:IsKnown() and |
||||
-- not Target:GetAuras():FindMy(FindWeakness):IsUp() and |
||||
-- DefaultAPL:GetVariable('ambush_condition') and StealthAPL:GetVariable('vanish_condition') |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.stealth_cds+=/vanish,if=talent.hidden_opportunity&!buff.audacity.up&(variable.vanish_opportunity_condition|buff.opportunity.stack<buff.opportunity.max_stack)&variable.ambush_condition&variable.vanish_condition |
||||
-- StealthAPL:AddSpell( |
||||
-- Vanish:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and HiddenOpportunity:IsKnown() and |
||||
-- not Player:GetAuras():FindMy(Audacity):IsUp() and |
||||
-- (StealthAPL:GetVariable('vanish_opportunity_condition') or |
||||
-- Player:GetAuras():FindMy(OpportunityAura):GetCount() < |
||||
-- MaxOpportunity()) and |
||||
-- DefaultAPL:GetVariable('ambush_condition') and StealthAPL:GetVariable('vanish_condition') |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.stealth_cds+=/vanish,if=(!talent.find_weakness|talent.audacity)&!talent.hidden_opportunity&variable.finish_condition&variable.vanish_condition |
||||
-- StealthAPL:AddSpell( |
||||
-- Vanish:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and (not FindWeakness:IsKnown() or Audacity:IsKnown()) and |
||||
-- not HiddenOpportunity:IsKnown() and |
||||
-- DefaultAPL:GetVariable('finish_condition') and StealthAPL:GetVariable('vanish_condition') |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.stealth_cds+=/variable,name=shadow_dance_condition,value=talent.shadow_dance&debuff.between_the_eyes.up&(!talent.ghostly_strike|debuff.ghostly_strike.up)&(!talent.dreadblades|!cooldown.dreadblades.ready)&(!talent.hidden_opportunity|!buff.audacity.up&(talent.fan_the_hammer.rank<2|!buff.opportunity.up)) |
||||
-- StealthAPL:AddVariable( |
||||
-- 'shadow_dance_condition', |
||||
-- function() |
||||
-- return ShadowDance:IsKnown() and Target:GetAuras():FindMy(BetweenTheEyes):IsUp() and |
||||
-- (not GhostlyStrike:IsKnown() or Target:GetAuras():FindMy(GhostlyStrike):IsUp()) and |
||||
-- (not Dreadblades:IsKnown() or not Dreadblades:CooldownUp()) and |
||||
-- (not HiddenOpportunity:IsKnown() or not Player:GetAuras():FindMy(Audacity):IsUp() and |
||||
-- (1 < 2 or not Player:GetAuras():FindMy(OpportunityAura):IsUp())) |
||||
-- end |
||||
-- ) |
||||
|
||||
-- -- actions.stealth_cds+=/shadow_dance,if=!talent.keep_it_rolling&variable.shadow_dance_condition&buff.slice_and_dice.up&(variable.finish_condition|talent.hidden_opportunity)&(!talent.hidden_opportunity|!cooldown.vanish.ready) |
||||
-- StealthAPL:AddSpell( |
||||
-- ShadowDance:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and not KeepItRolling:IsKnown() and |
||||
-- StealthAPL:GetVariable('shadow_dance_condition') and |
||||
-- Player:GetAuras():FindMy(SliceAndDice):IsUp() and |
||||
-- (DefaultAPL:GetVariable('finish_condition') or HiddenOpportunity:IsKnown()) and |
||||
-- (not HiddenOpportunity:IsKnown() or not Vanish:CooldownUp()) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- -- actions.stealth_cds+=/shadow_dance,if=talent.keep_it_rolling&variable.shadow_dance_condition&(cooldown.keep_it_rolling.remains<=30|cooldown.keep_it_rolling.remains>120&(variable.finish_condition|talent.hidden_opportunity)) |
||||
-- StealthAPL:AddSpell( |
||||
-- ShadowDance:CastableIf( |
||||
-- function(self) |
||||
-- return self:IsKnownAndUsable() and KeepItRolling:IsKnown() and |
||||
-- StealthAPL:GetVariable('shadow_dance_condition') and |
||||
-- (KeepItRolling:GetCooldownRemaining() <= 30 or |
||||
-- KeepItRolling:GetCooldownRemaining() > 120 and |
||||
-- (DefaultAPL:GetVariable('finish_condition') or HiddenOpportunity:IsKnown())) |
||||
-- end |
||||
-- ):SetTarget(Target) |
||||
-- ) |
||||
|
||||
-- OutlawModule:Sync(function() |
||||
-- print(BetweenTheEyes:IsKnownAndUsable()) |
||||
-- DefaultAPL:Execute() |
||||
-- end) |
||||
|
||||
-- Bastion:Register(OutlawModule) |
@ -1,226 +0,0 @@ |
||||
local Tinkr, _Bastion = ... |
||||
|
||||
---@type Bastion |
||||
local Bastion = _Bastion |
||||
|
||||
local ProtModule = Bastion.Module:New('paladin_protection') |
||||
local Player = Bastion.UnitManager:Get('player') |
||||
local Target = Bastion.UnitManager:Get('target') |
||||
local None = Bastion.UnitManager:Get('none') |
||||
|
||||
local CrusaderAura = Bastion.SpellBook:GetSpell(32223) |
||||
local DevoAura = Bastion.SpellBook:GetSpell(465) |
||||
local Consecrate = Bastion.SpellBook:GetSpell(26573) |
||||
local ConsecrateAura = Bastion.SpellBook:GetSpell(188370) |
||||
local Judgement = Bastion.SpellBook:GetSpell(275779) |
||||
local AvengersShield = Bastion.SpellBook:GetSpell(31935) |
||||
local OfDuskAndDawn = Bastion.SpellBook:GetSpell(385125) |
||||
local BlessingOfTheDusk = Bastion.SpellBook:GetSpell(385126) |
||||
local BlessingOfTheDawn = Bastion.SpellBook:GetSpell(385127) |
||||
local ShieldOfTheRighteous = Bastion.SpellBook:GetSpell(53600) |
||||
local BlessedHammer = Bastion.SpellBook:GetSpell(204019) |
||||
local AutoAttack = Bastion.SpellBook:GetSpell(6603) |
||||
local WoG = Bastion.SpellBook:GetSpell(85673) |
||||
local ShinningLight = Bastion.SpellBook:GetSpell(327510) |
||||
|
||||
local HolyPower = Enum.PowerType.HolyPower |
||||
|
||||
---@type Rebuke |
||||
local Rebuke = Tinkr:require("scripts/bastion/scripts/paladin/shared/rebuke", Bastion) |
||||
|
||||
---@type HammerOfWrath |
||||
local HammerOfWrath = Tinkr:require("scripts/bastion/scripts/paladin/shared/hammer-of-wrath", Bastion) |
||||
|
||||
local AvengersShieldTarget = Bastion.UnitManager:CreateCustomUnit('avengersshield', function() |
||||
local target = nil |
||||
|
||||
Bastion.UnitManager:EnumEnemies(function(unit) |
||||
if unit:IsDead() then |
||||
return false |
||||
end |
||||
|
||||
if not Player:CanSee(unit) then |
||||
return false |
||||
end |
||||
|
||||
if not Player:IsFacing(unit) then |
||||
return false |
||||
end |
||||
|
||||
if not AvengersShield:IsInRange(unit) then |
||||
return false |
||||
end |
||||
|
||||
if unit:IsCastingOrChanneling() and unit:IsInterruptibleAt(5) then |
||||
target = unit |
||||
return true |
||||
end |
||||
|
||||
return false |
||||
end) |
||||
|
||||
if target == nil then |
||||
if Target:Exists() then |
||||
target = Target |
||||
else |
||||
target = None |
||||
end |
||||
end |
||||
|
||||
return target |
||||
end) |
||||
|
||||
local WoGTarget = Bastion.UnitManager:CreateCustomUnit('wordofglory', function() |
||||
if not WoG:IsKnownAndUsable() then return None end |
||||
|
||||
local lowest = nil |
||||
local lowestHP = math.huge |
||||
|
||||
Bastion.UnitManager:EnumFriends(function(unit) |
||||
if unit:IsDead() then |
||||
return false |
||||
end |
||||
|
||||
if WoG:IsInRange(unit) then |
||||
return false |
||||
end |
||||
|
||||
if not Player:CanSee(unit) then |
||||
return false |
||||
end |
||||
|
||||
if not unit:GetHealthPercent() <= 55 then |
||||
return false |
||||
end |
||||
|
||||
local hp = unit:GetHP() |
||||
if hp < lowestHP then |
||||
lowest = unit |
||||
lowestHP = hp |
||||
end |
||||
|
||||
return false |
||||
end) |
||||
|
||||
if not lowest then |
||||
lowest = None |
||||
end |
||||
|
||||
return lowest |
||||
end) |
||||
|
||||
---@return boolean |
||||
local function CombatRotation() |
||||
-- Attack the target is auto attack isnt active. |
||||
if AutoAttack:IsKnownAndUsable() and not IsCurrentSpell(AutoAttack:GetID()) and Player:InMelee(Target) and not Target:IsDead() then |
||||
AutoAttack:Cast(Target) |
||||
end |
||||
|
||||
-- Kick |
||||
Rebuke() |
||||
|
||||
-- Cast Consecrate if an enemy is in range, and the player isnt moving. |
||||
if Consecrate:IsKnownAndUsable() and not Player:IsMoving() and not Player:GetAuras():FindMy(ConsecrateAura):IsUp() and Player:GetEnemies(10) >= 1 then |
||||
return Consecrate:Cast(Player) |
||||
end |
||||
|
||||
if WoG:IsKnownAndUsable() and Player:GetAuras():FindMy(ShinningLight):IsUp() and Player:GetHealthPercent() <= 50 and not Player:IsCastingOrChanneling() then |
||||
return WoG:Cast(Player) |
||||
end |
||||
|
||||
-- Handle SoR specially if DuskAndDawn is known. |
||||
if OfDuskAndDawn:IsKnown() then |
||||
local HpToSor = 3 |
||||
|
||||
if Player:GetAuras():FindMy(BlessingOfTheDusk):IsUp() and Player:GetAuras():FindMy(BlessingOfTheDawn):GetRemainingTime() < 9 then |
||||
HpToSor = 5 |
||||
end |
||||
|
||||
if Player:GetPower(HolyPower) > 3 then |
||||
HpToSor = 5 |
||||
end |
||||
|
||||
if Player:GetPower(HolyPower) == HpToSor and ShieldOfTheRighteous:IsKnownAndUsable() and ShieldOfTheRighteous:IsInRange(Target) and not Player:IsCastingOrChanneling() then |
||||
ShieldOfTheRighteous:Cast(Target) |
||||
end |
||||
else |
||||
-- If Dusk And Dawn isnt known, rip SoR normally. |
||||
if ShieldOfTheRighteous:IsKnownAndUsable() and ShieldOfTheRighteous:IsInRange(Target) and not Player:IsCastingOrChanneling() then |
||||
ShieldOfTheRighteous:Cast(Target) |
||||
end |
||||
end |
||||
|
||||
-- Avengers shield with higher prio than Judgement in AOE. Prefer targets that are casting. |
||||
if Player:GetEnemies(10) > 1 and AvengersShield:IsKnownAndUsable() and AvengersShieldTarget:Exists() then |
||||
return AvengersShield:Cast(AvengersShieldTarget) |
||||
end |
||||
|
||||
-- Judgement |
||||
if Judgement:IsKnownAndUsable() and Player:GetPower(HolyPower) < 5 and Target:Exists() and Judgement:IsInRange(Target) then |
||||
return Judgement:Cast(Target) |
||||
end |
||||
|
||||
-- Hammer of Wrath |
||||
if HammerOfWrath() then |
||||
return true |
||||
end |
||||
|
||||
-- Avengers shield with lower prio than Judgement in ST. Prefer targets that are casting. |
||||
if Player:GetEnemies(10) == 1 and AvengersShield:IsKnownAndUsable() and AvengersShieldTarget:Exists() then |
||||
return AvengersShield:Cast(AvengersShieldTarget) |
||||
end |
||||
|
||||
-- Blessed Hammer if there are more than 1 enemy in 10 yds. |
||||
if BlessedHammer:IsKnownAndUsable() and Player:GetPower(HolyPower) < 5 and Player:GetEnemies(10) >= 1 then |
||||
return BlessedHammer:Cast(Player) |
||||
end |
||||
|
||||
if Player:GetAuras():FindMy(ShinningLight):IsUp() and WoGTarget:Exists() and not Player:IsCastingOrChanneling() then |
||||
return WoG:Cast(WoGTarget) |
||||
end |
||||
|
||||
-- Refresh Consecrate if we've got nothing else to cast. |
||||
if Consecrate:IsKnownAndUsable() and Player:GetEnemies(10) >= 1 and not Player:IsMoving() then |
||||
return Consecrate:Cast(Player) |
||||
end |
||||
|
||||
return false |
||||
end |
||||
|
||||
---@return boolean |
||||
local function OutOfCombatRotation() |
||||
return false |
||||
end |
||||
|
||||
local isRunning = false |
||||
|
||||
ProtModule:Sync(function() |
||||
if not isRunning then |
||||
Bastion:Print('Prot Paladin Started') |
||||
isRunning = true |
||||
end |
||||
|
||||
if not Player:IsAlive() then |
||||
return false |
||||
end |
||||
|
||||
-- Cast Crusader Aura if talented and the player is mounted. |
||||
if Player:IsMounted() and CrusaderAura:IsKnownAndUsable() and not Player:GetAuras():FindMy(CrusaderAura):IsUp() and not Player:IsCastingOrChanneling() then |
||||
return CrusaderAura:Cast(Player) |
||||
end |
||||
|
||||
-- Cast Devo Aura if the player is not mounted. |
||||
if not Player:IsMounted() and DevoAura:IsKnownAndUsable() and not Player:GetAuras():FindMy(DevoAura):IsUp() and not Player:IsCastingOrChanneling() then |
||||
return DevoAura:Cast(Player) |
||||
end |
||||
|
||||
if Player:IsAffectingCombat() then |
||||
-- Combat Rotation |
||||
return CombatRotation() |
||||
else |
||||
-- Out Of Combat Rotation |
||||
return OutOfCombatRotation() |
||||
end |
||||
end) |
||||
|
||||
Bastion:Register(ProtModule) |
@ -1,69 +0,0 @@ |
||||
local Tinkr, _Bastion = ... |
||||
|
||||
---@type Bastion |
||||
local Bastion = _Bastion |
||||
|
||||
local Player = Bastion.UnitManager:Get('player') |
||||
local Target = Bastion.UnitManager:Get('target') |
||||
local None = Bastion.UnitManager:Get('none') |
||||
|
||||
local _HammerOfWrath = Bastion.SpellBook:GetSpell(24275) |
||||
local AvengingWrath = Bastion.SpellBook:GetSpell(389539) |
||||
|
||||
local HammerOfWrathTarget = Bastion.UnitManager:CreateCustomUnit('hammerofwrath', function() |
||||
if not _HammerOfWrath:IsKnownAndUsable() then return None end |
||||
|
||||
if Player:GetAuras():FindMy(AvengingWrath):IsUp() and _HammerOfWrath:IsKnownAndUsable() and Target:Exists() and Target:IsEnemy() and Target:IsAffectingCombat() and _HammerOfWrath:IsInRange(Target) then |
||||
return Target |
||||
end |
||||
|
||||
local how = nil |
||||
|
||||
Bastion.UnitManager:EnumEnemies(function(unit) |
||||
if unit:IsDead() then |
||||
return false |
||||
end |
||||
|
||||
if not Player:CanSee(unit) then |
||||
return false |
||||
end |
||||
|
||||
if not Player:IsFacing(unit) then |
||||
return false |
||||
end |
||||
|
||||
if not _HammerOfWrath:IsInRange(unit) then |
||||
return false |
||||
end |
||||
|
||||
if Player:GetAuras():FindMy(AvengingWrath):IsUp() then |
||||
how = unit |
||||
return true |
||||
end |
||||
|
||||
if unit:GetHealthPercent() <= 20 then |
||||
how = unit |
||||
return true |
||||
end |
||||
|
||||
return false |
||||
end) |
||||
|
||||
if how == nil then |
||||
how = None |
||||
end |
||||
|
||||
return how |
||||
end) |
||||
|
||||
---@alias HammerOfWrath fun():boolean |
||||
|
||||
---@type HammerOfWrath |
||||
function HammerOfWrath() |
||||
if HammerOfWrathTarget:Exists() and not Player:IsCastingOrChanneling() then |
||||
return _HammerOfWrath:Cast(HammerOfWrathTarget) |
||||
end |
||||
return false |
||||
end |
||||
|
||||
return HammerOfWrath |
@ -1,57 +0,0 @@ |
||||
local Tinkr, _Bastion = ... |
||||
|
||||
---@type Bastion |
||||
local Bastion = _Bastion |
||||
|
||||
local Player = Bastion.UnitManager:Get('player') |
||||
local None = Bastion.UnitManager:Get('none') |
||||
|
||||
local _Rebuke = Bastion.SpellBook:GetSpell(96231) |
||||
|
||||
local RebukeTarget = Bastion.UnitManager:CreateCustomUnit('rebuke', function() |
||||
local kick = 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) > 40 then |
||||
return false |
||||
end |
||||
|
||||
if unit:IsInterruptibleAt(10) and _Rebuke:IsInRange(unit) and Player:IsFacing(unit) then |
||||
kick = unit |
||||
return true |
||||
end |
||||
|
||||
-- TODO: Only consider this if the player is in an M+ dungeon |
||||
-- if Player:InMelee(unit) and Player:IsFacing(unit) and Bastion.MythicPlusUtils:CastingCriticalKick(unit, 5) then |
||||
-- kick = unit |
||||
-- return true |
||||
-- end |
||||
|
||||
return false |
||||
end) |
||||
|
||||
if kick == nil then |
||||
kick = None |
||||
end |
||||
|
||||
return kick |
||||
end) |
||||
|
||||
---@alias Rebuke fun() |
||||
|
||||
---@type Rebuke |
||||
function Rebuke() |
||||
if RebukeTarget:Exists() and not Player:IsCastingOrChanneling() and _Rebuke:IsKnownAndUsable() then |
||||
_Rebuke:Cast(RebukeTarget) |
||||
end |
||||
end |
||||
|
||||
return Rebuke |
@ -1,758 +0,0 @@ |
||||
local Tinkr, Bastion = ... |
||||
|
||||
local RestoModule = Bastion.Module:New('resto_druid') |
||||
local Evaluator = Tinkr.Util.Evaluator |
||||
local Player = Bastion.UnitManager:Get('player') |
||||
local None = Bastion.UnitManager:Get('none') |
||||
local Target = Bastion.UnitManager:Get('target') |
||||
|
||||
local AnomalyDetectionMarkI = Bastion.SpellBook:GetSpell(382499) |
||||
local AutoAttack = Bastion.SpellBook:GetSpell(6603) |
||||
local MechanismBypass = Bastion.SpellBook:GetSpell(382501) |
||||
local OverloadElementalDeposit = Bastion.SpellBook:GetSpell(388213) |
||||
local ReviveBattlePets = Bastion.SpellBook:GetSpell(125439) |
||||
local WarStomp = Bastion.SpellBook:GetSpell(20549) |
||||
local ArmorSkills = Bastion.SpellBook:GetSpell(76275) |
||||
local Brawn = Bastion.SpellBook:GetSpell(154743) |
||||
local Cultivation = Bastion.SpellBook:GetSpell(20552) |
||||
local Endurance = Bastion.SpellBook:GetSpell(20550) |
||||
local Languages = Bastion.SpellBook:GetSpell(79746) |
||||
local MasterRiding = Bastion.SpellBook:GetSpell(90265) |
||||
local NatureResistance = Bastion.SpellBook:GetSpell(20551) |
||||
local WeaponSkills = Bastion.SpellBook:GetSpell(76300) |
||||
local ActivateEmpowerment = Bastion.SpellBook:GetSpell(357857) |
||||
local BlessingofOhnara = Bastion.SpellBook:GetSpell(384522) |
||||
local BronzeTimelock = Bastion.SpellBook:GetSpell(374990) |
||||
local ChampionAbility = Bastion.SpellBook:GetSpell(356550) |
||||
local CenarionWard = Bastion.SpellBook:GetSpell(102351) |
||||
local CombatAlly = Bastion.SpellBook:GetSpell(211390) |
||||
local ConstructAbility = Bastion.SpellBook:GetSpell(347013) |
||||
local CovenantAbility = Bastion.SpellBook:GetSpell(313347) |
||||
local GarrisonAbility = Bastion.SpellBook:GetSpell(161691) |
||||
local HeartEssence = Bastion.SpellBook:GetSpell(296208) |
||||
local HuntingCompanion = Bastion.SpellBook:GetSpell(376280) |
||||
local SanityRestorationOrb = Bastion.SpellBook:GetSpell(314955) |
||||
local SignatureAbility = Bastion.SpellBook:GetSpell(326526) |
||||
local SkywardAscent = Bastion.SpellBook:GetSpell(372610) |
||||
local SummonPocopoc = Bastion.SpellBook:GetSpell(360078) |
||||
local SurgeForward = Bastion.SpellBook:GetSpell(372608) |
||||
local Throw = Bastion.SpellBook:GetSpell(385265) |
||||
local VenthyrAbility = Bastion.SpellBook:GetSpell(315594) |
||||
local WartimeAbility = Bastion.SpellBook:GetSpell(264739) |
||||
local WhirlingSurge = Bastion.SpellBook:GetSpell(361584) |
||||
local PocopocZoneAbilitySkill = Bastion.SpellBook:GetSpell(363942) |
||||
local DragonridingBasics = Bastion.SpellBook:GetSpell(376777) |
||||
local LiftOff = Bastion.SpellBook:GetSpell(383363) |
||||
local ThrilloftheSkies = Bastion.SpellBook:GetSpell(383366) |
||||
local Vigor = Bastion.SpellBook:GetSpell(383359) |
||||
local WindsoftheIsles = Bastion.SpellBook:GetSpell(373586) |
||||
local Barkskin = Bastion.SpellBook:GetSpell(22812) |
||||
local BearForm = Bastion.SpellBook:GetSpell(5487) |
||||
local CatForm = Bastion.SpellBook:GetSpell(768) |
||||
local Cyclone = Bastion.SpellBook:GetSpell(33786) |
||||
local EntanglingRoots = Bastion.SpellBook:GetSpell(339) |
||||
local FerociousBite = Bastion.SpellBook:GetSpell(22568) |
||||
local FrenziedRegeneration = Bastion.SpellBook:GetSpell(22842) |
||||
local Growl = Bastion.SpellBook:GetSpell(6795) |
||||
local Innervate = Bastion.SpellBook:GetSpell(29166) |
||||
local Mangle = Bastion.SpellBook:GetSpell(33917) |
||||
local MarkoftheWild = Bastion.SpellBook:GetSpell(1126) |
||||
local Moonfire = Bastion.SpellBook:GetSpell(8921) |
||||
local MoonfireAura = Bastion.SpellBook:GetSpell(164812) |
||||
local Prowl = Bastion.SpellBook:GetSpell(5215) |
||||
local Rebirth = Bastion.SpellBook:GetSpell(20484) |
||||
local Regrowth = Bastion.SpellBook:GetSpell(8936) |
||||
local Rejuvenation = Bastion.SpellBook:GetSpell(774) |
||||
local RejuvenationAura = Bastion.SpellBook:GetSpell(25299) |
||||
local Revive = Bastion.SpellBook:GetSpell(50769) |
||||
local Rip = Bastion.SpellBook:GetSpell(1079) |
||||
local Shred = Bastion.SpellBook:GetSpell(5221) |
||||
local Soothe = Bastion.SpellBook:GetSpell(2908) |
||||
local StampedingRoar = Bastion.SpellBook:GetSpell(106898) |
||||
local Sunfire = Bastion.SpellBook:GetSpell(93402) |
||||
local SunfireAura = Bastion.SpellBook:GetSpell(164815) |
||||
local Swiftmend = Bastion.SpellBook:GetSpell(18562) |
||||
local TeleportMoonglade = Bastion.SpellBook:GetSpell(18960) |
||||
local Thrash = Bastion.SpellBook:GetSpell(106832) |
||||
local TigerDash = Bastion.SpellBook:GetSpell(252216) |
||||
local TravelForm = Bastion.SpellBook:GetSpell(783) |
||||
local UrsolsVortex = Bastion.SpellBook:GetSpell(102793) |
||||
local WildGrowth = Bastion.SpellBook:GetSpell(48438) |
||||
local Wrath = Bastion.SpellBook:GetSpell(5176) |
||||
local AquaticForm = Bastion.SpellBook:GetSpell(276012) |
||||
local FlightForm = Bastion.SpellBook:GetSpell(276029) |
||||
local TigerDash = Bastion.SpellBook:GetSpell(252216) |
||||
local Efflorescence = Bastion.SpellBook:GetSpell(145205) |
||||
local IncarnationTreeofLife = Bastion.SpellBook:GetSpell(33891) |
||||
local Ironbark = Bastion.SpellBook:GetSpell(102342) |
||||
local Lifebloom = Bastion.SpellBook:GetSpell(33763) |
||||
local LifebloomAura = Bastion.SpellBook:GetSpell(188550) |
||||
local NaturesCure = Bastion.SpellBook:GetSpell(88423) |
||||
local NaturesSwiftness = Bastion.SpellBook:GetSpell(132158) |
||||
local Revitalize = Bastion.SpellBook:GetSpell(212040) |
||||
local Tranquility = Bastion.SpellBook:GetSpell(740) |
||||
local MasteryHarmony = Bastion.SpellBook:GetSpell(77495) |
||||
local Moonfire = Bastion.SpellBook:GetSpell(8921) |
||||
local Wrath = Bastion.SpellBook:GetSpell(5176) |
||||
local BearForm = Bastion.SpellBook:GetSpell(5487) |
||||
local AdaptiveSwarm = Bastion.SpellBook:GetSpell(391888) |
||||
local AdaptiveSwarmBuff = Bastion.SpellBook:GetSpell(391891) |
||||
local ClearCasting = Bastion.SpellBook:GetSpell(16870) |
||||
local ConvokeTheSpirits = Bastion.SpellBook:GetSpell(391528) |
||||
local Flourish = Bastion.SpellBook:GetSpell(197721) |
||||
local SoulOfTheForest = Bastion.SpellBook:GetSpell(114108) |
||||
local Bursting = Bastion.SpellBook:GetSpell(240443) |
||||
local Rake = Bastion.SpellBook:GetSpell(1822) |
||||
local RakeAura = Bastion.SpellBook:GetSpell(155722) |
||||
local Starsurge = Bastion.SpellBook:GetSpell(197626) |
||||
local NaturesVigil = Bastion.SpellBook:GetSpell(124974) |
||||
local SpringBlossoms = Bastion.SpellBook:GetSpell(207386) |
||||
local RakeDebuff = Bastion.SpellBook:GetSpell(155722) |
||||
|
||||
|
||||
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 |
||||
end) |
||||
|
||||
if not lowest then |
||||
lowest = Player |
||||
end |
||||
|
||||
return lowest |
||||
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(NaturesCure) 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 PurgeTarget = Bastion.UnitManager:CreateCustomUnit('purge', function(unit) |
||||
local purge = 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) > 40 then |
||||
return false |
||||
end |
||||
|
||||
if not unit:IsDead() and Player:CanSee(unit) and |
||||
unit:GetAuras():HasAnyStealableAura() then |
||||
purge = unit |
||||
return true |
||||
end |
||||
end) |
||||
|
||||
if purge == nil then |
||||
purge = None |
||||
end |
||||
|
||||
return purge |
||||
end) |
||||
|
||||
local Tank = Bastion.UnitManager:CreateCustomUnit('tank', function(unit) |
||||
local tank = nil |
||||
|
||||
Bastion.UnitManager:EnumFriends(function(unit) |
||||
if Player:GetDistance(unit) > 40 then |
||||
return false |
||||
end |
||||
|
||||
if not Player:CanSee(unit) then |
||||
return false |
||||
end |
||||
|
||||
if unit:IsDead() then |
||||
return false |
||||
end |
||||
|
||||
if unit:IsTank() then |
||||
tank = unit |
||||
return true |
||||
end |
||||
|
||||
return false |
||||
end) |
||||
|
||||
if tank == nil then |
||||
tank = Player |
||||
end |
||||
|
||||
return tank |
||||
end) |
||||
|
||||
local RejuvUnit = Bastion.UnitManager:CreateCustomUnit('rejuv', 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 |
||||
( |
||||
not unit:GetAuras():FindMy(Rejuvenation):IsUp() or |
||||
unit:GetAuras():FindMy(Rejuvenation):GetRemainingTime() <= 3.6) then |
||||
local hp = unit:GetHP() |
||||
if hp < lowestHP then |
||||
lowest = unit |
||||
lowestHP = hp |
||||
end |
||||
end |
||||
end) |
||||
|
||||
|
||||
if lowest == nil then |
||||
lowest = Player |
||||
end |
||||
|
||||
return lowest |
||||
end) |
||||
|
||||
local SwiftmendUnit = Bastion.UnitManager:CreateCustomUnit('swiftmend', 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 ( |
||||
Player:CanSee(unit) and ( |
||||
(unit:GetAuras():FindMy(Regrowth):IsUp()) |
||||
or |
||||
( |
||||
unit:GetAuras():FindMy(Rejuvenation):IsUp() and |
||||
not unit:GetAuras():FindMy(WildGrowth):IsUp()) |
||||
) |
||||
) 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 WildGrowthUnit = Bastion.UnitManager:CreateCustomUnit('wildgrowth', 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 Player:CanSee(unit) and ( |
||||
( |
||||
Player:GetAuras():FindMy(SoulOfTheForest):IsUp() and |
||||
( |
||||
Player:GetAuras():FindMy(SoulOfTheForest):GetRemainingTime() <= 5 or |
||||
unit:GetPartyHPAround(30, 90) >= 2)) or |
||||
(unit:GetPartyHPAround(30, 90) >= 3 or unit:GetPartyHPAround(30, 85) >= 2)) |
||||
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 Explosive = Bastion.UnitManager:CreateCustomUnit('explosive', function(unit) |
||||
local explosive = nil |
||||
|
||||
Bastion.ObjectManager.explosives:each(function(unit) |
||||
if unit:IsDead() then |
||||
return false |
||||
end |
||||
|
||||
if not Player:CanSee(unit) then |
||||
return false |
||||
end |
||||
|
||||
if Player:GetDistance(unit) <= 40 then |
||||
explosive = unit |
||||
return true |
||||
end |
||||
end) |
||||
|
||||
if explosive == nil then |
||||
explosive = None |
||||
end |
||||
|
||||
return explosive |
||||
end) |
||||
|
||||
local RakeTarget = Bastion.UnitManager:CreateCustomUnit('rake', function(unit) |
||||
local rakeTarget = 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) > 40 then |
||||
return false |
||||
end |
||||
|
||||
if not unit:IsDead() and Player:CanSee(unit) and unit:InCombatOdds() > 80 and unit:InMelee(Player) and |
||||
Player:IsFacing(unit) and |
||||
( |
||||
not unit:GetAuras():FindMy(RakeDebuff):IsUp() or |
||||
unit:GetAuras():FindMy(RakeDebuff):GetRemainingTime() <= 3.6) then |
||||
rakeTarget = unit |
||||
end |
||||
end) |
||||
|
||||
|
||||
if rakeTarget == nil then |
||||
rakeTarget = None |
||||
end |
||||
|
||||
return rakeTarget |
||||
end) |
||||
|
||||
local MoonfireTarget = Bastion.UnitManager:CreateCustomUnit('moonfire', function(unit) |
||||
local moonfireTarget = 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) > 40 then |
||||
return false |
||||
end |
||||
|
||||
if not unit:IsDead() and Player:CanSee(unit) and unit:InCombatOdds() > 80 and |
||||
( |
||||
not unit:GetAuras():FindMy(MoonfireAura):IsUp() or |
||||
unit:GetAuras():FindMy(MoonfireAura):GetRemainingTime() <= 3.6) then |
||||
moonfireTarget = unit |
||||
end |
||||
end) |
||||
|
||||
if moonfireTarget == nil then |
||||
moonfireTarget = None |
||||
end |
||||
|
||||
return moonfireTarget |
||||
end) |
||||
|
||||
local SunfireTarget = Bastion.UnitManager:CreateCustomUnit('sunfire', function(unit) |
||||
local sunfireTarget = 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) > 40 then |
||||
return false |
||||
end |
||||
|
||||
if not unit:IsDead() and Player:CanSee(unit) and unit:InCombatOdds() > 80 and |
||||
( |
||||
not unit:GetAuras():FindMy(SunfireAura):IsUp() or |
||||
unit:GetAuras():FindMy(SunfireAura):GetRemainingTime() <= 3.6) then |
||||
sunfireTarget = unit |
||||
end |
||||
end) |
||||
|
||||
if sunfireTarget == nil then |
||||
sunfireTarget = None |
||||
end |
||||
|
||||
return sunfireTarget |
||||
end) |
||||
|
||||
local RestoCommands = Bastion.Command:New('resto') |
||||
|
||||
local PLACE_EFFLO = false |
||||
|
||||
RestoCommands:Register('efflo', 'Request the engine to place an Efflorescence', function() |
||||
PLACE_EFFLO = true |
||||
Bastion.Notifications:AddNotification(Efflorescence:GetIcon(), "Efflorescence requested") |
||||
end) |
||||
|
||||
local DefaultAPL = Bastion.APL:New('default') |
||||
local DamageAPL = Bastion.APL:New('damage') |
||||
|
||||
DamageAPL:AddSpell( |
||||
Rake:CastableIf(function(self) |
||||
return RakeTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and |
||||
( |
||||
not RakeTarget:GetAuras():FindMy(RakeDebuff):IsUp() or |
||||
RakeTarget:GetAuras():FindMy(RakeDebuff):GetRemainingTime() <= 3.6) |
||||
end):SetTarget(RakeTarget) |
||||
) |
||||
|
||||
DamageAPL:AddSpell( |
||||
FerociousBite:CastableIf(function(self) |
||||
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and |
||||
Player:GetComboPoints() >= 5 |
||||
end):SetTarget(Target) |
||||
) |
||||
|
||||
DamageAPL:AddSpell( |
||||
Shred:CastableIf(function(self) |
||||
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and |
||||
Player:GetComboPoints() < 5 |
||||
end):SetTarget(Target) |
||||
) |
||||
|
||||
|
||||
DefaultAPL:AddSpell( |
||||
Efflorescence:CastableIf(function(self) |
||||
return PLACE_EFFLO and Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
end):SetTarget(None):OnCast(function(self) |
||||
local loc = Bastion.UnitManager:FindFriendsCentroid(10, 40) |
||||
PLACE_EFFLO = false |
||||
self:Click(loc) |
||||
end) |
||||
) |
||||
|
||||
CatForm:OnCast(function(self) |
||||
if not Player:GetAuras():FindMy(Prowl):IsUp() and not Player:IsAffectingCombat() then |
||||
Prowl:Cast(Player) |
||||
end |
||||
end) |
||||
|
||||
DefaultAPL:AddAction( |
||||
'cat_form_shift', |
||||
function() |
||||
if (IsShiftKeyDown()) and not Player:IsMounted() and |
||||
not Player:GetAuras():FindMy(CatForm):IsUp() and |
||||
not Player:IsCastingOrChanneling() then |
||||
CatForm:Cast(Player) |
||||
elseif (not IsShiftKeyDown() and Player:IsAffectingCombat()) and Player:GetAuras():FindMy(CatForm):IsUp() then |
||||
CancelShapeshiftForm() |
||||
end |
||||
end |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
NaturesCure:CastableIf(function(self) |
||||
return DispelTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and |
||||
self:IsInRange(DispelTarget) and DispelTarget:GetAuras():HasAnyDispelableAura(NaturesCure) |
||||
end):SetTarget(DispelTarget) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Soothe:CastableIf(function(self) |
||||
return PurgeTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and |
||||
self:IsInRange(PurgeTarget) and PurgeTarget:GetAuras():HasAnyStealableAura() |
||||
end):SetTarget(PurgeTarget) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
NaturesSwiftness:CastableIf(function(self) |
||||
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(Lowest) and Lowest:GetHP() < 70 |
||||
end):SetTarget(Lowest) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
ConvokeTheSpirits:CastableIf(function(self) |
||||
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and |
||||
self:IsInRange(Player) and (Player:GetPartyHPAround(40, 70) >= 2 or Player:GetPartyHPAround(40, 75) >= 3) |
||||
and (Flourish:IsKnownAndUsable() or Flourish:GetTimeSinceLastCast() > 10) |
||||
end):SetTarget(Player) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Flourish:CastableIf(function(self) |
||||
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and |
||||
self:IsInRange(Player) and (Player:GetPartyHPAround(40, 70) >= 2 or Player:GetPartyHPAround(40, 75) >= 3) and |
||||
(not ConvokeTheSpirits:IsKnownAndUsable() and ConvokeTheSpirits:GetTimeSinceLastCast() > 10) and |
||||
WildGrowth:GetTimeSinceLastCast() <= 6 |
||||
end):SetTarget(Player) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
NaturesVigil:CastableIf(function(self) |
||||
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and |
||||
self:IsInRange(Player) and Flourish:GetTimeSinceLastCast() <= 5 |
||||
end):SetTarget(Player) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
AdaptiveSwarm:CastableIf(function(self) |
||||
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(Lowest) |
||||
end):SetTarget(Lowest) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Swiftmend:CastableIf(function(self) |
||||
return SwiftmendUnit:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(SwiftmendUnit) and |
||||
( |
||||
SwiftmendUnit:GetHP() <= 60 or |
||||
( |
||||
Lowest:GetPartyHPAround(30, 90) >= 3 or Lowest:GetPartyHPAround(30, 85) >= 2 |
||||
) |
||||
) |
||||
end):SetTarget(SwiftmendUnit) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
WildGrowth:CastableIf(function(self) |
||||
return WildGrowthUnit:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(WildGrowthUnit) and |
||||
( |
||||
Player:GetAuras():FindMy(SoulOfTheForest):IsUp() |
||||
or |
||||
(WildGrowthUnit:GetPartyHPAround(30, 90) >= 3 or WildGrowthUnit:GetPartyHPAround(30, 85) >= 2) |
||||
) and |
||||
not Player:IsMoving() |
||||
end):SetTarget(WildGrowthUnit) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Regrowth:CastableIf(function(self) |
||||
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(Lowest) and Lowest:GetHP() < 65 and |
||||
Player:GetAuras():FindMy(SoulOfTheForest):IsUp() and not Player:IsMoving() |
||||
end):SetTarget(Lowest) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Regrowth:CastableIf(function(self) |
||||
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(Lowest) and Lowest:GetHP() < 70 and |
||||
( |
||||
NaturesSwiftness:GetTimeSinceLastCast() < 2 or Player:GetAuras():FindMy(NaturesSwiftness):IsUp() or |
||||
NaturesSwiftness:IsKnownAndUsable()) and not Player:IsMoving() and |
||||
not Player:GetAuras():FindMy(SoulOfTheForest):IsUp() |
||||
end):SetTarget(Lowest) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
CenarionWard:CastableIf(function(self) |
||||
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(Lowest) and Lowest:GetHP() <= 90 |
||||
end):SetTarget(Lowest) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Ironbark:CastableIf(function(self) |
||||
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(Lowest) and Lowest:GetHP() <= 70 and not Lowest:GetAuras():FindMy(CenarionWard):IsUp() |
||||
end):SetTarget(Lowest) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Rejuvenation:CastableIf(function(self) |
||||
return RejuvUnit:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(RejuvUnit) and (RejuvUnit:GetHP() <= 94) and |
||||
not Player:GetAuras():FindMy(SoulOfTheForest):IsUp() |
||||
end):SetTarget(RejuvUnit) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Lifebloom:CastableIf(function(self) |
||||
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and |
||||
( |
||||
not Player:GetAuras():FindMy(LifebloomAura):IsUp() or |
||||
Player:GetAuras():FindMy(LifebloomAura):GetRemainingTime() <= 4.5) and Player:IsAffectingCombat() |
||||
end):SetTarget(Player) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Lifebloom:CastableIf(function(self) |
||||
return Tank:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and |
||||
( |
||||
not Tank:GetAuras():FindMy(LifebloomAura):IsUp() or |
||||
Tank:GetAuras():FindMy(LifebloomAura):GetRemainingTime() <= 4.5) and Tank:IsAffectingCombat() |
||||
end):SetTarget(Tank) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Regrowth:CastableIf(function(self) |
||||
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(Lowest) and |
||||
( |
||||
not Player:GetAuras():FindMy(Regrowth):IsUp() and Lowest:GetHP() < 70 or |
||||
(Lowest:GetHP() <= 85 and Player:GetAuras():FindMy(ClearCasting):IsUp())) and |
||||
not Player:GetAuras():FindMy(SoulOfTheForest):IsUp() and |
||||
not Player:IsMoving() |
||||
end):SetTarget(Lowest) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Rejuvenation:CastableIf(function(self) |
||||
return RejuvUnit:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(RejuvUnit) and (RejuvUnit:GetHP() <= 94 or Player:GetPartyHPAround(40, 90) >= 2) and |
||||
not Player:GetAuras():FindMy(SoulOfTheForest):IsUp() |
||||
end):SetTarget(RejuvUnit) |
||||
) |
||||
|
||||
|
||||
DefaultAPL:AddSpell( |
||||
Moonfire:CastableIf(function(self) |
||||
return Explosive:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
end):SetTarget(Explosive) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Sunfire:CastableIf(function(self) |
||||
return SunfireTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(SunfireTarget) and |
||||
( |
||||
not SunfireTarget:GetAuras():FindMy(SunfireAura):IsUp() or |
||||
SunfireTarget:GetAuras():FindMy(SunfireAura):GetRemainingTime() <= 5.4) and |
||||
SunfireTarget:IsHostile() and |
||||
SunfireTarget:IsAffectingCombat() and Player:GetPP() >= 25 |
||||
end):SetTarget(SunfireTarget) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Moonfire:CastableIf(function(self) |
||||
return MoonfireTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(MoonfireTarget) and |
||||
( |
||||
not MoonfireTarget:GetAuras():FindMy(MoonfireAura):IsUp() or |
||||
MoonfireTarget:GetAuras():FindMy(MoonfireAura):GetRemainingTime() <= 5.4) and |
||||
MoonfireTarget:IsHostile() and |
||||
MoonfireTarget:IsAffectingCombat() and Player:GetPP() >= 25 |
||||
end):SetTarget(MoonfireTarget) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Starsurge:CastableIf(function(self) |
||||
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(Target) and Target:IsHostile() and |
||||
Target:IsAffectingCombat() and Player:GetPP() >= 25 |
||||
end):SetTarget(Target) |
||||
) |
||||
|
||||
DefaultAPL:AddSpell( |
||||
Wrath:CastableIf(function(self) |
||||
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
||||
and Player:CanSee(Target) and not Player:IsMoving() and |
||||
Target:IsHostile() and |
||||
Target:IsAffectingCombat() and Player:GetPP() >= 25 |
||||
end):SetTarget(Target) |
||||
) |
||||
|
||||
RestoModule:Sync(function() |
||||
if IsShiftKeyDown() and Player:GetAuras():FindMy(CatForm):IsUp() then |
||||
return DamageAPL:Execute() |
||||
end |
||||
DefaultAPL:Execute() |
||||
end) |
||||
|
||||
Bastion:Register(RestoModule) |
File diff suppressed because it is too large
Load Diff
@ -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,54 +0,0 @@ |
||||
local |
||||
Tinkr, |
||||
---@type Bastion |
||||
Bastion = ... |
||||
|
||||
local ArcaneModule = Bastion.Module:New('arcane') |
||||
local Player = Bastion.UnitManager:Get('player') |
||||
local Target = Bastion.UnitManager:Get('target') |
||||
local None = Bastion.UnitManager:Get('none') |
||||
local AutoAttack = Bastion.SpellBook:GetSpell(6603) |
||||
|
||||
local CDsEnabled = false |
||||
|
||||
local Command = Bastion.Command:New('arcane') |
||||
|
||||
Command:Register('cooldowns', 'Toggle Arcane CDs', function() |
||||
CDsEnabled = not CDsEnabled |
||||
Bastion:Print('Arcane Cooldowns ' .. (CDsEnabled and 'enabled' or 'disabled')) |
||||
end) |
||||
|
||||
---@return boolean |
||||
local function CombatRotation() |
||||
return false |
||||
end |
||||
|
||||
|
||||
---@return boolean |
||||
local function OutOfCombatRotation() |
||||
return false |
||||
end |
||||
|
||||
|
||||
local isRunning = false |
||||
|
||||
ArcaneModule:Sync(function() |
||||
if not isRunning then |
||||
Bastion:Print('Arcane Started') |
||||
isRunning = true |
||||
end |
||||
|
||||
if not Player:IsAlive() or Player:IsMounted() then |
||||
return false |
||||
end |
||||
|
||||
if Player:IsAffectingCombat() or IsCurrentSpell(AutoAttack:GetID()) then |
||||
-- Combat Rotation |
||||
return CombatRotation() |
||||
else |
||||
-- Out Of Combat Rotation |
||||
return OutOfCombatRotation() |
||||
end |
||||
end) |
||||
|
||||
Bastion:Register(ArcaneModule) |
@ -1,54 +0,0 @@ |
||||
local |
||||
Tinkr, |
||||
---@type Bastion |
||||
Bastion = ... |
||||
|
||||
local FireModule = Bastion.Module:New('fire') |
||||
local Player = Bastion.UnitManager:Get('player') |
||||
local Target = Bastion.UnitManager:Get('target') |
||||
local None = Bastion.UnitManager:Get('none') |
||||
local AutoAttack = Bastion.SpellBook:GetSpell(6603) |
||||
|
||||
local CDsEnabled = false |
||||
|
||||
local Command = Bastion.Command:New('fire') |
||||
|
||||
Command:Register('cooldowns', 'Toggle Fire CDs', function() |
||||
CDsEnabled = not CDsEnabled |
||||
Bastion:Print('Fire Cooldowns ' .. (CDsEnabled and 'enabled' or 'disabled')) |
||||
end) |
||||
|
||||
---@return boolean |
||||
local function CombatRotation() |
||||
return false |
||||
end |
||||
|
||||
|
||||
---@return boolean |
||||
local function OutOfCombatRotation() |
||||
return false |
||||
end |
||||
|
||||
|
||||
local isRunning = false |
||||
|
||||
FireModule:Sync(function() |
||||
if not isRunning then |
||||
Bastion:Print('Fire Started') |
||||
isRunning = true |
||||
end |
||||
|
||||
if not Player:IsAlive() or Player:IsMounted() then |
||||
return false |
||||
end |
||||
|
||||
if Player:IsAffectingCombat() or IsCurrentSpell(AutoAttack:GetID()) then |
||||
-- Combat Rotation |
||||
return CombatRotation() |
||||
else |
||||
-- Out Of Combat Rotation |
||||
return OutOfCombatRotation() |
||||
end |
||||
end) |
||||
|
||||
Bastion:Register(FireModule) |
@ -1,59 +0,0 @@ |
||||
local |
||||
Tinkr, |
||||
---@type Bastion |
||||
Bastion = ... |
||||
|
||||
local IcyVeins = Bastion.SpellBook:GetSpell(12472) |
||||
local FrozenOrb = Bastion.SpellBook:GetSpell(84714) |
||||
local Blizzard = Bastion.SpellBook:GetSpell(190356) |
||||
|
||||
Bastion.ToggleManager:Add({ |
||||
id = 'Frost_CdsEnabled', |
||||
icon = IcyVeins:GetIcon(), |
||||
state = false |
||||
}) |
||||
|
||||
Bastion.ToggleManager:Add({ |
||||
id = 'Frost_FrozenOrbEnabled', |
||||
icon = FrozenOrb:GetIcon(), |
||||
state = false |
||||
}) |
||||
|
||||
Bastion.ToggleManager:Add({ |
||||
id = 'Frost_AutoAOE', |
||||
icon = Blizzard:GetIcon(), |
||||
state = true |
||||
}) |
||||
|
||||
---@alias GetFrostOption fun(option: "CdsEnabled" | "FrozenOrbEnabled" | 'AutoAOE'): boolean |
||||
|
||||
---@type GetFrostOption |
||||
local function GetFrostOption(option) |
||||
return Bastion.ToggleManager:GetState("Frost_" .. option) |
||||
end |
||||
|
||||
local Command = Bastion.Command:New('frost') |
||||
|
||||
Command:Register('aoe', 'Toggle bastion on/off', function() |
||||
Bastion.ToggleManager:Toggle("Frost_AutoAOE") |
||||
end) |
||||
|
||||
Command:Register('cds', 'Toggle bastion on/off', function() |
||||
Bastion.ToggleManager:Toggle("Frost_CdsEnabled") |
||||
|
||||
if GetFrostOption("FrozenOrbEnabled") and not GetFrostOption("CdsEnabled") then |
||||
Bastion.ToggleManager:Toggle("Frost_FrozenOrbEnabled") |
||||
elseif not GetFrostOption("FrozenOrbEnabled") and GetFrostOption("CdsEnabled") then |
||||
Bastion.ToggleManager:Toggle("Frost_FrozenOrbEnabled") |
||||
end |
||||
end) |
||||
|
||||
Command:Register('orb', 'Toggle bastion on/off', function() |
||||
Bastion.ToggleManager:Toggle("Frost_FrozenOrbEnabled") |
||||
|
||||
if not GetFrostOption("FrozenOrbEnabled") and GetFrostOption("CdsEnabled") then |
||||
Bastion.ToggleManager:Toggle("Frost_CdsEnabled") |
||||
end |
||||
end) |
||||
|
||||
return GetFrostOption |
@ -1,206 +0,0 @@ |
||||
local |
||||
Tinkr, |
||||
---@type Bastion |
||||
Bastion = ... |
||||
|
||||
local FrostModule = Bastion.Module:New('frost') |
||||
|
||||
local Player = Bastion.UnitManager:Get('player') |
||||
local Target = Bastion.UnitManager:Get('target') |
||||
local None = Bastion.UnitManager:Get('none') |
||||
|
||||
local AutoAttack = Bastion.SpellBook:GetSpell(6603) |
||||
local Frostbolt = Bastion.SpellBook:GetSpell(116) |
||||
local IceLance = Bastion.SpellBook:GetSpell(30455) |
||||
local Flurry = Bastion.SpellBook:GetSpell(44614) |
||||
local BrainFreeze = Bastion.SpellBook:GetSpell(190446) |
||||
local FingersOfFrost = Bastion.SpellBook:GetSpell(44544) |
||||
local WintersChill = Bastion.SpellBook:GetSpell(228358) |
||||
local FrostNova = Bastion.SpellBook:GetSpell(122) |
||||
local IceNova = Bastion.SpellBook:GetSpell(157997) |
||||
local IcyVeins = Bastion.SpellBook:GetSpell(12472) |
||||
local FrozenOrb = Bastion.SpellBook:GetSpell(84714) |
||||
local Blizzard = Bastion.SpellBook:GetSpell(190356) |
||||
local RuneOfPower = Bastion.SpellBook:GetSpell(116011) |
||||
|
||||
---@type GetRangedTargetCount |
||||
local GetRangedTargetCount = Tinkr:require("scripts/bastion/scripts/shared/get-ranged-target-count", Bastion) |
||||
|
||||
local EnableDrawROP = Tinkr:require("scripts/bastion/scripts/shared/draw-rop", Bastion) |
||||
|
||||
---@type GetFrostOption |
||||
local GetFrostOption = Tinkr:require("scripts/bastion/scripts/frost/frost-gui", Bastion) |
||||
|
||||
---@param unit Unit |
||||
local function isUnitFrozen(unit) |
||||
if not unit:Exists() then return false end |
||||
|
||||
if unit:GetAuras():FindMy(IceNova):IsUp() or unit:GetAuras():FindMy(FrostNova):IsUp() then |
||||
return true |
||||
end |
||||
|
||||
return false |
||||
end |
||||
|
||||
local IceLanceTarget = Bastion.UnitManager:CreateCustomUnit('icelance', function() |
||||
if not IceLance:IsKnownAndUsable() then return None end |
||||
|
||||
local icelance_target = nil |
||||
|
||||
Bastion.UnitManager:EnumEnemies(function(unit) |
||||
if unit:IsDead() then |
||||
return false |
||||
end |
||||
|
||||
if not Player:CanSee(unit) then |
||||
return false |
||||
end |
||||
|
||||
if not IceLance:IsInRange(unit) then |
||||
return false |
||||
end |
||||
|
||||
if not Player:IsFacing(unit) then |
||||
return false |
||||
end |
||||
|
||||
if IceLance:IsInFlightToUnit(unit) then |
||||
return false |
||||
end |
||||
|
||||
if isUnitFrozen(unit) then |
||||
icelance_target = unit |
||||
return true |
||||
end |
||||
|
||||
return false |
||||
end) |
||||
|
||||
if icelance_target == nil then |
||||
icelance_target = None |
||||
end |
||||
|
||||
return icelance_target |
||||
end) |
||||
|
||||
local FrozenOrbTarget = Bastion.UnitManager:CreateCustomUnit('frozen_orb', function() |
||||
local unit = Bastion.UnitManager:GetEnemyWithMostEnemies(40, 10) |
||||
|
||||
if not unit then |
||||
if Target:Exists() and Target:GetDistance(Player) <= 40 then |
||||
unit = Target |
||||
else |
||||
unit = None |
||||
end |
||||
end |
||||
|
||||
return unit |
||||
end) |
||||
|
||||
local HasRotatedForOrb = false |
||||
|
||||
FrozenOrb:OnCast(function() |
||||
HasRotatedForOrb = false |
||||
end) |
||||
|
||||
---@return boolean |
||||
local function CombatRotation() |
||||
local targetCount = GetRangedTargetCount(40) |
||||
|
||||
if GetFrostOption("CdsEnabled") and IcyVeins:IsKnownAndUsable() and not Player:IsMoving() and Target:Exists() then |
||||
return IcyVeins:Cast(Player) |
||||
end |
||||
|
||||
if GetFrostOption("CdsEnabled") and RuneOfPower:IsKnownAndUsable() and not Player:GetAuras():FindMy(RuneOfPower):IsUp() and not Player:IsMoving() and Target:Exists() and IcyVeins:GetLastCastTime() ~= false and GetTime() - IcyVeins:GetLastCastTime() > 5 then |
||||
return RuneOfPower:Cast(Player) |
||||
end |
||||
|
||||
if FrozenOrb:IsKnownAndUsable() and GetFrostOption("FrozenOrbEnabled") and FrozenOrbTarget:Exists() then |
||||
if not HasRotatedForOrb then |
||||
print("TURNING TO ORB TARGET") |
||||
FaceObject(FrozenOrbTarget:GetGUID()) |
||||
SendMovementHeartbeat() |
||||
HasRotatedForOrb = true |
||||
else |
||||
return FrozenOrb:Cast(Player) |
||||
end |
||||
end |
||||
|
||||
if IceLanceTarget:Exists() then |
||||
return IceLance:Cast(IceLanceTarget) |
||||
end |
||||
|
||||
if Target:Exists() and Player:CanSee(Target) and IceLance:IsKnownAndUsable() and IceLance:IsInRange(Target) then |
||||
-- Winters Chill |
||||
if Target:GetAuras():FindMy(WintersChill):IsUp() then |
||||
local winters_chill_stacks = Target:GetAuras():FindMy(WintersChill):GetCount() |
||||
print("WC STACKS: ", winters_chill_stacks) |
||||
if winters_chill_stacks == 1 and not IceLance:IsInFlightToUnit(Target) then |
||||
return IceLance:Cast(Target) |
||||
end |
||||
|
||||
if winters_chill_stacks > 1 then |
||||
return IceLance:Cast(Target) |
||||
end |
||||
end |
||||
|
||||
-- Fingers of Frost |
||||
if Player:GetAuras():FindMy(FingersOfFrost):IsUp() then |
||||
local fof_stacks = Player:GetAuras():FindMy(FingersOfFrost):GetCount() |
||||
print("FOF STACKS: ", fof_stacks) |
||||
if fof_stacks == 1 and not IceLance:IsInFlightToUnit(Target) then |
||||
return IceLance:Cast(Target) |
||||
end |
||||
|
||||
if fof_stacks > 1 then |
||||
return IceLance:Cast(Target) |
||||
end |
||||
end |
||||
end |
||||
|
||||
if Target:Exists() and Player:CanSee(Target) and Flurry:IsKnownAndUsable() and Player:GetAuras():FindMy(BrainFreeze):IsUp() then |
||||
local CastingSpell = Player:GetCastingOrChannelingSpell() |
||||
|
||||
if Player:IsMoving() or (CastingSpell ~= nil and CastingSpell:GetID() == Frostbolt:GetID()) then |
||||
return Flurry:Cast(Target) |
||||
end |
||||
end |
||||
|
||||
if Target:Exists() and Player:CanSee(Target) and not Player:IsMoving() and Frostbolt:IsKnownAndUsable() and Frostbolt:IsInRange(Target) then |
||||
return Frostbolt:Cast(Target) |
||||
end |
||||
|
||||
return false |
||||
end |
||||
|
||||
|
||||
---@return boolean |
||||
local function OutOfCombatRotation() |
||||
return false |
||||
end |
||||
|
||||
|
||||
local isRunning = false |
||||
|
||||
FrostModule:Sync(function() |
||||
if not isRunning then |
||||
Bastion:Print('Frost Started') |
||||
isRunning = true |
||||
end |
||||
|
||||
EnableDrawROP() |
||||
|
||||
if not Player:IsAlive() or Player:IsMounted() then |
||||
return false |
||||
end |
||||
|
||||
if Player:IsAffectingCombat() or IsCurrentSpell(AutoAttack:GetID()) then |
||||
-- Combat Rotation |
||||
return CombatRotation() |
||||
else |
||||
-- Out Of Combat Rotation |
||||
return OutOfCombatRotation() |
||||
end |
||||
end) |
||||
|
||||
Bastion:Register(FrostModule) |
@ -1,45 +0,0 @@ |
||||
local |
||||
Tinkr, |
||||
---@type Bastion |
||||
Bastion = ... |
||||
|
||||
local Player = Bastion.UnitManager:Get('player') |
||||
|
||||
local RuneOfPower = Bastion.SpellBook:GetSpell(116011) |
||||
|
||||
local Draw = Tinkr.Util.Draw:New() |
||||
|
||||
Draw:Sync(function(draw) |
||||
for i, object in ipairs(Objects()) do |
||||
local name = ObjectName(object) |
||||
|
||||
if name == RuneOfPower:GetName() then |
||||
local creator = ObjectCreator(object) |
||||
|
||||
if tostring(creator) == tostring(Player:GetGUID()) then |
||||
local distance = ObjectDistance('player', object) |
||||
local ropX, ropY, ropZ = ObjectPosition(object) |
||||
|
||||
draw:Circle(ropX, ropY, ropZ, 8) |
||||
draw:SetColor(69, 7, 58) |
||||
|
||||
if distance > 8 then |
||||
draw:SetColor(252, 3, 207) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end) |
||||
|
||||
local isEnabled = false |
||||
|
||||
-- Draws a circle around the players Rune of Power to make it easier to stay within range. |
||||
|
||||
local function EnableDrawROP() |
||||
if not isEnabled then |
||||
isEnabled = true |
||||
Draw:Enable() |
||||
end |
||||
end |
||||
|
||||
return EnableDrawROP |
@ -1,25 +0,0 @@ |
||||
local |
||||
Tinkr, |
||||
---@type Bastion |
||||
Bastion = ... |
||||
|
||||
local Player = Bastion.UnitManager:Get('player') |
||||
|
||||
---@alias GetRangedTargetCount fun(range: number): number |
||||
|
||||
---@type GetRangedTargetCount |
||||
local function GetRangedTargetCount(range) |
||||
local count = 0 |
||||
|
||||
Bastion.UnitManager:EnumEnemies(function(unit) |
||||
if not unit:IsDead() and unit:IsAffectingCombat() and Player:CanSee(unit) and Player:GetDistance(unit) <= range and Player:IsFacing(unit) then |
||||
count = count + 1 |
||||
return false |
||||
end |
||||
return false |
||||
end) |
||||
|
||||
return count |
||||
end |
||||
|
||||
return GetRangedTargetCount |
@ -1,201 +0,0 @@ |
||||
local Tinkr, _Bastion = ... |
||||
|
||||
---@class Bastion |
||||
local Bastion = _Bastion |
||||
|
||||
---@alias BigWigsBars table<string, { spellId: number, duration: number, startTime: number, pauseTime: number | nil }> |
||||
|
||||
---@class ContentUtils |
||||
local ContentUtils = { |
||||
---@type InterruptList |
||||
interruptList = {}, |
||||
---@type TankBusterList |
||||
tankBusterList = {}, |
||||
---@type ImportantAuraList |
||||
importantAuras = {}, |
||||
---@type BigWigsBars |
||||
bars = {}, |
||||
isBigWigsEnabled = false |
||||
} |
||||
|
||||
ContentUtils.__index = ContentUtils |
||||
|
||||
local function BWEventCallBack(event, ...) |
||||
if event == "BigWigs_StartBar" then |
||||
local addon, spellId, text, duration, icon, isCD = ... |
||||
local now = GetTime() |
||||
|
||||
print('START BAR', text) |
||||
|
||||
ContentUtils.bars[text] = ContentUtils.bars[text] or {} |
||||
|
||||
ContentUtils.bars[text].duration = duration |
||||
ContentUtils.bars[text].startTime = now |
||||
ContentUtils.bars[text].spellId = spellId |
||||
elseif event == "BigWigs_StopBar" then |
||||
local addon, text = ... |
||||
|
||||
print('STOP BAR', text) |
||||
|
||||
if ContentUtils.bars[text] then |
||||
ContentUtils.bars[text] = nil |
||||
end |
||||
elseif event == "BigWigs_PauseBar" then |
||||
local addon, text = ... |
||||
|
||||
print('PAUSE BAR', text) |
||||
|
||||
if ContentUtils.bars[text] then |
||||
ContentUtils.bars[text].pauseTime = GetTime() |
||||
end |
||||
elseif event == "BigWigs_ResumeBar" then |
||||
local addon, text = ... |
||||
|
||||
print('RESUME BAR', text) |
||||
|
||||
if ContentUtils.bars[text] and ContentUtils.bars[text].pauseTime then |
||||
local pauseTime = ContentUtils.bars[text].pauseTime |
||||
local startTime = ContentUtils.bars[text].startTime |
||||
local duration = ContentUtils.bars[text].duration |
||||
|
||||
local newDuration = duration - (pauseTime - startTime) |
||||
|
||||
ContentUtils.bars[text].pauseTime = nil |
||||
ContentUtils.bars[text].duration = newDuration |
||||
ContentUtils.bars[text].startTime = GetTime() |
||||
end |
||||
elseif event == "BigWigs_StopBars" or event == "BigWigs_OnBossDisable" then |
||||
ContentUtils.bars = {} |
||||
end |
||||
end |
||||
|
||||
---@type InterruptList |
||||
local _interruptList = Tinkr:require("scripts/bastion/ContentUtils/lists/interrupt-list", Bastion) |
||||
---@type TankBusterList |
||||
local _tankBusterList = Tinkr:require("scripts/bastion/ContentUtils/lists/tank-buster-list", Bastion) |
||||
---@type ImportantAuraList |
||||
local _importantAuraList = Tinkr:require("scripts/bastion/ContentUtils/lists/important-aura-list", Bastion) |
||||
|
||||
|
||||
---@return ContentUtils |
||||
function ContentUtils:New() |
||||
local self = setmetatable({}, ContentUtils) |
||||
|
||||
self.interruptList = _interruptList |
||||
self.tankBusterList = _tankBusterList |
||||
self.importantAuras = _importantAuraList |
||||
if BigWigsLoader then |
||||
print("BigWigs Enabled!") |
||||
self.isBigWigsEnabled = true |
||||
BigWigsLoader.RegisterMessage({}, 'BigWigs_StartBar', BWEventCallBack) |
||||
BigWigsLoader.RegisterMessage({}, 'BigWigs_StopBar', BWEventCallBack) |
||||
BigWigsLoader.RegisterMessage({}, 'BigWigs_PauseBar', BWEventCallBack) |
||||
BigWigsLoader.RegisterMessage({}, 'BigWigs_ResumeBar', BWEventCallBack) |
||||
BigWigsLoader.RegisterMessage({}, 'BigWigs_StopBars', BWEventCallBack) |
||||
BigWigsLoader.RegisterMessage({}, 'BigWigs_OnBossDisable', BWEventCallBack) |
||||
end |
||||
|
||||
return self |
||||
end |
||||
|
||||
---@param unit Unit |
||||
---@param percent number |
||||
---@return Interrupt | nil |
||||
function ContentUtils:CastingCriticalStop(unit, percent) |
||||
local castingSpell = unit:GetCastingOrChannelingSpell() |
||||
|
||||
local npcSpells = self.interruptList[unit:GetID()] |
||||
|
||||
if npcSpells and castingSpell then |
||||
local spellID = castingSpell:GetID() |
||||
|
||||
local spellTraits = npcSpells[spellID] |
||||
|
||||
if not spellTraits then |
||||
return nil |
||||
end |
||||
|
||||
local castPercent = unit:GetChannelOrCastPercentComplete() |
||||
|
||||
if castPercent >= percent then |
||||
return spellTraits |
||||
end |
||||
end |
||||
|
||||
return nil |
||||
end |
||||
|
||||
function ContentUtils:RefreshBars() |
||||
if self.isBigWigsEnabled then |
||||
for key, value in pairs(self.bars) do |
||||
local expireTime = value.duration + value.startTime |
||||
|
||||
if expireTime < GetTime() then |
||||
self.bars[key] = nil |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
---@param spellId number |
||||
---@param timeUntilCast number |
||||
---@return boolean |
||||
function ContentUtils:IsSpellCastSoon(spellId, timeUntilCast) |
||||
if self.isBigWigsEnabled then |
||||
self:RefreshBars() |
||||
for key, value in pairs(self.bars) do |
||||
if value.spellId == spellId and not value.pauseTime then |
||||
local expireTime = value.duration + value.startTime |
||||
|
||||
local timeUntilSpell = expireTime - GetTime() |
||||
|
||||
if timeUntilSpell > 0 and timeUntilSpell <= timeUntilCast then |
||||
return true |
||||
end |
||||
end |
||||
end |
||||
end |
||||
return false |
||||
end |
||||
|
||||
---@param unit Unit |
||||
---@param timeUntilCast? number |
||||
---@return TankBuster | nil |
||||
function ContentUtils:CastingTankBuster(unit, timeUntilCast) |
||||
local npcSpells = self.tankBusterList[unit:GetID()] |
||||
|
||||
if npcSpells then |
||||
-- If timeUntilCast is provided, check if any of this NPC |
||||
if timeUntilCast then |
||||
for key, value in pairs(self.bars) do |
||||
local spellTraits = npcSpells[value.spellId] |
||||
|
||||
if spellTraits and not value.pauseTime and ((value.startTime + value.duration) - GetTime()) <= timeUntilCast then |
||||
return spellTraits |
||||
end |
||||
end |
||||
end |
||||
|
||||
local castingSpell = unit:GetCastingOrChannelingSpell() |
||||
|
||||
if castingSpell then |
||||
if npcSpells[castingSpell:GetID()] then return npcSpells[castingSpell:GetID()] end |
||||
end |
||||
|
||||
end |
||||
|
||||
return nil |
||||
end |
||||
|
||||
---@param friend Unit |
||||
---@return ImportantAura | nil |
||||
function ContentUtils:HasImportantAura(friend) |
||||
local traits = nil |
||||
friend:GetAuras():ForEach(function(spellId) |
||||
local auraTraits = self.importantAuras[spellId] |
||||
if auraTraits then traits = auraTraits end |
||||
end) |
||||
return traits |
||||
end |
||||
|
||||
return ContentUtils |
@ -1,193 +0,0 @@ |
||||
---@alias ImportantAura { isMagicDispel: boolean | nil, isPoisonDispel: boolean | nil, isDiseaseDispel: boolean | nil, isDiffusable: boolean | nil } |
||||
---@alias ImportantAuraList table<number, ImportantAura> |
||||
|
||||
---@type ImportantAuraList |
||||
local _ImportantAuraList = { |
||||
-- Primal Chill |
||||
[372682] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Primal Chill |
||||
[373589] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Rolling Thunder |
||||
[392641] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Burning Touch |
||||
[373869] = { |
||||
isMagicDispel = true, |
||||
isDiffusable = true |
||||
}, |
||||
-- Shock Blast |
||||
[392924] = { |
||||
isMagicDispel = true, |
||||
isDiffusable = true |
||||
}, |
||||
-- Storm Slam |
||||
[381515] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Thunder Clap |
||||
[386028] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Tempest |
||||
[386025] = { |
||||
isMagicDispel = true, |
||||
isDiffusable = true |
||||
}, |
||||
-- Frightful Roar |
||||
[386063] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Bloodcurdling Shout |
||||
[373395] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Conductive Strike |
||||
[376827] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Storm Shock |
||||
[381530] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Mystic Vapors |
||||
[387564] = { |
||||
isMagicDispel = true, |
||||
isDiffusable = true |
||||
}, |
||||
-- Erratic Growth |
||||
[375602] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Crystaline Rupture |
||||
[370766] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Waking Bane |
||||
[386546] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Waking Bane |
||||
[386549] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Forbiden Knowledge |
||||
[371352] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Icy Bindings |
||||
[377488] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Absolute Zero |
||||
[396722] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Dragon Strike |
||||
[384978] = { |
||||
isMagicDispel = true, |
||||
isDiffusable = true |
||||
}, |
||||
-- Monotonous Lecture |
||||
[388392] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Thunderstrike |
||||
[215429] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Seal Magic |
||||
[209404] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Mana Fang |
||||
[209516] = { |
||||
isMagicDispel = true, |
||||
isDiffusable = true |
||||
}, |
||||
-- Suppress |
||||
[209413] = { |
||||
isMagicDispel = true, |
||||
}, |
||||
-- Bewitch |
||||
[211470] = { |
||||
isMagicDispel = true, |
||||
isDiffusable = true |
||||
}, |
||||
-- Impending Doom |
||||
[397907] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Withering Soul |
||||
[208165] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Criple |
||||
[214690] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Carrion Swarm |
||||
[214688] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Shadow Word: Frailty |
||||
[152819] = { |
||||
isMagicDispel = true, |
||||
isDiffusable = true |
||||
}, |
||||
-- Tainted Ripple |
||||
[397878] = { |
||||
isMagicDispel = true |
||||
}, |
||||
-- Haunting Scream |
||||
[395859] = { |
||||
isMagicDispel = true, |
||||
}, |
||||
-- Throw Torch |
||||
[114803] = { |
||||
isMagicDispel = true, |
||||
isDiffusable = true |
||||
}, |
||||
-- Sleepy Soliloquy |
||||
[395872] = { |
||||
isMagicDispel = true, |
||||
}, |
||||
-- Serpent Strike |
||||
[106823] = { |
||||
isMagicDispel = true, |
||||
}, |
||||
-- Necrotic Burst |
||||
[156718] = { |
||||
isDiseaseDispel = true |
||||
}, |
||||
-- Plague Spit |
||||
[153524] = { |
||||
isDiseaseDispel = true |
||||
}, |
||||
-- Death Venom |
||||
[156717] = { |
||||
isPoisonDispel = true |
||||
}, |
||||
-- Lasher Toxin |
||||
[389033] = { |
||||
isPoisonDispel = true |
||||
}, |
||||
-- Touch of Nothingness |
||||
[106113] = { |
||||
isMagicDispel = true, |
||||
}, |
||||
-- Arcane Lockdown |
||||
[207278] = { |
||||
isDiffusable = true |
||||
}, |
||||
-- Hinder |
||||
[215204] = { |
||||
isDiffusable = true |
||||
} |
||||
} |
||||
|
||||
return _ImportantAuraList |
@ -1,662 +0,0 @@ |
||||
|
||||
---@alias Interrupt { kickable: boolean, sweepable: boolean, paraliseable: boolean } |
||||
---@alias InterruptList table<number, table<number, Interrupt>> |
||||
|
||||
---@type InterruptList |
||||
local _InterruptList = { |
||||
-- kick, stun, disorient, incap |
||||
-- |
||||
-- HoV |
||||
-- |
||||
-- Thunder Caller |
||||
[95842] = { |
||||
-- Thunderous Blast |
||||
[198585] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Mystic |
||||
[95834] = { |
||||
-- Holy Radiance |
||||
[215433] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Runcarver |
||||
[96664] = { |
||||
-- Etch |
||||
[198959] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Marksman |
||||
[96640] = { |
||||
-- Penetrating Shot |
||||
[199210] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Shieldmaiden |
||||
[95832] = { |
||||
-- Mortal Hew |
||||
[199050] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Shieldmaiden 2 |
||||
[101639] = { |
||||
-- Mortal Hew |
||||
[199050] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Odyn Add |
||||
[102019] = { |
||||
-- Surge |
||||
[198750] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- |
||||
-- Court of Stars |
||||
-- |
||||
-- Duskwatch Guard |
||||
[111563] = { |
||||
-- Fortification |
||||
[209033] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Duskwatch Guard 2 |
||||
[104246] = { |
||||
-- Fortification |
||||
[209033] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Sentry |
||||
[104251] = { |
||||
-- Sound the Alarm |
||||
[210261] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Construct |
||||
[104270] = { |
||||
-- Suppress |
||||
[209413] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
}, |
||||
-- Charging Station |
||||
[225100] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Bound Energy |
||||
[105705] = { |
||||
-- Charged Blast |
||||
[212031] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Arcane Manifestation |
||||
[105704] = { |
||||
-- Drain Magic |
||||
[209485] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Watchful Inquisitor |
||||
[105715] = { |
||||
-- Searing Glare |
||||
[211299] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
}, |
||||
-- Eye Storm |
||||
[212784] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Blazing Imp |
||||
[104295] = { |
||||
-- Drifting Embers |
||||
[211401] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
}, |
||||
-- Drifting Embers 2 |
||||
[211406] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
}, |
||||
-- Fireball |
||||
[211412] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Shadow Mistress |
||||
[104300] = { |
||||
-- Bewitch |
||||
[211470] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Balgarr |
||||
[104274] = { |
||||
-- Disintegration Beam |
||||
[207980] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
}, |
||||
-- Disintigration Beam 2 |
||||
[207981] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
}, |
||||
-- Impending Doom |
||||
[397907] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
}, |
||||
-- Impending Doom 2 |
||||
[397908] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Talixae Flamewreath |
||||
[104217] = { |
||||
-- Withering Soul |
||||
[208165] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- |
||||
-- RLP |
||||
-- |
||||
-- Earthshaper |
||||
[187969] = { |
||||
-- Tectonic Slam |
||||
[372735] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Chillweaver |
||||
[188067] = { |
||||
-- Ice Shield |
||||
[384933] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
}, |
||||
-- Ice Shield 2 |
||||
[372749] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
}, |
||||
-- Ice Shield 3 |
||||
[372743] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Meledrusa |
||||
[188252] = { |
||||
-- Frost Overload |
||||
[373680] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
}, |
||||
-- Frost Overload 2 |
||||
[373688] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Cinderweaver |
||||
[190207] = { |
||||
-- Cinderbolt 1 |
||||
[384194] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
}, |
||||
-- Cinderbolt 2 |
||||
[384197] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Flame Dancer |
||||
[190206] = { |
||||
-- Flame Dance |
||||
[385536] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Blazebound Firestorm |
||||
[189886] = { |
||||
-- Roaring Blaze |
||||
[373017] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Tempest Channeler |
||||
[198047] = { |
||||
-- Thunder Bolt |
||||
[392576] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Flame Channeler |
||||
[197985] = { |
||||
-- Flashfire |
||||
[392451] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
}, |
||||
-- Flashfire |
||||
[392452] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
}, |
||||
}, |
||||
-- |
||||
-- NO |
||||
-- |
||||
-- Hornsounder |
||||
[192796] = { |
||||
-- Rally The Clan |
||||
[383823] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Plainstomper |
||||
[191847] = { |
||||
-- Disruptive Shout |
||||
[384365] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Lancemaster |
||||
[192800] = { |
||||
-- Disruptive Shout |
||||
[384365] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Arcblade |
||||
[194898] = { |
||||
-- Arcing Strike |
||||
[387135] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Stormcaller Botoo |
||||
[194317] = { |
||||
-- Stormbolt |
||||
[386012] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Thunderbeast |
||||
[195696] = { |
||||
-- Chain Lightning |
||||
[387127] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
[194894] = { |
||||
-- Tempest |
||||
[386025] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
}, |
||||
-- Tempest 2 |
||||
[386024] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
}, |
||||
-- Summon Squall |
||||
[386015] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
}, |
||||
-- Stormbolt |
||||
[386012] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Squall |
||||
[194895] = { |
||||
-- Surge |
||||
[386026] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Stormcaller Arynga |
||||
[195265] = { |
||||
-- Stormbolt |
||||
[386012] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Nokhud Neophyte |
||||
[196263] = { |
||||
-- Stormbolt |
||||
[386012] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Stormcaller Solongo |
||||
[194315] = { |
||||
-- Stormbolt |
||||
[386012] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Stormcaller Zarii |
||||
[194316] = { |
||||
-- Stormbolt |
||||
[386012] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Soulharvester Galtmaa |
||||
[195927] = { |
||||
-- Death Bolt Volley |
||||
[387411] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Soulharvester Tumen |
||||
[195929] = { |
||||
-- Death Bolt Volley |
||||
[387411] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Soulharvester Mandakh |
||||
[195930] = { |
||||
-- Death Bolt Volley |
||||
[387411] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Soulharvester Duuren |
||||
[195928] = { |
||||
-- Death Bolt Volley |
||||
[387411] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Beastcaller |
||||
[195878] = { |
||||
-- Desecrated Roar |
||||
[387440] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
}, |
||||
-- Heavy Slash |
||||
[387826] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Mystic |
||||
[195877] = { |
||||
-- Swift Wind |
||||
[387596] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Risen Warrior |
||||
[195855] = { |
||||
-- Mortal Strike |
||||
[388801] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Teera |
||||
[186339] = { |
||||
-- Guardian Wind |
||||
[384808] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Batak |
||||
[193462] = { |
||||
-- Bloodcurdling Shout |
||||
[373395] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Balakar Add |
||||
[190294] = { |
||||
-- Storm Bolt |
||||
[376725] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- |
||||
-- AV |
||||
-- |
||||
-- Lasher |
||||
[196102] = { |
||||
-- Mystic Vapors |
||||
[387564] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
--Arcane Tender |
||||
[196115] = { |
||||
-- Erratic Growth |
||||
[375596] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
--Arcane Tender 2 |
||||
[191164] = { |
||||
-- Erratic Growth |
||||
[375596] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Crystal Fury |
||||
[187160] = { |
||||
-- Shards |
||||
[370764] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Arcane Elemental |
||||
[186741] = { |
||||
-- Waking Bane |
||||
[386546] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Curator |
||||
[187154] = { |
||||
-- Heavy Tome |
||||
[389804] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Rune Seal Keeper |
||||
[187155] = { |
||||
-- Icy Bindings |
||||
[377488] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Crystal Fury |
||||
[196116] = { |
||||
-- Shards |
||||
[370764] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Vault Guard |
||||
[190510] = { |
||||
-- Ice Cutter |
||||
[377105] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Frog |
||||
[187246] = { |
||||
-- Null Stomp |
||||
[386526] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- |
||||
-- AA |
||||
-- |
||||
-- Scepter |
||||
[196576] = { |
||||
-- Mystic Blast |
||||
[396812] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
}, |
||||
-- Arcane Rain |
||||
[388886] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Textbook |
||||
[196044] = { |
||||
-- Lecture |
||||
[388392] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Eagle |
||||
[192333] = { |
||||
-- Call The Flock |
||||
[377389] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Echoknight |
||||
[196200] = { |
||||
-- Whirlwind |
||||
[387910] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Invoker |
||||
[196202] = { |
||||
-- Arcane Missiles |
||||
[387975] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- |
||||
-- SMBG |
||||
-- |
||||
-- Bone Mender |
||||
[75713] = { |
||||
-- Shadow Mend |
||||
[152818] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Ritual Bones |
||||
[75715] = { |
||||
-- Void Slash |
||||
[164907] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Defiled Spirit |
||||
[75451] = { |
||||
-- Cry of Anguish |
||||
[398154] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Dominator |
||||
[76446] = { |
||||
-- Voidlash |
||||
[156776] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Spider |
||||
[76104] = { |
||||
-- Necrotic Burst |
||||
[156718] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Bat |
||||
[75459] = { |
||||
-- Plague Spit |
||||
[153524] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- |
||||
-- TJS |
||||
-- |
||||
-- Waterspeaker |
||||
[200126] = { |
||||
-- Hydrolance |
||||
[397888] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
}, |
||||
-- Tidal Burst |
||||
[397889] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Wise Mari |
||||
[56448] = { |
||||
-- Hydrolance |
||||
[397801] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Haunting Sha |
||||
[59555] = { |
||||
-- Gaze |
||||
[114646] = { |
||||
kickable = false, sweepable = true, paraliseable = true |
||||
}, |
||||
-- Scream |
||||
[398859] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Fish |
||||
[59546] = { |
||||
-- Sleepy |
||||
[395872] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Hozen |
||||
[59552] = { |
||||
-- Fit of Rage |
||||
[396018] = { |
||||
kickable = true, sweepable = false, paraliseable = false |
||||
} |
||||
}, |
||||
-- Golden Beetle |
||||
[59545] = { |
||||
-- Staggering Blow |
||||
[396019] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Tiger |
||||
[59544] = { |
||||
-- Cat Nap |
||||
[396073] = { |
||||
kickable = true, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Mistweaver |
||||
[200137] = { |
||||
-- Defilling Mist |
||||
[397914] = { |
||||
kickable = true, sweepable = true, paraliseable = true |
||||
} |
||||
}, |
||||
-- Guardian |
||||
[200131] = { |
||||
-- Leg Sweep |
||||
[397899] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
}, |
||||
-- Minion of Doubt |
||||
[57109] = { |
||||
-- Dark Claw |
||||
[397931] = { |
||||
kickable = false, sweepable = true, paraliseable = false |
||||
} |
||||
} |
||||
} |
||||
|
||||
return _InterruptList |
@ -1,416 +0,0 @@ |
||||
|
||||
---@alias TankBuster { shouldZen: boolean | nil, shouldDampen: boolean | nil, shouldDiffuse: boolean | nil, shouldFort: boolean | nil, shouldBubble: boolean | nil, shouldPurify: boolean | nil } |
||||
---@alias TankBusterList table<number, table<number, TankBuster>> |
||||
|
||||
---@type TankBusterList |
||||
local _TankBusterList = { |
||||
-- |
||||
-- RLP |
||||
-- |
||||
-- Primal Juggernaut |
||||
[188244] = { |
||||
-- Crushing Smash |
||||
[372730] = { |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Defier Draghar |
||||
[187897] = { |
||||
-- Steel Barrage |
||||
[372047] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Thunderhead |
||||
[197698] = { |
||||
-- Thunder Jaw |
||||
[392395] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldPurify = true, |
||||
shouldZen = true |
||||
} |
||||
}, |
||||
-- Flamegullet |
||||
[197697] = { |
||||
-- Fire Maw |
||||
[392394] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldPurify = true, |
||||
shouldZen = true |
||||
} |
||||
}, |
||||
-- Kokia |
||||
[189232] = { |
||||
-- Searing Blows |
||||
[372858] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldFort = true, |
||||
shouldPurify = true, |
||||
shouldZen = true |
||||
}, |
||||
}, |
||||
-- Erkhart |
||||
[190485] = { |
||||
-- Stormslam |
||||
[381512] = { |
||||
shouldPurify = true, |
||||
shouldZen = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldFort = true |
||||
} |
||||
}, |
||||
-- |
||||
-- NO |
||||
-- |
||||
-- Raging Tempest |
||||
[186615] = { |
||||
-- Energy Surge |
||||
[384686] = { |
||||
shouldDampen = true, |
||||
shouldPurify = true, |
||||
shouldFort = true |
||||
} |
||||
}, |
||||
-- Beastcaller |
||||
[195878] = { |
||||
-- Heavy Slash |
||||
[387826] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Maruuk |
||||
[186338] = { |
||||
-- Brutalize |
||||
[382836] = { |
||||
shouldDampen = true, |
||||
shouldZen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Balakar |
||||
[186151] = { |
||||
-- Rending Strike |
||||
[375937] = { |
||||
shouldDampen = true, |
||||
shouldZen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- |
||||
-- AV |
||||
-- |
||||
-- Leymore |
||||
[186644] = { |
||||
-- Infused Strike |
||||
[374789] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldZen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Vault Guard |
||||
[190510] = { |
||||
-- Ice Cutter |
||||
[377105] = { |
||||
shouldPurify = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
} |
||||
}, |
||||
-- Scalebane |
||||
[191739] = { |
||||
-- Ice Cutter |
||||
[377105] = { |
||||
shouldPurify = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
}, |
||||
-- Spellfrost Breath |
||||
[391120] = { |
||||
shouldPurify = true, |
||||
shouldZen = true, |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
} |
||||
}, |
||||
-- Azureblade |
||||
[186739] = { |
||||
-- Arcane Cleave |
||||
[372222] = { |
||||
shouldZen = true, |
||||
shouldPurify = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
} |
||||
}, |
||||
-- Umbreskul |
||||
[186738] = { |
||||
-- Dragon Strike |
||||
[384978] = { |
||||
shouldZen = true, |
||||
shouldPurify = true, |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldFort = true |
||||
} |
||||
}, |
||||
-- |
||||
-- AA |
||||
-- |
||||
-- Battleaxe |
||||
[196577] = { |
||||
-- Severing Slash |
||||
[388911] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Crawth |
||||
[191736] = { |
||||
-- Savage Peck |
||||
[376997] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldZen = true, |
||||
shouldPurify = true, |
||||
shouldFort = true |
||||
} |
||||
}, |
||||
-- Overgrown Ancient |
||||
[196482] = { |
||||
-- Barkbreaker |
||||
[388544] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true, |
||||
shouldFort = true |
||||
} |
||||
}, |
||||
-- |
||||
-- HOV |
||||
-- |
||||
-- Storm Drake |
||||
[97068] = { |
||||
-- Lightning Breath |
||||
[198888] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Hymdall |
||||
[94960] = { |
||||
-- Bloodletting Sweep |
||||
[193092] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldZen = true, |
||||
shouldPurify = true, |
||||
shouldFort = true |
||||
} |
||||
}, |
||||
-- Hyrja |
||||
[95833] = { |
||||
[192018] = { |
||||
shouldZen = true, |
||||
shouldPurify = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldFort = true |
||||
} |
||||
}, |
||||
-- Storm Drake |
||||
[99891] = { |
||||
-- Lightning Breath |
||||
[198888] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldPurify = true, |
||||
} |
||||
}, |
||||
-- Angerhoof Bull |
||||
[96611] = { |
||||
-- Piercing Horns |
||||
[199151] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Steeljaw Grizzly |
||||
[96677] = { |
||||
-- Rending Claws |
||||
[185425] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldFort = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- King Ranulf |
||||
[97083] = { |
||||
-- Sever |
||||
[199652] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- King Haldor |
||||
[95843] = { |
||||
-- Sever |
||||
[199652] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- King Bjorn |
||||
[97081] = { |
||||
-- Sever |
||||
[199652] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- King Tor |
||||
[97084] = { |
||||
-- Sever |
||||
[199652] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- God-King Skovald |
||||
[95675] = { |
||||
-- Savaga Slash |
||||
[193668] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldZen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- |
||||
-- CoS |
||||
-- |
||||
-- Sentry |
||||
[104270] = { |
||||
-- Charged Smash |
||||
[209495] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true, |
||||
} |
||||
}, |
||||
-- Gereth the Vile |
||||
[108151] = { |
||||
-- Vampiric Claws |
||||
[373364] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldZen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- |
||||
-- SMBG |
||||
-- |
||||
-- Reanimated Ritual Bones |
||||
[75715] = { |
||||
-- Shadow Slash |
||||
[75715] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldFort = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- |
||||
-- TJS |
||||
-- |
||||
-- Haunting Sha |
||||
[59555] = { |
||||
-- Haunting Gaze |
||||
[114646] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldFort = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Songbird |
||||
[59553] = { |
||||
-- Vicious Peck |
||||
[396007] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = false, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- The Golden Beetle |
||||
[59545] = { |
||||
[396019] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Sha-Touched Guardian |
||||
[200131] = { |
||||
-- Setting Sun Kick |
||||
[397094] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Minion of Doubt |
||||
[57109] = { |
||||
-- Dark Claw |
||||
[397931] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldPurify = true |
||||
} |
||||
}, |
||||
-- Liu Flameheart |
||||
[56732] = { |
||||
-- Jade Serpent Strike |
||||
[106841] = { |
||||
shouldBubble = true, |
||||
shouldDampen = true, |
||||
shouldDiffuse = true, |
||||
shouldFort = true, |
||||
shouldPurify = true, |
||||
shouldZen = true |
||||
} |
||||
} |
||||
} |
||||
|
||||
return _TankBusterList |
@ -0,0 +1,115 @@ |
||||
local Tinkr, Bastion = ... |
||||
|
||||
---@class Library |
||||
---@field name string |
||||
---@field dependencies table |
||||
---@field exports table |
||||
---@field resolved table |
||||
local Library = { |
||||
name = nil, |
||||
dependencies = {}, |
||||
exports = { |
||||
default = function() |
||||
return nil |
||||
end |
||||
}, |
||||
resolved = nil |
||||
} |
||||
|
||||
Library.__index = Library |
||||
|
||||
---@param name string |
||||
---@param library table |
||||
---@return Library |
||||
function Library:New(library) |
||||
local self = { |
||||
name = library.name or nil, |
||||
dependencies = {}, |
||||
exports = library.exports or { |
||||
default = function() |
||||
return nil |
||||
end |
||||
}, |
||||
resolved = nil |
||||
} |
||||
|
||||
self = setmetatable(self, Library) |
||||
|
||||
return self |
||||
end |
||||
|
||||
function Library:ResolveExport(export) |
||||
if type(export) == 'function' then |
||||
return export(self) |
||||
end |
||||
|
||||
return export |
||||
end |
||||
|
||||
function Library:Resolve() |
||||
if not self.exports then |
||||
error("Library " .. self.name .. " has no exports") |
||||
end |
||||
|
||||
if self.resolved then |
||||
if self.exports.default then |
||||
return self.resolved[1], self.resolved[2] |
||||
end |
||||
|
||||
return unpack(self.resolved) |
||||
end |
||||
|
||||
if self.exports.default then |
||||
-- return default first if it exists |
||||
local default = self.exports.default |
||||
local remaining = {} |
||||
for k, v in pairs(self.exports) do |
||||
if k ~= 'default' then |
||||
remaining[k] = self:ResolveExport(v) |
||||
end |
||||
end |
||||
|
||||
self.resolved = {self:ResolveExport(default), remaining} |
||||
|
||||
return self.resolved[1], self.resolved[2] |
||||
end |
||||
|
||||
self.resolved = {} |
||||
|
||||
for k, v in pairs(self.exports) do |
||||
self.resolved[k] = self:ResolveExport(v) |
||||
end |
||||
|
||||
return unpack(self.resolved) |
||||
end |
||||
|
||||
function Library:DependsOn(other) |
||||
for _, dependency in pairs(self.dependencies) do |
||||
if dependency == other then |
||||
return true |
||||
end |
||||
end |
||||
|
||||
return false |
||||
end |
||||
|
||||
---@param library string |
||||
function Library:Import(library) |
||||
local lib = Bastion:GetLibrary(library) |
||||
|
||||
if not lib then |
||||
error("Library " .. library .. " does not exist") |
||||
end |
||||
|
||||
if not table.contains(self.dependencies, library) then |
||||
table.insert(self.dependencies, library) |
||||
end |
||||
|
||||
if lib:DependsOn(self.name) then |
||||
error("Circular dependency detected between " .. self.name .. " and " .. library) |
||||
end |
||||
|
||||
return lib:Resolve() |
||||
end |
||||
|
||||
return Library |
@ -0,0 +1,585 @@ |
||||
local Tinkr, Bastion = ... |
||||
|
||||
---@class MythicPlusUtils |
||||
local MythicPlusUtils = { |
||||
debuffLogging = false, |
||||
castLogging = false, |
||||
random = '', |
||||
loggedCasts = {}, |
||||
loggedDebuffs = {}, |
||||
kickList = {}, |
||||
aoeBosses = {} |
||||
} |
||||
|
||||
MythicPlusUtils.__index = MythicPlusUtils |
||||
|
||||
---@return MythicPlusUtils |
||||
function MythicPlusUtils:New() |
||||
local self = setmetatable({}, MythicPlusUtils) |
||||
|
||||
---@diagnostic disable-next-line: assign-type-mismatch |
||||
self.random = math.random(1000000, 9999999) |
||||
|
||||
self.aoeBosses = { |
||||
[196482] = true, |
||||
[188252] = true, |
||||
[186644] = true, |
||||
[104217] = true, |
||||
} |
||||
|
||||
self.tankBusters = { |
||||
[397931] = true, -- https://www.wowhead.com/spell=397931/dark-claw |
||||
[396019] = true, -- https://www.wowhead.com/spell=396019/staggering-blow |
||||
[372730] = true, -- https://www.wowhead.com/spell=372730/crushing-smash |
||||
[395303] = true, -- https://www.wowhead.com/spell=395303/thunder-jaw |
||||
[392395] = true, -- https://www.wowhead.com/spell=392395/thunder-jaw |
||||
[372858] = true, -- https://www.wowhead.com/spell=372858/searing-blows |
||||
[372859] = true, -- https://www.wowhead.com/spell=372859/searing-blows |
||||
[387135] = true, -- https://www.wowhead.com/spell=387135/arcing-strike |
||||
[388801] = true, -- https://www.wowhead.com/spell=388801/mortal-strike |
||||
[387826] = true, -- https://www.wowhead.com/spell=387826/heavy-slash |
||||
[370764] = true, -- https://www.wowhead.com/spell=370764/piercing-shards |
||||
[377105] = true, -- https://www.wowhead.com/spell=377105/ice-cutter |
||||
[388911] = true, -- https://www.wowhead.com/spell=388911/severing-slash |
||||
[388912] = true, -- https://www.wowhead.com/spell=388912/severing-slash |
||||
[199050] = true, -- https://www.wowhead.com/spell=199050/mortal-hew |
||||
[164907] = true, -- https://www.wowhead.com/spell=164907/void-slash |
||||
[377991] = true, -- https://www.wowhead.com/spell=377991/storm-slash |
||||
[376997] = true, -- https://www.wowhead.com/spell=376997/savage-peck |
||||
[192018] = true, -- https://www.wowhead.com/spell=192018/shield-of-light |
||||
[106823] = true, -- https://www.wowhead.com/spell=106823/serpent-strike |
||||
[106841] = true, -- https://www.wowhead.com/spell=106841/jade-serpent-strike |
||||
[381512] = true, -- https://www.wowhead.com/spell=381512/stormslam |
||||
[381514] = true, -- https://www.wowhead.com/spell=381514/stormslam |
||||
[381513] = true, -- https://www.wowhead.com/spell=381513/stormslam |
||||
[381515] = true, -- https://www.wowhead.com/spell=381515/stormslam |
||||
[372222] = true, -- https://www.wowhead.com/spell=372222/arcane-cleave |
||||
[385958] = true, -- https://www.wowhead.com/spell=385958/arcane-expulsion |
||||
[382836] = true, -- https://www.wowhead.com/spell=382836/brutalize |
||||
[376827] = true, -- https://www.wowhead.com/spell=376827/conductive-strike not sure if we defensive on these or the other strike NO final boss |
||||
[375937] = true, -- https://www.wowhead.com/spell=375937/rending-strike not sure if we defensive on these or the other strike NO final boss |
||||
[198888] = true, -- https://www.wowhead.com/spell=198888/lightning-breath |
||||
[384978] = true, -- https://www.wowhead.com/spell=384978/dragon-strike |
||||
[388923] = true, -- https://www.wowhead.com/spell=388923/burst-forth |
||||
} |
||||
|
||||
self.kickList = { |
||||
-- Ruby life pools |
||||
[372735] = { -- Techtonic Slam |
||||
[187969] = { |
||||
false, true, true -- Kick, Stun, Disorient |
||||
} |
||||
}, |
||||
[384933] = { -- Ice Shield |
||||
[188067] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[372749] = { -- Ice Shield |
||||
[188067] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[372743] = { -- Ice Shield |
||||
[188067] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[371984] = { |
||||
[188067] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[373680] = { |
||||
[188252] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[373688] = { |
||||
[188252] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[385310] = { |
||||
[195119] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[384194] = { |
||||
[190207] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[384197] = { |
||||
[190207] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[373017] = { |
||||
[189886] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[392576] = { |
||||
[198047] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[392451] = { |
||||
[197985] = { |
||||
true, true, false, |
||||
} |
||||
}, |
||||
[392452] = { |
||||
[197985] = { |
||||
true, true, false, |
||||
} |
||||
}, |
||||
-- Nokhud |
||||
[383823] = { |
||||
[192796] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[384492] = { |
||||
[192794] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[384365] = { |
||||
[192800] = { |
||||
true, false, false |
||||
}, |
||||
[191847] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[386012] = { |
||||
[194317] = { |
||||
true, false, false |
||||
}, |
||||
[195265] = { |
||||
true, false, false |
||||
}, |
||||
[194315] = { |
||||
true, false, false |
||||
}, |
||||
[194316] = { |
||||
true, false, false |
||||
} |
||||
|
||||
}, |
||||
[386028] = { |
||||
[195696] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[386024] = { |
||||
[194894] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[386025] = { |
||||
[194894] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[387629] = { |
||||
[195876] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[387608] = { |
||||
[195842] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[387611] = { |
||||
[195842] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[387440] = { |
||||
[195878] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[373395] = { |
||||
[199717] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[376725] = { |
||||
[190294] = { |
||||
true, true, true |
||||
}, |
||||
}, |
||||
[370764] = { |
||||
[187160] = { |
||||
false, true, true |
||||
}, |
||||
[196116] = { |
||||
false, true, true |
||||
}, |
||||
}, |
||||
[387564] = { |
||||
[196102] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[375596] = { |
||||
[196115] = { |
||||
true, false, false |
||||
}, |
||||
[191164] = { |
||||
true, false, false |
||||
}, |
||||
|
||||
}, |
||||
[386549] = { |
||||
[186741] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[386546] = { |
||||
[186741] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[389804] = { |
||||
[187154] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[377488] = { |
||||
[187155] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[377105] = { |
||||
[190510] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[373932] = { |
||||
[190187] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
-- AA |
||||
[387910] = { |
||||
[196200] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[387975] = { |
||||
[196202] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[388863] = { |
||||
[196045] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[388392] = { |
||||
[196044] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[396812] = { |
||||
[196576] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[377389] = { |
||||
[192333] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[397888] = { |
||||
[200126] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[397801] = { |
||||
[56448] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[395859] = { |
||||
[59555] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[395872] = { |
||||
[59546] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[396018] = { |
||||
[59552] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[396073] = { |
||||
[59544] = { |
||||
true, true, false |
||||
} |
||||
}, |
||||
[397899] = { |
||||
[200131] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[397914] = { |
||||
[200137] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
-- sbg |
||||
[152818] = { |
||||
[75713] = { |
||||
true, true, false |
||||
} |
||||
}, |
||||
[398154] = { |
||||
[75451] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[156776] = { |
||||
[76446] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[156772] = { |
||||
[77700] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[153524] = { |
||||
[75459] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[156718] = { |
||||
[76104] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[225100] = { |
||||
[104270] = { |
||||
true, false, false |
||||
} |
||||
}, |
||||
[210261] = { |
||||
[104251] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[209027] = { |
||||
[104246] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[212031] = { |
||||
[105705] = { |
||||
false, true, false |
||||
} |
||||
}, |
||||
[212784] = { |
||||
[105715] = { |
||||
false, true, false |
||||
} |
||||
}, |
||||
[198585] = { |
||||
[95842] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[198959] = { |
||||
[96664] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[215433] = { |
||||
[95834] = { |
||||
true, true, true |
||||
} |
||||
}, |
||||
[199210] = { |
||||
[96640] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[199090] = { |
||||
[96611] = { |
||||
false, true, true |
||||
} |
||||
}, |
||||
[185425] = { |
||||
[96677] = { |
||||
false, true, false |
||||
} |
||||
}, |
||||
[195696] = { |
||||
[387125] = { |
||||
true, false, false |
||||
} |
||||
} |
||||
} |
||||
|
||||
Bastion.Globals.EventManager:RegisterWoWEvent('UNIT_AURA', function(unit, auras) |
||||
if not self.debuffLogging then |
||||
return |
||||
end |
||||
|
||||
if auras.addedAuras then |
||||
local addedAuras = auras.addedAuras |
||||
|
||||
if #addedAuras > 0 then |
||||
for i = 1, #addedAuras do |
||||
local aura = Bastion.Aura:CreateFromUnitAuraInfo(addedAuras[i]) |
||||
|
||||
if not self.loggedDebuffs[aura:GetSpell():GetID()] and not aura:IsBuff() then |
||||
WriteFile('bastion-MPlusDebuffs-' .. self.random .. '.lua', [[ |
||||
AuraName: ]] .. aura:GetName() .. [[ |
||||
AuraID: ]] .. aura:GetSpell():GetID() .. "\n" .. [[ |
||||
]], true) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end) |
||||
|
||||
Bastion.Globals.EventManager:RegisterWoWEvent('UNIT_SPELLCAST_START', function(unitTarget, castGUID, spellID) |
||||
if not self.castLogging then |
||||
return |
||||
end |
||||
|
||||
if self.loggedCasts[spellID] then |
||||
return |
||||
end |
||||
|
||||
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 |
||||
|
||||
WriteFile('bastion-MPlusCasts-' .. self.random .. '.lua', [[ |
||||
CastName: ]] .. name .. [[ |
||||
CastID: ]] .. spellID .. "\n" .. [[ |
||||
]], true) |
||||
end) |
||||
|
||||
Bastion.Globals.EventManager:RegisterWoWEvent('UNIT_SPELLCAST_CHANNEL_START', function(unitTarget, castGUID, spellID) |
||||
if not self.castLogging then |
||||
return |
||||
end |
||||
|
||||
if self.loggedCasts[spellID] then |
||||
return |
||||
end |
||||
|
||||
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 |
||||
|
||||
WriteFile('bastion-MPlusCasts-' .. self.random .. '.lua', [[ |
||||
CastName: ]] .. name .. [[ |
||||
CastID: ]] .. spellID .. "\n" .. [[ |
||||
]], true) |
||||
end) |
||||
|
||||
return self |
||||
end |
||||
|
||||
---@return nil |
||||
function MythicPlusUtils:ToggleDebuffLogging() |
||||
self.debuffLogging = not self.debuffLogging |
||||
end |
||||
|
||||
---@return nil |
||||
function MythicPlusUtils:ToggleCastLogging() |
||||
self.castLogging = not self.castLogging |
||||
end |
||||
|
||||
---@param unit Unit |
||||
---@param percent number |
||||
---@return boolean |
||||
function MythicPlusUtils:CastingCriticalKick(unit, percent) |
||||
local castingSpell = unit:GetCastingOrChannelingSpell() |
||||
|
||||
if castingSpell then |
||||
local spellID = castingSpell:GetID() |
||||
local kickEntry = self.kickList[spellID] |
||||
if not kickEntry then |
||||
return false |
||||
end |
||||
|
||||
local npcTraits = kickEntry[unit:GetID()] |
||||
|
||||
if not npcTraits then |
||||
return false |
||||
end |
||||
|
||||
local isKick, isStun, isDisorient = unpack(npcTraits) |
||||
|
||||
if isKick and unit:IsInterruptibleAt(percent) then |
||||
return true |
||||
end |
||||
end |
||||
|
||||
return false |
||||
end |
||||
|
||||
---@param unit Unit |
||||
---@param percent number |
||||
---@return boolean |
||||
function MythicPlusUtils:CastingCriticalStun(unit, percent) |
||||
local castingSpell = unit:GetCastingOrChannelingSpell() |
||||
|
||||
if castingSpell then |
||||
local spellID = castingSpell:GetID() |
||||
local kickEntry = self.kickList[spellID] |
||||
if not kickEntry then |
||||
return false |
||||
end |
||||
|
||||
local npcTraits = kickEntry[unit:GetID()] |
||||
|
||||
if not npcTraits then |
||||
return false |
||||
end |
||||
|
||||
local isKick, isStun, isDisorient = unpack(npcTraits) |
||||
|
||||
if (isStun or isDisorient) and not isKick and unit:IsInterruptibleAt(percent, true) then |
||||
return true |
||||
end |
||||
end |
||||
|
||||
return false |
||||
end |
||||
|
||||
---@param unit Unit |
||||
---@return boolean |
||||
function MythicPlusUtils:IsAOEBoss(unit) |
||||
return self.aoeBosses[unit:GetID()] |
||||
end |
||||
|
||||
return MythicPlusUtils |
@ -1,104 +0,0 @@ |
||||
local |
||||
Tinkr, |
||||
---@type Bastion |
||||
Bastion = ... |
||||
|
||||
---@alias Toggle { x: number, icon: number, state: boolean, id: string, texture?: Texture } |
||||
|
||||
local BUTTON_SIZE = 54 |
||||
|
||||
---@class ToggleManager |
||||
local ToggleManager = { |
||||
---@type table<string, Toggle> |
||||
toggles = {} |
||||
} |
||||
|
||||
---@return number |
||||
function ToggleManager:NumActiveToggles() |
||||
local count = 0 |
||||
|
||||
for i, toggle in pairs(self.toggles) do |
||||
count = count + 1 |
||||
end |
||||
|
||||
return count |
||||
end |
||||
|
||||
---@param newToggle { icon: number, state: boolean, id: string } |
||||
function ToggleManager:Add(newToggle) |
||||
if self.toggles[newToggle.id] then |
||||
self.toggles[newToggle.id].icon = newToggle.icon |
||||
self.toggles[newToggle.id].state = newToggle.state |
||||
else |
||||
local highestX = nil |
||||
|
||||
for i, toggle in pairs(self.toggles) do |
||||
if highestX == nil or toggle.x > highestX then |
||||
highestX = toggle.x |
||||
end |
||||
end |
||||
|
||||
if highestX == nil then |
||||
highestX = 2 |
||||
else |
||||
highestX = highestX + BUTTON_SIZE |
||||
end |
||||
|
||||
self.toggles[newToggle.id] = { |
||||
x = highestX, |
||||
state = newToggle.state, |
||||
icon = newToggle.icon, |
||||
id = newToggle.id |
||||
} |
||||
end |
||||
end |
||||
|
||||
function ToggleManager:Refresh() |
||||
for i, toggle in pairs(self.toggles) do |
||||
if not toggle.texture then |
||||
local frame = CreateFrame("Frame", nil, UIParent) |
||||
frame:SetSize(BUTTON_SIZE, BUTTON_SIZE) |
||||
frame:SetPoint("BOTTOMLEFT", toggle.x, 230) |
||||
|
||||
local Texture = frame:CreateTexture() |
||||
Texture:SetAllPoints(frame) |
||||
Texture:SetTexture(toggle.icon) |
||||
if not toggle.state then |
||||
Texture:SetDesaturated(true) |
||||
end |
||||
self.toggles[toggle.id].texture = Texture |
||||
end |
||||
-- else |
||||
-- local desaturation = toggle.texture:GetDesaturation() |
||||
|
||||
-- if not toggle.state and desaturation == 0 then |
||||
-- toggle.texture:SetDesaturated(true) |
||||
-- elseif toggle.state and desaturation == 1 then |
||||
-- toggle.texture:SetDesaturated(false) |
||||
-- end |
||||
-- end |
||||
end |
||||
end |
||||
|
||||
---@param id string |
||||
function ToggleManager:Toggle(id) |
||||
if self.toggles[id] then |
||||
self.toggles[id].state = not self.toggles[id].state |
||||
|
||||
local desaturation = self.toggles[id].texture:GetDesaturation() |
||||
|
||||
if not self.toggles[id].state and desaturation == 0 then |
||||
self.toggles[id].texture:SetDesaturated(true) |
||||
elseif self.toggles[id].state and desaturation == 1 then |
||||
self.toggles[id].texture:SetDesaturated(false) |
||||
end |
||||
end |
||||
end |
||||
|
||||
---@param id string |
||||
---@return boolean |
||||
function ToggleManager:GetState(id) |
||||
if self.toggles[id] then return self.toggles[id].state else return false end |
||||
end |
||||
|
||||
return ToggleManager |
@ -1,262 +1,412 @@ |
||||
local Tinkr = ... |
||||
|
||||
local Evaulator = Tinkr.Evaluator |
||||
|
||||
---@class Bastion |
||||
local Bastion = { |
||||
DebugMode = false |
||||
} |
||||
local Bastion = {DebugMode = false} |
||||
Bastion.__index = Bastion |
||||
|
||||
function Bastion.require(class) |
||||
return Tinkr:require("scripts/bastion/src/" .. class .. "/" .. class, Bastion) |
||||
function Bastion:Require(file) |
||||
-- If require starts with an @ then we require from the scripts/bastion/scripts folder |
||||
if file:sub(1, 1) == '@' then |
||||
file = file:sub(2) |
||||
-- print('1') |
||||
return require('scripts/bastion/scripts/' .. file, Bastion) |
||||
elseif file:sub(1, 1) == "~" then |
||||
file = file:sub(2) |
||||
-- print("2") |
||||
return require('scripts/bastion/' .. file, Bastion) |
||||
else |
||||
-- print("Normal req") |
||||
return require(file, Bastion) |
||||
end |
||||
end |
||||
|
||||
---@type ToggleManager |
||||
Bastion.ToggleManager = Bastion.require("ToggleManager") |
||||
---@type ClassMagic |
||||
Bastion.ClassMagic = Bastion.require("ClassMagic") |
||||
---@type List |
||||
Bastion.List = Bastion.require("List") |
||||
---@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"):New() |
||||
---@type Spell |
||||
Bastion.Spell = Bastion.require("Spell") |
||||
---@type SpellBook |
||||
Bastion.SpellBook = Bastion.require("SpellBook"):New() |
||||
---@type Item |
||||
Bastion.Item = Bastion.require("Item") |
||||
---@type ItemBook |
||||
Bastion.ItemBook = Bastion.require("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 ContentUtils |
||||
Bastion.ContentUtils = Bastion.require("ContentUtils"):New() |
||||
---@type NotificationsList |
||||
Bastion.Notifications = Bastion.NotificationsList:New() |
||||
|
||||
Bastion.modules = {} |
||||
---@type table<string, { duration: number, requestTime: number }> |
||||
Bastion.pausedModules = {} |
||||
Bastion.Enabled = false |
||||
|
||||
Bastion.EventManager:RegisterWoWEvent('UNIT_AURA', function(unit, auras) |
||||
local u = Bastion.UnitManager[unit] |
||||
|
||||
if u then |
||||
u:GetAuras():OnUpdate(auras) |
||||
end |
||||
end) |
||||
local function Load(dir) |
||||
local dir = dir |
||||
|
||||
Bastion.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", function(...) |
||||
local unit, castGUID, spellID = ... |
||||
if dir:sub(1, 1) == '@' then |
||||
dir = dir:sub(2) |
||||
dir = 'scripts/bastion/scripts/' .. dir |
||||
end |
||||
|
||||
local spell = Bastion.SpellBook:GetIfRegistered(spellID) |
||||
if dir:sub(1, 1) == '~' then |
||||
dir = dir:sub(2) |
||||
dir = 'scripts/bastion/' .. dir |
||||
end |
||||
|
||||
if unit == "player" and spell then |
||||
spell.lastCastAt = GetTime() |
||||
local files = ListFiles(dir) |
||||
|
||||
if spell:GetPostCastFunction() then |
||||
spell:GetPostCastFunction()(spell) |
||||
for i = 1, #files do |
||||
local file = files[i] |
||||
if file:sub(-4) == ".lua" or file:sub(-5) == '.luac' then |
||||
Bastion:Require(dir .. file:sub(1, -5)) |
||||
end |
||||
end |
||||
end) |
||||
end |
||||
|
||||
local pguid = UnitGUID("player") |
||||
function Bastion.require(class) |
||||
-- return require("scripts/bastion/src/" .. class .. "/" .. class, Bastion) |
||||
return Bastion:Require("~/src/" .. class .. "/" .. class) |
||||
end |
||||
|
||||
Bastion.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function() |
||||
local args = { CombatLogGetCurrentEventInfo() } |
||||
-- 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) |
||||
|
||||
local sourceGUID = args[4] |
||||
local destGUID = args[8] |
||||
Bastion.Globals.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", |
||||
function(...) |
||||
local unit, castGUID, spellID = ... |
||||
|
||||
local u = Bastion.UnitManager[sourceGUID] |
||||
local u2 = Bastion.UnitManager[destGUID] |
||||
local spell = Bastion.Globals.SpellBook:GetIfRegistered(spellID) |
||||
|
||||
local t = GetTime() |
||||
if unit == "player" and spell then |
||||
spell.lastCastAt = GetTime() |
||||
|
||||
if u then |
||||
u:SetLastCombatTime(t) |
||||
end |
||||
if spell:GetPostCastFunction() then |
||||
spell:GetPostCastFunction()(spell) |
||||
end |
||||
end |
||||
end) |
||||
|
||||
if u2 then |
||||
u2:SetLastCombatTime(t) |
||||
end |
||||
end) |
||||
local pguid = UnitGUID("player") |
||||
local missed = {} |
||||
|
||||
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.Globals.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", |
||||
function() |
||||
local args = {CombatLogGetCurrentEventInfo()} |
||||
|
||||
for k, v in pairs(Bastion.pausedModules) do |
||||
if (v.duration + v.requestTime) < GetTime() then |
||||
Bastion:Print('Module ', k, ' unpaused.') |
||||
Bastion.pausedModules[k] = nil |
||||
end |
||||
end |
||||
local subEvent = args[2] |
||||
local sourceGUID = args[4] |
||||
local destGUID = args[8] |
||||
local spellID = args[12] |
||||
|
||||
Bastion.ToggleManager:Refresh() |
||||
-- if sourceGUID == pguid then |
||||
-- local args = { CombatLogGetCurrentEventInfo() } |
||||
|
||||
if Bastion.Enabled then |
||||
Bastion.ObjectManager:Refresh() |
||||
for i = 1, #Bastion.modules do |
||||
if not Bastion.pausedModules[Bastion.modules[i].name] then |
||||
Bastion.modules[i]:Tick() |
||||
-- for i = 1, #args do |
||||
-- Log(tostring(args[i])) |
||||
-- 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 == pguid and spellID == |
||||
408 then |
||||
local missType = args[15] |
||||
|
||||
if missType == "IMMUNE" then |
||||
local castingSpell = u:GetCastingOrChannelingSpell() |
||||
|
||||
if castingSpell then |
||||
if not missed[castingSpell:GetID()] then |
||||
missed[castingSpell:GetID()] = true |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end) |
||||
|
||||
function Bastion:Register(module) |
||||
table.insert(Bastion.modules, module) |
||||
Bastion:Print("Registered", module) |
||||
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 |
||||
|
||||
-- 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] |
||||
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 |
||||
|
||||
return nil |
||||
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 |
||||
end |
||||
|
||||
function Bastion:Print(...) |
||||
local args = { ... } |
||||
local str = "|cFFDF362D[Bastion]|r |cFFFFFFFF" |
||||
for i = 1, #args do |
||||
str = str .. tostring(args[i]) .. " " |
||||
return nil |
||||
end |
||||
print(str) |
||||
end |
||||
|
||||
function Bastion:Debug(...) |
||||
if not Bastion.DebugMode then |
||||
return |
||||
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 |
||||
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 |
||||
|
||||
-- use spellName and spellSubName here |
||||
local spellID = select(7, GetSpellInfo(spellName)) |
||||
if C_Spell.GetSpellInfo then |
||||
local info = C_Spell.GetSpellInfo(spellName) |
||||
spellID = info.spellID |
||||
else |
||||
spellID = select(7, GetSpellInfo(spellName)) |
||||
end |
||||
|
||||
if spellID then |
||||
WriteFile('bastion-' .. UnitClass('player') .. '-' .. rand .. '.lua', |
||||
"local " .. spellName .. " = Bastion.SpellBook:GetSpell(" .. spellID .. ")", true) |
||||
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 |
||||
else |
||||
Bastion:Print("Module not found") |
||||
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 |
||||
|
||||
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) |
||||
|
||||
---@param library Library |
||||
function Bastion:RegisterLibrary(library) |
||||
LIBRARIES[library.name] = library |
||||
end |
||||
end) |
||||
|
||||
Command:Register('pause', 'Pause a module for X seconds', function (args) |
||||
if Bastion.Enabled then |
||||
local duration = args[3] |
||||
local moduleName = args[2] |
||||
|
||||
local RequestedModule = Bastion:FindModule(moduleName) |
||||
|
||||
if RequestedModule and not Bastion.pausedModules[moduleName] then |
||||
Bastion:Print("Pausing module ", moduleName, " for ", duration) |
||||
Bastion.pausedModules[moduleName] = { duration = duration, requestTime = GetTime() } |
||||
elseif not Bastion.pausedModules[moduleName] then |
||||
Bastion:Print("Unable to find module ", moduleName) |
||||
|
||||
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 |
||||
end |
||||
end |
||||
end |
||||
|
||||
return true |
||||
end |
||||
|
||||
end) |
||||
|
||||
if UnitClass('player') == 'Mage' then |
||||
if GetSpecialization() == 1 then |
||||
Tinkr:require("scripts/bastion/scripts/arcane", Bastion) |
||||
Eval('RunMacroText("/bastion module arcane")', 'bastion') |
||||
elseif GetSpecialization() == 2 then |
||||
Tinkr:require("scripts/bastion/scripts/fire", Bastion) |
||||
Eval('RunMacroText("/bastion module fire")', 'bastion') |
||||
elseif GetSpecialization() == 3 then |
||||
Tinkr:require("scripts/bastion/scripts/frost/frost", Bastion) |
||||
Eval('RunMacroText("/bastion module frost")', 'bastion') |
||||
function Bastion:Import(library) |
||||
local lib = self:GetLibrary(library) |
||||
|
||||
if not lib then error("Library " .. library .. " not found") end |
||||
|
||||
return lib:Resolve() |
||||
end |
||||
|
||||
function Bastion:GetLibrary(name) |
||||
if not LIBRARIES[name] then |
||||
error("Library " .. name .. " not found") |
||||
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 |
||||
-- end |
||||
|
||||
return library |
||||
end |
||||
|
||||
-- if not Bastion:CheckLibraryDependencies() then |
||||
-- return |
||||
-- end |
||||
|
||||
Load("@Libraries/") |
||||
Load("@Modules/") |
||||
Load("@") |
||||
end |
||||
|
||||
Bastion.Bootstrap() |
||||
|
Loading…
Reference in new issue