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.
bastion/scripts/shadowpriest.lua

417 lines
17 KiB

local Tinkr, Bastion = ...
Tinkr:require("scripts.bastion.ui", Bastion)
local ShadowModule = Bastion.Module:New('shadow')
local Evaluator = Tinkr.Util.Evaluator
local Player = Bastion.UnitManager:Get('player')
local None = Bastion.UnitManager:Get('none')
local Target = Bastion.UnitManager:Get('target')
local myconf = Tinkr.Util.Config:New('shadow_priest') -- for saving variables
local ArcaneTorrent = Bastion.SpellBook:GetSpell(232633)
local AutoAttack = Bastion.SpellBook:GetSpell(6603)
local AngelicFeather = Bastion.SpellBook:GetSpell(121536)
local DesperatePrayer = Bastion.SpellBook:GetSpell(19236)
local DispelMagic = Bastion.SpellBook:GetSpell(528)
local DominateMind = Bastion.SpellBook:GetSpell(205364)
local Fade = Bastion.SpellBook:GetSpell(586)
local FlashHeal = Bastion.SpellBook:GetSpell(2061)
local LeapofFaith = Bastion.SpellBook:GetSpell(73325)
local Levitate = Bastion.SpellBook:GetSpell(1706)
local MassDispel = Bastion.SpellBook:GetSpell(32375)
local MindBlast = Bastion.SpellBook:GetSpell(8092)
local MindSoothe = Bastion.SpellBook:GetSpell(453)
local MindVision = Bastion.SpellBook:GetSpell(2096)
local Mindgames = Bastion.SpellBook:GetSpell(375901)
local PowerInfusion = Bastion.SpellBook:GetSpell(10060)
local PowerWordFortitude = Bastion.SpellBook:GetSpell(21562)
local PowerWordShield = Bastion.SpellBook:GetSpell(17)
local PsychicScream = Bastion.SpellBook:GetSpell(8122)
local Resurrection = Bastion.SpellBook:GetSpell(2006)
local ShadowWordDeath = Bastion.SpellBook:GetSpell(32379)
local ShadowWordPain = Bastion.SpellBook:GetSpell(589)
local VampiricEmbrace = Bastion.SpellBook:GetSpell(15286)
local DarkAscension = Bastion.SpellBook:GetSpell(391109)
local DevouringPlague = Bastion.SpellBook:GetSpell(335467)
local Dispersion = Bastion.SpellBook:GetSpell(47585)
local Halo = Bastion.SpellBook:GetSpell(120644)
local MindFlay = Bastion.SpellBook:GetSpell(15407)
local MindFlayInsanity = Bastion.SpellBook:GetSpell(391399)
local MindSpike = Bastion.SpellBook:GetSpell(73510)
local Mindbender = Bastion.SpellBook:GetSpell(200174)
local ShadowCrash = Bastion.SpellBook:GetSpell(205385)
local Shadowform = Bastion.SpellBook:GetSpell(232698)
local Silence = Bastion.SpellBook:GetSpell(15487)
local SurgeofDarkness = Bastion.SpellBook:GetSpell(87160)
local VampiricTouch = Bastion.SpellBook:GetSpell(34914)
local VoidTorrent = Bastion.SpellBook:GetSpell(263165)
local function checktotem(totemname)
for index = 1, MAX_TOTEMS do
local haveTotem, totemName, startTime, duration, icon = GetTotemInfo(index)
if not totemName then return false end
if string.find(totemName, totemname) then
return true
end
end
return false
end
local InterruptTarget = Bastion.UnitManager:CreateCustomUnit('silence', 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) > 40 then return false end
if Player:InMelee(unit) and unit:IsInterruptible(5) and Player:IsFacing(unit) then
interrupt = unit
return true
end
end)
if interrupt == nil then
interrupt = None
end
return interrupt
end)
local Tank = Bastion.UnitManager:CreateCustomUnit('tank', function(unit)
local tank = nil
Bastion.UnitManager:EnumFriends(function(unit)
if Player:GetDistance(unit) > 40 then return false end
if not Player:CanSee(unit) then return false end
if unit:IsDead() then return false end
if unit:IsTank() then
tank = unit
return true
end
return false
end)
if tank == nil then
tank = None
end
return tank
end)
local Explosive = Bastion.UnitManager:CreateCustomUnit('explosive', function(unit)
local explosive = 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) > 40 then return false end
if Player:InMelee(unit) and unit:GetID() == 120651 and Player:IsFacing(unit) then
explosive = unit
return true
end
end)
if explosive == nil then
explosive = None
end
return explosive
end)
local RestingAPL = Bastion.APL:New('resting')
local OpenerAPL = Bastion.APL:New('opener')
local STAPL = Bastion.APL:New('st')
local AOEAPL = Bastion.APL:New('aoe')
local UtilityAPL = Bastion.APL:New('utility')
-- Resting - Out of Combat Actions
local usepwf = myconf:Read('pwf')
local useshadowform = myconf:Read('shadowform')
RestingAPL:AddSpell(
PowerWordFortitude:CastableIf(function(self)
return usepwf == 'yes' and self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and not Player:GetAuras():FindMy(PowerWordFortitude):IsUp() and not IsMounted()
end):SetTarget(Player)
)
RestingAPL:AddSpell(
Shadowform:CastableIf(function(self)
return useshadowform == 'yes' and self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and not Player:GetAuras():FindMy(Shadowform):IsUp() and not IsMounted()
end):SetTarget(Player)
)
-- Opener spells
local opener = myconf:Read('opener')
OpenerAPL:AddSpell(
ShadowCrash:CastableIf(function(self)
return opener == 'crash' and Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(None):OnCast(function(self)
local loc = Target:GetPosition()
self:Click(loc)
end)
)
OpenerAPL:AddSpell(
ShadowWordPain:CastableIf(function(self)
return opener == 'swp' and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Target:GetAuras():FindMy(ShadowWordPain):IsUp()
end):SetTarget(Target)
)
-- Utility spells
UtilityAPL:AddSpell(
Silence:CastableIf(function(self)
return InterruptTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(InterruptTarget)
)
-- Single Target Action Priority List
-- Make sure your target has both Shadow Word: Pain and Vampiric Touch active. Prioritise Shadow Crash over Vampiric Touch for this.
STAPL:AddSpell(
ShadowWordPain:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Target:GetAuras():FindMy(ShadowWordPain):IsUp()
end):SetTarget(Target)
)
-- Cast Mindbender on cooldown
STAPL:AddSpell(
Mindbender:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Target)
)
-- Cast Dark Ascension on cooldown
STAPL:AddSpell(
DarkAscension:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
-- Cast Power Infusion if Dark Ascension is active
STAPL:AddSpell(
PowerInfusion:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetAuras():FindMy(DarkAscension):IsUp()
end):SetTarget(Player)
)
-- Use offensive trinkets and potions.
-- Cast Mind Blast if you have two charges
STAPL:AddSpell(
MindBlast:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and MindBlast:GetCharges() == 2
end):SetTarget(Target)
)
-- Cast Shadow Word: Death if Mindbender is active
STAPL:AddSpell(
ShadowWordDeath:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and checktotem("Mindbender")
end):SetTarget(Target)
)
-- Cast Devouring Plague if you're close to capping Insanity or the debuff will expire
STAPL:AddSpell(
DevouringPlague:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetPower(Enum.PowerType.Insanity) >= 80
end):SetTarget(Target)
)
-- Cast Vampiric Touch if you are within pandemic range to maintain uptime
STAPL:AddSpell(
VampiricTouch:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and (not Target:GetAuras():FindMy(VampiricTouch):IsUp() or Target:GetAuras():FindMy(VampiricTouch):GetRemainingTime() <= 6.3)
end):SetTarget(Target)
)
-- Cast Shadow Word: Death if the target is below 20% hp
STAPL:AddSpell(
ShadowWordDeath:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Target:GetHealthPercent() <= 20
end):SetTarget(Target)
)
-- Cast Mind Blast
STAPL:AddSpell(
MindBlast:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Target)
)
-- Cast Mindgames
STAPL:AddSpell(
Mindgames:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Target)
)
-- Cast Shadow Crash, even if your DoTs are not close to expiring
STAPL:AddSpell(
ShadowCrash:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(None):OnCast(function(self)
local loc = Target:GetPosition()
self:Click(loc)
end)
)
-- Cast Void Torrent
STAPL:AddSpell(
VoidTorrent:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Target)
)
-- Cast Mind Spike if you have a Surge of Darkness proc
STAPL:AddSpell(
MindSpike:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:GetAuras():FindMy(SurgeofDarkness):IsUp()
end):SetTarget(Target)
)
-- Cast Mind Flay: Insanity
STAPL:AddSpell(
MindFlayInsanity:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Target)
)
-- Cast Mind Spike
STAPL:AddSpell(
MindSpike:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Target)
)
-- Cast Mind Flay
STAPL:AddSpell(
MindFlay:CastableIf(function(self)
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Target)
)
-- Cast Shadow Word: Pain if you're moving and nothing else is available
STAPL:AddSpell(
ShadowWordPain:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Player:IsMoving()
end):SetTarget(Target)
)
-- Module that dictates APL flow
ShadowModule:Sync(function()
if not Player:IsAffectingCombat() then
RestingAPL:Execute()
end
if not Player:IsAffectingCombat() and Target:Exists() then
OpenerAPL:Execute()
end
if Player:IsAffectingCombat() and Target:Exists() then
STAPL:Execute()
end
end)
Bastion:Register(ShadowModule)
local tab1 =
{
layoutConfig = { padding = { top = 40 } },
rows = {
[1] = { shadpr = { type = 'header', label = 'Open Combat' } },
[2] = { opener = { type = 'dropdown', label = 'Opener', column = 6, order = 1,
options = {
{ text = 'Shadow Word: Pain', value = 'swp'},
{ text = 'Shadow Crash', value = 'crash'},
{ text = 'None', value = 'none'},
},
initialValue = myconf:Read('opener', 'shield'),
onValueChanged = function(_, value) myconf:Write('opener', value) end }, },
[3] = { swp1 = { type = 'checkbox', label = 'Spread SWP', column = 6, order = 1,
initialValue = myconf:Read('swpspread', false),
onValueChanged = function(_, flag) myconf:Write('swpspread', flag) end },
swp2 = { type = 'slider', label = 'Max Targets', column = 6, order = 2,
min = 1, max = 10, precision = 0,
initialValue = myconf:Read('swptargets', 3),
onValueChanged = function(_, value) myconf:Write('swptargets', value) end }, },
[4] = { shadpr = { type = 'header', label = 'Defensives' } },
[5] = { shield1 = { type = 'checkbox', label = 'Power Word: Shield', column = 6, order = 1,
initialValue = myconf:Read('pws', false),
onValueChanged = function(_, flag) myconf:Write('pws', flag) end },
shield2 = { type = 'slider', label = 'Player Health', column = 6, order = 2,
min = 1, max = 100, precision = 0,
initialValue = myconf:Read('pwspercent', 35),
onValueChanged = function(_, value) myconf:Write('pwspercent', value) end }, },
[6] = { dispersion1 = { type = 'checkbox', label = 'Dispersion', column = 6, order = 1,
initialValue = myconf:Read('dispersion', false),
onValueChanged = function(_, flag) myconf:Write('dispersion', flag) end },
dispersion2 = { type = 'slider', label = 'Player Health', column = 6, order = 2,
min = 1, max = 100, precision = 0,
initialValue = myconf:Read('dispersionpercent', 35),
onValueChanged = function(_, value) myconf:Write('dispersionpercent', value) end }, },
[7] = { shadpr = { type = 'header', label = 'Interrupts' } },
[8] = { silence = { type = 'checkbox', label = 'Silence on CD', column = 6, order = 1,
initialValue = myconf:Read('silence', false),
onValueChanged = function(_, flag) myconf:Write('silence', flag) end },
horror = { type = 'checkbox', label = 'Psychic Horror on CD', column = 6, order = 2,
initialValue = myconf:Read('horror', false),
onValueChanged = function(_, flag) myconf:Write('horror', flag) end }, },
[9] = { shadpr = { type = 'header', label = 'Purify Disease' } },
[10] = { incombat = { type = 'checkbox', label = 'In Combat', column = 6, order = 1,
initialValue = myconf:Read('purifyic', false),
onValueChanged = function(_, flag) myconf:Write('purifyic', flag) end },
outcombat = { type = 'checkbox', label = 'Out of Combat', column = 6, order = 2,
initialValue = myconf:Read('purifyooc', false),
onValueChanged = function(_, flag) myconf:Write('purifyooc', flag) end }, },
[11] = { shadpr = { type = 'header', label = 'Dispel Magic' } },
[12] = { incombat = { type = 'checkbox', label = 'In Combat', column = 12, order = 1,
initialValue = myconf:Read('dispelic', false),
onValueChanged = function(_, flag) myconf:Write('dispelic', flag) end }, },
[13] = { shadpr = { type = 'header', label = 'Dispel Delay Time' } },
[14] = { delay = { type = 'slider', label = 'In seconds', column = 6, order = 1,
min = 0.5, max = 2, precision = 1,
initialValue = myconf:Read('dispeldelay', 1),
onValueChanged = function(_, value) myconf:Write('dispeldelay', value) end }, },
},
}
local tab2 =
{
layoutConfig = { padding = { top = 40 } },
rows = {
[1] = { shadpr = { type = 'header', label = 'Player Healing' } },
[2] = { incombat = { type = 'checkbox', label = 'In Combat Healing', column = 6, order = 1,
initialValue = myconf:Read('playericheal', false),
onValueChanged = function(_, flag) myconf:Write('playericheal', flag) end },
outcombat = { type = 'checkbox', label = 'Out of Combat Healing', column = 6, order = 2,
initialValue = myconf:Read('playeroocheal', false),
onValueChanged = function(_, flag) myconf:Write('playeroocheal', flag) end }, },
[3] = { shadowmend1 = { type = 'checkbox', label = 'Shadow Mend', column = 6, order = 1,
initialValue = myconf:Read('shadowmend', false),
onValueChanged = function(_, flag) myconf:Write('shadowmend', flag) end },
shadowmend2 = { type = 'slider', label = 'Player Health', column = 6, order = 2,
min = 1, max = 100, precision = 0,
initialValue = myconf:Read('shadowmendpercent', 35),
onValueChanged = function(_, value) myconf:Write('shadowmendpercent', value) end }, },
},
}
local shadpriestconfig = {
layoutConfig = { padding = { top = 30 } },
rows = {
[1] = {
container = {
type = 'tab',
fullSize = true,
tabs = {
{
name = 'player',
title = 'Player Settings',
layout = tab1
},
{
name = 'group',
title = 'Healing',
layout = tab2
}
},
}
},
},
}
Bastion.setupsettingsframe(shadpriestconfig, 'Rex Shadow Priest', 400, 600, 1.00, 1.00, 1.00) --, 0.00, 0.44, 0.87, 'enhsha') --Title of Settings Frame, Width, Height, ClassRGB, Rotation Name