From 0db6aad180f1c63a60a8063a01873efb3ba2c86d Mon Sep 17 00:00:00 2001 From: 4n0n <4n0n@tinkr.site> Date: Mon, 6 Feb 2023 21:05:13 -0600 Subject: [PATCH] Add basic damage apl to resto, update subtlety to better handle variables --- scripts/restodruid.lua | 163 ++++++++++++++++++++++++++++---- scripts/subtlety.lua | 108 +++++++++++++++------ src/Unit/Unit.lua | 5 + src/UnitManager/UnitManager.lua | 2 +- 4 files changed, 230 insertions(+), 48 deletions(-) diff --git a/scripts/restodruid.lua b/scripts/restodruid.lua index 58fcc15..c5c2954 100644 --- a/scripts/restodruid.lua +++ b/scripts/restodruid.lua @@ -107,6 +107,8 @@ local RakeAura = Bastion.SpellBook:GetSpell(155722) local Starsurge = Bastion.SpellBook:GetSpell(197626) local NaturesVigil = Bastion.SpellBook:GetSpell(124974) local SpringBlossoms = Bastion.SpellBook:GetSpell(207386) +local RakeDebuff = Bastion.SpellBook:GetSpell(155722) + local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit) local lowest = nil @@ -385,6 +387,104 @@ local Explosive = Bastion.UnitManager:CreateCustomUnit('explosive', function(uni return explosive end) +local RakeTarget = Bastion.UnitManager:CreateCustomUnit('rake', function(unit) + local rakeTarget = nil + + Bastion.UnitManager:EnumEnemies(function(unit) + if unit:IsDead() then + return false + end + + if not Player:CanSee(unit) then + return false + end + + if Player:GetDistance(unit) > 40 then + return false + end + + if not unit:IsDead() and Player:CanSee(unit) and unit:InCombatOdds() > 80 and unit:InMelee(Player) and + Player:IsFacing(unit) and + ( + not unit:GetAuras():FindMy(RakeDebuff):IsUp() or + unit:GetAuras():FindMy(RakeDebuff):GetRemainingTime() <= 3.6) then + rakeTarget = unit + end + + end) + + + if rakeTarget == nil then + rakeTarget = None + end + + return rakeTarget +end) + +local MoonfireTarget = Bastion.UnitManager:CreateCustomUnit('moonfire', function(unit) + local moonfireTarget = nil + + Bastion.UnitManager:EnumEnemies(function(unit) + if unit:IsDead() then + return false + end + + if not Player:CanSee(unit) then + return false + end + + if Player:GetDistance(unit) > 40 then + return false + end + + if not unit:IsDead() and Player:CanSee(unit) and unit:InCombatOdds() > 80 and + ( + not unit:GetAuras():FindMy(MoonfireAura):IsUp() or + unit:GetAuras():FindMy(MoonfireAura):GetRemainingTime() <= 3.6) then + moonfireTarget = unit + end + + end) + + if moonfireTarget == nil then + moonfireTarget = None + end + + return moonfireTarget +end) + +local SunfireTarget = Bastion.UnitManager:CreateCustomUnit('sunfire', function(unit) + local sunfireTarget = nil + + Bastion.UnitManager:EnumEnemies(function(unit) + if unit:IsDead() then + return false + end + + if not Player:CanSee(unit) then + return false + end + + if Player:GetDistance(unit) > 40 then + return false + end + + if not unit:IsDead() and Player:CanSee(unit) and unit:InCombatOdds() > 80 and + ( + not unit:GetAuras():FindMy(SunfireAura):IsUp() or + unit:GetAuras():FindMy(SunfireAura):GetRemainingTime() <= 3.6) then + sunfireTarget = unit + end + + end) + + if sunfireTarget == nil then + sunfireTarget = None + end + + return sunfireTarget +end) + local RestoCommands = Bastion.Command:New('resto') local PLACE_EFFLO = false @@ -397,6 +497,29 @@ end) local DefaultAPL = Bastion.APL:New('default') local DamageAPL = Bastion.APL:New('damage') +DamageAPL:AddSpell( + Rake:CastableIf(function(self) + return RakeTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and + ( + not RakeTarget:GetAuras():FindMy(RakeDebuff):IsUp() or + RakeTarget:GetAuras():FindMy(RakeDebuff):GetRemainingTime() <= 3.6) + end):SetTarget(RakeTarget) +) + +DamageAPL:AddSpell( + FerociousBite:CastableIf(function(self) + return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and + Player:GetComboPoints() >= 5 + end):SetTarget(Target) +) + +DamageAPL:AddSpell( + Shred:CastableIf(function(self) + return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and + Player:GetComboPoints() < 5 + end):SetTarget(Target) +) + DefaultAPL:AddSpell( Moonfire:CastableIf(function(self) return Explosive:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() @@ -413,12 +536,20 @@ DefaultAPL:AddSpell( end) ) +CatForm:OnCast(function(self) + if not Player:GetAuras():FindMy(Prowl):IsUp() and not Player:IsAffectingCombat() then + Prowl:Cast(Player) + end +end) + DefaultAPL:AddAction( 'cat_form_shift', function() - if IsShiftKeyDown() and not Player:GetAuras():FindMy(CatForm):IsUp() and not Player:IsCastingOrChanneling() then + if (IsShiftKeyDown() or not Player:IsAffectingCombat()) and not Player:IsMounted() 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 + elseif (not IsShiftKeyDown() and Player:IsAffectingCombat()) and Player:GetAuras():FindMy(CatForm):IsUp() then CancelShapeshiftForm() end end @@ -585,26 +716,26 @@ DefaultAPL:AddSpell( DefaultAPL:AddSpell( Sunfire:CastableIf(function(self) - return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() - and Player:CanSee(Target) and + return SunfireTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + and Player:CanSee(SunfireTarget) 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) + not SunfireTarget:GetAuras():FindMy(SunfireAura):IsUp() or + SunfireTarget:GetAuras():FindMy(SunfireAura):GetRemainingTime() <= 5.4) and + SunfireTarget:IsHostile() and + SunfireTarget:IsAffectingCombat() and Player:GetPP() >= 25 + end):SetTarget(SunfireTarget) ) DefaultAPL:AddSpell( Moonfire:CastableIf(function(self) - return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() - and Player:CanSee(Target) and + return MoonfireTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + and Player:CanSee(MoonfireTarget) 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 MoonfireTarget:GetAuras():FindMy(MoonfireAura):IsUp() or + MoonfireTarget:GetAuras():FindMy(MoonfireAura):GetRemainingTime() <= 5.4) and + MoonfireTarget:IsHostile() and + MoonfireTarget:IsAffectingCombat() and Player:GetPP() >= 25 + end):SetTarget(MoonfireTarget) ) DefaultAPL:AddSpell( diff --git a/scripts/subtlety.lua b/scripts/subtlety.lua index 770186c..640c1f5 100644 --- a/scripts/subtlety.lua +++ b/scripts/subtlety.lua @@ -992,8 +992,6 @@ local RuptureTarget = Bastion.UnitManager:CreateCustomUnit('rupture', function() end) local function GetRimeDuration(topCard) - -- // card order is [ 2 3 4 5 6 7 8 A ] - if topCard == RimeCards.Two then return 0 elseif topCard == RimeCards.Three then @@ -1248,6 +1246,52 @@ DefaultAPL:AddVariable( -- # Account for ShT reaction time by ignoring low-CP animacharged matches in the 0.5s preceeding a potential ShT proc -- actions+=/variable,name=effective_combo_points,value=effective_combo_points +-- DefaultAPL:AddVariable( +-- 'effective_combo_points', +-- function() +-- local cur = Player:GetComboPoints() or 0 +-- if not EchoingReprimand:IsKnown() then +-- return cur +-- end + +-- if cur < 2 or cur > 5 then +-- return cur +-- end + +-- if Player:GetAuras():FindMy(EchoingReprimand):IsUp() or Player:GetAuras():FindMy(EchoingReprimand2):IsUp() or +-- Player:GetAuras():FindMy(EchoingReprimand3):IsUp() or +-- Player:GetAuras():FindMy(EchoingReprimand4):IsUp() or +-- Player:GetAuras():FindMy(EchoingReprimand5):IsUp() +-- then +-- return 7 +-- end + +-- return cur +-- end +-- ) + +-- -- actions+=/variable,name=effective_combo_points,if=talent.echoing_reprimand.enabled&effective_combo_points>combo_points&combo_points.deficit>2&time_to_sht.4.plus<0.5&!variable.is_next_cp_animacharged,value=combo_points +-- DefaultAPL:AddVariable( +-- 'effective_combo_points', +-- function() +-- if not EchoingReprimand:IsKnown() then +-- return 0 +-- end + +-- local cur = Player:GetComboPoints() or 0 +-- local deficit = Player:GetComboPointsDeficit() or 0 + +-- if cur > Player:GetComboPoints() and deficit > 2 and +-- Player:GetAuras():FindMy(EchoingReprimand4):GetRemainingTime() < 0.5 and +-- not DefaultAPL:GetVariable('is_next_cp_animacharged') +-- then +-- return cur +-- end + +-- return 0 +-- end +-- ) + DefaultAPL:AddVariable( 'effective_combo_points', function() @@ -1268,14 +1312,6 @@ DefaultAPL:AddVariable( return 7 end - return cur - end -) - --- actions+=/variable,name=effective_combo_points,if=talent.echoing_reprimand.enabled&effective_combo_points>combo_points&combo_points.deficit>2&time_to_sht.4.plus<0.5&!variable.is_next_cp_animacharged,value=combo_points -DefaultAPL:AddVariable( - 'effective_combo_points', - function() if not EchoingReprimand:IsKnown() then return 0 end @@ -1290,10 +1326,10 @@ DefaultAPL:AddVariable( return cur end - return 0 + -- return 0 + return cur end ) - -- # Check CDs at first -- actions+=/call_action_list,name=cds DefaultAPL:AddAPL( @@ -1995,31 +2031,41 @@ StealthCDsAPL:AddSpell( -- # CP thresholds for entering Shadow Dance Default to start dance with 0 or 1 combo point -- actions.stealth_cds+=/variable,name=shd_combo_points,value=combo_points<=1 -StealthCDsAPL:AddVariable( - 'shd_combo_points', - function(self) - return Player:GetComboPoints() <= 1 - end -) +-- StealthCDsAPL:AddVariable( +-- 'shd_combo_points', +-- function(self) +-- return Player:GetComboPoints() <= 1 +-- end +-- ) + +-- -- # Use stealth cooldowns with high combo points when playing shuriken tornado or with high target counts +-- -- actions.stealth_cds+=/variable,name=shd_combo_points,value=combo_points.deficit<=1,if=spell_targets.shuriken_storm>(4-2*talent.shuriken_tornado.enabled)|variable.priority_rotation&spell_targets.shuriken_storm>=4 +-- StealthCDsAPL:AddVariable( +-- 'shd_combo_points', +-- function(self) +-- return Player:GetComboPointsDeficit() <= 1 and +-- ((Player:GetEnemies(10) > (4 - 2 * (ShurikenTornado:IsKnown() and 1 or 0))) or +-- (DefaultAPL:GetVariable('priority_rotation') and +-- Player:GetEnemies(10) >= 4)) +-- end +-- ) + +-- -- # Use stealth cooldowns on any combo point on 4 targets +-- -- actions.stealth_cds+=/variable,name=shd_combo_points,value=1,if=spell_targets.shuriken_storm=(4-talent.seal_fate) +-- StealthCDsAPL:AddVariable( +-- 'shd_combo_points', +-- function(self) +-- return Player:GetEnemies(10) == (4 - (SealFate:IsKnown() and 1 or 0)) +-- end +-- ) --- # Use stealth cooldowns with high combo points when playing shuriken tornado or with high target counts --- actions.stealth_cds+=/variable,name=shd_combo_points,value=combo_points.deficit<=1,if=spell_targets.shuriken_storm>(4-2*talent.shuriken_tornado.enabled)|variable.priority_rotation&spell_targets.shuriken_storm>=4 StealthCDsAPL:AddVariable( 'shd_combo_points', function(self) - return Player:GetComboPointsDeficit() <= 1 and + return (Player:GetComboPoints() <= 1) or (Player:GetComboPointsDeficit() <= 1 and ((Player:GetEnemies(10) > (4 - 2 * (ShurikenTornado:IsKnown() and 1 or 0))) or (DefaultAPL:GetVariable('priority_rotation') and - Player:GetEnemies(10) >= 4)) - end -) - --- # Use stealth cooldowns on any combo point on 4 targets --- actions.stealth_cds+=/variable,name=shd_combo_points,value=1,if=spell_targets.shuriken_storm=(4-talent.seal_fate) -StealthCDsAPL:AddVariable( - 'shd_combo_points', - function(self) - return Player:GetEnemies(10) == (4 - (SealFate:IsKnown() and 1 or 0)) + Player:GetEnemies(10) >= 4))) or (Player:GetEnemies(10) == (4 - (SealFate:IsKnown() and 1 or 0))) end ) diff --git a/src/Unit/Unit.lua b/src/Unit/Unit.lua index 9e8ddf4..256c078 100644 --- a/src/Unit/Unit.lua +++ b/src/Unit/Unit.lua @@ -41,6 +41,11 @@ function Unit:__eq(other) end -- tostring +---ToString +--- +---```lua +---print(Unit:New('player')) +---``` ---@return string function Unit:__tostring() return "Bastion.__Unit(" .. tostring(self:GetOMToken()) .. ")" .. " - " .. (self:GetName() or '') diff --git a/src/UnitManager/UnitManager.lua b/src/UnitManager/UnitManager.lua index 7c6f239..059fd92 100644 --- a/src/UnitManager/UnitManager.lua +++ b/src/UnitManager/UnitManager.lua @@ -182,7 +182,7 @@ function UnitManager:CreateCustomUnit(token, cb) return cachedUnit end --- Enum Friends (party/raid members) +---@description Enumerates all friendly units in the battlefield ---@param cb fun(unit: Unit):boolean ---@return nil function UnitManager:EnumFriends(cb)