local Tinkr, Bastion = ... local Util = Tinkr.Util if UnitClass('player') ~= 'Shaman' then return end Bastion.Rotation = {} local BR = Bastion.Rotation BR.Units = { Player = Bastion.UnitManager:Get('player'), Target = Bastion.UnitManager:Get('target'), None = Bastion.UnitManager:Get('none') } local ShamanModule = Bastion.Module:New('Shaman') local SpellBook = Bastion.Globals.SpellBook local Player = BR.Units.Player local None = BR.Units.None local Target = BR.Units.Target Tinkr:require("scripts/bastion/scripts/ShamanSettings", Bastion) BR.myconf = Tinkr.Util.Config:New('shaman') -- for saving variables local function _highestrank(spell) local name = GetSpellInfo(spell) local highrankid = (select(7, GetSpellInfo(name))) if not highrankid then highrankid = 1 end return highrankid end local s = { -- Basic Attack AutoAttack = SpellBook:GetSpell(6603), -- Shocks EarthShock = SpellBook:GetSpell(_highestrank(8042)), FrostShock = SpellBook:GetSpell(_highestrank(8056)), FlameShock = SpellBook:GetSpell(_highestrank(8050)), -- Specific Ranks for Utility EarthShockRank1 = SpellBook:GetSpell(8042), -- Rank 1 (Interrupt) FrostShockRank1 = SpellBook:GetSpell(8056), -- Rank 1 (Slow), -- Healing Spells HealingWave = SpellBook:GetSpell(_highestrank(331)), LesserHealingWave = SpellBook:GetSpell(_highestrank(8004)), ChainHeal = SpellBook:GetSpell(_highestrank(1064)), -- Healing Sub Ranks (Healing Wave) HealingWaveRank1 = SpellBook:GetSpell(331), -- Rank 1 HealingWaveRank2 = SpellBook:GetSpell(332), -- Rank 2 HealingWaveRank3 = SpellBook:GetSpell(547), -- Rank 3 HealingWaveRank4 = SpellBook:GetSpell(913), -- Rank 4 HealingWaveRank5 = SpellBook:GetSpell(939), -- Rank 5 HealingWaveRank6 = SpellBook:GetSpell(959), -- Rank 6 HealingWaveRank7 = SpellBook:GetSpell(8005), -- Rank 7 HealingWaveRank8 = SpellBook:GetSpell(10395), -- Rank 8 HealingWaveRank9 = SpellBook:GetSpell(10396), -- Rank 9 (Max Rank) -- Healing Sub Ranks (Lesser Healing Wave) LesserHealingWaveRank1 = SpellBook:GetSpell(8004), -- Rank 1 LesserHealingWaveRank2 = SpellBook:GetSpell(8008), -- Rank 2 LesserHealingWaveRank3 = SpellBook:GetSpell(8010), -- Rank 3 LesserHealingWaveRank4 = SpellBook:GetSpell(10466), -- Rank 4 LesserHealingWaveRank5 = SpellBook:GetSpell(10467), -- Rank 5 LesserHealingWaveRank6 = SpellBook:GetSpell(10468), -- Rank 6 (Max Rank) -- Healing Sub Ranks (Chain Heal) ChainHealRank1 = SpellBook:GetSpell(1064), -- Rank 1 ChainHealRank2 = SpellBook:GetSpell(10622), -- Rank 2 ChainHealRank3 = SpellBook:GetSpell(10623), -- Rank 3 ChainHealRank4 = SpellBook:GetSpell(25422), -- Rank 4 (Max Rank) -- Totems EarthbindTotem = SpellBook:GetSpell(2484), StoneclawTotem = SpellBook:GetSpell(_highestrank(5730)), StrengthOfEarthTotem = SpellBook:GetSpell(_highestrank(8075)), TremorTotem = SpellBook:GetSpell(_highestrank(8143)), SearingTotem = SpellBook:GetSpell(_highestrank(3599)), FireNovaTotem = SpellBook:GetSpell(_highestrank(1535)), HealingStreamTotem = SpellBook:GetSpell(_highestrank(5394)), ManaSpringTotem = SpellBook:GetSpell(_highestrank(5675)), WindfuryTotem = SpellBook:GetSpell(_highestrank(8512)), GraceOfAirTotem = SpellBook:GetSpell(_highestrank(8835)), -- Buffs LightningShield = SpellBook:GetSpell(_highestrank(324)), -- Offensive Spells LightningBolt = SpellBook:GetSpell(_highestrank(403)), ChainLightning = SpellBook:GetSpell(_highestrank(421)), -- Utility Purge = SpellBook:GetSpell(_highestrank(370)), CurePoison = SpellBook:GetSpell(526), CureDisease = SpellBook:GetSpell(2870), GhostWolf = SpellBook:GetSpell(2645), WaterWalking = SpellBook:GetSpell(_highestrank(546)), WaterBreathing = SpellBook:GetSpell(_highestrank(131)), -- Weapon Buffs FlametongueWeapon = SpellBook:GetSpell(_highestrank(8024)), FrostbrandWeapon = SpellBook:GetSpell(_highestrank(8033)), WindfuryWeapon = SpellBook:GetSpell(_highestrank(8232)), RockbiterWeapon = SpellBook:GetSpell(_highestrank(8017)), -- Talents ElementalMastery = SpellBook:GetSpell(16166), NaturesSwiftness = SpellBook:GetSpell(16188), ManaTideTotem = SpellBook:GetSpell(_highestrank(16190)), --Buffs refreshment = SpellBook:GetList(430, 431, 432, 1133, 1135, 1137, 10250, 22734, 27089, 433, 434, 435, 1127, 1129, 1131, 5004, 11199, 11200, 22731, 25696) } -- Create APLs local DefaultAPL = Bastion.APL:New('default') local HealingAPL = Bastion.APL:New('healing') local DamageAPL = Bastion.APL:New('damage') local CooldownAPL = Bastion.APL:New('cooldown') local DefensiveAPL = Bastion.APL:New('defensive') -- Default APL --DefaultAPL:AddAPL(DefensiveAPL, function() return true end) --DefaultAPL:AddAPL(CooldownAPL, function() return true end) DefaultAPL:AddAPL(HealingAPL, function() return true end) --DefaultAPL:AddAPL(ExecuteAPL, function() return true end) --DefaultAPL:AddAPL(DamagePriorityAPL, function() return not HealingNeeded() and AggressiveDamagePhase() end) --DefaultAPL:AddAPL(DamageAPL, function() return not HealingNeeded() end) local DispelTarget = Bastion.UnitManager:CreateCustomUnit('dispel', function(unit) local lowest = nil local lowestHP = math.huge Bastion.UnitManager:EnumFriends(function(unit) if unit:IsDead() then return false end if not Player:CanSee(unit) then return false end if Player:GetDistance(unit) > 40 then return false end if not unit:IsDead() and Player:CanSee(unit) and (unit:GetAuras():HasAnyDispelableAura(s.CurePoison) or unit:GetAuras():HasAnyDispelableAura(s.CureDisease)) then local hp = unit:GetHP() if hp < lowestHP then lowest = unit lowestHP = hp end end end) if lowest == nil then lowest = None end return lowest end) local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit) local lowest = nil local lowestHP = math.huge Bastion.UnitManager:EnumFriends(function(unit) if unit:IsDead() then return false end if Player:GetDistance(unit) > 40 then return false end if not Player:CanSee(unit) then return false end local hp = unit:GetHP() if hp < lowestHP then lowest = unit lowestHP = hp end if not lowest then lowest = Player end end) if lowest == nil then lowest = None end return lowest end) local InterruptTarget = Bastion.UnitManager:CreateCustomUnit('interrupttarget', function(unit) local interrupt = nil Bastion.UnitManager:EnumEnemies(function(unit) if unit:IsDead() then return false end if not Player:CanSee(unit) then return false end if Player:GetDistance(unit) > 20 then return false end if unit:IsInterruptibleAt(40) and Player:IsFacing(unit) then interrupt = unit --print(unit) return true end end) if interrupt == nil then interrupt = None end return interrupt end) local PurgeTarget = Bastion.UnitManager:CreateCustomUnit('purgetarget', function(unit) local purgeTarget = nil local highestPriority = 0 -- List of high-priority buffs to purge local highPriorityBuffs = { 642, -- Divine Shield 1022, -- Blessing of Protection 19752, -- Divine Intervention 1044, -- Blessing of Freedom 6940, -- Blessing of Sacrifice 1461, -- Arcane Intellect 23028, -- Arcane Brilliance 10157, -- Arcane Intellect (Rank 6) 27126, -- Arcane Brilliance (Rank 2) } Bastion.UnitManager:EnumEnemies(function(unit) -- Basic checks if unit:IsDead() then return false end if not Player:CanSee(unit) then return false end if Player:GetDistance(unit) > 30 then return false end if not Player:IsFacing(unit) then return false end if not unit:IsAffectingCombat() then return false end -- Check if unit has purgeable buffs if unit:GetAuras():HasPurgeableBuff() then local currentPriority = 0 -- Check if unit has any high priority buffs for _, buffId in ipairs(highPriorityBuffs) do if unit:GetAuras():Find(buffId):IsUp() then currentPriority = 2 break end end -- If no high priority buffs found, but unit has other purgeable buffs if currentPriority == 0 then currentPriority = 1 end -- Update target if this unit has higher priority if currentPriority > highestPriority then purgeTarget = unit highestPriority = currentPriority end end end) if purgeTarget == nil then purgeTarget = None end return purgeTarget end) -- Utility function to check if healing is needed local function HealingNeeded() return Lowest:Exists() and Lowest:GetHP() < 90 end -- Utility function to check if emergency healing is needed local function EmergencyHealingNeeded() return Lowest:Exists() and Lowest:GetHP() < 50 end local function out_of_combat_function() if Player:GetAuras():FindAnyOf(s.refreshment):IsUp() then return end end HealingAPL:AddSpell( s.LesserHealingWave:CastableIf(function(self) if not Lowest:Exists() then return false end if Lowest:GetHP() > 20 then return false end return self:IsKnownAndUsable() and HealingNeeded() end):SetTarget(Lowest) ) HealingAPL:AddSpell( s.HealingWave:CastableIf(function(self) if not Lowest:Exists() then return false end if Lowest:GetHP() > 50 or Lowest:GetHP() < 20 then return false end return self:IsKnownAndUsable() and HealingNeeded() end):SetTarget(Lowest) ) HealingAPL:AddSpell( s.CurePoison:CastableIf(function(self) if not DispelTarget:Exists() then return false end return (DispelTarget:GetAuras():HasAnyDispelableAura(s.CurePoison)) and self:IsKnownAndUsable() end):SetTarget(DispelTarget) ) HealingAPL:AddSpell( s.CureDisease:CastableIf(function(self) if not DispelTarget:Exists() then return false end return (DispelTarget:GetAuras():HasAnyDispelableAura(s.CureDisease)) and self:IsKnownAndUsable() end):SetTarget(DispelTarget) ) DamageAPL:AddSpell( s.Purge:CastableIf(function(self) if not PurgeTarget:Exists() then return false end return self:IsKnownAndUsable() and PurgeTarget:GetAuras():HasPurgeableBuff() end):SetTarget(PurgeTarget) ) ShamanModule:Sync(function() if Player:GetAuras():FindAnyOf(s.refreshment):IsUp() then return end if Player:IsDead() then return end if Player:IsCastingOrChanneling() then return end if IsMounted() then return end if InterruptTarget:Exists() and s.EarthShockRank1:IsKnownAndUsable() then s.EarthShockRank1:Cast(InterruptTarget) end if Player:IsAffectingCombat() then DefaultAPL:Execute() else if Player:GetPP() > 5 then HealingAPL:Execute() end out_of_combat_function() end end) Bastion:Register(ShamanModule) ShamanModule:Toggle()