local Tinkr, Bastion = ... local HolyPriestModule = Bastion.Module:New('HolyPriest') local Player = Bastion.UnitManager:Get('player') local Target = Bastion.UnitManager:Get('target') -- Initialize SpellBook local SpellBook = Bastion.SpellBook:New() -- Spells local HolyFire = SpellBook:GetSpell(14914) local ShadowWordPain = SpellBook:GetSpell(589) local Smite = SpellBook:GetSpell(585) local PrayerOfMending = SpellBook:GetSpell(33076) local CircleOfHealing = SpellBook:GetSpell(204883) local PrayerOfHealing = SpellBook:GetSpell(596) local HolyWordSanctify = SpellBook:GetSpell(34861) local Halo = SpellBook:GetSpell(120517) local Lightwell = SpellBook:GetSpell(372835) local HolyWordSalvation = SpellBook:GetSpell(265202) local DivineHymn = SpellBook:GetSpell(64843) local FlashHeal = SpellBook:GetSpell(2061) local Heal = SpellBook:GetSpell(2060) local BindingHeal = SpellBook:GetSpell(32546) local Renew = SpellBook:GetSpell(139) local HolyWordSerenity = SpellBook:GetSpell(2050) local GuardianSpirit = SpellBook:GetSpell(47788) local PowerWordShield = SpellBook:GetSpell(17) local Fade = SpellBook:GetSpell(586) local DesperatePrayer = SpellBook:GetSpell(19236) local Apotheosis = SpellBook:GetSpell(200183) local SymbolOfHope = SpellBook:GetSpell(64901) local HolyWordChastise = SpellBook:GetSpell(88625) local DivineStarTalent = SpellBook:GetSpell(110744) local EmpyrealBlaze = SpellBook:GetSpell(372616) local AnsweredPrayers = SpellBook:GetSpell(393886) local answeredPrayersStacks = 0 local PrayerCircle = SpellBook:GetSpell(195329) local EmpyrealBlazeAura = SpellBook:GetSpell(372617) -- Buffs and Debuffs local SurgeOfLight = SpellBook:GetSpell(114255) local Apotheosis = SpellBook:GetSpell(200183) local PowerWordShield = SpellBook:GetSpell(17) local TranslucentImage = SpellBook:GetSpell(373446) local ProtectiveLight = SpellBook:GetSpell(193065) local ShadowWordPainDebuff = SpellBook:GetSpell(589) -- 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) local Tank = Bastion.UnitManager:CreateCustomUnit('tank', function(unit) local tank = nil Bastion.UnitManager:EnumFriends(function(unit) if Player:GetDistance(unit) > 40 or not Player:CanSee(unit) or unit:IsDead() then return false end if unit:IsTank() then tank = unit return true end end) return tank or Player end) local SWPTarget = Bastion.UnitManager:CreateCustomUnit('swptarget', function(unit) local target = nil local lowestDuration = 100 Bastion.UnitManager:EnumEnemies(function(unit) if unit:IsAffectingCombat() and unit:GetDistance(Player) <= 40 and Player:CanSee(unit) then local aura = unit:GetAuras():FindMy(ShadowWordPainDebuff) if not aura:IsUp() then target = unit return true elseif aura:GetRemainingTime() < lowestDuration then target = unit lowestDuration = aura:GetRemainingTime() end end end) return target or Target 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') -- Helper Functions local function GetAnsweredPrayersStacks() -- Implement logic to track Answered Prayers stacks -- This is a placeholder and should be replaced with actual implementation return 0 end local function ShouldUseHalo() return Player:GetPartyHPAround(30, 80) >= 3 end local function GetEnemiesWithoutSWP(range) local count = 0 Bastion.UnitManager:EnumEnemies(function(unit) if unit:IsAffectingCombat() and unit:GetDistance(Player) <= range and not unit:GetAuras():FindMy(ShadowWordPainDebuff):IsUp() then count = count + 1 end end) return count end -- Default APL DefaultAPL:AddSpell( PrayerOfMending:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() end):SetTarget(Tank) ) DefaultAPL:AddSpell( CircleOfHealing:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetPartyHPAround(30, 90) >= 3 and not Player:GetAuras():FindMy(PrayerCircle):IsUp() end):SetTarget(Player) ) DefaultAPL:AddSpell( PrayerOfHealing:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetPartyHPAround(30, 85) >= 3 and Player:GetAuras():FindMy(PrayerCircle):IsUp() end):SetTarget(Player) ) DefaultAPL:AddSpell( HolyWordSanctify:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetPartyHPAround(30, 80) >= 3 end):SetTarget(Player) ) DefaultAPL:AddSpell( FlashHeal:CastableIf(function(self) return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Lowest:GetHP() < 70 and (Player:GetAuras():FindMy(SurgeOfLight):IsUp() or Player:GetAuras():FindMy(Apotheosis):IsUp()) end):SetTarget(Lowest) ) DefaultAPL:AddSpell( Heal:CastableIf(function(self) return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Lowest:GetHP() < 85 and not Player:IsMoving() end):SetTarget(Lowest) ) DefaultAPL:AddSpell( BindingHeal:CastableIf(function(self) return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Lowest:GetHP() < 80 and Player:GetHP() < 80 and not Player:IsMoving() end):SetTarget(Lowest) ) DefaultAPL:AddSpell( Renew:CastableIf(function(self) return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Lowest:GetHP() < 90 and not Lowest:GetAuras():FindMy(Renew):IsUp() end):SetTarget(Lowest) ) DefaultAPL:AddSpell( HolyWordSerenity:CastableIf(function(self) return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Lowest:GetHP() < 60 end):SetTarget(Lowest) ) -- Cooldown APL CooldownAPL:AddSpell( Apotheosis:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and (answeredPrayersStacks >= 50 or Player:GetPartyHPAround(40, 75) >= 3) end):SetTarget(Player) ) CooldownAPL:AddSpell( DivineHymn:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetPartyHPAround(40, 70) >= 4 end):SetTarget(Player) ) CooldownAPL:AddSpell( HolyWordSalvation:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetPartyHPAround(40, 65) >= 4 end):SetTarget(Player) ) CooldownAPL:AddSpell( Halo:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and ShouldUseHalo() end):SetTarget(Player) ) CooldownAPL:AddSpell( Lightwell:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetPartyHPAround(40, 80) >= 3 end):SetTarget(Player) ) CooldownAPL:AddSpell( SymbolOfHope:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetPartyHPAround(40, 85) >= 3 end):SetTarget(Player) ) -- Defensive APL DefensiveAPL:AddSpell( Fade:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetHP() < 90 end):SetTarget(Player) ) DefensiveAPL:AddSpell( DesperatePrayer:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetHP() < 50 end):SetTarget(Player) ) DefensiveAPL:AddSpell( GuardianSpirit:CastableIf(function(self) return Tank:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Tank:GetHP() < 40 end):SetTarget(Tank) ) DefensiveAPL:AddSpell( PowerWordShield:CastableIf(function(self) return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Lowest:GetHP() < 85 and not Lowest:GetAuras():FindMy(PowerWordShield):IsUp() end):SetTarget(Lowest) ) -- DPS APL DpsAPL:AddSpell( HolyWordChastise:CastableIf(function(self) return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and EmpyrealBlaze:IsKnownAndUsable() end):SetTarget(Target):OnCast(function() EmpyrealBlaze:Cast(Player) end) ) DpsAPL:AddSpell( HolyFire:CastableIf(function(self) return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and (Player:GetAuras():FindMy(EmpyrealBlazeAura):IsUp() or not EmpyrealBlaze:IsKnownAndUsable()) end):SetTarget(Target) ) DpsAPL:AddSpell( ShadowWordPain:CastableIf(function(self) return SWPTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and (not SWPTarget:GetAuras():FindMy(ShadowWordPainDebuff):IsUp() or SWPTarget:GetAuras():FindMy(ShadowWordPainDebuff):GetRemainingTime() < 4.8) end):SetTarget(SWPTarget) ) DpsAPL:AddSpell( Smite:CastableIf(function(self) return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetPartyHPAround(40, 90) == 0 and GetEnemiesWithoutSWP(40) == 0 end):SetTarget(Target) ) -- Module Sync HolyPriestModule:Sync(function() if Player:IsAffectingCombat() then DefensiveAPL:Execute() CooldownAPL:Execute() DefaultAPL:Execute() DpsAPL:Execute() else -- Out of combat logic local enemiesWithoutSWP = GetEnemiesWithoutSWP(40) if enemiesWithoutSWP > 0 then ShadowWordPain:Cast(SWPTarget) end end end) Bastion.Globals.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function() local _, subEvent, _, sourceGUID, _, _, _, _, _, _, _, spellID = CombatLogGetCurrentEventInfo() if sourceGUID == Player:GetGUID() and subEvent == "SPELL_HEAL" and spellID == 33076 then answeredPrayersStacks = answeredPrayersStacks + 1 if answeredPrayersStacks >= 50 then answeredPrayersStacks = 0 end end end) Bastion:Register(HolyPriestModule)