forked from Bastion/Bastion
Compare commits
68 Commits
@ -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,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,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,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 |
@ -1,276 +1,412 @@ |
|||||||
local Tinkr = ... |
local Tinkr = ... |
||||||
|
|
||||||
|
local Evaulator = Tinkr.Evaluator |
||||||
|
|
||||||
---@class Bastion |
---@class Bastion |
||||||
local Bastion = { |
local Bastion = {DebugMode = false} |
||||||
DebugMode = false |
|
||||||
} |
|
||||||
Bastion.__index = Bastion |
Bastion.__index = Bastion |
||||||
|
|
||||||
function Bastion.require(class) |
function Bastion:Require(file) |
||||||
return Tinkr:require("scripts/bastion/src/" .. class .. "/" .. class, Bastion) |
-- 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 |
end |
||||||
|
|
||||||
---@type ClassMagic |
local function Load(dir) |
||||||
Bastion.ClassMagic = Bastion.require("ClassMagic") |
local dir = dir |
||||||
---@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") |
|
||||||
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 MythicPlusUtils |
|
||||||
Bastion.MythicPlusUtils = Bastion.require("MythicPlusUtils"):New() |
|
||||||
---@type NotificationsList |
|
||||||
Bastion.Notifications = Bastion.NotificationsList:New() |
|
||||||
|
|
||||||
Bastion.modules = {} |
|
||||||
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) |
|
||||||
|
|
||||||
Bastion.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", function(...) |
if dir:sub(1, 1) == '@' then |
||||||
local unit, castGUID, spellID = ... |
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 |
local files = ListFiles(dir) |
||||||
spell.lastCastAt = GetTime() |
|
||||||
|
|
||||||
if spell:GetPostCastFunction() then |
for i = 1, #files do |
||||||
spell:GetPostCastFunction()(spell) |
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 |
||||||
end) |
end |
||||||
|
|
||||||
local pguid = UnitGUID("player") |
function Bastion.require(class) |
||||||
local missed = {} |
-- return require("scripts/bastion/src/" .. class .. "/" .. class, Bastion) |
||||||
|
return Bastion:Require("~/src/" .. class .. "/" .. class) |
||||||
|
end |
||||||
|
|
||||||
Bastion.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function() |
-- fenv for all required files |
||||||
local args = { CombatLogGetCurrentEventInfo() } |
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 subEvent = args[2] |
Bastion.Globals.EventManager:RegisterWoWEvent("UNIT_SPELLCAST_SUCCEEDED", |
||||||
local sourceGUID = args[4] |
function(...) |
||||||
local destGUID = args[8] |
local unit, castGUID, spellID = ... |
||||||
local spellID = args[12] |
|
||||||
|
|
||||||
-- if sourceGUID == pguid then |
local spell = Bastion.Globals.SpellBook:GetIfRegistered(spellID) |
||||||
-- local args = { CombatLogGetCurrentEventInfo() } |
|
||||||
|
|
||||||
-- for i = 1, #args do |
if unit == "player" and spell then |
||||||
-- Log(tostring(args[i])) |
spell.lastCastAt = GetTime() |
||||||
-- end |
|
||||||
-- end |
|
||||||
|
|
||||||
local u = Bastion.UnitManager[sourceGUID] |
if spell:GetPostCastFunction() then |
||||||
local u2 = Bastion.UnitManager[destGUID] |
spell:GetPostCastFunction()(spell) |
||||||
|
end |
||||||
|
end |
||||||
|
end) |
||||||
|
|
||||||
local t = GetTime() |
local pguid = UnitGUID("player") |
||||||
|
local missed = {} |
||||||
|
|
||||||
if u then |
Bastion.Globals.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", |
||||||
u:SetLastCombatTime(t) |
function() |
||||||
end |
local args = {CombatLogGetCurrentEventInfo()} |
||||||
|
|
||||||
|
local subEvent = args[2] |
||||||
|
local sourceGUID = args[4] |
||||||
|
local destGUID = args[8] |
||||||
|
local spellID = args[12] |
||||||
|
|
||||||
|
-- if sourceGUID == pguid then |
||||||
|
-- local args = { CombatLogGetCurrentEventInfo() } |
||||||
|
|
||||||
|
-- for i = 1, #args do |
||||||
|
-- Log(tostring(args[i])) |
||||||
|
-- end |
||||||
|
-- end |
||||||
|
|
||||||
if u2 then |
local u = Bastion.UnitManager[sourceGUID] |
||||||
u2:SetLastCombatTime(t) |
local u2 = Bastion.UnitManager[destGUID] |
||||||
|
|
||||||
if subEvent == "SPELL_MISSED" and sourceGUID == pguid and spellID == 408 then |
local t = GetTime() |
||||||
local missType = args[15] |
|
||||||
|
|
||||||
if missType == "IMMUNE" then |
if u then u:SetLastCombatTime(t) end |
||||||
local castingSpell = u:GetCastingOrChannelingSpell() |
|
||||||
|
|
||||||
if castingSpell then |
if u2 then |
||||||
if not missed[castingSpell:GetID()] then |
u2:SetLastCombatTime(t) |
||||||
missed[castingSpell:GetID()] = true |
|
||||||
|
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 |
end |
||||||
end |
end |
||||||
end |
end) |
||||||
end) |
|
||||||
|
|
||||||
Bastion.Ticker = C_Timer.NewTicker(0.1, function() |
Bastion.Ticker = C_Timer.NewTicker(0.1, function() |
||||||
if not Bastion.CombatTimer:IsRunning() and UnitAffectingCombat("player") then |
if not Bastion.CombatTimer:IsRunning() and UnitAffectingCombat("player") then |
||||||
Bastion.CombatTimer:Start() |
Bastion.CombatTimer:Start() |
||||||
elseif Bastion.CombatTimer:IsRunning() and not UnitAffectingCombat("player") then |
elseif Bastion.CombatTimer:IsRunning() and |
||||||
|
not UnitAffectingCombat("player") then |
||||||
Bastion.CombatTimer:Reset() |
Bastion.CombatTimer:Reset() |
||||||
end |
end |
||||||
|
|
||||||
if Bastion.Enabled then |
if Bastion.Enabled then |
||||||
Bastion.ObjectManager:Refresh() |
Bastion.ObjectManager:Refresh() |
||||||
for i = 1, #Bastion.modules do |
for i = 1, #MODULES do MODULES[i]:Tick() end |
||||||
Bastion.modules[i]:Tick() |
|
||||||
end |
|
||||||
end |
end |
||||||
end) |
end) |
||||||
|
|
||||||
function Bastion:Register(module) |
function Bastion:Register(module) |
||||||
table.insert(Bastion.modules, module) |
table.insert(MODULES, module) |
||||||
Bastion:Print("Registered", module) |
Bastion:Print("Registered", module) |
||||||
end |
|
||||||
|
|
||||||
-- Find a module by name |
|
||||||
function Bastion:FindModule(name) |
|
||||||
for i = 1, #Bastion.modules do |
|
||||||
if Bastion.modules[i].name == name then |
|
||||||
return Bastion.modules[i] |
|
||||||
end |
|
||||||
end |
end |
||||||
|
|
||||||
return nil |
-- Find a module by name |
||||||
end |
function Bastion:FindModule(name) |
||||||
|
for i = 1, #MODULES do |
||||||
|
if MODULES[i].name == name then return MODULES[i] end |
||||||
|
end |
||||||
|
|
||||||
function Bastion:Print(...) |
return nil |
||||||
local args = { ... } |
|
||||||
local str = "|cFFDF362D[Bastion]|r |cFFFFFFFF" |
|
||||||
for i = 1, #args do |
|
||||||
str = str .. tostring(args[i]) .. " " |
|
||||||
end |
end |
||||||
print(str) |
|
||||||
end |
|
||||||
|
|
||||||
function Bastion:Debug(...) |
function Bastion:Print(...) |
||||||
if not Bastion.DebugMode then |
local args = {...} |
||||||
return |
local str = "|cFFDF362D[Bastion]|r |cFFFFFFFF" |
||||||
|
for i = 1, #args do str = str .. tostring(args[i]) .. " " end |
||||||
|
print(str) |
||||||
end |
end |
||||||
local args = { ... } |
|
||||||
local str = "|cFFDF6520[Bastion]|r |cFFFFFFFF" |
function Bastion:Debug(...) |
||||||
for i = 1, #args do |
if not Bastion.DebugMode then return end |
||||||
str = str .. tostring(args[i]) .. " " |
local args = {...} |
||||||
|
local str = "|cFFDF6520[Bastion]|r |cFFFFFFFF" |
||||||
|
for i = 1, #args do str = str .. tostring(args[i]) .. " " end |
||||||
|
print(str) |
||||||
end |
end |
||||||
print(str) |
|
||||||
end |
|
||||||
|
|
||||||
local Command = Bastion.Command:New('bastion') |
local Command = Bastion.Command:New('bastion') |
||||||
|
|
||||||
Command:Register('toggle', 'Toggle bastion on/off', function() |
Command:Register('toggle', 'Toggle bastion on/off', function() |
||||||
Bastion.Enabled = not Bastion.Enabled |
Bastion.Enabled = not Bastion.Enabled |
||||||
if Bastion.Enabled then |
if Bastion.Enabled then |
||||||
Bastion:Print("Enabled") |
Bastion:Print("Enabled") |
||||||
else |
else |
||||||
Bastion:Print("Disabled") |
Bastion:Print("Disabled") |
||||||
end |
end |
||||||
end) |
end) |
||||||
|
|
||||||
Command:Register('debug', 'Toggle debug mode on/off', function() |
Command:Register('debug', 'Toggle debug mode on/off', function() |
||||||
Bastion.DebugMode = not Bastion.DebugMode |
Bastion.DebugMode = not Bastion.DebugMode |
||||||
if Bastion.DebugMode then |
if Bastion.DebugMode then |
||||||
Bastion:Print("Debug mode enabled") |
Bastion:Print("Debug mode enabled") |
||||||
else |
else |
||||||
Bastion:Print("Debug mode disabled") |
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 |
|
||||||
end |
end |
||||||
|
end) |
||||||
|
|
||||||
-- use spellName and spellSubName here |
Command:Register('dumpspells', 'Dump spells to a file', function() |
||||||
local spellID = select(7, GetSpellInfo(spellName)) |
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 |
||||||
|
|
||||||
|
if C_Spell.GetSpellInfo then |
||||||
|
local info = C_Spell.GetSpellInfo(spellName) |
||||||
|
spellID = info.spellID |
||||||
|
else |
||||||
|
spellID = select(7, GetSpellInfo(spellName)) |
||||||
|
end |
||||||
|
|
||||||
if spellID then |
if spellID then |
||||||
WriteFile('bastion-' .. UnitClass('player') .. '-' .. rand .. '.lua', |
spellName = spellName:gsub("[%W%s]", "") |
||||||
"local " .. spellName .. " = Bastion.SpellBook:GetSpell(" .. spellID .. ")", true) |
WriteFile('bastion-' .. UnitClass('player') .. '-' .. rand .. |
||||||
|
'.lua', |
||||||
|
"local " .. spellName .. |
||||||
|
" = Bastion.Globals.SpellBook:GetSpell(" .. |
||||||
|
spellID .. ")\n", true) |
||||||
|
end |
||||||
|
i = i + 1 |
||||||
end |
end |
||||||
i = i + 1 |
end) |
||||||
end |
|
||||||
end) |
Command:Register('module', 'Toggle a module on/off', function(args) |
||||||
|
local module = Bastion:FindModule(args[2]) |
||||||
Command:Register('module', 'Toggle a module on/off', function(args) |
if module then |
||||||
local module = Bastion:FindModule(args[2]) |
module:Toggle() |
||||||
if module then |
if module.enabled then |
||||||
module:Toggle() |
Bastion:Print("Enabled", module.name) |
||||||
if module.enabled then |
else |
||||||
Bastion:Print("Enabled", module.name) |
Bastion:Print("Disabled", module.name) |
||||||
|
end |
||||||
else |
else |
||||||
Bastion:Print("Disabled", module.name) |
Bastion:Print("Module not found") |
||||||
end |
end |
||||||
else |
end) |
||||||
Bastion:Print("Module not found") |
|
||||||
end |
Command:Register('mplus', 'Toggle m+ module on/off', function(args) |
||||||
end) |
local cmd = args[2] |
||||||
|
if cmd == 'debuffs' then |
||||||
Command:Register('mplus', 'Toggle m+ module on/off', function(args) |
Bastion.MythicPlusUtils:ToggleDebuffLogging() |
||||||
local cmd = args[2] |
Bastion:Print("Debuff logging", Bastion.MythicPlusUtils |
||||||
if cmd == 'debuffs' then |
.debuffLogging and "enabled" or "disabled") |
||||||
Bastion.MythicPlusUtils:ToggleDebuffLogging() |
return |
||||||
Bastion:Print("Debuff logging", Bastion.MythicPlusUtils.debuffLogging and "enabled" or "disabled") |
end |
||||||
return |
|
||||||
|
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 |
||||||
|
|
||||||
if cmd == 'casts' then |
function Bastion:CheckLibraryDependencies() |
||||||
Bastion.MythicPlusUtils:ToggleCastLogging() |
for k, v in pairs(LIBRARIES) do |
||||||
Bastion:Print("Cast logging", Bastion.MythicPlusUtils.castLogging and "enabled" or "disabled") |
if v.dependencies then |
||||||
return |
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 |
||||||
|
|
||||||
Bastion:Print("[MythicPlusUtils] Unknown command") |
function Bastion:Import(library) |
||||||
Bastion:Print("Available commands:") |
local lib = self:GetLibrary(library) |
||||||
Bastion:Print("debuffs") |
|
||||||
Bastion:Print("casts") |
|
||||||
end) |
|
||||||
|
|
||||||
Command:Register('missed', 'Dump the list of immune kidney shot spells', function() |
if not lib then error("Library " .. library .. " not found") end |
||||||
for k, v in pairs(missed) do |
|
||||||
Bastion:Print(k) |
return lib:Resolve() |
||||||
end |
end |
||||||
end) |
|
||||||
|
|
||||||
local files = ListFiles("scripts/bastion/scripts") |
function Bastion:GetLibrary(name) |
||||||
|
if not LIBRARIES[name] then |
||||||
|
error("Library " .. name .. " not found") |
||||||
|
end |
||||||
|
|
||||||
for i = 1, #files do |
local library = LIBRARIES[name] |
||||||
local file = files[i] |
|
||||||
if file:sub( -4) == ".lua" or file:sub( -5) == '.luac' then |
-- if library.dependencies then |
||||||
Tinkr:require("scripts/bastion/scripts/" .. file:sub(1, -5), Bastion) |
-- 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 |
end |
||||||
|
|
||||||
|
-- if not Bastion:CheckLibraryDependencies() then |
||||||
|
-- return |
||||||
|
-- end |
||||||
|
|
||||||
|
Load("@Libraries/") |
||||||
|
Load("@Modules/") |
||||||
|
Load("@") |
||||||
end |
end |
||||||
|
|
||||||
|
Bastion.Bootstrap() |
||||||
|
Loading…
Reference in new issue