diff --git a/HolyPriest.lua b/HolyPriest.lua new file mode 100644 index 0000000..4690d1c --- /dev/null +++ b/HolyPriest.lua @@ -0,0 +1,326 @@ +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) \ No newline at end of file