forked from vibe/Bastion
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.
337 lines
12 KiB
337 lines
12 KiB
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()
|
|
|