diff --git a/README.md b/README.md index b1c71f0..11f6732 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,18 @@ +All credit to 4n0n for creating the Bastion framework! + Bastion aims to be a highly performant and complete World of Warcraft data visualization layer, as such developers may leverage it to create combat rotations, gathering bots, quest bots, and much more! -Pull requests are welcome and encouraged, however I do ask that scripts such as rotations live in their own repository, -for the moment the included restoration druid rotation is the exception as it serves as a learning resource for developers -to reference in creating their own scripts. - Feel free to browse around the [Wiki](https://git.tinkr.site/4n0n/bastion/wiki) or just start by reading the code! ## Quick Start -- [Download](https://git.tinkr.site/4n0n/bastion/archive/main.zip) or clone the repository. +- [Download](https://git.tinkr.site/RexUK/bastion/archive/main.zip) or clone the repository. - Move the bastion folder to your `Tinkr/scripts` folder. -- Once in-game type `/bastion toggle` to enable the engine. \ No newline at end of file +- Once in-game type `/bastion interface` to open the main menu. + +## Latest changes +Added Unit:IsIndoors() to Unit.lua +Changed _bastion.lua to not automatically load all modules +Added class/spec checks to _bastion.lua to only load the class/spec you're in game with +Implemented GUI though Gui.lua based on Kaminaris StdUI - https://github.com/kaminaris/StdUi + diff --git a/scripts/outlaw.lua b/scripts/outlaw.lua deleted file mode 100644 index dd8b41a..0000000 --- a/scripts/outlaw.lua +++ /dev/null @@ -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)=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( 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= 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=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= 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=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.audacity120&(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) diff --git a/scripts/outlawbak.lua b/scripts/outlawbak.lua new file mode 100644 index 0000000..959ecb5 --- /dev/null +++ b/scripts/outlawbak.lua @@ -0,0 +1,608 @@ +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 RollTheBones = Bastion.SpellBook:GetSpell(315508) +local SliceAndDice = Bastion.SpellBook:GetSpell(315496) +local BetweenTheEyes = Bastion.SpellBook:GetSpell(315341) +local BladeRush = Bastion.SpellBook:GetSpell(271877) +local Vanish = Bastion.SpellBook:GetSpell(1856) +local Dispatch = Bastion.SpellBook:GetSpell(2098) +local Ambush = Bastion.SpellBook:GetSpell(8676) +local Stealth = Bastion.SpellBook:GetSpell(1784) +local PistolShot = Bastion.SpellBook:GetSpell(185763) +local Opportunity = Bastion.SpellBook:GetSpell(195627) +local SinisterStrike = Bastion.SpellBook:GetSpell(193315) +local GrandMelee = Bastion.SpellBook:GetSpell(193358) +local Broadside = Bastion.SpellBook:GetSpell(193356) +local TrueBearing = Bastion.SpellBook:GetSpell(193359) +local RuthlessPrecision = Bastion.SpellBook:GetSpell(193357) +local SkullAndCrossbones = Bastion.SpellBook:GetSpell(199603) +local BuriedTreasure = Bastion.SpellBook:GetSpell(199600) +local AdrenalineRush = Bastion.SpellBook:GetSpell(13750) +local ShadowDance = Bastion.SpellBook:GetSpell(185313) +local Audacity = Bastion.SpellBook:GetSpell(381845) +local Flagellation = Bastion.SpellBook:GetSpell(323654) +local Dreadblades = Bastion.SpellBook:GetSpell(343142) +local JollyRoger = Bastion.SpellBook:GetSpell(199603) +local BladeFlurry = Bastion.SpellBook:GetSpell(13877) +local Kick = Bastion.SpellBook:GetSpell(1766) +local MarkedForDeath = Bastion.SpellBook:GetSpell(137619) +local CrimsonVial = Bastion.SpellBook:GetSpell(185311) +local Shiv = Bastion.SpellBook:GetSpell(5938) +local KidneyShot = Bastion.SpellBook:GetSpell(408) +local InstantPoison = Bastion.SpellBook:GetSpell(315584) +local AtrophicPosion = Bastion.SpellBook:GetSpell(381637) +local Evasion = Bastion.SpellBook:GetSpell(5277) +local TricksOfTheTrade = Bastion.SpellBook:GetSpell(57934) +local CheapShot = Bastion.SpellBook:GetSpell(1833) +local BagOfTricks = Bastion.SpellBook:GetSpell(312411) +local AutoAttack = Bastion.SpellBook:GetSpell(6603) + +local IrideusFragment = Bastion.ItemBook:GetItem(193743) +local Healthstone = Bastion.ItemBook:GetItem(5512) +local WindscarWhetstone = Bastion.ItemBook:GetItem(137486) + +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 AOEAPL = Bastion.APL:New('aoe') +local SpecialAPL = Bastion.APL:New('special') + +SpecialAPL:AddSpell( + Kick:CastableIf(function(self) + return KickTarget:Exists() and Player:InMelee(KickTarget) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() + end):SetTarget(KickTarget) +) + +SpecialAPL:AddSpell( + SinisterStrike:CastableIf(function(self) + return Explosive:Exists() and not Player:IsCastingOrChanneling() + end):SetTarget(Explosive) +) + +SpecialAPL:AddSpell( + KidneyShot:CastableIf(function(self) + return KickTarget:Exists() and Player:InMelee(KickTarget) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + (Player:GetComboPoints(Target) >= 5 or + ( + Player:GetComboPoints(Target) >= 4 and + (Player:GetAuras():FindMy(Broadside):IsUp() or Player:GetAuras():FindMy(Opportunity):IsUp()))) + + end):SetTarget(KickTarget) +) + +SpecialAPL:AddSpell( + CheapShot:CastableIf(function(self) + return KickTarget:Exists() and Player:InMelee(KickTarget) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and Player:GetAuras():FindMy(Stealth):IsUp() + end):SetTarget(KickTarget) +) + +SpecialAPL:AddSpell( + Stealth:CastableIf(function(self) + return self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and not Player:IsAffectingCombat() and + not Player:GetAuras():FindMy(Stealth):IsUp() and not IsMounted() + end):SetTarget(Player) +) + +SpecialAPL:AddSpell( + CrimsonVial:CastableIf(function(self) + return self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetHealthPercent() < 70 + end):SetTarget(Player) +) + +SpecialAPL:AddSpell( + Shiv:CastableIf(function(self) + return PurgeTarget:Exists() and Player:InMelee(PurgeTarget) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and PurgeTarget:GetAuras():HasAnyStealableAura() + end):SetTarget(PurgeTarget) +) + +SpecialAPL:AddSpell( + InstantPoison:CastableIf(function(self) + return self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + not Player:GetAuras():FindMy(InstantPoison):IsUp() and not Player:IsMoving() + end):SetTarget(Player) +) + +SpecialAPL:AddSpell( + AtrophicPosion:CastableIf(function(self) + return self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + not Player:GetAuras():FindMy(AtrophicPosion):IsUp() and not Player:IsMoving() + end):SetTarget(Player) +) + +SpecialAPL:AddItem( + Healthstone:UsableIf(function(self) + return self:IsEquippedAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetHealthPercent() < 40 + end):SetTarget(Player) +) + +SpecialAPL:AddSpell( + TricksOfTheTrade:CastableIf(function(self) + return Tank:Exists() and self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:IsTanking(Target) + end):SetTarget(Tank) +) + +SpecialAPL:AddSpell( + Evasion:CastableIf(function(self) + return self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetHealthPercent() < 40 + end):SetTarget(Player) +) + +SpecialAPL:AddItem( + IrideusFragment:UsableIf(function(self) + return self:IsEquippedAndUsable() and + not Player:IsCastingOrChanneling() and (Player:GetMeleeAttackers() > 2 or Target:IsBoss()) + end):SetTarget(Player) +) + +SpecialAPL:AddItem( + WindscarWhetstone:UsableIf(function(self) + return self:IsEquippedAndUsable() and + not Player:IsCastingOrChanneling() and (Player:GetMeleeAttackers() > 2 or Target:IsBoss()) + end):SetTarget(Player) +) + +SpecialAPL:AddSpell( + BagOfTricks:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() + end):SetTarget(Target) +) + +-- Adrenaline Rush on cooldown. +DefaultAPL:AddSpell( + AdrenalineRush:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() + end):SetTarget(Player) +) + +-- Roll the Bones if you have no combat enhancements active. +DefaultAPL:AddSpell( + RollTheBones:CastableIf(function(self) + local numBuffs = 0 + if Player:GetAuras():FindMy(Broadside):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(BuriedTreasure):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(GrandMelee):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(RuthlessPrecision):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(SkullAndCrossbones):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(TrueBearing):IsUp() then + numBuffs = numBuffs + 1 + end + return self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + ((not Player:GetAuras():FindMy(Broadside):IsUp() and + not Player:GetAuras():FindMy(TrueBearing):IsUp()) or numBuffs < 2) + end):SetTarget(Player) +) +-- Slice and Dice if at max, or -1 from maximum combo points with Broadside or Opportunity active, if missing or has has 12 or less seconds remaining. +DefaultAPL:AddSpell( + SliceAndDice:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + (Player:GetComboPoints(Target) >= 5 or + ( + Player:GetComboPoints(Target) >= 4 and + (Player:GetAuras():FindMy(Broadside):IsUp() or Player:GetAuras():FindMy(Opportunity):IsUp()))) and + ( + not Player:GetAuras():FindMy(SliceAndDice):IsUp() or + Player:GetAuras():FindMy(SliceAndDice):GetRemainingTime() <= 12 + ) + end):SetTarget(Target) +) + +-- Between the Eyes on cooldown if at max, or -1 from maximum combo points with Broadside or Opportunity active. +DefaultAPL:AddSpell( + BetweenTheEyes:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + (Player:GetComboPoints(Target) >= 5 or + ( + Player:GetComboPoints(Target) >= 4 and + (Player:GetAuras():FindMy(Broadside):IsUp() or Player:GetAuras():FindMy(Opportunity):IsUp()))) + end):SetTarget(Target) +) + +-- Dispatch if at max, or -1 from maximum combo points with Broadside or Opportunity active. +DefaultAPL:AddSpell( + Dispatch:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + (Player:GetComboPoints(Target) >= 5 or + ( + Player:GetComboPoints(Target) >= 4 and + (Player:GetAuras():FindMy(Broadside):IsUp() or Player:GetAuras():FindMy(Opportunity):IsUp()))) + end):SetTarget(Target) +) + +-- Shadow Dance at or below 3 combo points, and do not have Audacity or Opportunity active and wait until you have at least 80 energy. While active Ambush becomes your highest priority builder. +DefaultAPL:AddSpell( + ShadowDance:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetComboPoints(Target) <= 3 and + not Player:GetAuras():FindMy(Audacity):IsUp() and + not Player:GetAuras():FindMy(Opportunity):IsUp() and + Player:GetPower() >= 80 + end):SetTarget(Player) +) + +-- Blade Rush if missing 50 or more energy and do not have Flagellation, Dreadblades or Shadow Dance active. +DefaultAPL:AddSpell( + BladeRush:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetPower() <= 50 and + not Player:GetAuras():FindMy(Flagellation):IsUp() and + not Player:GetAuras():FindMy(Dreadblades):IsUp() and + not Player:GetAuras():FindMy(ShadowDance):IsUp() + end):SetTarget(Player) +) + +-- Vanish followed by Ambush if you won't overcap combo points and wait until you have at least 50 energy. +DefaultAPL:AddSpell( + Vanish:CastableIf(function(self) + return Tank:Exists() and Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetComboPoints(Target) <= 4 and + Player:GetPower() >= 50 and not Player:GetAuras():FindMy(Stealth):IsUp() + end):SetTarget(Player) +) + +-- Pistol Shot if you have an Opportunity proc and won't overcap combo points. +DefaultAPL:AddSpell( + PistolShot:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetAuras():FindMy(Opportunity):IsUp() and + Player:GetComboPoints(Target) <= 4 + end):SetTarget(Target) +) + +-- Use Ambush Icon Ambush instead of Sinister Strike Icon Sinister Strike whenever it is available to cast from any of the procs or cooldowns. +DefaultAPL:AddSpell( + Ambush:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() + end):SetTarget(Target) +) + +-- Sinister Strike if you won't overcap combo points. +DefaultAPL:AddSpell( + SinisterStrike:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetComboPoints(Target) < 5 + end):SetTarget(Target) +) + +-- AOE APL + +-- Adrenaline Rush on cooldown. +AOEAPL:AddSpell( + AdrenalineRush:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() + end):SetTarget(Player) +) + +-- Roll the Bones if you have no combat enhancements active. +-- Roll the Bones has a large outcome of buffs which include; Broadside, Buried Treasure, Grand Melee, Ruthless Precision, Skull and Crossbones, and True Bearing. The buffs you want to keep this tier are going to be Broadside and True Bearing as single buffs or any combination of 2 or more buffs. Any of the other 4 buffs as a single means it's worth recasting Roll the Bones as soon as you are able to. + +AOEAPL:AddSpell( + RollTheBones:CastableIf(function(self) + local numBuffs = 0 + if Player:GetAuras():FindMy(Broadside):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(BuriedTreasure):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(GrandMelee):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(RuthlessPrecision):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(SkullAndCrossbones):IsUp() then + numBuffs = numBuffs + 1 + end + if Player:GetAuras():FindMy(TrueBearing):IsUp() then + numBuffs = numBuffs + 1 + end + return self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + ((not Player:GetAuras():FindMy(Broadside):IsUp() and + not Player:GetAuras():FindMy(TrueBearing):IsUp()) or numBuffs < 2) + end):SetTarget(Player) +) + +-- Blade Flurry when missing. +AOEAPL:AddSpell( + BladeFlurry:CastableIf(function(self) + return self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + (not Player:GetAuras():FindMy(self):IsUp() or Player:GetAuras():FindMy(self):GetRemainingTime() <= 2) + end):SetTarget(Player) +) + +-- Slice and Dice if at max, or -1 from maximum combo points with Broadside or Opportunity active, if missing or has has 12 or less seconds remaining. +AOEAPL:AddSpell( + SliceAndDice:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + (Player:GetComboPoints(Target) >= 5 or + (Player:GetComboPoints(Target) >= 4 and + (Player:GetAuras():FindMy(Broadside):IsUp() or + Player:GetAuras():FindMy(Opportunity):IsUp()))) and + (not Player:GetAuras():FindMy(self):IsUp() or + Player:GetAuras():FindMy(self):GetRemainingTime() <= 12) + end):SetTarget(Player) +) + +-- Between the Eyes on cooldown if at max, or -1 from maximum combo points with Broadside or Opportunity active. +AOEAPL:AddSpell( + BetweenTheEyes:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + (Player:GetComboPoints(Target) >= 5 or + (Player:GetComboPoints(Target) >= 4 and + (Player:GetAuras():FindMy(Broadside):IsUp() or + Player:GetAuras():FindMy(Opportunity):IsUp()))) + end):SetTarget(Target) +) + +-- Dispatch if at max, or -1 from maximum combo points with Broadside or Opportunity active. +AOEAPL:AddSpell( + Dispatch:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + (Player:GetComboPoints(Target) >= 5 or + (Player:GetComboPoints(Target) >= 4 and + (Player:GetAuras():FindMy(Broadside):IsUp() or + Player:GetAuras():FindMy(Opportunity):IsUp()))) + end):SetTarget(Target) +) + +-- Shadow Dance at or below 3 combo points, and do not have Audacity or Opportunity active and wait until you have at least 80 energy. While active Ambush becomes your highest priority builder. +AOEAPL:AddSpell( + ShadowDance:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetComboPoints(Target) <= 3 and + not Player:GetAuras():FindMy(Audacity):IsUp() and + not Player:GetAuras():FindMy(Opportunity):IsUp() and + Player:GetPower() >= 80 + end):SetTarget(Player) +) + +-- Blade Rush if missing 50 or more energy and do not have Flagellation, Dreadblades or Shadow Dance active. +AOEAPL:AddSpell( + BladeRush:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetPower() >= 50 and + not Player:GetAuras():FindMy(Flagellation):IsUp() and + not Player:GetAuras():FindMy(Dreadblades):IsUp() and + not Player:GetAuras():FindMy(ShadowDance):IsUp() + end):SetTarget(Player) +) + +-- Vanish followed by Ambush if you won't overcap combo points and wait until you have at least 50 energy. +AOEAPL:AddSpell( + Vanish:CastableIf(function(self) + return Tank:Exists() and Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetComboPoints(Target) < 5 and + Player:GetPower() >= 50 and not Player:GetAuras():FindMy(Stealth):IsUp() + end):SetTarget(Player) +) + +-- Pistol Shot if you have an Opportunity proc and won't overcap combo points. +AOEAPL:AddSpell( + PistolShot:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetAuras():FindMy(Opportunity):IsUp() and + Player:GetComboPoints(Target) < 5 + end):SetTarget(Target) +) + +AOEAPL:AddSpell( + Ambush:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() + end):SetTarget(Target) +) + +-- Sinister Strike if you won't overcap combo points. +AOEAPL:AddSpell( + SinisterStrike:CastableIf(function(self) + return Target:Exists() and Player:InMelee(Target) and + self:IsKnownAndUsable() and + not Player:IsCastingOrChanneling() and + Player:GetComboPoints(Target) < 5 + end):SetTarget(Target) +) + +OutlawModule:Sync(function() + SpecialAPL:Execute() + if Player:GetMeleeAttackers() > 1 then + AOEAPL:Execute() + else + DefaultAPL:Execute() + end +end) + +Bastion:Register(OutlawModule) diff --git a/scripts/restodruid.lua b/scripts/restodruid.lua index 58fcc15..08fa91f 100644 --- a/scripts/restodruid.lua +++ b/scripts/restodruid.lua @@ -6,6 +6,8 @@ local Player = Bastion.UnitManager:Get('player') local None = Bastion.UnitManager:Get('none') local Target = Bastion.UnitManager:Get('target') +local myconf = Tinkr.Util.Config:New('resto_druid') + local AnomalyDetectionMarkI = Bastion.SpellBook:GetSpell(382499) local AutoAttack = Bastion.SpellBook:GetSpell(6603) local MechanismBypass = Bastion.SpellBook:GetSpell(382501) @@ -89,6 +91,7 @@ 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 MoonkinForm = Bastion.SpellBook:GetSpell(197625) local Revitalize = Bastion.SpellBook:GetSpell(212040) local Tranquility = Bastion.SpellBook:GetSpell(740) local MasteryHarmony = Bastion.SpellBook:GetSpell(77495) @@ -385,14 +388,14 @@ local Explosive = Bastion.UnitManager:CreateCustomUnit('explosive', function(uni return explosive end) -local RestoCommands = Bastion.Command:New('resto') +-- local RestoCommands = Bastion.Command:New('rex') -local PLACE_EFFLO = false +-- 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) +-- 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') @@ -405,20 +408,21 @@ DefaultAPL:AddSpell( DefaultAPL:AddSpell( Efflorescence:CastableIf(function(self) - return PLACE_EFFLO and Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + return IsShiftKeyDown() 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 + --local loc = Target:GetPosition() self:Click(loc) + + end) ) DefaultAPL:AddAction( 'cat_form_shift', function() - if IsShiftKeyDown() and not Player:GetAuras():FindMy(CatForm):IsUp() and not Player:IsCastingOrChanneling() then - CatForm:Cast(Player) - elseif not IsShiftKeyDown() and Player:GetAuras():FindMy(CatForm):IsUp() then + if IsAltKeyDown() and not Player:GetAuras():FindMy(MoonkinForm):IsUp() and not Player:IsCastingOrChanneling() then + MoonkinForm:Cast(Player) + elseif not IsAltKeyDown() and Player:GetAuras():FindMy(MoonkinForm):IsUp() then CancelShapeshiftForm() end end @@ -441,23 +445,30 @@ DefaultAPL:AddSpell( DefaultAPL:AddSpell( NaturesSwiftness:CastableIf(function(self) return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() - and Player:CanSee(Lowest) and Lowest:GetHP() < 70 + and Player:CanSee(Lowest) and + (Lowest:GetHP() < 70 or (Player:GetPartyHPAround(40, 65) >= 2 or Player:GetPartyHPAround(40, 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) + self:IsInRange(Player) and (Player:GetPartyHPAround(40, 65) >= 2 or Player:GetPartyHPAround(40, 60) >= 3) + end):SetTarget(Player) +) +DefaultAPL:AddSpell( + MarkoftheWild:CastableIf(function(self) + return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and + not Player:GetAuras():FindMy(MarkoftheWild):IsUp() 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 + self:IsInRange(Player) and (Player:GetPartyHPAround(40, 65) >= 2 or Player:GetPartyHPAround(40, 70) >= 3) and + (not ConvokeTheSpirits:IsKnownAndUsable() and ConvokeTheSpirits:GetTimeSinceLastCast() > 7) and WildGrowth:GetTimeSinceLastCast() <= 6 end):SetTarget(Player) ) @@ -471,7 +482,7 @@ DefaultAPL:AddSpell( DefaultAPL:AddSpell( AdaptiveSwarm:CastableIf(function(self) - return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:IsAffectingCombat() and Player:CanSee(Lowest) end):SetTarget(Lowest) ) @@ -481,7 +492,7 @@ DefaultAPL:AddSpell( return SwiftmendUnit:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:CanSee(SwiftmendUnit) and ( - SwiftmendUnit:GetHP() <= 60 or + SwiftmendUnit:GetHP() <= 80 or ( Lowest:GetPartyHPAround(30, 90) >= 3 or Lowest:GetPartyHPAround(30, 85) >= 2 ) @@ -494,10 +505,12 @@ DefaultAPL:AddSpell( 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 + ( + Player:GetAuras():FindMy(SoulOfTheForest):IsUp() and + ( + Player:GetAuras():FindMy(SoulOfTheForest):GetRemainingTime() <= 5 or + WildGrowthUnit:GetPartyHPAround(30, 90) >= 2)) or + (WildGrowthUnit:GetPartyHPAround(30, 90) >= 3 or WildGrowthUnit:GetPartyHPAround(30, 85) >= 2)) and not Player:IsMoving() end):SetTarget(WildGrowthUnit) ) @@ -538,7 +551,7 @@ DefaultAPL:AddSpell( 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 + and Player:CanSee(RejuvUnit) and RejuvUnit:GetHP() <= 90 and not Player:GetAuras():FindMy(SoulOfTheForest):IsUp() end):SetTarget(RejuvUnit) ) @@ -575,60 +588,214 @@ DefaultAPL:AddSpell( end):SetTarget(Lowest) ) +DamageAPL:AddSpell( + Sunfire:CastableIf(function(self) + return Bastion.UnitManager['target']:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + and Player:CanSee(Bastion.UnitManager['target']) and + ( + not Bastion.UnitManager['target']:GetAuras():FindMy(SunfireAura):IsUp() or + Bastion.UnitManager['target']:GetAuras():FindMy(SunfireAura):GetRemainingTime() <= 5.4) and + Bastion.UnitManager['target']:IsHostile() and + Bastion.UnitManager['target']:IsAffectingCombat() and Player:GetPP() >= 25 + end):SetTarget(Bastion.UnitManager['target']) +) 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) + Innervate:CastableIf(function(self) + return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:IsAffectingCombat() + and Player:GetPP() <= 60 + end):SetTarget(Player) ) - DefaultAPL:AddSpell( - Sunfire:CastableIf(function(self) - return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() - and Player:CanSee(Target) and - ( - not Target:GetAuras():FindMy(SunfireAura):IsUp() or - Target:GetAuras():FindMy(SunfireAura):GetRemainingTime() <= 5.4) and - Target:IsHostile() and - Target:IsAffectingCombat() and Player:GetPP() >= 25 - end):SetTarget(Target) + TravelForm:CastableIf(function(self) + return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Player:IsAffectingCombat() and not IsMounted() + and Player:IsMoving() and not Player:GetAuras():FindMy(TravelForm):IsUp() and not Player:IsIndoors() + end):SetTarget(Player) ) - DefaultAPL:AddSpell( + CatForm:CastableIf(function(self) + return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Player:IsAffectingCombat() and not IsMounted() + and Player:IsMoving() and not Player:GetAuras():FindMy(CatForm):IsUp() and Player:IsIndoors() + end):SetTarget(Player) +) +DamageAPL:AddSpell( Moonfire:CastableIf(function(self) - return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() - and Player:CanSee(Target) and + return Bastion.UnitManager['target']:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + and Player:CanSee(Bastion.UnitManager['target']) and ( - not Target:GetAuras():FindMy(MoonfireAura):IsUp() or - Target:GetAuras():FindMy(MoonfireAura):GetRemainingTime() <= 5.4) and - Target:IsHostile() and - Target:IsAffectingCombat() and Player:GetPP() >= 25 - end):SetTarget(Target) + not Bastion.UnitManager['target']:GetAuras():FindMy(MoonfireAura):IsUp() or + Bastion.UnitManager['target']:GetAuras():FindMy(MoonfireAura):GetRemainingTime() <= 5.4) and + Bastion.UnitManager['target']:IsHostile() and + Bastion.UnitManager['target']:IsAffectingCombat() and Player:GetPP() >= 25 + end):SetTarget(Bastion.UnitManager['target']) ) -DefaultAPL:AddSpell( +DamageAPL: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) + return Bastion.UnitManager['target']:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + and Player:CanSee(Bastion.UnitManager['target']) and Bastion.UnitManager['target']:IsHostile() and + Bastion.UnitManager['target']:IsAffectingCombat() and Player:GetPP() >= 25 + end):SetTarget(Bastion.UnitManager['target']) ) -DefaultAPL:AddSpell( +DamageAPL: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) + return Bastion.UnitManager['target']:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + and Player:CanSee(Bastion.UnitManager['target']) and not Player:IsMoving() and + Bastion.UnitManager['target']:IsHostile() and + Bastion.UnitManager['target']:IsAffectingCombat() and Player:GetPP() >= 25 + end):SetTarget(Bastion.UnitManager['target']) ) RestoModule:Sync(function() - if IsShiftKeyDown() and Player:GetAuras():FindMy(CatForm):IsUp() then + if IsAltKeyDown() and Player:GetAuras():FindMy(MoonkinForm):IsUp() then return DamageAPL:Execute() end DefaultAPL:Execute() end) - Bastion:Register(RestoModule) + +local tab1 = +{ + layoutConfig = { padding = { top = 40 } }, + rows = { + [1] = { shadpr = { type = 'header', label = 'Open Combat' } }, + + [2] = { opener = { type = 'dropdown', label = 'Healing', column = 6, order = 1, + options = { + { text = 'Healing 1', value = 'swp'}, + { text = 'Healing 2', value = 'crash'}, + { text = 'None', value = 'none'}, + }, + initialValue = myconf:Read('opener', 'shield'), + onValueChanged = function(_, value) myconf:Write('opener', value) end }, }, + + [3] = { swp1 = { type = 'checkbox', label = 'Spread SWP', column = 6, order = 1, + initialValue = myconf:Read('swpspread', false), + onValueChanged = function(_, flag) myconf:Write('swpspread', flag) end }, + + swp2 = { type = 'slider', label = 'Max Targets', column = 6, order = 2, + min = 1, max = 10, precision = 0, + initialValue = myconf:Read('swptargets', 3), + onValueChanged = function(_, value) myconf:Write('swptargets', value) end }, }, + + [4] = { shadpr = { type = 'header', label = 'Defensives' } }, + + [5] = { shield1 = { type = 'checkbox', label = 'Power Word: Shield', column = 6, order = 1, + initialValue = myconf:Read('pws', false), + onValueChanged = function(_, flag) myconf:Write('pws', flag) end }, + + shield2 = { type = 'slider', label = 'Player Health', column = 6, order = 2, + min = 1, max = 100, precision = 0, + initialValue = myconf:Read('pwspercent', 35), + onValueChanged = function(_, value) myconf:Write('pwspercent', value) end }, }, + + [6] = { dispersion1 = { type = 'checkbox', label = 'Dispersion', column = 6, order = 1, + initialValue = myconf:Read('dispersion', false), + onValueChanged = function(_, flag) myconf:Write('dispersion', flag) end }, + + dispersion2 = { type = 'slider', label = 'Player Health', column = 6, order = 2, + min = 1, max = 100, precision = 0, + initialValue = myconf:Read('dispersionpercent', 35), + onValueChanged = function(_, value) myconf:Write('dispersionpercent', value) end }, }, + + [7] = { shadpr = { type = 'header', label = 'Interrupts' } }, + + [8] = { silence = { type = 'checkbox', label = 'Silence on CD', column = 6, order = 1, + initialValue = myconf:Read('silence', false), + onValueChanged = function(_, flag) myconf:Write('silence', flag) end }, + + horror = { type = 'checkbox', label = 'Psychic Horror on CD', column = 6, order = 2, + initialValue = myconf:Read('horror', false), + onValueChanged = function(_, flag) myconf:Write('horror', flag) end }, }, + + [9] = { shadpr = { type = 'header', label = 'Purify Disease' } }, + + [10] = { incombat = { type = 'checkbox', label = 'In Combat', column = 6, order = 1, + initialValue = myconf:Read('purifyic', false), + onValueChanged = function(_, flag) myconf:Write('purifyic', flag) end }, + + outcombat = { type = 'checkbox', label = 'Out of Combat', column = 6, order = 2, + initialValue = myconf:Read('purifyooc', false), + onValueChanged = function(_, flag) myconf:Write('purifyooc', flag) end }, }, + + [11] = { shadpr = { type = 'header', label = 'Dispel Magic' } }, + + [12] = { incombat = { type = 'checkbox', label = 'In Combat', column = 12, order = 1, + initialValue = myconf:Read('dispelic', false), + onValueChanged = function(_, flag) myconf:Write('dispelic', flag) end }, }, + + [13] = { shadpr = { type = 'header', label = 'Dispel Delay Time' } }, + + [14] = { delay = { type = 'slider', label = 'In seconds', column = 6, order = 1, + min = 0.5, max = 2, precision = 1, + initialValue = myconf:Read('dispeldelay', 1), + onValueChanged = function(_, value) myconf:Write('dispeldelay', value) end }, }, + + }, +} + +local tab2 = +{ + layoutConfig = { padding = { top = 40 } }, + rows = { + [1] = { shadpr = { type = 'header', label = 'Player Healing' } }, + + [2] = { incombat = { type = 'checkbox', label = 'In Combat Healing', column = 6, order = 1, + initialValue = myconf:Read('playericheal', false), + onValueChanged = function(_, flag) myconf:Write('playericheal', flag) end }, + + outcombat = { type = 'checkbox', label = 'Out of Combat Healing', column = 6, order = 2, + initialValue = myconf:Read('playeroocheal', false), + onValueChanged = function(_, flag) myconf:Write('playeroocheal', flag) end }, }, + + [3] = { shadowmend1 = { type = 'checkbox', label = 'Shadow Mend', column = 6, order = 1, + initialValue = myconf:Read('shadowmend', false), + onValueChanged = function(_, flag) myconf:Write('shadowmend', flag) end }, + + shadowmend2 = { type = 'slider', label = 'Player Health', column = 6, order = 2, + min = 1, max = 100, precision = 0, + initialValue = myconf:Read('shadowmendpercent', 35), + onValueChanged = function(_, value) myconf:Write('shadowmendpercent', value) end }, }, + + }, +} + +local restodruidconfig = { + layoutConfig = { padding = { top = 30 } }, + rows = { + [1] = { + container = { + type = 'tab', + fullSize = true, + tabs = { + { + name = 'player', + title = 'Player Settings', + layout = tab1 + }, + { + name = 'group', + title = 'Healing', + layout = tab2 + } + }, + } + }, + }, +} +Bastion.settingstemplate(restodruidconfig, 'Resto Druid', 400, 600, 1.00, 1.00, 1.00) --, 0.00, 0.44, 0.87, 'enhsha') --Title of Settings Frame, Width, Height, ClassRGB, Rotation Name + +-- Class colours +-- Death Knight 0.77 0.12 0.23 Red +-- Demon Hunter 0.64 0.19 0.79 Dark Magenta +-- Druid 1.00 0.49 0.04 Orange +-- Evoker 0.20 0.58 0.50 Dark Emerald +-- Hunter 0.67 0.83 0.45 Green +-- Mage 0.25 0.78 0.92 Light Blue +-- Monk 0.00 1.00 0.60 Spring Green +-- Paladin 0.96 0.55 0.73 Pink +-- Priest 1.00 1.00 1.00 White +-- Rogue 1.00 0.96 0.41 Yellow +-- Shaman 0.00 0.44 0.87 Blue +-- Warlock 0.53 0.53 0.93 Purple +-- Warrior 0.78 0.61 0.43 Tan \ No newline at end of file diff --git a/scripts/shadowpriest.lua b/scripts/shadowpriest.lua index 24e030d..0625181 100644 --- a/scripts/shadowpriest.lua +++ b/scripts/shadowpriest.lua @@ -1,7 +1,5 @@ local Tinkr, Bastion = ... -Tinkr:require("scripts.bastion.ui", Bastion) - local ShadowModule = Bastion.Module:New('shadow') local Evaluator = Tinkr.Util.Evaluator local Player = Bastion.UnitManager:Get('player') @@ -122,13 +120,13 @@ local usepwf = myconf:Read('pwf') local useshadowform = myconf:Read('shadowform') RestingAPL:AddSpell( PowerWordFortitude:CastableIf(function(self) - return usepwf == 'yes' and self:IsKnownAndUsable() and + return usepwf and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Player:GetAuras():FindMy(PowerWordFortitude):IsUp() and not IsMounted() end):SetTarget(Player) ) RestingAPL:AddSpell( Shadowform:CastableIf(function(self) - return useshadowform == 'yes' and self:IsKnownAndUsable() and + return useshadowform and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Player:GetAuras():FindMy(Shadowform):IsUp() and not IsMounted() end):SetTarget(Player) ) @@ -289,7 +287,7 @@ local tab1 = { layoutConfig = { padding = { top = 40 } }, rows = { - [1] = { shadpr = { type = 'header', label = 'Open Combat' } }, + [1] = { shadpr = { type = 'label', label = 'Open Combat' } }, [2] = { opener = { type = 'dropdown', label = 'Opener', column = 6, order = 1, options = { @@ -300,18 +298,19 @@ local tab1 = initialValue = myconf:Read('opener', 'shield'), onValueChanged = function(_, value) myconf:Write('opener', value) end }, }, - [3] = { swp1 = { type = 'checkbox', label = 'Spread SWP', column = 6, order = 1, - initialValue = myconf:Read('swpspread', false), - onValueChanged = function(_, flag) myconf:Write('swpspread', flag) end }, + [3] = { shadpr = { type = 'label', label = 'Buffs' } }, + + [4] = { pwf = { type = 'checkbox', label = 'Power Word: Fortitude', column = 6, order = 1, + initialValue = myconf:Read('pwf', false), + onValueChanged = function(_, flag) myconf:Write('pwf', flag) end }, - swp2 = { type = 'slider', label = 'Max Targets', column = 6, order = 2, - min = 1, max = 10, precision = 0, - initialValue = myconf:Read('swptargets', 3), - onValueChanged = function(_, value) myconf:Write('swptargets', value) end }, }, + shadform = { type = 'checkbox', label = 'Shadowform', column = 6, order = 2, + initialValue = myconf:Read('shadowform', false), + onValueChanged = function(_, flag) myconf:Write('shadowform', flag) end }, }, - [4] = { shadpr = { type = 'header', label = 'Defensives' } }, + [5] = { shadpr = { type = 'header', label = 'Defensives' } }, - [5] = { shield1 = { type = 'checkbox', label = 'Power Word: Shield', column = 6, order = 1, + [6] = { shield1 = { type = 'checkbox', label = 'Power Word: Shield', column = 6, order = 1, initialValue = myconf:Read('pws', false), onValueChanged = function(_, flag) myconf:Write('pws', flag) end }, @@ -320,7 +319,7 @@ local tab1 = initialValue = myconf:Read('pwspercent', 35), onValueChanged = function(_, value) myconf:Write('pwspercent', value) end }, }, - [6] = { dispersion1 = { type = 'checkbox', label = 'Dispersion', column = 6, order = 1, + [7] = { dispersion1 = { type = 'checkbox', label = 'Dispersion', column = 6, order = 1, initialValue = myconf:Read('dispersion', false), onValueChanged = function(_, flag) myconf:Write('dispersion', flag) end }, @@ -329,9 +328,9 @@ local tab1 = initialValue = myconf:Read('dispersionpercent', 35), onValueChanged = function(_, value) myconf:Write('dispersionpercent', value) end }, }, - [7] = { shadpr = { type = 'header', label = 'Interrupts' } }, + [8] = { shadpr = { type = 'header', label = 'Interrupts' } }, - [8] = { silence = { type = 'checkbox', label = 'Silence on CD', column = 6, order = 1, + [9] = { silence = { type = 'checkbox', label = 'Silence on CD', column = 6, order = 1, initialValue = myconf:Read('silence', false), onValueChanged = function(_, flag) myconf:Write('silence', flag) end }, @@ -339,9 +338,9 @@ local tab1 = initialValue = myconf:Read('horror', false), onValueChanged = function(_, flag) myconf:Write('horror', flag) end }, }, - [9] = { shadpr = { type = 'header', label = 'Purify Disease' } }, + [10] = { shadpr = { type = 'header', label = 'Purify Disease' } }, - [10] = { incombat = { type = 'checkbox', label = 'In Combat', column = 6, order = 1, + [11] = { incombat = { type = 'checkbox', label = 'In Combat', column = 6, order = 1, initialValue = myconf:Read('purifyic', false), onValueChanged = function(_, flag) myconf:Write('purifyic', flag) end }, @@ -349,15 +348,15 @@ local tab1 = initialValue = myconf:Read('purifyooc', false), onValueChanged = function(_, flag) myconf:Write('purifyooc', flag) end }, }, - [11] = { shadpr = { type = 'header', label = 'Dispel Magic' } }, + [12] = { shadpr = { type = 'header', label = 'Dispel Magic' } }, - [12] = { incombat = { type = 'checkbox', label = 'In Combat', column = 12, order = 1, + [13] = { incombat = { type = 'checkbox', label = 'In Combat', column = 12, order = 1, initialValue = myconf:Read('dispelic', false), onValueChanged = function(_, flag) myconf:Write('dispelic', flag) end }, }, - [13] = { shadpr = { type = 'header', label = 'Dispel Delay Time' } }, + [14] = { shadpr = { type = 'header', label = 'Dispel Delay Time' } }, - [14] = { delay = { type = 'slider', label = 'In seconds', column = 6, order = 1, + [15] = { delay = { type = 'slider', label = 'In seconds', column = 6, order = 1, min = 0.5, max = 2, precision = 1, initialValue = myconf:Read('dispeldelay', 1), onValueChanged = function(_, value) myconf:Write('dispeldelay', value) end }, }, @@ -406,7 +405,7 @@ local shadpriestconfig = { }, { name = 'group', - title = 'Healing', + title = 'Placeholder', layout = tab2 } }, @@ -414,4 +413,19 @@ local shadpriestconfig = { }, }, } -Bastion.setupsettingsframe(shadpriestconfig, 'Rex Shadow Priest', 400, 600, 1.00, 1.00, 1.00) --, 0.00, 0.44, 0.87, 'enhsha') --Title of Settings Frame, Width, Height, ClassRGB, Rotation Name \ No newline at end of file +Bastion.settingstemplate(shadpriestconfig, 'Shadow Priest', 400, 600, 1.00, 1.00, 1.00) --, 0.00, 0.44, 0.87, 'enhsha') --Title of Settings Frame, Width, Height, ClassRGB, Rotation Name + +-- Class colours +-- Death Knight 0.77 0.12 0.23 Red +-- Demon Hunter 0.64 0.19 0.79 Dark Magenta +-- Druid 1.00 0.49 0.04 Orange +-- Evoker 0.20 0.58 0.50 Dark Emerald +-- Hunter 0.67 0.83 0.45 Green +-- Mage 0.25 0.78 0.92 Light Blue +-- Monk 0.00 1.00 0.60 Spring Green +-- Paladin 0.96 0.55 0.73 Pink +-- Priest 1.00 1.00 1.00 White +-- Rogue 1.00 0.96 0.41 Yellow +-- Shaman 0.00 0.44 0.87 Blue +-- Warlock 0.53 0.53 0.93 Purple +-- Warrior 0.78 0.61 0.43 Tan \ No newline at end of file diff --git a/scripts/subtlety.lua b/scripts/subtlety.lua index b95ad99..55c0350 100644 --- a/scripts/subtlety.lua +++ b/scripts/subtlety.lua @@ -775,7 +775,6 @@ local GrandMelee = Bastion.SpellBook:GetSpell(193358) local Broadside = Bastion.SpellBook:GetSpell(193356) local TrueBearing = Bastion.SpellBook:GetSpell(193359) local RuthlessPrecision = Bastion.SpellBook:GetSpell(193357) -local DeviousStratagem = Bastion.SpellBook:GetSpell(193531) local SkullAndCrossbones = Bastion.SpellBook:GetSpell(199603) local ShadowFocus = Bastion.SpellBook:GetSpell(108209) local BuriedTreasure = Bastion.SpellBook:GetSpell(199600) @@ -844,8 +843,7 @@ local FindWeakness = Bastion.SpellBook:GetSpell(91023) local ImprovedShurikenStorm = Bastion.SpellBook:GetSpell(319951) -local RefreshingHealingPotion = Bastion.ItemBook:GetItem(191380) -local ElementalPotionOfPower = Bastion.ItemBook:GetItem(191389) + local IrideusFragment = Bastion.ItemBook:GetItem(193743) local Healthstone = Bastion.ItemBook:GetItem(5512) local WindscarWhetstone = Bastion.ItemBook:GetItem(137486) @@ -999,38 +997,6 @@ local FinishAPL = Bastion.APL:New('finish') local BuildAPL = Bastion.APL:New('build') local ItemsAPL = Bastion.APL:New('items') -ItemsAPL:AddItem( - Healthstone:UsableIf(function(self) - return self:IsEquippedAndUsable() and - not Player:IsCastingOrChanneling() and - Player:GetHealthPercent() < 40 - end):SetTarget(Player) -) - -ItemsAPL:AddItem( - RefreshingHealingPotion:UsableIf(function(self) - return self:IsEquippedAndUsable() and - not Player:IsCastingOrChanneling() and - Player:GetHealthPercent() < 40 - end):SetTarget(Player) -) - -ItemsAPL:AddSpell( - TricksOfTheTrade:CastableIf(function(self) - return Tank:Exists() and self:IsKnownAndUsable() and - not Player:IsCastingOrChanneling() and - Player:IsTanking(Target) - end):SetTarget(Tank) -) - -ItemsAPL:AddSpell( - Evasion:CastableIf(function(self) - return self:IsKnownAndUsable() and - not Player:IsCastingOrChanneling() and - Player:GetHealthPercent() < 40 - end):SetTarget(Player) -) - ItemsAPL:AddItem( IrideusFragment:UsableIf(function(self) return self:IsEquippedAndUsable() and @@ -1038,13 +1004,6 @@ ItemsAPL:AddItem( end):SetTarget(Player) ) -ItemsAPL:AddItem( - ElementalPotionOfPower:UsableIf(function(self) - return self:IsEquippedAndUsable() and - not Player:IsCastingOrChanneling() and (Player:GetMeleeAttackers() > 2 or Target:IsBoss()) - end):SetTarget(Player) -) - ItemsAPL:AddItem( WindscarWhetstone:UsableIf(function(self) return Target:Exists() and Player:InMelee(Target) and self:IsEquippedAndUsable() and @@ -1110,7 +1069,7 @@ DefaultAPL:AddVariable( 'snd_condition', function() return Player:GetAuras():FindMy(SliceAndDice):IsUp() or - Player:GetEnemies(10) >= ConsumeCPMax() + Player:GetEnemies(10) >= Player:GetComboPointsMax() end ) @@ -1207,7 +1166,7 @@ DefaultAPL:AddAPL( DefaultAPL:AddSpell( SliceAndDice:CastableIf( function(self) - return self:IsKnownAndUsable() and Player:GetEnemies(10) < ConsumeCPMax() and + return self:IsKnownAndUsable() and Player:GetEnemies(10) < Player:GetComboPointsMax() and Player:GetAuras():FindMy(SliceAndDice):GetRemainingTime() < Player:GetGCD() and Player:GetAuras():FindMy(SliceAndDice):GetRemainingTime() > 6 and Player:GetComboPoints() >= 4 @@ -1258,7 +1217,7 @@ DefaultAPL:AddAPL( DefaultAPL:AddAPL( FinishAPL, function() - return DefaultAPL:GetVariable('effective_combo_points') >= ConsumeCPMax() + return DefaultAPL:GetVariable('effective_combo_points') >= Player:GetComboPointsMax() end ) @@ -1346,9 +1305,9 @@ BuildAPL:AddSpell( BuildAPL:AddVariable( 'anima_helper', function() - return not EchoingReprimand:IsKnown() or ((not (DefaultAPL:GetVariable('is_next_cp_animacharged') and + return not EchoingReprimand:IsKnown() or (not (DefaultAPL:GetVariable('is_next_cp_animacharged') and (Player:GetTimeToShurikenTornado(3) < 0.5 or Player:GetTimeToShurikenTornado(4) < 1) and - Player:GetPower() < 60))) + Player:GetPower() < 60)) end ) @@ -1388,8 +1347,7 @@ CDsAPL:AddSpell( CDsAPL:AddSpell( SymbolsOfDeath:CastableIf( function(self) - return Player:IsAffectingCombat() and self:IsKnownAndUsable() and - Player:GetAuras():FindMy(ShurikenTornado):IsUp() and + return self:IsKnownAndUsable() and Player:GetAuras():FindMy(ShurikenTornado):IsUp() and Player:GetAuras():FindMy(ShurikenTornado):GetRemainingTime() <= 3.5 end ):SetTarget(Player) @@ -1592,16 +1550,6 @@ FinishAPL:AddVariable( end ) --- return ( cp + 1 ) * p()->buffs.slice_and_dice->data().duration(); -function GetTriggeredDuration() - return (Player:GetComboPoints() + 1) * 6 -end - --- return p()->buffs.slice_and_dice->remains() < get_triggered_duration( as( p()->current_effective_cp( false ) ) ) * 0.3; -function Refreshable(aura, target) - return target:GetAuras():FindMy(aura):GetRemainingTime() < GetTriggeredDuration() * 0.3 -end - -- actions.finish+=/slice_and_dice,if=!variable.premed_snd_condition&spell_targets.shuriken_storm<6&!buff.shadow_dance.up&buff.slice_and_dice.remains 6 and - Refreshable(Rupture, Target) + Target:GetAuras():FindMy(Rupture):GetRemainingTime() < 6 end ):SetTarget(Target) ) @@ -1706,7 +1654,7 @@ FinishAPL:AddSpell( not DefaultAPL:GetVariable('priority_rotation') and Player:GetEnemies(10) >= 2 and RuptureTarget:TimeToDie() >= (2 * Player:GetComboPoints()) and - Refreshable(Rupture, RuptureTarget) + RuptureTarget:GetAuras():FindMy(Rupture):GetRemainingTime() < 6 end ):SetTarget(RuptureTarget) ) @@ -1913,25 +1861,11 @@ StealthedAPL:AddSpell( ):SetTarget(Target) ) ---[[ - double consume_cp_max() const - { - return COMBO_POINT_MAX + as( talent.rogue.deeper_stratagem->effectN( 2 ).base_value() + - talent.outlaw.devious_stratagem->effectN( 2 ).base_value() + - talent.subtlety.secret_stratagem->effectN( 2 ).base_value() ); - } -]] - -function ConsumeCPMax() - return 5 + (DeeperStratagem:IsKnownAndUsable() and 1 or 0) + (DeviousStratagem:IsKnownAndUsable() and 1 or 0) + - (SecretStratagem:IsKnownAndUsable() and 1 or 0) -end - -- actions.stealthed+=/call_action_list,name=finish,if=variable.effective_combo_points>=cp_max_spend StealthedAPL:AddAPL( FinishAPL, function(self) - return DefaultAPL:GetVariable('effective_combo_points') >= ConsumeCPMax() + return DefaultAPL:GetVariable('effective_combo_points') >= Player:GetComboPointsMax() end ) diff --git a/src/APL/APL.lua b/src/APL/APL.lua index 0356ff6..ebb1f4a 100644 --- a/src/APL/APL.lua +++ b/src/APL/APL.lua @@ -1,5 +1,4 @@ -- Create an APL trait for the APL class ----@class APLTrait local APLTrait = {} APLTrait.__index = APLTrait @@ -30,7 +29,6 @@ function APLTrait:__tostring() end -- Create an APL actor for the APL class ----@class APLActor local APLActor = {} APLActor.__index = APLActor @@ -118,7 +116,7 @@ function APLActor:__tostring() end -- APL (Attack priority list) class ----@class APL + local APL = {} APL.__index = APL diff --git a/src/Aura/Aura.lua b/src/Aura/Aura.lua index 7734694..a1ca4e9 100644 --- a/src/Aura/Aura.lua +++ b/src/Aura/Aura.lua @@ -1,7 +1,6 @@ local Tinkr, Bastion = ... -- Create a new Aura class ----@class Aura local Aura = {} function Aura:__index(k) @@ -18,19 +17,6 @@ function Aura:__index(k) return response end --- Equals -function Aura:__eq(other) - if getmetatable(other) == Aura then - return self:GetSpell():GetID() == other:GetSpell():GetID() - end - - if getmetatable(other) == Bastion.Spell then - return self:GetSpell():GetID() == other:GetID() - end - - return false -end - function Aura:__tostring() return "Bastion.__Aura(" .. self:GetSpell():GetID() .. ")" .. " - " .. (self:GetName() or "''") end diff --git a/src/AuraTable/AuraTable.lua b/src/AuraTable/AuraTable.lua index 577208b..893e106 100644 --- a/src/AuraTable/AuraTable.lua +++ b/src/AuraTable/AuraTable.lua @@ -1,7 +1,6 @@ local Tinkr, Bastion = ... -- Create a new AuraTable class ----@class AuraTable local AuraTable = {} AuraTable.__index = AuraTable @@ -197,7 +196,6 @@ function AuraTable:Clear() end -- Check if the unit has a specific aura ----@return Aura function AuraTable:Find(spell) local auras = self:GetUnitAuras() local aurasub = auras[spell:GetID()] @@ -219,7 +217,6 @@ function AuraTable:Find(spell) return Bastion.Aura:New() end ----@return Aura function AuraTable:FindMy(spell) local aurasub = self.playerAuras[spell:GetID()] @@ -241,7 +238,6 @@ function AuraTable:FindMy(spell) end -- Find any ----@return Aura function AuraTable:FindAny(spell) local a = self:Find(spell) if a:IsValid() then diff --git a/src/Cache/Cache.lua b/src/Cache/Cache.lua index d2c75c1..a88f0b0 100644 --- a/src/Cache/Cache.lua +++ b/src/Cache/Cache.lua @@ -1,4 +1,3 @@ ----@class Cache local Cache = {} Cache.__index = Cache diff --git a/src/Cacheable/Cacheable.lua b/src/Cacheable/Cacheable.lua index ab0dfe1..b344814 100644 --- a/src/Cacheable/Cacheable.lua +++ b/src/Cacheable/Cacheable.lua @@ -1,14 +1,10 @@ local Tinkr, Bastion = ... -- Define a Cacheable class ----@class Cacheable local Cacheable = { cache = nil, callback = nil, - value = nil, - __eq = function(self, other) - return self.value.__eq(self.value, other) - end + value = nil } -- On index check the cache to be valid and return the value or reconstruct the value and return it diff --git a/src/Class/Class.lua b/src/Class/Class.lua index a553475..d9c4a97 100644 --- a/src/Class/Class.lua +++ b/src/Class/Class.lua @@ -1,7 +1,6 @@ local Tinkr, Bastion = ... -- Create a new Class class ----@class Class local Class = {} function Class:__index(k) diff --git a/src/ClassMagic/ClassMagic.lua b/src/ClassMagic/ClassMagic.lua index 8b6f747..b4bef57 100644 --- a/src/ClassMagic/ClassMagic.lua +++ b/src/ClassMagic/ClassMagic.lua @@ -1,8 +1,6 @@ ----@class ClassMagic local ClassMagic = {} ClassMagic.__index = ClassMagic ----@return any function ClassMagic:Resolve(Class, key) if Class[key] or Class[key] == false then return Class[key] diff --git a/src/Command/Command.lua b/src/Command/Command.lua index f8c69fb..1341ed9 100644 --- a/src/Command/Command.lua +++ b/src/Command/Command.lua @@ -1,5 +1,5 @@ -- Create a wow command handler class ----@class Command + local Command = {} Command.__index = Command diff --git a/src/EventManager/EventManager.lua b/src/EventManager/EventManager.lua index b880614..28775bc 100644 --- a/src/EventManager/EventManager.lua +++ b/src/EventManager/EventManager.lua @@ -1,5 +1,5 @@ -- Create an EventManager class ----@class EventManager + local EventManager = { events = {}, eventHandlers = {}, diff --git a/ui.lua b/src/GUI/Gui.lua similarity index 69% rename from ui.lua rename to src/GUI/Gui.lua index 0b4acfd..bb94016 100644 --- a/ui.lua +++ b/src/GUI/Gui.lua @@ -1,13 +1,10 @@ local Tinkr, Bastion = ... ---local Common = Tinkr.Common ---local Exports = Tinkr:require('Routine.Modules.Exports') -local Command = Tinkr.Util.Commands:New('rex') ---local OM = Tinkr.Util.ObjectManager + +--local Command = Bastion.Command:New('bastion') --UI Co-ordinates local GUI = { points = {"CENTER"}, } local SETTINGS = { points = {"CENTER"}, } -local ESP = { points = {"CENTER"}, } local BUTTONS = { points = {"CENTER"}, } Tinkr:require('scripts.bastion.libs.LibStub.LibStub', Bastion) @@ -38,28 +35,14 @@ Tinkr:require("scripts.bastion.libs.StdUi.widgets.Tab", Bastion) Tinkr:require("scripts.bastion.libs.StdUi.widgets.Spell", Bastion) Tinkr:require("scripts.bastion.libs.StdUi.widgets.ContextMenu", Bastion) --- Class colours --- Death Knight 0.77 0.12 0.23 Red --- Demon Hunter 0.64 0.19 0.79 Dark Magenta --- Druid 1.00 0.49 0.04 Orange --- Hunter 0.67 0.83 0.45 Green --- Mage 0.25 0.78 0.92 Light Blue --- Monk 0.00 1.00 0.60 Spring Green --- Paladin 0.96 0.55 0.73 Pink --- Priest 1.00 1.00 1.00 White --- Rogue 1.00 0.96 0.41 Yellow --- Shaman 0.00 0.44 0.87 Blue --- Warlock 0.53 0.53 0.93 Purple --- Warrior 0.78 0.61 0.43 Tan - --Initial Frame Setup -function Bastion.setupsettingsframe(config, title, width, height, newr, newg, newb) +function Bastion.settingstemplate(config, title, width, height, newr, newg, newb) local StdUi = LibStub('StdUi'):NewInstance() StdUi.config = { font = { family = 'GameFontNormal', size = 10, - titleSize = 12, + titleSize = 10, effect = 'NONE', strata = 'OVERLAY', color = { @@ -100,7 +83,6 @@ function Bastion.setupsettingsframe(config, title, width, height, newr, newg, ne local settingsframe = StdUi:Window(UIParent, width, height, title) settingsframe:Hide() settingsframe:SetPoint(SETTINGS.points[1], SETTINGS.points[2], SETTINGS.points[3], SETTINGS.points[4], SETTINGS.points[5]) - --settingsframe:SetFont(StdUi.config.font.family,StdUi.config.font.titleSize) StdUi:BuildWindow(settingsframe, config) StdUi:EasyLayout(settingsframe, { padding = { top = 40 } }) settingsframe:SetScript("OnMouseUp", function(self) @@ -109,12 +91,9 @@ function Bastion.setupsettingsframe(config, title, width, height, newr, newg, ne SETTINGS.points = {a, nil, c, d, e} end) - --Main Menu (Settings, Enable Rotation, ESP, Buttons) + --Main Menu (Settings, Enable Rotation, etc) _G.buttons = {} local enabled = false - local espenabled = false - local espunitsenabled = false - local espobjectsenabled = false buttons.aoeenabled = false buttons.buffsenabled = false buttons.cooldownsenabled = false @@ -122,10 +101,9 @@ function Bastion.setupsettingsframe(config, title, width, height, newr, newg, ne buttons.dpsenabled = false buttons.healenabled = false buttons.rotationenabled = false - local mainmenu = StdUi:Window(nil, 150, 310, title) + _G.mainmenu = StdUi:Window(nil, 150, 280, title) mainmenu:Hide() mainmenu:SetPoint(GUI.points[1], GUI.points[2], GUI.points[3], GUI.points[4], GUI.points[5]) - --mainmenu:SetFont(StdUi.config.font.family,StdUi.config.font.titleSize) mainmenu:SetUserPlaced(true) local aoebutton = StdUi:HighlightButton(mainmenu, 130, 20, 'AOE') StdUi:GlueTop(aoebutton, mainmenu, 10, -40, 'LEFT') @@ -141,32 +119,13 @@ function Bastion.setupsettingsframe(config, title, width, height, newr, newg, ne StdUi:GlueTop(healbutton, dpsbutton, 0, -30, 'LEFT') local enablebutton = StdUi:HighlightButton(mainmenu, 130, 20, 'Rotation') StdUi:GlueTop(enablebutton, healbutton, 0, -30, 'LEFT') - local espbutton = StdUi:Button(mainmenu, 130, 20, 'Open ESP') - StdUi:GlueTop(espbutton, enablebutton, 0, -30, 'LEFT') local settingsbutton = StdUi:Button(mainmenu, 130, 20, 'Settings') - StdUi:GlueTop(settingsbutton, espbutton, 0, -30, 'LEFT') + StdUi:GlueTop(settingsbutton, enablebutton, 0, -30, 'LEFT') mainmenu:SetScript("OnMouseUp", function(self) self:StopMovingOrSizing() local a,b,c,d,e = self:GetPoint() GUI.points = {a, nil, c, d, e} end) - --ESP Menu - local espmenu = StdUi:Window(nil, 200, 140, 'ESP Settings') - espmenu:Hide() - espmenu:SetPoint(ESP.points[1], ESP.points[2], ESP.points[3], ESP.points[4], ESP.points[5]) - --espmenu:SetFont(StdUi.config.font.family,StdUi.config.font.titleSize) - espmenu:SetUserPlaced(true) - local enableespcheck = StdUi:Button(espmenu, 180, 20, 'Enable/Disable ESP'); - StdUi:GlueTop(enableespcheck, espmenu, 10, -40, 'LEFT'); - local espunitscheck = StdUi:Button(espmenu, 180, 20, 'Show Units'); - StdUi:GlueTop(espunitscheck, enableespcheck, 0, -30, 'LEFT'); - local espobjectscheck = StdUi:Button(espmenu, 180, 20, 'Show Objects'); - StdUi:GlueTop(espobjectscheck, espunitscheck, 0, -30, 'LEFT'); - espmenu:SetScript("OnMouseUp", function(self) - self:StopMovingOrSizing() - local a,b,c,d,e = self:GetPoint() - ESP.points = {a, nil, c, d, e} - end) --Open/Hide Settings Window OnClick settingsbutton:SetScript('OnClick', function () if settingsframe:IsShown() then @@ -175,48 +134,6 @@ function Bastion.setupsettingsframe(config, title, width, height, newr, newg, ne settingsframe:Show() end end) - --Enable/Disable Rotation OnClick - enablebutton:SetScript('OnClick', function () - if enabled == false then - Eval('RunMacroText("/bastion toggle")', 'bastion') - enabled = true - elseif enabled == true then - Eval('RunMacroText("/bastion toggle")', 'bastion') - enabled = false - end - end) - --Open/Hide ESP Window OnClick - espbutton:SetScript('OnClick', function () - if espmenu:IsShown() then - espmenu:Hide() - else - espmenu:Show() - end - end) - --Enable/Disable ESP Draw OnClick - enableespcheck:SetScript('OnClick', function () - if espenabled == false then - rexesp('enable', nil, nil) - espenabled = true - elseif espenabled == true then - rexesp('disable', nil, nil) - espenabled = false - end - end) - --Enable/Disable ESP Units OnClick - espunitscheck:SetScript('OnClick', function () - if espunitsenabled == false then - rexesp(nil, 'unitenable', nil) - espunitsenabled = true - end - end) - --Enable/Disable ESP Objects OnClick - espobjectscheck:SetScript('OnClick', function () - if espobjectsenabled == false then - rexesp(nil, nil, 'objectenable') - espobjectsenabled = true - end - end) --Enable/Disable AOE Button OnClick aoebutton:SetScript('OnClick', function() if buttons.aoeenabled == false then @@ -289,13 +206,13 @@ function Bastion.setupsettingsframe(config, title, width, height, newr, newg, ne buttons.rotationenabled = false end end) - --Toggle Main Menu - Command:Register({'open'}, function() - if mainmenu:IsShown() then - mainmenu:Hide() - else - mainmenu:Show() - end - end) + -- --Toggle Main Menu + -- Command:Register('interface', 'Opens interface menu', function() + -- if mainmenu:IsShown() then + -- mainmenu:Hide() + -- else + -- mainmenu:Show() + -- end + -- end) end \ No newline at end of file diff --git a/src/Item/Item.lua b/src/Item/Item.lua index 86fc333..205c638 100644 --- a/src/Item/Item.lua +++ b/src/Item/Item.lua @@ -1,7 +1,6 @@ local Tinkr, Bastion = ... -- Create a new Item class ----@class Item local Item = { UsableIfFunc = false, PreUseFunc = false, @@ -30,11 +29,6 @@ function Item:__index(k) return response end --- Equals -function Item:__eq(other) - return self:GetID() == other:GetID() -end - -- tostring function Item:__tostring() return "Bastion.__Item(" .. self:GetID() .. ")" .. " - " .. self:GetName() @@ -176,21 +170,18 @@ function Item:Usable() end -- Set a script to check if the Item is Usable ----@param func fun(self:Item):boolean function Item:UsableIf(func) self.UsableIfFunc = func return self end -- Set a script to run before the Item has been Use ----@param func fun(self:Item) function Item:PreUse(func) self.PreUseFunc = func return self end -- Set a script to run after the Item has been Use ----@param func fun(self:Item) function Item:OnUse(func) self.OnUseFunc = func return self @@ -287,8 +278,6 @@ function Item:GetChargesRemaining() end -- Create a condition for the Item ----@param name string ----@param func fun(self:Item) function Item:Condition(name, func) self.conditions[name] = { func = func diff --git a/src/ItemBook/ItemBook.lua b/src/ItemBook/ItemBook.lua index 34282c3..9b3eebb 100644 --- a/src/ItemBook/ItemBook.lua +++ b/src/ItemBook/ItemBook.lua @@ -1,7 +1,6 @@ local Tinkr, Bastion = ... -- Create a new ItemBook class ----@class ItemBook local ItemBook = {} ItemBook.__index = ItemBook @@ -13,7 +12,6 @@ function ItemBook:New() end -- Get a spell from the ItemBook ----@return Item function ItemBook:GetItem(id) if self.items[id] == nil then self.items[id] = Bastion.Item:New(id) diff --git a/src/List/List.lua b/src/List/List.lua index 95c4f47..bc03ebe 100644 --- a/src/List/List.lua +++ b/src/List/List.lua @@ -1,6 +1,5 @@ local Tinkr, Bastion = ... ----@class List local List = {} List.__index = List diff --git a/src/Module/Module.lua b/src/Module/Module.lua index 5c853dc..6c19d98 100644 --- a/src/Module/Module.lua +++ b/src/Module/Module.lua @@ -1,6 +1,5 @@ -- Create a module class for a bastion module ----@class Module local Module = {} Module.__index = Module diff --git a/src/MythicPlusUtils/MythicPlusUtils.lua b/src/MythicPlusUtils/MythicPlusUtils.lua index 60784dc..4dac63f 100644 --- a/src/MythicPlusUtils/MythicPlusUtils.lua +++ b/src/MythicPlusUtils/MythicPlusUtils.lua @@ -1,6 +1,5 @@ local Tinkr, Bastion = ... ----@class MythicPlusUtils local MythicPlusUtils = { debuffLogging = false, random = '' @@ -13,71 +12,117 @@ function MythicPlusUtils:New() self.random = math.random(1000000, 9999999) self.kickList = { + -- Algeth'ar Academy - [396812] = true, -- https://www.wowhead.com/spell=396812/mystic-blast - [388392] = true, -- https://www.wowhead.com/spell=388392/monotonous-lecture - [388863] = true, -- https://www.wowhead.com/spell=388863/mana-void - [388862] = true, -- https://www.wowhead.com/spell=388862/surge - [377389] = true, -- https://www.wowhead.com/spell=377389/call-of-the-flock - [388623] = true, -- https://www.wowhead.com/spell=388623/branch-out - [396640] = true, -- https://www.wowhead.com/spell=396640/healing-touch - [387975] = true, -- https://www.wowhead.com/spell=387975/arcane-missiles - [387843] = true, -- https://www.wowhead.com/spell=387843/astral-bomb + [388392] = true, -- Monotonous Lecture + [396812] = true, -- Mystic Blast + [377389] = true, -- Call of the Flock + [396640] = true, -- Healing Touch + [387843] = true, -- Astral Bomb + [387955] = true, -- Celestial Shield + [387910] = true, -- Astral Whirlwind + + -- Azure Vault + -- [375602] = true, -- Erratic Growth + [387564] = true, -- Mystic Vapors + -- [386546] = true, -- Waking Bane + [389804] = true, -- Heavy Tome + [377488] = true, -- Icy Bindings + + -- Brackenhide + [382249] = true, -- Earth Bolt + [367500] = true, -- Hideous Cackle + [377950] = true, -- Greater Healing Rapids + [385029] = true, -- Screech + [373804] = true, -- Touch of Decay + [381770] = true, -- Gushing Ooze + [374544] = true, -- Burst of Decay + + -- Halls of Infusion + [374066] = true, -- Earth Shield + [374339] = true, -- Demoralizing Shout + [374045] = true, -- Expulse + [374080] = true, -- Blasting Gust + [389443] = true, -- Purifying Blast + [395694] = true, -- Elemental Focus + [374563] = true, -- Dazzle + [385141] = true, -- Thunderstorm + [374706] = true, -- Pyretic Burst + [375384] = true, -- Rumbling Earth + [375950] = true, -- Ice Shards + [377348] = true, -- Tidal Divergence + [377402] = true, -- Aqueous Barrier + [387618] = true, -- Infuse + + -- Neltharus + [378282] = true, -- Molten Core + [372615] = true, -- Ember Reach + [395427] = true, -- Burning Roar + [372538] = true, -- Melt + [384161] = true, -- Mote of Combustion + [382795] = true, -- Molten Barrier + + -- Nokhud + [384365] = true, -- Disruptive Shout + [386024] = true, -- Tempest + [387411] = true, -- Death Bolt Volley + [387606] = true, -- Dominate + [376725] = true, -- Storm Bolt + [384808] = true, -- Guardian Wind + [383823] = true, -- Rally the Clan (CC to interrupt) + [387135] = true, -- Arcing Strike (CC to interrupt) + [373395] = true, -- Bloodcurdling Shout + + -- Ruby Life Pools + [373017] = true, -- Roaring Blaze + [392398] = true, -- Crackling Detonation + [392451] = true, -- Flashfire + [385310] = true, -- Lightning Bolt + [375602] = true, -- Erratic Growth + -- [386546] = true, -- Waking Bane + -- [387564] = true, -- Mystic Vapors + [373932] = true, -- Illusionary Bolt + [386546] = true, -- Waking Bane + + -- Uldaman + [369675] = true, -- Chain Lightning + [369674] = true, -- Stone Spike + [369823] = true, -- Spiked Carapace + [369603] = true, -- Defensive Bulwark + [369399] = true, -- Stone Bolt + [369400] = true, -- Earthen Ward -- Court of Stars - [211401] = true, -- https://wowhead.com/spell=211401 - [207980] = true, -- https://wowhead.com/spell=207980 - [208165] = true, -- https://wowhead.com/spell=208165 - [207881] = true, -- https://wowhead.com/spell=207881 - [209413] = true, -- https://wowhead.com/spell=209413 + [211401] = true, -- Drifting Embers + [211464] = true, -- Fel Detonation + [207980] = true, -- Disintegration Beam + [208165] = true, -- Withering Soul + [207881] = true, -- Infernal Eruption -- Halls of Valor - [198595] = true, -- https://wowhead.com/spell=198595 - [198959] = true, -- https://wowhead.com/spell=198959 - [215433] = true, -- https://wowhead.com/spell=215433 - [192288] = true, -- https://wowhead.com/spell=192288 - [199726] = true, -- https://wowhead.com/spell=199726 - [198750] = true, -- https://wowhead.com/spell=198750 - - -- Ruby Life Pools - [372749] = true, -- https://wowhead.com/spell=372749 - [373803] = true, -- https://wowhead.com/spell=373803 - [373017] = true, -- https://wowhead.com/spell=373017 - [392398] = true, -- https://wowhead.com/spell=392398 - [392451] = true, -- https://wowhead.com/spell=392451 - [385310] = true, -- https://wowhead.com/spell=385310 + [198595] = true, -- Thunderous Bolt + [198959] = true, -- Etch + [192288] = true, -- Searing Light + [199726] = true, -- Unruly Yell + [198750] = true, -- Surge -- Shadowmoon Burial Grounds - [152818] = true, -- https://wowhead.com/spell=152818 - [156776] = true, -- https://wowhead.com/spell=156776 - [156722] = true, -- https://wowhead.com/spell=156722 - [398206] = true, -- https://wowhead.com/spell=398206 - [153524] = true, -- https://wowhead.com/spell=153524 - [156718] = true, -- https://wowhead.com/spell=156718 + [152818] = true, -- Shadow Mend + [153153] = true, -- Dark Communion (CC to interrupt) + [156776] = true, -- Rending Voidlash + [156722] = true, -- Void Bolt + [398206] = true, -- Death Blast + [156718] = true, -- Necrotic Burst + [153524] = true, -- Plague Spit -- Temple of the Jade Serpent - [397888] = true, -- https://wowhead.com/spell=397888 - [395859] = true, -- https://wowhead.com/spell=395859 - [396073] = true, -- https://wowhead.com/spell=396073 - [397914] = true, -- https://wowhead.com/spell=397914 - - -- The Azure Vault - [375602] = true, -- https://wowhead.com/spell=375602 - [387564] = true, -- https://wowhead.com/spell=387564 - [373932] = true, -- https://wowhead.com/spell=373932 - [386546] = true, -- https://wowhead.com/spell=386546 - [389804] = true, -- https://wowhead.com/spell=389804 - [377488] = true, -- https://wowhead.com/spell=377488 - [377503] = true, -- https://wowhead.com/spell=377503 - - -- NO - [384365] = true, -- https://wowhead.com/spell=384365 - [386012] = true, -- https://wowhead.com/spell=386012 - [386024] = true, -- https://wowhead.com/spell=386024 - [387411] = true, -- https://wowhead.com/spell=387411 - [387606] = true, -- https://wowhead.com/spell=387606 - [373395] = true, -- https://wowhead.com/spell=373395 - [376725] = true, -- https://wowhead.com/spell=376725 + [397888] = true, -- Hydrolance + [114646] = true, -- Haunting Gaze + [395859] = true, -- Haunting Scream + [396073] = true, -- Cat Nap + [397914] = true, -- Defiling Mist + + [315584] = true } Bastion.EventManager:RegisterWoWEvent('UNIT_AURA', function(unit, auras) diff --git a/src/NotificationsList/NotificationsList.lua b/src/NotificationsList/NotificationsList.lua index a2e1a87..7572d07 100644 --- a/src/NotificationsList/NotificationsList.lua +++ b/src/NotificationsList/NotificationsList.lua @@ -1,6 +1,5 @@ -- Create a NotificationsList class ----@class NotificationsList local NotificationsList = { notifications = {} } @@ -12,14 +11,14 @@ function NotificationsList:New() -- Create a frame for the notifications self.frame = CreateFrame("Frame", "BastionNotificationsList", UIParent) - self.frame:SetSize(600, 60) + self.frame:SetSize(300, 100) self.frame:SetPoint("TOP", UIParent, "TOP", 0, -100) self.frame:SetFrameStrata("HIGH") -- Remove notifications after 5 seconds C_Timer.NewTicker(0.1, function() for i, notification in ipairs(self.notifications) do - if GetTime() - notification.addedAt > notification.duration then + if GetTime() - notification.addedAt > 2 then notification:Remove() table.remove(self.notifications, i) end @@ -30,21 +29,18 @@ function NotificationsList:New() end -- Create a notification class for the notifications list (takes icon and text) ----@class Notification local Notification = { } Notification.__index = Notification -- Constructor -function Notification:New(list, icon, text, duration) +function Notification:New(list, icon, text) local self = setmetatable({}, Notification) - if not duration then duration = 2 end - -- Create a frame for the notification self.frame = CreateFrame("Frame", nil, list.frame) - self.frame:SetSize(5, 5) - self.frame:SetPoint("CENTER", list.frame, "CENTER", 0, 0) + self.frame:SetSize(300, 100) + self.frame:SetPoint("TOP", list.frame, "TOP", 0, 0) self.frame:SetFrameStrata("HIGH") -- Create a texture for the icon @@ -54,16 +50,12 @@ function Notification:New(list, icon, text, duration) self.icon:SetTexture(icon) -- Create a fontstring for the text - self.text = self.frame:CreateFontString(nil, "BACKGROUND", "NumberFontNormal") - self.text:SetPoint("LEFT", self.frame, "LEFT", 32 + 16, 0) + self.text = self.frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal") + self.text:SetPoint("CENTER", self.frame, "CENTER", 10, 0) self.text:SetText(text) - self.text:SetFont("Fonts\\OpenSans-Bold.ttf", 18) - - -- set the frame size to the size of the text + icon - self.frame:SetSize(self.text:GetStringWidth() + 32 + 16, 32) + self.text:SetFont("Fonts\\FRIZQT__.TTF", 14) self.addedAt = GetTime() - self.duration = duration self.list = list return self @@ -83,9 +75,9 @@ function Notification:Remove() end -- Add a notification to the list -function NotificationsList:AddNotification(icon, text, duration) +function NotificationsList:AddNotification(icon, text) -- Create a new notification - local notification = Notification:New(self, icon, text, duration) + local notification = Notification:New(self, icon, text) -- Add the notification to the list table.insert(self.notifications, notification) @@ -100,7 +92,7 @@ function NotificationsList:Update() -- Loop through the notifications for i, notification in ipairs(self.notifications) do -- Set the position of the notification - notification.frame:SetPoint("CENTER", self.frame, "CENTER", 0, -42 * (i - 1)) + notification.frame:SetPoint("TOP", self.frame, "TOP", 0, -50 * (i - 1)) end end diff --git a/src/ObjectManager/ObjectManager.lua b/src/ObjectManager/ObjectManager.lua index 7855cc8..d90b561 100644 --- a/src/ObjectManager/ObjectManager.lua +++ b/src/ObjectManager/ObjectManager.lua @@ -1,6 +1,5 @@ local Tinkr, Bastion = ... ----@class ObjectManager local ObjectManager = {} ObjectManager.__index = ObjectManager diff --git a/src/Refreshable/Refreshable.lua b/src/Refreshable/Refreshable.lua index 3d2616b..1018c1c 100644 --- a/src/Refreshable/Refreshable.lua +++ b/src/Refreshable/Refreshable.lua @@ -1,14 +1,10 @@ local Tinkr, Bastion = ... -- Define a Refreshable class ----@class Refreshable local Refreshable = { cache = nil, callback = nil, - value = nil, - __eq = function(self, other) - return self.value.__eq(self.value, other) - end + value = nil } -- On index check the cache to be valid and return the value or reconstruct the value and return it diff --git a/src/Spell/Spell.lua b/src/Spell/Spell.lua index 86f0d3a..a474928 100644 --- a/src/Spell/Spell.lua +++ b/src/Spell/Spell.lua @@ -1,7 +1,6 @@ local Tinkr, Bastion = ... -- Create a new Spell class ----@class Spell local Spell = { CastableIfFunc = false, PreCastFunc = false, @@ -31,11 +30,6 @@ function Spell:__index(k) return response end --- Equals -function Spell:__eq(other) - return self:GetID() == other:GetID() -end - -- tostring function Spell:__tostring() return "Bastion.__Spell(" .. self:GetID() .. ")" .. " - " .. self:GetName() @@ -56,7 +50,6 @@ function Spell:GetID() end -- Add post cast func ----@param func fun(self:Spell) function Spell:PostCast(func) self.PostCastFunc = func return self @@ -180,21 +173,18 @@ function Spell:Castable() end -- Set a script to check if the spell is castable ----@param func fun(spell:Spell):boolean function Spell:CastableIf(func) self.CastableIfFunc = func return self end -- Set a script to run before the spell has been cast ----@param func fun(spell:Spell) function Spell:PreCast(func) self.PreCastFunc = func return self end -- Set a script to run after the spell has been cast ----@param func fun(spell:Spell) function Spell:OnCast(func) self.OnCastFunc = func return self diff --git a/src/SpellBook/SpellBook.lua b/src/SpellBook/SpellBook.lua index 952596f..b06f69f 100644 --- a/src/SpellBook/SpellBook.lua +++ b/src/SpellBook/SpellBook.lua @@ -1,12 +1,10 @@ local Tinkr, Bastion = ... -- Create a new SpellBook class ----@class SpellBook local SpellBook = {} SpellBook.__index = SpellBook -- Constructor ----@return SpellBook function SpellBook:New() local self = setmetatable({}, SpellBook) self.spells = {} @@ -14,7 +12,6 @@ function SpellBook:New() end -- Get a spell from the spellbook ----@return Spell function SpellBook:GetSpell(id) if self.spells[id] == nil then self.spells[id] = Bastion.Spell:New(id) @@ -23,7 +20,6 @@ function SpellBook:GetSpell(id) return self.spells[id] end ----@return Spell function SpellBook:GetIfRegistered(id) return self.spells[id] end diff --git a/src/Timer/Timer.lua b/src/Timer/Timer.lua index 15adcc9..14ec866 100644 --- a/src/Timer/Timer.lua +++ b/src/Timer/Timer.lua @@ -1,7 +1,6 @@ local Tinkr, Bastion = ... -- Create a new Timer class ----@class Timer local Timer = { startTime = nil, resetAfterCombat = false, diff --git a/src/Unit/Unit.lua b/src/Unit/Unit.lua index 63ada7f..d60328f 100644 --- a/src/Unit/Unit.lua +++ b/src/Unit/Unit.lua @@ -1,12 +1,9 @@ local Tinkr, Bastion = ... -- Create a new Unit class ----@class Unit local Unit = { cache = nil, - ---@type AuraTable aura_table = nil, - ---@type Unit unit = nil, last_shadow_techniques = 0, swings_since_sht = 0, @@ -28,11 +25,6 @@ function Unit:__index(k) return response end --- Equals -function Unit:__eq(other) - return UnitIsUnit(self.unit, other.unit) -end - -- tostring function Unit:__tostring() return "Bastion.__Unit(" .. tostring(self.unit) .. ")" .. " - " .. (self:GetName() or '') @@ -224,7 +216,12 @@ end -- Get if the unit is affecting combat function Unit:IsAffectingCombat() - return UnitAffectingCombat(self.unit) + return UnitAffectingCombat('player', self.unit) +end + +-- Is the unit indoors +function Unit:IsIndoors() + return IsIndoors() end -- Get the units class id @@ -234,7 +231,6 @@ function Unit:GetClass() end -- Get the units auras ----@return AuraTable function Unit:GetAuras() return self.aura_table end @@ -678,7 +674,7 @@ function Unit:IsStealthed() local Sepsis = Bastion.SpellBook:GetSpell(328305) - return self:GetAuras():FindAny(Stealth) or self:GetAuras():FindAny(ShadowDance) + return self:GetAuras():FindAny(Stealth) or self:GetAuras():FindAny(ShadowDance) end -- Get unit swing timers diff --git a/src/UnitManager/UnitManager.lua b/src/UnitManager/UnitManager.lua index c6a3ea0..53a6b54 100644 --- a/src/UnitManager/UnitManager.lua +++ b/src/UnitManager/UnitManager.lua @@ -48,7 +48,6 @@ local function Validate(token) end -- Create a new UnitManager class ----@class UnitManager local UnitManager = { units = {}, customUnits = {}, @@ -109,7 +108,6 @@ function UnitManager:Validate(token) end -- Get or create a unit ----@return Unit function UnitManager:Get(token) -- if not Validate(token) then -- error("UnitManager:Get - Invalid token: " .. token) @@ -147,9 +145,6 @@ function UnitManager:SetObject(unit) end -- Create a custom unit and cache it for .5 seconds ----@param token string ----@param cb fun():Unit ----@return Unit function UnitManager:CreateCustomUnit(token, cb) local unit = cb() local cachedUnit = Bastion.Cacheable:New(unit, cb) @@ -180,7 +175,6 @@ function UnitManager:EnumFriends(cb) end -- Enum Enemies (object manager) ----@param cb fun(unit: Unit):boolean function UnitManager:EnumEnemies(cb) Bastion.ObjectManager.activeEnemies:each(function(unit) if cb(unit) then diff --git a/src/Vector3/Vector3.lua b/src/Vector3/Vector3.lua index 0aaabf8..406d9be 100644 --- a/src/Vector3/Vector3.lua +++ b/src/Vector3/Vector3.lua @@ -1,6 +1,5 @@ -- Create a Vector3 class ----@class Vector3 local Vector3 = {} Vector3.__index = Vector3 diff --git a/src/_bastion.lua b/src/_bastion.lua index 955230e..b9a5e71 100644 --- a/src/_bastion.lua +++ b/src/_bastion.lua @@ -1,6 +1,5 @@ local Tinkr = ... ----@class Bastion local Bastion = { DebugMode = false } @@ -10,54 +9,31 @@ function Bastion.require(class) return Tinkr:require("scripts/bastion/src/" .. class .. "/" .. class, Bastion) end ----@type ClassMagic Bastion.ClassMagic = Bastion.require("ClassMagic") ----@type List Bastion.List = Bastion.require("List") ----@type NotificationsList, Notification Bastion.NotificationsList, Bastion.Notification = Bastion.require("NotificationsList") ----@type Vector3 Bastion.Vector3 = Bastion.require("Vector3") ----@type 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.Gui = Bastion.require("Gui") Bastion.CombatTimer = Bastion.Timer:New('combat') ----@type MythicPlusUtils Bastion.MythicPlusUtils = Bastion.require("MythicPlusUtils"):New() ----@type NotificationsList Bastion.Notifications = Bastion.NotificationsList:New() Bastion.modules = {} @@ -202,11 +178,28 @@ Command:Register('mplus', 'Toggle m+ module on/off', function(args) Bastion:Print("debuffs") end) -local files = ListFiles("scripts/bastion/scripts") - -for i = 1, #files do - local file = files[i] - if file:sub(-4) == ".lua" or file:sub(-5) == '.luac' then - Tinkr:require("scripts/bastion/scripts/" .. file:sub(1, -5), Bastion) +--Toggle Main Menu +Command:Register('interface', 'Opens interface menu', function() + if mainmenu:IsShown() then + mainmenu:Hide() + else + mainmenu:Show() end -end + end) + +-- local files = ListFiles("scripts/bastion/scripts") + +-- for i = 1, #files do +-- local file = files[i] +-- if file:sub(-4) == ".lua" or file:sub(-5) == '.luac' then +-- Tinkr:require("scripts/bastion/scripts/" .. file:sub(1, -5), Bastion) +-- end +-- end + +if UnitClass('player') == 'Priest' and GetSpecialization() == 3 then + Tinkr:require("scripts/bastion/scripts/shadowpriest", Bastion) + Eval('RunMacroText("/bastion module shadow")', 'bastion') +elseif UnitClass('player') == 'Druid' and GetSpecialization() == 4 then + Tinkr:require("scripts/bastion/scripts/restodruid", Bastion) + Eval('RunMacroText("/bastion module resto_druid")', 'bastion') +end \ No newline at end of file