From de8943105a6e318cc46168cf3d8a9ea61a8526f2 Mon Sep 17 00:00:00 2001 From: Emlembow <36314674+Emlembow@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:08:38 -0700 Subject: [PATCH] 8/10 Good enough --- MistweaverMonk.lua | 160 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 151 insertions(+), 9 deletions(-) diff --git a/MistweaverMonk.lua b/MistweaverMonk.lua index 042910f..d79b4fd 100644 --- a/MistweaverMonk.lua +++ b/MistweaverMonk.lua @@ -23,15 +23,22 @@ local Restoral = SpellBook:GetSpell(388615) local InvokeYulon = SpellBook:GetSpell(322118) local InvokeChiJi = SpellBook:GetSpell(325197) local SoothingMist = SpellBook:GetSpell(115175) -local ManaTea = SpellBook:GetSpell(197908) +local ManaTea = SpellBook:GetSpell(115294) local CelestialConduit = SpellBook:GetSpell(443028) +local UnityWithin = SpellBook:GetSpell(443591) local FortifyingBrew = SpellBook:GetSpell(243435) local DiffuseMagic = SpellBook:GetSpell(122783) local LifeCocoon = SpellBook:GetSpell(116849) local JadefireStomp = SpellBook:GetSpell(388193) local SheilunsGift = SpellBook:GetSpell(399491) +local TouchOfDeath = SpellBook:GetSpell(322109) +local SpearHandStrike = SpellBook:GetSpell(116705) +local LegSweep = SpellBook:GetSpell(119381) +-- Add Rising Mist spell +local RisingMist = SpellBook:GetSpell(274909) + -- Buffs local TeachingsOfTheMonastery = SpellBook:GetSpell(202090) local StrengthOfTheBlackOx = SpellBook:GetSpell(392883) @@ -56,11 +63,31 @@ local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit) return lowest or Player end) +-- Create a custom unit for finding a Touch of Death target +local TouchOfDeathTarget = Bastion.UnitManager:CreateCustomUnit('touchofdeath', function(unit) + local todTarget = nil + + Bastion.UnitManager:EnumEnemies(function(unit) + if unit:IsDead() or Player:GetDistance(unit) > 5 or not Player:CanSee(unit) then + return false + end + + -- Check if unit is eligible for Touch of Death + if unit:GetHP() <= Player:GetMaxHealth() * 0.15 or Player:GetHP() > unit:GetMaxHealth() then + todTarget = unit + return true + end + end) + + return todTarget or Bastion.UnitManager:Get('none') +end) + -- APLs local DefaultAPL = Bastion.APL:New('default') local CooldownAPL = Bastion.APL:New('cooldown') local DefensiveAPL = Bastion.APL:New('defensive') local DpsAPL = Bastion.APL:New('dps') +local InterruptAPL = Bastion.APL:New('interrupt') -- Helper Functions local function ShouldUseRenewingMist() @@ -75,6 +102,59 @@ local function NeedsUrgentHealing() return Lowest:GetHP() < 70 or Player:GetPartyHPAround(30, 80) >= 3 end +-- Add this helper function near the top of the file, after the SpellBook initialization +local function GetPlayerManaPercent() + return (UnitPower("player", Enum.PowerType.Mana) / UnitPowerMax("player", Enum.PowerType.Mana)) * 100 +end + +-- Add a variable to track Mana Tea stacks +local manaTea = SpellBook:GetSpell(115294) +local manaTeaStacks = 0 + +-- Add a function to update Mana Tea stacks +local function UpdateManaTeaStacks() + manaTeaStacks = Player:GetAuras():FindMy(manaTea):GetCount() +end + +-- Add this helper function near the top of the file +local function GetRandomInterruptDelay() + return math.random(50, 90) +end + +-- Add this near the top of the file, after the SpellBook initialization +local interruptThresholds = {} + +-- Modify the Interrupt APL +InterruptAPL:AddSpell( + SpearHandStrike:CastableIf(function(self) + if not self:IsKnownAndUsable() or not Target:IsCasting() or not Target:IsInterruptible() or not Player:IsWithinCombatDistance(Target, 5) then + return false + end + + local spellName, _, _, startTimeMS, endTimeMS = UnitCastingInfo(Target:GetOMToken()) + if not spellName then return false end + + local castDuration = (endTimeMS - startTimeMS) / 1000 + local currentCastTime = (GetTime() * 1000 - startTimeMS) / 1000 + local castPercentage = (currentCastTime / castDuration) * 100 + + -- Generate a random interrupt threshold if it doesn't exist + if not interruptThresholds[self:GetID()] then + interruptThresholds[self:GetID()] = GetRandomInterruptDelay() + end + + -- Check if the cast percentage is at or above the threshold + if castPercentage >= interruptThresholds[self:GetID()] then + return true + end + + return false + end):SetTarget(Target):OnCast(function(self) + -- Reset the interrupt threshold after successful interrupt + interruptThresholds[self:GetID()] = nil + end) +) + -- Default APL DefaultAPL:AddSpell( SheilunsGift:CastableIf(function(self) @@ -98,7 +178,17 @@ DefaultAPL:AddSpell( DefaultAPL:AddSpell( RisingSunKick:CastableIf(function(self) return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() - end):SetTarget(Target) + end):SetTarget(Target):OnCast(function() + -- Trigger Rising Mist effect + if RisingMist:IsKnown() then + Bastion.UnitManager:EnumFriends(function(unit) + local renewingMist = unit:GetAuras():FindMy(RenewingMist) + if renewingMist:IsUp() then + renewingMist:Refresh() + end + end) + end + end) ) DefaultAPL:AddSpell( @@ -109,7 +199,9 @@ DefaultAPL:AddSpell( DefaultAPL:AddSpell( EnvelopingMist:CastableIf(function(self) - return Lowest:Exists() and ShouldUseEnvelopingMist() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + return Lowest:Exists() and ShouldUseEnvelopingMist() and self:IsKnownAndUsable() + and not Player:IsCastingOrChanneling() + and (Player:GetAuras():FindMy(ManaTea):IsUp() or GetPlayerManaPercent() > 30) end):SetTarget(Lowest) ) @@ -143,8 +235,21 @@ CooldownAPL:AddSpell( CooldownAPL:AddSpell( ManaTea:CastableIf(function(self) + UpdateManaTeaStacks() return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() - and Player:GetMana() < 50 + and (GetPlayerManaPercent() < 50 or manaTeaStacks >= 18 or Player:GetEnemies(8) >= 3) + end):SetTarget(Player):OnCast(function() + -- Cast an Enveloping Mist immediately after Mana Tea + if EnvelopingMist:IsKnownAndUsable() and Lowest:Exists() then + EnvelopingMist:Cast(Lowest) + end + end) +) + +-- Add Unity Within to the CooldownAPL +CooldownAPL:AddSpell( + UnityWithin:CastableIf(function(self) + return self:IsKnownAndUsable() end):SetTarget(Player) ) @@ -213,7 +318,32 @@ DpsAPL:AddSpell( end):SetTarget(Player) ) +DpsAPL:AddSpell( + TouchOfDeath:CastableIf(function(self) + return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + and TouchOfDeathTarget:Exists() + end):SetTarget(TouchOfDeathTarget) +) +-- Add Celestial Conduit to the CooldownAPL +CooldownAPL:AddSpell( + CelestialConduit:CastableIf(function(self) + return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() + and Player:GetPartyHPAround(20, 80) >= 3 -- Use when 3 or more party members within 20 yards are below 80% HP + and Player:GetEnemies(20) >= 2 -- Ensure there are at least 2 enemies within 20 yards for increased effectiveness + end):SetTarget(Player):OnCast(function() + -- Logic to handle the channeling of Celestial Conduit + C_Timer.NewTicker(0.5, function() + if not Player:IsCastingOrChanneling() then return end + -- Continue DPS rotation while channeling + if RisingSunKick:IsKnownAndUsable() and Player:IsWithinCombatDistance(Target, 5) then + RisingSunKick:Cast(Target) + elseif BlackoutKick:IsKnownAndUsable() and Player:IsWithinCombatDistance(Target, 5) then + BlackoutKick:Cast(Target) + end + end, 8) -- 8 ticks over 4 seconds + end) +) -- Module Sync RestoMonkModule:Sync(function() @@ -222,16 +352,29 @@ RestoMonkModule:Sync(function() end if Player:IsAffectingCombat() then + UpdateManaTeaStacks() + if manaTeaStacks >= 19 then + ManaTea:Cast(Player) + end + + InterruptAPL:Execute() DefensiveAPL:Execute() - -- Prioritize DPS in Mythic+, but still maintain healing - if NeedsUrgentHealing() then + -- Prioritize Unity Within + if UnityWithin:IsKnownAndUsable() then + UnityWithin:Cast(Player) + elseif TouchOfDeath:IsKnownAndUsable() and TouchOfDeathTarget:Exists() then + TouchOfDeath:Cast(TouchOfDeathTarget) + elseif CelestialConduit:IsKnownAndUsable() and Player:GetPartyHPAround(20, 80) >= 3 and Player:GetEnemies(20) >= 2 then + CelestialConduit:Cast(Player) + elseif RisingMist:IsKnown() and RisingSunKick:IsKnownAndUsable() then + RisingSunKick:Cast(Target) + elseif NeedsUrgentHealing() then CooldownAPL:Execute() DefaultAPL:Execute() else DpsAPL:Execute() - -- Weave in essential healing abilities if RenewingMist:GetCharges() >= 2 then RenewingMist:Cast(Lowest) end @@ -241,8 +384,7 @@ RestoMonkModule:Sync(function() end end else - -- Out of combat logic - if Lowest:GetHP() < 90 then + if not Player:IsMounted() and Lowest:GetHP() < 90 then DefaultAPL:Execute() end end