|
|
@ -23,15 +23,22 @@ local Restoral = SpellBook:GetSpell(388615) |
|
|
|
local InvokeYulon = SpellBook:GetSpell(322118) |
|
|
|
local InvokeYulon = SpellBook:GetSpell(322118) |
|
|
|
local InvokeChiJi = SpellBook:GetSpell(325197) |
|
|
|
local InvokeChiJi = SpellBook:GetSpell(325197) |
|
|
|
local SoothingMist = SpellBook:GetSpell(115175) |
|
|
|
local SoothingMist = SpellBook:GetSpell(115175) |
|
|
|
local ManaTea = SpellBook:GetSpell(197908) |
|
|
|
local ManaTea = SpellBook:GetSpell(115294) |
|
|
|
local CelestialConduit = SpellBook:GetSpell(443028) |
|
|
|
local CelestialConduit = SpellBook:GetSpell(443028) |
|
|
|
|
|
|
|
local UnityWithin = SpellBook:GetSpell(443591) |
|
|
|
local FortifyingBrew = SpellBook:GetSpell(243435) |
|
|
|
local FortifyingBrew = SpellBook:GetSpell(243435) |
|
|
|
local DiffuseMagic = SpellBook:GetSpell(122783) |
|
|
|
local DiffuseMagic = SpellBook:GetSpell(122783) |
|
|
|
local LifeCocoon = SpellBook:GetSpell(116849) |
|
|
|
local LifeCocoon = SpellBook:GetSpell(116849) |
|
|
|
local JadefireStomp = SpellBook:GetSpell(388193) |
|
|
|
local JadefireStomp = SpellBook:GetSpell(388193) |
|
|
|
local SheilunsGift = SpellBook:GetSpell(399491) |
|
|
|
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 |
|
|
|
-- Buffs |
|
|
|
local TeachingsOfTheMonastery = SpellBook:GetSpell(202090) |
|
|
|
local TeachingsOfTheMonastery = SpellBook:GetSpell(202090) |
|
|
|
local StrengthOfTheBlackOx = SpellBook:GetSpell(392883) |
|
|
|
local StrengthOfTheBlackOx = SpellBook:GetSpell(392883) |
|
|
@ -56,11 +63,31 @@ local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit) |
|
|
|
return lowest or Player |
|
|
|
return lowest or Player |
|
|
|
end) |
|
|
|
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 |
|
|
|
-- APLs |
|
|
|
local DefaultAPL = Bastion.APL:New('default') |
|
|
|
local DefaultAPL = Bastion.APL:New('default') |
|
|
|
local CooldownAPL = Bastion.APL:New('cooldown') |
|
|
|
local CooldownAPL = Bastion.APL:New('cooldown') |
|
|
|
local DefensiveAPL = Bastion.APL:New('defensive') |
|
|
|
local DefensiveAPL = Bastion.APL:New('defensive') |
|
|
|
local DpsAPL = Bastion.APL:New('dps') |
|
|
|
local DpsAPL = Bastion.APL:New('dps') |
|
|
|
|
|
|
|
local InterruptAPL = Bastion.APL:New('interrupt') |
|
|
|
|
|
|
|
|
|
|
|
-- Helper Functions |
|
|
|
-- Helper Functions |
|
|
|
local function ShouldUseRenewingMist() |
|
|
|
local function ShouldUseRenewingMist() |
|
|
@ -75,6 +102,59 @@ local function NeedsUrgentHealing() |
|
|
|
return Lowest:GetHP() < 70 or Player:GetPartyHPAround(30, 80) >= 3 |
|
|
|
return Lowest:GetHP() < 70 or Player:GetPartyHPAround(30, 80) >= 3 |
|
|
|
end |
|
|
|
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 |
|
|
|
-- Default APL |
|
|
|
DefaultAPL:AddSpell( |
|
|
|
DefaultAPL:AddSpell( |
|
|
|
SheilunsGift:CastableIf(function(self) |
|
|
|
SheilunsGift:CastableIf(function(self) |
|
|
@ -98,7 +178,17 @@ DefaultAPL:AddSpell( |
|
|
|
DefaultAPL:AddSpell( |
|
|
|
DefaultAPL:AddSpell( |
|
|
|
RisingSunKick:CastableIf(function(self) |
|
|
|
RisingSunKick:CastableIf(function(self) |
|
|
|
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
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( |
|
|
|
DefaultAPL:AddSpell( |
|
|
@ -109,7 +199,9 @@ DefaultAPL:AddSpell( |
|
|
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
DefaultAPL:AddSpell( |
|
|
|
EnvelopingMist:CastableIf(function(self) |
|
|
|
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) |
|
|
|
end):SetTarget(Lowest) |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
@ -143,8 +235,21 @@ CooldownAPL:AddSpell( |
|
|
|
|
|
|
|
|
|
|
|
CooldownAPL:AddSpell( |
|
|
|
CooldownAPL:AddSpell( |
|
|
|
ManaTea:CastableIf(function(self) |
|
|
|
ManaTea:CastableIf(function(self) |
|
|
|
|
|
|
|
UpdateManaTeaStacks() |
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
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) |
|
|
|
end):SetTarget(Player) |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
@ -213,7 +318,32 @@ DpsAPL:AddSpell( |
|
|
|
end):SetTarget(Player) |
|
|
|
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 |
|
|
|
-- Module Sync |
|
|
|
RestoMonkModule:Sync(function() |
|
|
|
RestoMonkModule:Sync(function() |
|
|
@ -222,16 +352,29 @@ RestoMonkModule:Sync(function() |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if Player:IsAffectingCombat() then |
|
|
|
if Player:IsAffectingCombat() then |
|
|
|
|
|
|
|
UpdateManaTeaStacks() |
|
|
|
|
|
|
|
if manaTeaStacks >= 19 then |
|
|
|
|
|
|
|
ManaTea:Cast(Player) |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InterruptAPL:Execute() |
|
|
|
DefensiveAPL:Execute() |
|
|
|
DefensiveAPL:Execute() |
|
|
|
|
|
|
|
|
|
|
|
-- Prioritize DPS in Mythic+, but still maintain healing |
|
|
|
-- Prioritize Unity Within |
|
|
|
if NeedsUrgentHealing() then |
|
|
|
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() |
|
|
|
CooldownAPL:Execute() |
|
|
|
DefaultAPL:Execute() |
|
|
|
DefaultAPL:Execute() |
|
|
|
else |
|
|
|
else |
|
|
|
DpsAPL:Execute() |
|
|
|
DpsAPL:Execute() |
|
|
|
|
|
|
|
|
|
|
|
-- Weave in essential healing abilities |
|
|
|
|
|
|
|
if RenewingMist:GetCharges() >= 2 then |
|
|
|
if RenewingMist:GetCharges() >= 2 then |
|
|
|
RenewingMist:Cast(Lowest) |
|
|
|
RenewingMist:Cast(Lowest) |
|
|
|
end |
|
|
|
end |
|
|
@ -241,8 +384,7 @@ RestoMonkModule:Sync(function() |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
else |
|
|
|
else |
|
|
|
-- Out of combat logic |
|
|
|
if not Player:IsMounted() and Lowest:GetHP() < 90 then |
|
|
|
if Lowest:GetHP() < 90 then |
|
|
|
|
|
|
|
DefaultAPL:Execute() |
|
|
|
DefaultAPL:Execute() |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|