You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
394 lines
13 KiB
394 lines
13 KiB
--Talents: C4QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzCzsMmxMmxM2w2sMbjHAz2yyMzyCImZgZYmFDsMzMDzGzMMLzEAAAAAEgFLz22sNzMBAA2A
|
|
|
|
local Tinkr, Bastion = ...
|
|
|
|
local RestoMonkModule = Bastion.Module:New('MistweaverMonk')
|
|
local Player = Bastion.UnitManager:Get('player')
|
|
local Target = Bastion.UnitManager:Get('target')
|
|
|
|
-- Initialize SpellBook
|
|
local SpellBook = Bastion.SpellBook:New()
|
|
|
|
-- Spells
|
|
local RenewingMist = SpellBook:GetSpell(115151)
|
|
local EnvelopingMist = SpellBook:GetSpell(124682)
|
|
local Vivify = SpellBook:GetSpell(116670)
|
|
local RisingSunKick = SpellBook:GetSpell(107428)
|
|
local ThunderFocusTea = SpellBook:GetSpell(116680)
|
|
local TigerPalm = SpellBook:GetSpell(100780)
|
|
local BlackoutKick = SpellBook:GetSpell(100784)
|
|
local SpinningCraneKick = SpellBook:GetSpell(101546)
|
|
local Revival = SpellBook:GetSpell(115310)
|
|
local Restoral = SpellBook:GetSpell(388615)
|
|
local InvokeYulon = SpellBook:GetSpell(322118)
|
|
local InvokeChiJi = SpellBook:GetSpell(325197)
|
|
local SoothingMist = SpellBook:GetSpell(115175)
|
|
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)
|
|
|
|
-- Custom Units
|
|
local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit)
|
|
local lowest = nil
|
|
local lowestHP = math.huge
|
|
|
|
Bastion.UnitManager:EnumFriends(function(unit)
|
|
if unit:IsDead() or Player:GetDistance(unit) > 40 or not Player:CanSee(unit) then
|
|
return false
|
|
end
|
|
|
|
local hp = unit:GetHP()
|
|
if hp < lowestHP then
|
|
lowest = unit
|
|
lowestHP = hp
|
|
end
|
|
end)
|
|
|
|
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()
|
|
return RenewingMist:GetCharges() >= 2
|
|
end
|
|
|
|
local function ShouldUseEnvelopingMist()
|
|
return Player:GetAuras():FindMy(StrengthOfTheBlackOx):IsUp()
|
|
end
|
|
|
|
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)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:GetPartyHPAround(40, 80) >= 3
|
|
end):SetTarget(Player)
|
|
)
|
|
|
|
DefaultAPL:AddSpell(
|
|
Vivify:CastableIf(function(self)
|
|
return Lowest:Exists() and Lowest:GetHP() < 70 and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
end):SetTarget(Lowest)
|
|
)
|
|
|
|
DefaultAPL:AddSpell(
|
|
RenewingMist:CastableIf(function(self)
|
|
return ShouldUseRenewingMist() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
end):SetTarget(Lowest)
|
|
)
|
|
|
|
DefaultAPL:AddSpell(
|
|
RisingSunKick:CastableIf(function(self)
|
|
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
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(
|
|
ThunderFocusTea:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
end):SetTarget(Player)
|
|
)
|
|
|
|
DefaultAPL:AddSpell(
|
|
EnvelopingMist:CastableIf(function(self)
|
|
return Lowest:Exists() and ShouldUseEnvelopingMist() and self:IsKnownAndUsable()
|
|
and not Player:IsCastingOrChanneling()
|
|
and (Player:GetAuras():FindMy(ManaTea):IsUp() or GetPlayerManaPercent() > 30)
|
|
end):SetTarget(Lowest)
|
|
)
|
|
|
|
DefaultAPL:AddSpell(
|
|
TigerPalm:CastableIf(function(self)
|
|
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
end):SetTarget(Target)
|
|
)
|
|
|
|
-- Cooldown APL
|
|
CooldownAPL:AddSpell(
|
|
CelestialConduit:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:GetPartyHPAround(40, 70) >= 3
|
|
end):SetTarget(Player)
|
|
)
|
|
|
|
CooldownAPL:AddSpell(
|
|
InvokeChiJi:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:GetPartyHPAround(40, 85) >= 2
|
|
end):SetTarget(Player)
|
|
)
|
|
|
|
CooldownAPL:AddSpell(
|
|
InvokeYulon:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:GetPartyHPAround(40, 75) >= 3
|
|
end):SetTarget(Player)
|
|
)
|
|
|
|
CooldownAPL:AddSpell(
|
|
ManaTea:CastableIf(function(self)
|
|
UpdateManaTeaStacks()
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
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)
|
|
)
|
|
|
|
-- Defensive APL
|
|
DefensiveAPL:AddSpell(
|
|
FortifyingBrew:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:GetHP() < 50
|
|
end):SetTarget(Player)
|
|
)
|
|
|
|
DefensiveAPL:AddSpell(
|
|
DiffuseMagic:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:GetHP() < 70
|
|
end):SetTarget(Player)
|
|
)
|
|
|
|
DefensiveAPL:AddSpell(
|
|
LifeCocoon:CastableIf(function(self)
|
|
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Lowest:GetHP() < 40
|
|
end):SetTarget(Lowest)
|
|
)
|
|
|
|
-- DPS APL
|
|
DpsAPL:AddSpell(
|
|
JadefireStomp:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
end):SetTarget(Player)
|
|
)
|
|
|
|
DpsAPL:AddSpell(
|
|
RisingSunKick:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:IsWithinCombatDistance(Target, 5) -- Assuming 5 is melee range
|
|
end):SetTarget(Target)
|
|
)
|
|
|
|
DpsAPL:AddSpell(
|
|
SpinningCraneKick:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:GetEnemies(8) >= 2
|
|
end):SetTarget(Player)
|
|
)
|
|
|
|
DpsAPL:AddSpell(
|
|
BlackoutKick:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:IsWithinCombatDistance(Target, 5)
|
|
end):SetTarget(Target)
|
|
)
|
|
|
|
DpsAPL:AddSpell(
|
|
TigerPalm:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:IsWithinCombatDistance(Target, 5)
|
|
and Player:GetAuras():FindMy(TeachingsOfTheMonastery):GetCount() < 3
|
|
end):SetTarget(Target)
|
|
)
|
|
|
|
DpsAPL:AddSpell(
|
|
SpinningCraneKick:CastableIf(function(self)
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
|
|
and Player:GetEnemies(8) >= 3
|
|
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()
|
|
if Player:IsMounted() then
|
|
return
|
|
end
|
|
|
|
if Player:IsAffectingCombat() then
|
|
UpdateManaTeaStacks()
|
|
if manaTeaStacks >= 19 then
|
|
ManaTea:Cast(Player)
|
|
end
|
|
|
|
InterruptAPL:Execute()
|
|
DefensiveAPL:Execute()
|
|
|
|
-- 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()
|
|
|
|
if RenewingMist:GetCharges() >= 2 then
|
|
RenewingMist:Cast(Lowest)
|
|
end
|
|
|
|
if Vivify:IsKnownAndUsable() and Lowest:GetHP() < 80 then
|
|
Vivify:Cast(Lowest)
|
|
end
|
|
end
|
|
else
|
|
if not Player:IsMounted() and Lowest:GetHP() < 90 then
|
|
DefaultAPL:Execute()
|
|
end
|
|
end
|
|
end)
|
|
|
|
Bastion:Register(RestoMonkModule)
|
|
|
|
|