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.
1879 lines
148 KiB
1879 lines
148 KiB
|
5 years ago
|
-- MageArcane.lua
|
||
|
|
-- June 2018
|
||
|
|
|
||
|
|
local addon, ns = ...
|
||
|
|
local Hekili = _G[ addon ]
|
||
|
|
|
||
|
|
local class = Hekili.Class
|
||
|
|
local state = Hekili.State
|
||
|
|
|
||
|
|
local PTR = ns.PTR
|
||
|
|
|
||
|
|
|
||
|
|
-- Conduits
|
||
|
|
-- [x] arcane_prodigy
|
||
|
|
-- [-] artifice_of_the_archmage
|
||
|
|
-- [-] magis_brand
|
||
|
|
-- [x] nether_precision
|
||
|
|
|
||
|
|
-- Covenant
|
||
|
|
-- [-] ire_of_the_ascended
|
||
|
|
-- [x] siphoned_malice
|
||
|
|
-- [x] gift_of_the_lich
|
||
|
|
-- [x] discipline_of_the_grove
|
||
|
|
|
||
|
|
-- Endurance
|
||
|
|
-- [-] cryofreeze
|
||
|
|
-- [-] diverted_energy
|
||
|
|
-- [x] tempest_barrier
|
||
|
|
|
||
|
|
-- Finesse
|
||
|
|
-- [x] flow_of_time
|
||
|
|
-- [x] incantation_of_swiftness
|
||
|
|
-- [x] winters_protection
|
||
|
|
-- [x] grounding_surge
|
||
|
|
|
||
|
|
|
||
|
|
if UnitClassBase( 'player' ) == 'MAGE' then
|
||
|
|
local spec = Hekili:NewSpecialization( 62, true )
|
||
|
|
|
||
|
|
spec:RegisterResource( Enum.PowerType.ArcaneCharges, {
|
||
|
|
arcane_orb = {
|
||
|
|
aura = "arcane_orb",
|
||
|
|
|
||
|
|
last = function ()
|
||
|
|
local app = state.buff.arcane_orb.applied
|
||
|
|
local t = state.query_time
|
||
|
|
|
||
|
|
return app + floor( t - app )
|
||
|
|
end,
|
||
|
|
|
||
|
|
interval = 0.5,
|
||
|
|
value = function () return state.active_enemies end,
|
||
|
|
},
|
||
|
|
} )
|
||
|
|
|
||
|
|
spec:RegisterResource( Enum.PowerType.Mana ) --[[, {
|
||
|
|
evocation = {
|
||
|
|
aura = "evocation",
|
||
|
|
|
||
|
|
last = function ()
|
||
|
|
local app = state.buff.evocation.applied
|
||
|
|
local t = state.query_time
|
||
|
|
|
||
|
|
return app + floor( t - app )
|
||
|
|
end,
|
||
|
|
|
||
|
|
interval = 0.1,
|
||
|
|
value = function () return state.mana.regen * 0.1 end,
|
||
|
|
}
|
||
|
|
} ) ]]
|
||
|
|
|
||
|
|
-- Talents
|
||
|
|
spec:RegisterTalents( {
|
||
|
|
amplification = 22458, -- 236628
|
||
|
|
rule_of_threes = 22461, -- 264354
|
||
|
|
arcane_familiar = 22464, -- 205022
|
||
|
|
|
||
|
|
master_of_time = 23072, -- 342249
|
||
|
|
shimmer = 22443, -- 212653
|
||
|
|
slipstream = 16025, -- 236457
|
||
|
|
|
||
|
|
incanters_flow = 22444, -- 1463
|
||
|
|
focus_magic = 22445, -- 321358
|
||
|
|
rune_of_power = 22447, -- 116011
|
||
|
|
|
||
|
|
resonance = 22453, -- 205028
|
||
|
|
arcane_echo = 22467, -- 342231
|
||
|
|
nether_tempest = 22470, -- 114923
|
||
|
|
|
||
|
|
chrono_shift = 22907, -- 235711
|
||
|
|
ice_ward = 22448, -- 205036
|
||
|
|
ring_of_frost = 22471, -- 113724
|
||
|
|
|
||
|
|
reverberate = 22455, -- 281482
|
||
|
|
arcane_orb = 22449, -- 153626
|
||
|
|
supernova = 22474, -- 157980
|
||
|
|
|
||
|
|
overpowered = 21630, -- 155147
|
||
|
|
time_anomaly = 21144, -- 210805
|
||
|
|
enlightened = 21145, -- 321387
|
||
|
|
} )
|
||
|
|
|
||
|
|
-- PvP Talents
|
||
|
|
spec:RegisterPvpTalents( {
|
||
|
|
arcane_empowerment = 61, -- 276741
|
||
|
|
arcanosphere = 5397, -- 353128
|
||
|
|
kleptomania = 3529, -- 198100
|
||
|
|
mass_invisibility = 637, -- 198158
|
||
|
|
master_of_escape = 635, -- 210476
|
||
|
|
netherwind_armor = 3442, -- 198062
|
||
|
|
prismatic_cloak = 3531, -- 198064
|
||
|
|
temporal_shield = 3517, -- 198111
|
||
|
|
torment_the_weak = 62, -- 198151
|
||
|
|
} )
|
||
|
|
|
||
|
|
-- Auras
|
||
|
|
spec:RegisterAuras( {
|
||
|
|
alter_time = {
|
||
|
|
id = 342246,
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
arcane_charge = {
|
||
|
|
duration = 3600,
|
||
|
|
max_stack = 4,
|
||
|
|
generate = function ()
|
||
|
|
local ac = buff.arcane_charge
|
||
|
|
|
||
|
|
if arcane_charges.current > 0 then
|
||
|
|
ac.count = arcane_charges.current
|
||
|
|
ac.applied = query_time
|
||
|
|
ac.expires = query_time + 3600
|
||
|
|
ac.caster = "player"
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
ac.count = 0
|
||
|
|
ac.applied = 0
|
||
|
|
ac.expires = 0
|
||
|
|
ac.caster = "nobody"
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
arcane_familiar = {
|
||
|
|
id = 210126,
|
||
|
|
duration = 3600,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
arcane_intellect = {
|
||
|
|
id = 1459,
|
||
|
|
duration = 3600,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
shared = "player", -- use anyone's buff on the player, not just player's.
|
||
|
|
},
|
||
|
|
arcane_orb = {
|
||
|
|
duration = 2.5,
|
||
|
|
max_stack = 1,
|
||
|
|
--[[ generate = function ()
|
||
|
|
local last = action.arcane_orb.lastCast
|
||
|
|
local ao = buff.arcane_orb
|
||
|
|
|
||
|
|
if query_time - last < 2.5 then
|
||
|
|
ao.count = 1
|
||
|
|
ao.applied = last
|
||
|
|
ao.expires = last + 2.5
|
||
|
|
ao.caster = "player"
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
ao.count = 0
|
||
|
|
ao.applied = 0
|
||
|
|
ao.expires = 0
|
||
|
|
ao.caster = "nobody"
|
||
|
|
end, ]]
|
||
|
|
},
|
||
|
|
arcane_power = {
|
||
|
|
id = 12042,
|
||
|
|
duration = function () return level > 55 and 15 or 10 end,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
blink = {
|
||
|
|
id = 1953,
|
||
|
|
},
|
||
|
|
chilled = {
|
||
|
|
id = 205708,
|
||
|
|
duration = 8,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
chrono_shift_buff = {
|
||
|
|
id = 236298,
|
||
|
|
duration = 5,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
chrono_shift = {
|
||
|
|
id = 236299,
|
||
|
|
duration = 5,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
clearcasting = {
|
||
|
|
id = function () return pvptalent.arcane_empowerment.enabled and 276743 or 263725 end,
|
||
|
|
duration = 15,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = function () return pvptalent.arcane_empowerment.enabled and 5 or 1 end,
|
||
|
|
copy = { 263725, 276743 }
|
||
|
|
},
|
||
|
|
enlightened = {
|
||
|
|
id = 321390,
|
||
|
|
duration = 3600,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
evocation = {
|
||
|
|
id = 12051,
|
||
|
|
duration = function () return 6 * haste end,
|
||
|
|
tick_time = function () return haste end,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
focus_magic = {
|
||
|
|
id = 321358,
|
||
|
|
duration = 1800,
|
||
|
|
max_stack = 1,
|
||
|
|
friendly = true,
|
||
|
|
},
|
||
|
|
focus_magic_buff = {
|
||
|
|
id = 321363,
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
frost_nova = {
|
||
|
|
id = 122,
|
||
|
|
duration = 8,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
greater_invisibility = {
|
||
|
|
id = 110960,
|
||
|
|
duration = 20,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
hypothermia = {
|
||
|
|
id = 41425,
|
||
|
|
duration = 30,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
ice_block = {
|
||
|
|
id = 45438,
|
||
|
|
duration = 10,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
incanters_flow = {
|
||
|
|
id = 116267,
|
||
|
|
duration = 3600,
|
||
|
|
max_stack = 5,
|
||
|
|
meta = {
|
||
|
|
stack = function() return state.incanters_flow_stacks end,
|
||
|
|
stacks = function() return state.incanters_flow_stacks end,
|
||
|
|
}
|
||
|
|
},
|
||
|
|
mirror_image = {
|
||
|
|
id = 55342,
|
||
|
|
duration = 40,
|
||
|
|
max_stack = 3,
|
||
|
|
generate = function ()
|
||
|
|
local mi = buff.mirror_image
|
||
|
|
|
||
|
|
if action.mirror_image.lastCast > 0 and query_time < action.mirror_image.lastCast + 40 then
|
||
|
|
mi.count = 1
|
||
|
|
mi.applied = action.mirror_image.lastCast
|
||
|
|
mi.expires = mi.applied + 40
|
||
|
|
mi.caster = "player"
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
mi.count = 0
|
||
|
|
mi.applied = 0
|
||
|
|
mi.expires = 0
|
||
|
|
mi.caster = "nobody"
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
mirrors_of_torment = {
|
||
|
|
id = 314793,
|
||
|
|
duration = 20,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 3,
|
||
|
|
},
|
||
|
|
nether_tempest = {
|
||
|
|
id = 114923,
|
||
|
|
duration = 12,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
presence_of_mind = {
|
||
|
|
id = 205025,
|
||
|
|
duration = 3600,
|
||
|
|
max_stack = function () return level > 53 and 3 or 2 end,
|
||
|
|
},
|
||
|
|
prismatic_barrier = {
|
||
|
|
id = 235450,
|
||
|
|
duration = 60,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
radiant_spark = {
|
||
|
|
id = 307443,
|
||
|
|
duration = 8,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
radiant_spark_vulnerability = {
|
||
|
|
id = 307454,
|
||
|
|
duration = 3.707,
|
||
|
|
max_stack = 4,
|
||
|
|
},
|
||
|
|
ring_of_frost = {
|
||
|
|
id = 82691,
|
||
|
|
duration = 10,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
rule_of_threes = {
|
||
|
|
id = 264774,
|
||
|
|
duration = 15,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
rune_of_power = {
|
||
|
|
id = 116014,
|
||
|
|
duration = 12,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
shimmer = {
|
||
|
|
id = 212653,
|
||
|
|
},
|
||
|
|
slow = {
|
||
|
|
id = 31589,
|
||
|
|
duration = 15,
|
||
|
|
type = "Magic",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
slow_fall = {
|
||
|
|
id = 130,
|
||
|
|
duration = 30,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
temporal_displacement = {
|
||
|
|
id = 80354,
|
||
|
|
duration = 600,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
touch_of_the_magi = {
|
||
|
|
id = 210824,
|
||
|
|
duration = 8,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
-- Azerite Powers
|
||
|
|
brain_storm = {
|
||
|
|
id = 273330,
|
||
|
|
duration = 30,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
|
||
|
|
equipoise = {
|
||
|
|
id = 264352,
|
||
|
|
duration = 3600,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
-- Conduits
|
||
|
|
nether_precision = {
|
||
|
|
id = 336889,
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 2
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
-- Legendaries
|
||
|
|
grisly_icicle = {
|
||
|
|
id = 348007,
|
||
|
|
duration = 8,
|
||
|
|
max_stack = 1
|
||
|
|
}
|
||
|
|
} )
|
||
|
|
|
||
|
|
|
||
|
|
do
|
||
|
|
-- Builds Disciplinary Command; written so that it can be ported to the other two Mage specs.
|
||
|
|
|
||
|
|
function Hekili:EmbedDisciplinaryCommand( x )
|
||
|
|
local file_id = x.id
|
||
|
|
|
||
|
|
x:RegisterAuras( {
|
||
|
|
disciplinary_command = {
|
||
|
|
id = 327371,
|
||
|
|
duration = 20,
|
||
|
|
},
|
||
|
|
|
||
|
|
disciplinary_command_arcane = {
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
|
||
|
|
disciplinary_command_frost = {
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
|
||
|
|
disciplinary_command_fire = {
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 1,
|
||
|
|
}
|
||
|
|
} )
|
||
|
|
|
||
|
|
local __last_arcane, __last_fire, __last_frost, __last_disciplinary_command = 0, 0, 0, 0
|
||
|
|
|
||
|
|
x:RegisterHook( "reset_precast", function ()
|
||
|
|
if now - __last_arcane < 10 then applyBuff( "disciplinary_command_arcane", 10 - ( now - __last_arcane ) ) end
|
||
|
|
if now - __last_fire < 10 then applyBuff( "disciplinary_command_fire", 10 - ( now - __last_fire ) ) end
|
||
|
|
if now - __last_frost < 10 then applyBuff( "disciplinary_command_frost", 10 - ( now - __last_frost ) ) end
|
||
|
|
|
||
|
|
if now - __last_disciplinary_command < 30 then
|
||
|
|
setCooldown( "buff_disciplinary_command", 30 - ( now - __last_disciplinary_command ) )
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
x:RegisterStateFunction( "update_disciplinary_command", function( elem )
|
||
|
|
if not legendary.disciplinary_command.enabled or cooldown.buff_disciplinary_command.remains > 0 then return end
|
||
|
|
|
||
|
|
if elem == "arcane" then applyBuff( "disciplinary_command_arcane" ) end
|
||
|
|
if elem == "fire" then applyBuff( "disciplinary_command_fire" ) end
|
||
|
|
if elem == "frost" then applyBuff( "disciplinary_command_frost" ) end
|
||
|
|
|
||
|
|
if cooldown.buff_disciplinary_command.remains == 0 and buff.disciplinary_command_arcane.up and buff.disciplinary_command_fire.up and buff.disciplinary_command_frost.up then
|
||
|
|
applyBuff( "disciplinary_command" )
|
||
|
|
setCooldown( "buff_disciplinary_command", 30 )
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
x:RegisterHook( "runHandler", function( action )
|
||
|
|
local a = class.abilities[ action ]
|
||
|
|
|
||
|
|
if a then
|
||
|
|
update_disciplinary_command( a.discipline or state.spec.key )
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
x:RegisterHook( "COMBAT_LOG_EVENT_UNFILTERED", function( event, _, subtype, _, sourceGUID, sourceName, _, _, destGUID, destName, destFlags, _, spellID, spellName )
|
||
|
|
if sourceGUID == GUID then
|
||
|
|
if subtype == "SPELL_CAST_SUCCESS" then
|
||
|
|
local ability = class.abilities[ spellID ]
|
||
|
|
|
||
|
|
if ability then
|
||
|
|
if ability.discipline == "frost" then
|
||
|
|
__last_frost = GetTime()
|
||
|
|
elseif ability.discipline == "fire" then
|
||
|
|
__last_fire = GetTime()
|
||
|
|
else
|
||
|
|
__last_arcane = GetTime()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
elseif subtype == "SPELL_AURA_APPLIED" and spellID == class.auras.disciplinary_command.id then
|
||
|
|
__last_disciplinary_command = GetTime()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
x:RegisterAbility( "buff_disciplinary_command", {
|
||
|
|
cooldown_special = function ()
|
||
|
|
local remains = ( now + offset ) - __last_disciplinary_command
|
||
|
|
|
||
|
|
if remains < 30 then
|
||
|
|
return __last_disciplinary_command, 30
|
||
|
|
end
|
||
|
|
|
||
|
|
return 0, 0
|
||
|
|
end,
|
||
|
|
unlisted = true,
|
||
|
|
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 30,
|
||
|
|
gcd = "off",
|
||
|
|
|
||
|
|
handler = function()
|
||
|
|
applyBuff( "disciplinary_command" )
|
||
|
|
end,
|
||
|
|
} )
|
||
|
|
end
|
||
|
|
|
||
|
|
Hekili:EmbedDisciplinaryCommand( spec )
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterHook( "spend", function( amt, resource )
|
||
|
|
if resource == "arcane_charges" then
|
||
|
|
if arcane_charges.current == 0 then
|
||
|
|
removeBuff( "arcane_charge" )
|
||
|
|
else
|
||
|
|
applyBuff( "arcane_charge", nil, arcane_charges.current )
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif resource == "mana" then
|
||
|
|
if azerite.equipoise.enabled and mana.percent < 70 then
|
||
|
|
removeBuff( "equipoise" )
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
spec:RegisterHook( "gain", function( amt, resource )
|
||
|
|
if resource == "arcane_charges" then
|
||
|
|
if arcane_charges.current == 0 then
|
||
|
|
removeBuff( "arcane_charge" )
|
||
|
|
else
|
||
|
|
if talent.rule_of_threes.enabled and arcane_charges.current >= 3 and arcane_charges.current - amt < 3 then
|
||
|
|
applyBuff( "rule_of_threes" )
|
||
|
|
end
|
||
|
|
applyBuff( "arcane_charge", nil, arcane_charges.current )
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterStateTable( "burn_info", setmetatable( {
|
||
|
|
__start = 0,
|
||
|
|
start = 0,
|
||
|
|
__average = 20,
|
||
|
|
average = 20,
|
||
|
|
n = 1,
|
||
|
|
__n = 1,
|
||
|
|
}, {
|
||
|
|
__index = function( t, k )
|
||
|
|
if k == "active" then
|
||
|
|
return t.start > 0
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
} ) )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterTotem( "rune_of_power", 609815 )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterStateTable( "incanters_flow", {
|
||
|
|
changed = 0,
|
||
|
|
count = 0,
|
||
|
|
direction = 0,
|
||
|
|
|
||
|
|
startCount = 0,
|
||
|
|
startTime = 0,
|
||
|
|
startIndex = 0,
|
||
|
|
|
||
|
|
values = {
|
||
|
|
[0] = { 0, 1 },
|
||
|
|
{ 1, 1 },
|
||
|
|
{ 2, 1 },
|
||
|
|
{ 3, 1 },
|
||
|
|
{ 4, 1 },
|
||
|
|
{ 5, 0 },
|
||
|
|
{ 5, -1 },
|
||
|
|
{ 4, -1 },
|
||
|
|
{ 3, -1 },
|
||
|
|
{ 2, -1 },
|
||
|
|
{ 1, 0 }
|
||
|
|
},
|
||
|
|
|
||
|
|
f = CreateFrame("Frame"),
|
||
|
|
fRegistered = false,
|
||
|
|
|
||
|
|
reset = setfenv( function ()
|
||
|
|
if talent.incanters_flow.enabled then
|
||
|
|
if not incanters_flow.fRegistered then
|
||
|
|
-- One-time setup.
|
||
|
|
incanters_flow.f:RegisterUnitEvent( "UNIT_AURA", "player" )
|
||
|
|
incanters_flow.f:SetScript( "OnEvent", function ()
|
||
|
|
-- Check to see if IF changed.
|
||
|
|
if state.talent.incanters_flow.enabled then
|
||
|
|
local flow = state.incanters_flow
|
||
|
|
local name, _, count = FindUnitBuffByID( "player", 116267, "PLAYER" )
|
||
|
|
local now = GetTime()
|
||
|
|
|
||
|
|
if name then
|
||
|
|
if count ~= flow.count then
|
||
|
|
if count == 1 then flow.direction = 0
|
||
|
|
elseif count == 5 then flow.direction = 0
|
||
|
|
else flow.direction = ( count > flow.count ) and 1 or -1 end
|
||
|
|
|
||
|
|
flow.changed = GetTime()
|
||
|
|
flow.count = count
|
||
|
|
end
|
||
|
|
else
|
||
|
|
flow.count = 0
|
||
|
|
flow.changed = GetTime()
|
||
|
|
flow.direction = 0
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
incanters_flow.fRegistered = true
|
||
|
|
end
|
||
|
|
|
||
|
|
if now - incanters_flow.changed >= 1 then
|
||
|
|
if incanters_flow.count == 1 and incanters_flow.direction == 0 then
|
||
|
|
incanters_flow.direction = 1
|
||
|
|
incanters_flow.changed = incanters_flow.changed + 1
|
||
|
|
elseif incanters_flow.count == 5 and incanters_flow.direction == 0 then
|
||
|
|
incanters_flow.direction = -1
|
||
|
|
incanters_flow.changed = incanters_flow.changed + 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if incanters_flow.count == 0 then
|
||
|
|
incanters_flow.startCount = 0
|
||
|
|
incanters_flow.startTime = incanters_flow.changed + floor( now - incanters_flow.changed )
|
||
|
|
incanters_flow.startIndex = 0
|
||
|
|
else
|
||
|
|
incanters_flow.startCount = incanters_flow.count
|
||
|
|
incanters_flow.startTime = incanters_flow.changed + floor( now - incanters_flow.changed )
|
||
|
|
incanters_flow.startIndex = 0
|
||
|
|
|
||
|
|
for i, val in ipairs( incanters_flow.values ) do
|
||
|
|
if val[1] == incanters_flow.count and val[2] == incanters_flow.direction then incanters_flow.startIndex = i; break end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
incanters_flow.count = 0
|
||
|
|
incanters_flow.changed = 0
|
||
|
|
incanters_flow.direction = 0
|
||
|
|
end
|
||
|
|
end, state ),
|
||
|
|
} )
|
||
|
|
|
||
|
|
spec:RegisterStateExpr( "incanters_flow_stacks", function ()
|
||
|
|
if not talent.incanters_flow.enabled then return 0 end
|
||
|
|
|
||
|
|
local index = incanters_flow.startIndex + floor( query_time - incanters_flow.startTime )
|
||
|
|
if index > 10 then index = index % 10 end
|
||
|
|
|
||
|
|
return incanters_flow.values[ index ][ 1 ]
|
||
|
|
end )
|
||
|
|
|
||
|
|
spec:RegisterStateExpr( "incanters_flow_dir", function()
|
||
|
|
if not talent.incanters_flow.enabled then return 0 end
|
||
|
|
|
||
|
|
local index = incanters_flow.startIndex + floor( query_time - incanters_flow.startTime )
|
||
|
|
if index > 10 then index = index % 10 end
|
||
|
|
|
||
|
|
return incanters_flow.values[ index ][ 2 ]
|
||
|
|
end )
|
||
|
|
|
||
|
|
-- Seemingly, a very silly way to track Incanter's Flow...
|
||
|
|
local incanters_flow_time_obj = setmetatable( { __stack = 0 }, {
|
||
|
|
__index = function( t, k )
|
||
|
|
if not state.talent.incanters_flow.enabled then return 0 end
|
||
|
|
|
||
|
|
local stack = t.__stack
|
||
|
|
local ticks = #state.incanters_flow.values
|
||
|
|
|
||
|
|
local start = state.incanters_flow.startIndex + floor( state.offset + state.delay )
|
||
|
|
|
||
|
|
local low_pos, high_pos
|
||
|
|
|
||
|
|
if k == "up" then low_pos = 5
|
||
|
|
elseif k == "down" then high_pos = 6 end
|
||
|
|
|
||
|
|
local time_since = ( state.query_time - state.incanters_flow.changed ) % 1
|
||
|
|
|
||
|
|
for i = 0, 10 do
|
||
|
|
local index = ( start + i )
|
||
|
|
if index > 10 then index = index % 10 end
|
||
|
|
|
||
|
|
local values = state.incanters_flow.values[ index ]
|
||
|
|
|
||
|
|
if values[ 1 ] == stack and ( not low_pos or index <= low_pos ) and ( not high_pos or index >= high_pos ) then
|
||
|
|
return max( 0, i - time_since )
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return 0
|
||
|
|
end
|
||
|
|
} )
|
||
|
|
|
||
|
|
spec:RegisterStateTable( "incanters_flow_time_to", setmetatable( {}, {
|
||
|
|
__index = function( t, k )
|
||
|
|
incanters_flow_time_obj.__stack = tonumber( k ) or 0
|
||
|
|
return incanters_flow_time_obj
|
||
|
|
end
|
||
|
|
} ) )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterStateExpr( "fake_mana_gem", function ()
|
||
|
|
return false
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterStateFunction( "start_burn_phase", function ()
|
||
|
|
burn_info.start = query_time
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterStateFunction( "stop_burn_phase", function ()
|
||
|
|
if burn_info.start > 0 then
|
||
|
|
burn_info.average = burn_info.average * burn_info.n
|
||
|
|
burn_info.average = burn_info.average + ( query_time - burn_info.start )
|
||
|
|
burn_info.n = burn_info.n + 1
|
||
|
|
|
||
|
|
burn_info.average = burn_info.average / burn_info.n
|
||
|
|
burn_info.start = 0
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterStateExpr( "burn_phase", function ()
|
||
|
|
return burn_info.start > 0
|
||
|
|
end )
|
||
|
|
|
||
|
|
spec:RegisterStateExpr( "average_burn_length", function ()
|
||
|
|
return burn_info.average or 15
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
local clearcasting_consumed = 0
|
||
|
|
|
||
|
|
spec:RegisterHook( "COMBAT_LOG_EVENT_UNFILTERED", function( event, _, subtype, _, sourceGUID, sourceName, _, _, destGUID, destName, destFlags, _, spellID, spellName )
|
||
|
|
if sourceGUID == GUID then
|
||
|
|
if subtype == "SPELL_CAST_SUCCESS" then
|
||
|
|
if spellID == 12042 then
|
||
|
|
burn_info.__start = GetTime()
|
||
|
|
Hekili:Print( "Burn phase started." )
|
||
|
|
elseif spellID == 12051 and burn_info.__start > 0 then
|
||
|
|
burn_info.__average = burn_info.__average * burn_info.__n
|
||
|
|
burn_info.__average = burn_info.__average + ( query_time - burn_info.__start )
|
||
|
|
burn_info.__n = burn_info.__n + 1
|
||
|
|
|
||
|
|
burn_info.__average = burn_info.__average / burn_info.__n
|
||
|
|
burn_info.__start = 0
|
||
|
|
Hekili:Print( "Burn phase ended." )
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif subtype == "SPELL_AURA_REMOVED" and ( spellID == 276743 or spellID == 263725 ) then
|
||
|
|
-- Clearcasting was consumed.
|
||
|
|
clearcasting_consumed = GetTime()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterVariable( "have_opened", function ()
|
||
|
|
local val = 0
|
||
|
|
|
||
|
|
if active_enemies > 2 then
|
||
|
|
val = 1
|
||
|
|
end
|
||
|
|
|
||
|
|
-- actions.calculations=variable,name=have_opened,op=set,value=1,if=variable.have_opened=0&prev_gcd.1.evocation&!(runeforge.siphon_storm|runeforge.temporal_warp)
|
||
|
|
if val == 0 and prev_gcd[1].evocation and not ( runeforge.siphon_storm.enabled or runeforge.temporal_warp.enabled ) then
|
||
|
|
val = 1
|
||
|
|
end
|
||
|
|
|
||
|
|
-- actions.calculations+=/variable,name=have_opened,op=set,value=1,if=variable.have_opened=0&buff.arcane_power.down&cooldown.arcane_power.remains&(runeforge.siphon_storm|runeforge.temporal_warp)
|
||
|
|
if val == 0 and buff.arcane_power.down and cooldown.arcane_power.remains > 0 and ( runeforge.siphon_storm.enabled or runeforge.temporal_warp.enabled ) then
|
||
|
|
val = 1
|
||
|
|
end
|
||
|
|
|
||
|
|
return val
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterStateExpr( "tick_reduction", function ()
|
||
|
|
return action.shifting_power.cdr / 4
|
||
|
|
end )
|
||
|
|
|
||
|
|
spec:RegisterStateExpr( "full_reduction", function ()
|
||
|
|
return action.shifting_power.cdr
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
local abs = math.abs
|
||
|
|
|
||
|
|
spec:RegisterHook( "reset_precast", function ()
|
||
|
|
if pet.rune_of_power.up then applyBuff( "rune_of_power", pet.rune_of_power.remains )
|
||
|
|
else removeBuff( "rune_of_power" ) end
|
||
|
|
|
||
|
|
if burn_info.__start > 0 and ( ( state.time == 0 and now - player.casttime > ( gcd.execute * 4 ) ) or ( now - burn_info.__start >= 45 ) ) and ( ( cooldown.evocation.remains == 0 and cooldown.arcane_power.remains < action.evocation.cooldown - 45 ) or ( cooldown.evocation.remains > cooldown.arcane_power.remains + 45 ) ) then
|
||
|
|
-- Hekili:Print( "Burn phase ended to avoid Evocation and Arcane Power desynchronization (%.2f seconds).", now - burn_info.__start )
|
||
|
|
burn_info.__start = 0
|
||
|
|
end
|
||
|
|
|
||
|
|
if buff.casting.up and buff.casting.v1 == 5143 and abs( action.arcane_missiles.lastCast - clearcasting_consumed ) < 0.15 then
|
||
|
|
applyBuff( "clearcasting_channel", buff.casting.remains )
|
||
|
|
end
|
||
|
|
|
||
|
|
burn_info.start = burn_info.__start
|
||
|
|
burn_info.average = burn_info.__average
|
||
|
|
burn_info.n = burn_info.__n
|
||
|
|
|
||
|
|
if arcane_charges.current > 0 then applyBuff( "arcane_charge", nil, arcane_charges.current ) end
|
||
|
|
|
||
|
|
fake_mana_gem = nil
|
||
|
|
|
||
|
|
incanters_flow.reset()
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
-- Abilities
|
||
|
|
spec:RegisterAbilities( {
|
||
|
|
alter_time = {
|
||
|
|
id = function () return buff.alter_time.down and 342247 or 342245 end,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = function () return talent.master_of_time.enabled and 30 or 60 end,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 0.01,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
toggle = "cooldowns",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 609811,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
if buff.alter_time.down then
|
||
|
|
applyBuff( "alter_time" )
|
||
|
|
else
|
||
|
|
removeBuff( "alter_time" )
|
||
|
|
if talent.master_of_time.enabled then setCooldown( "blink", 0 ) end
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
copy = 342247,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
arcane_barrage = {
|
||
|
|
id = 44425,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 3,
|
||
|
|
hasteCD = true,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 236205,
|
||
|
|
|
||
|
|
-- velocity = 24, -- ignore this, bc charges are consumed on cast.
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
if level > 51 then gain( 0.02 * mana.max * arcane_charges.current, "mana" ) end
|
||
|
|
|
||
|
|
spend( arcane_charges.current, "arcane_charges" )
|
||
|
|
removeBuff( "arcane_harmony" )
|
||
|
|
|
||
|
|
if talent.chrono_shift.enabled then
|
||
|
|
applyBuff( "chrono_shift_buff" )
|
||
|
|
applyDebuff( "target", "chrono_shift" )
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
arcane_blast = {
|
||
|
|
id = 30451,
|
||
|
|
cast = function ()
|
||
|
|
if buff.presence_of_mind.up then return 0 end
|
||
|
|
return 2.25 * ( 1 - ( 0.08 * arcane_charges.current ) ) * haste end,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function ()
|
||
|
|
if buff.rule_of_threes.up then return 0 end
|
||
|
|
local mult = 0.0275 * ( 1 + arcane_charges.current ) * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 )
|
||
|
|
if azerite.equipoise.enabled and mana.pct < 70 then return ( mana.modmax * mult ) - 190 end
|
||
|
|
return mana.modmax * mult
|
||
|
|
end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 135735,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
if buff.presence_of_mind.up then
|
||
|
|
removeStack( "presence_of_mind" )
|
||
|
|
if buff.presence_of_mind.down then setCooldown( "presence_of_mind", 60 ) end
|
||
|
|
end
|
||
|
|
removeBuff( "rule_of_threes" )
|
||
|
|
removeStack( "nether_precision" )
|
||
|
|
gain( 1, "arcane_charges" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
arcane_explosion = {
|
||
|
|
id = 1449,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
discipline = "arcane",
|
||
|
|
|
||
|
|
spend = function ()
|
||
|
|
if not pvptalent.arcane_empowerment.enabled and buff.clearcasting.up then return 0 end
|
||
|
|
return 0.1 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 )
|
||
|
|
end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 136116,
|
||
|
|
|
||
|
|
usable = function () return not state.spec.arcane or target.distance < 10, "target out of range" end,
|
||
|
|
handler = function ()
|
||
|
|
if buff.expanded_potential.up then removeBuff( "expanded_potential" )
|
||
|
|
else
|
||
|
|
removeStack( "clearcasting" )
|
||
|
|
if legendary.sinful_delight.enabled then gainChargeTime( "mirrors_of_torment", 3 ) end
|
||
|
|
end
|
||
|
|
gain( 1, "arcane_charges" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
summon_arcane_familiar = {
|
||
|
|
id = 205022,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 10,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 1041232,
|
||
|
|
|
||
|
|
nobuff = "arcane_familiar",
|
||
|
|
essential = true,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
if buff.arcane_familiar.down then mana.max = mana.max * 1.10 end
|
||
|
|
applyBuff( "arcane_familiar" )
|
||
|
|
end,
|
||
|
|
|
||
|
|
copy = "arcane_familiar"
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
arcane_intellect = {
|
||
|
|
id = 1459,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.04 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
nobuff = "arcane_intellect",
|
||
|
|
essential = true,
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 135932,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "arcane_intellect" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
arcane_missiles = {
|
||
|
|
id = 5143,
|
||
|
|
cast = function () return ( buff.clearcasting.up and 0.8 or 1 ) * 2.5 * haste end,
|
||
|
|
channeled = true,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function ()
|
||
|
|
if buff.rule_of_threes.up or buff.clearcasting.up then return 0 end
|
||
|
|
return 0.15 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 136096,
|
||
|
|
|
||
|
|
aura = function () return buff.clearcasting_channel.up and "clearcasting_channel" or "casting" end,
|
||
|
|
breakchannel = function ()
|
||
|
|
removeBuff( "clearcasting_channel" )
|
||
|
|
end,
|
||
|
|
|
||
|
|
tick_time = function ()
|
||
|
|
if buff.clearcasting_channel.up then return buff.clearcasting_channel.tick_time end
|
||
|
|
return 0.5 * haste
|
||
|
|
end,
|
||
|
|
|
||
|
|
start = function ()
|
||
|
|
if buff.clearcasting.up then
|
||
|
|
removeStack( "clearcasting" )
|
||
|
|
if legendary.sinful_delight.enabled then gainChargeTime( "mirrors_of_torment", 3 ) end
|
||
|
|
applyBuff( "clearcasting_channel" )
|
||
|
|
elseif buff.rule_of_threes.up then removeBuff( "rule_of_threes" ) end
|
||
|
|
|
||
|
|
if buff.expanded_potential.up then removeBuff( "expanded_potential" ) end
|
||
|
|
|
||
|
|
if conduit.arcane_prodigy.enabled and cooldown.arcane_power.remains > 0 then
|
||
|
|
reduceCooldown( "arcane_power", conduit.arcane_prodigy.mod * 0.1 )
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
tick = function () if legendary.arcane_harmony.enabled then addStack( "arcane_harmony", nil, 1 ) end end,
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
arcane_harmony = {
|
||
|
|
id = 332777,
|
||
|
|
duration = 3600,
|
||
|
|
max_stack = 18
|
||
|
|
},
|
||
|
|
clearcasting_channel = {
|
||
|
|
duration = function () return 2.5 * haste end,
|
||
|
|
tick_time = function () return ( 2.5 / 6 ) * haste end,
|
||
|
|
max_stack = 1,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
arcane_orb = {
|
||
|
|
id = 153626,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 20,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.01 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 1033906,
|
||
|
|
|
||
|
|
talent = "arcane_orb",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
gain( 1, "arcane_charges" )
|
||
|
|
applyBuff( "arcane_orb" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
arcane_power = {
|
||
|
|
id = 12042,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = function () return ( essence.vision_of_perfection.enabled and 0.87 or 1 ) * 120 end,
|
||
|
|
gcd = "off",
|
||
|
|
|
||
|
|
toggle = "cooldowns",
|
||
|
|
nobuff = "arcane_power", -- don't overwrite a free proc.
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 136048,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "arcane_power" )
|
||
|
|
if talent.rune_of_power.enabled then applyBuff( "rune_of_power" ) end
|
||
|
|
start_burn_phase()
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
blink = {
|
||
|
|
id = function () return talent.shimmer.enabled and 212653 or 1953 end,
|
||
|
|
cast = 0,
|
||
|
|
charges = function () return talent.shimmer.enabled and 2 or nil end,
|
||
|
|
cooldown = function () return ( talent.shimmer.enabled and 20 or 15 ) - conduit.flow_of_time.mod * 0.001 end,
|
||
|
|
recharge = function () return ( talent.shimmer.enabled and ( 20 - conduit.flow_of_time.mod * 0.001 ) or nil ) end,
|
||
|
|
gcd = "off",
|
||
|
|
|
||
|
|
spend = function () return 0.02 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = function () return talent.shimmer.enabled and 135739 or 135736 end,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
if conduit.tempest_barrier.enabled then applyBuff( "tempest_barrier" ) end
|
||
|
|
end,
|
||
|
|
|
||
|
|
copy = { 212653, 1953, "shimmer", "blink_any" },
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
tempest_barrier = {
|
||
|
|
id = 337299,
|
||
|
|
duration = 15,
|
||
|
|
max_stack = 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
conjure_mana_gem = {
|
||
|
|
id = 759,
|
||
|
|
cast = 3,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 0.18,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 134132,
|
||
|
|
|
||
|
|
usable = function ()
|
||
|
|
if GetItemCount( 36799 ) ~= 0 or fake_mana_gem then return false, "already has a mana_gem" end
|
||
|
|
return true
|
||
|
|
end,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
fake_mana_gem = true
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
mana_gem = {
|
||
|
|
name = "|cff00ccff[Mana Gem]|r",
|
||
|
|
known = function ()
|
||
|
|
return IsUsableItem( 36799 ) or state.fake_mana_gem
|
||
|
|
end,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 120,
|
||
|
|
gcd = "off",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 134132,
|
||
|
|
|
||
|
|
item = 36799,
|
||
|
|
bagItem = true,
|
||
|
|
|
||
|
|
usable = function ()
|
||
|
|
if GetItemCount( 36799 ) == 0 and not fake_mana_gem then return false, "requires mana_gem in bags" end
|
||
|
|
return true
|
||
|
|
end,
|
||
|
|
|
||
|
|
readyTime = function ()
|
||
|
|
local start, duration = GetItemCooldown( 36799 )
|
||
|
|
return max( 0, start + duration - query_time )
|
||
|
|
end,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
gain( 0.25 * health.max, "health" )
|
||
|
|
end,
|
||
|
|
|
||
|
|
copy = "use_mana_gem"
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
--[[ shimmer = {
|
||
|
|
id = 212653,
|
||
|
|
cast = 0,
|
||
|
|
charges = 2,
|
||
|
|
cooldown = 20,
|
||
|
|
recharge = 20,
|
||
|
|
gcd = "off",
|
||
|
|
|
||
|
|
spend = function () return 0.02 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 135739,
|
||
|
|
|
||
|
|
talent = "shimmer",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
-- applies shimmer (212653)
|
||
|
|
end,
|
||
|
|
}, ]]
|
||
|
|
|
||
|
|
|
||
|
|
--[[ conjure_refreshment = {
|
||
|
|
id = 190336,
|
||
|
|
cast = 3,
|
||
|
|
cooldown = 15,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 0.03,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 134029,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
end,
|
||
|
|
}, ]]
|
||
|
|
|
||
|
|
|
||
|
|
counterspell = {
|
||
|
|
id = 2139,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = function () return 24 - ( conduit.grounding_surge.mod * 0.1 ) end, -- Assume always successful.
|
||
|
|
gcd = "off",
|
||
|
|
|
||
|
|
interrupt = true,
|
||
|
|
toggle = "interrupts",
|
||
|
|
|
||
|
|
spend = function () return 0.02 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 135856,
|
||
|
|
|
||
|
|
debuff = "casting",
|
||
|
|
readyTime = state.timeToInterrupt,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
interrupt()
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
evocation = {
|
||
|
|
id = 12051,
|
||
|
|
cast = function () return 6 * haste end,
|
||
|
|
charges = 1,
|
||
|
|
cooldown = 90,
|
||
|
|
recharge = 90,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
channeled = true,
|
||
|
|
fixedCast = true,
|
||
|
|
|
||
|
|
-- toggle = "cooldowns",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 136075,
|
||
|
|
|
||
|
|
aura = "evocation",
|
||
|
|
tick_time = function () return haste end,
|
||
|
|
|
||
|
|
start = function ()
|
||
|
|
stop_burn_phase()
|
||
|
|
applyBuff( "evocation" )
|
||
|
|
if azerite.brain_storm.enabled then
|
||
|
|
gain( 2, "arcane_charges" )
|
||
|
|
applyBuff( "brain_storm" )
|
||
|
|
end
|
||
|
|
|
||
|
|
if legendary.siphon_storm.enabled then
|
||
|
|
applyBuff( "siphon_storm" )
|
||
|
|
end
|
||
|
|
|
||
|
|
mana.regen = mana.regen * 8.5 / haste
|
||
|
|
end,
|
||
|
|
|
||
|
|
tick = function ()
|
||
|
|
if legendary.siphon_storm.enabled then
|
||
|
|
addStack( "siphon_storm", nil, 1 )
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
finish = function ()
|
||
|
|
mana.regen = mana.regen / 8.5 * haste
|
||
|
|
end,
|
||
|
|
|
||
|
|
breakchannel = function ()
|
||
|
|
removeBuff( "evocation" )
|
||
|
|
mana.regen = mana.regen / 8.5 * haste
|
||
|
|
end,
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
-- Legendary
|
||
|
|
siphon_storm = {
|
||
|
|
id = 332934,
|
||
|
|
duration = 30,
|
||
|
|
max_stack = 5
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
fire_blast = {
|
||
|
|
id = 319836,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 12,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
discipline = "fire",
|
||
|
|
|
||
|
|
spend = 0.01,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 135807,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
if legendary.sinful_delight.enabled then gainChargeTime( "mirrors_of_torment", 3 ) end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
focus_magic = {
|
||
|
|
id = 321358,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 0.02,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 135754,
|
||
|
|
|
||
|
|
talent = "focus_magic",
|
||
|
|
|
||
|
|
usable = function () return active_dot.focus_magic == 0 and group, "can apply one in a group" end,
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "focus_magic" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
frostbolt = {
|
||
|
|
id = 116,
|
||
|
|
cast = 1.874,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
discipline = "frost",
|
||
|
|
|
||
|
|
spend = 0.02,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 135846,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "chilled" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
frost_nova = {
|
||
|
|
id = 122,
|
||
|
|
cast = 0,
|
||
|
|
charges = function () return talent.ice_ward.enabled and 2 or nil end,
|
||
|
|
cooldown = 30,
|
||
|
|
recharge = 30,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
discipline = "frost",
|
||
|
|
|
||
|
|
spend = function () return 0.02 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 135848,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "frost_nova" )
|
||
|
|
if legendary.grisly_icicle.enabled then applyDebuff( "target", "grisly_icicle" ) end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
greater_invisibility = {
|
||
|
|
id = 110959,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 120,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
toggle = "defensives",
|
||
|
|
defensive = true,
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 575584,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "greater_invisibility" )
|
||
|
|
if conduit.incantation_of_swiftness.enabled then applyBuff( "incantation_of_swiftness" ) end
|
||
|
|
end,
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
-- Conduit
|
||
|
|
incantation_of_swiftness = {
|
||
|
|
id = 337278,
|
||
|
|
duration = 6,
|
||
|
|
max_stack = 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
ice_block = {
|
||
|
|
id = 45438,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = function () return 240 + ( conduit.winters_protection.mod * 0.001 ) end,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
toggle = "defensives",
|
||
|
|
defensive = true,
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 135841,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "ice_block" )
|
||
|
|
applyDebuff( "player", "hypothermia" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
mirror_image = {
|
||
|
|
id = 55342,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 120,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.02 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
toggle = "cooldowns",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 135994,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "mirror_image", nil, 3 )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
nether_tempest = {
|
||
|
|
id = 114923,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.02 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 610471,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "nether_tempest" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
polymorph = {
|
||
|
|
id = 118,
|
||
|
|
cast = 1.7,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.04 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 136071,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "polymorph" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
presence_of_mind = {
|
||
|
|
id = 205025,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 60,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
toggle = "cooldowns",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 136031,
|
||
|
|
|
||
|
|
nobuff = "presence_of_mind",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "presence_of_mind", nil, level > 53 and 3 or 2 )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
prismatic_barrier = {
|
||
|
|
id = 235450,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 25,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
defensive = true,
|
||
|
|
|
||
|
|
spend = function() return 0.03 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 135991,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "prismatic_barrier" )
|
||
|
|
if legendary.triune_ward.enabled then
|
||
|
|
applyBuff( "blazing_barrier" )
|
||
|
|
applyBuff( "ice_barrier" )
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
remove_curse = {
|
||
|
|
id = 475,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 8,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.01 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 136082,
|
||
|
|
|
||
|
|
debuff = "dispellable_curse",
|
||
|
|
handler = function ()
|
||
|
|
removeDebuff( "player", "dispellable_curse" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
ring_of_frost = {
|
||
|
|
id = 113724,
|
||
|
|
cast = 2,
|
||
|
|
cooldown = 45,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.08 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 464484,
|
||
|
|
|
||
|
|
talent = "ring_of_frost",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
rune_of_power = {
|
||
|
|
id = 116011,
|
||
|
|
cast = 1.5,
|
||
|
|
charges = 2,
|
||
|
|
cooldown = 40,
|
||
|
|
recharge = 40,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 609815,
|
||
|
|
|
||
|
|
nobuff = "rune_of_power",
|
||
|
|
talent = "rune_of_power",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "rune_of_power" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
slow = {
|
||
|
|
id = 31589,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.01 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 136091,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "slow" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
slow_fall = {
|
||
|
|
id = 130,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.01 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 135992,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "slow_fall" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
spellsteal = {
|
||
|
|
id = 30449,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return 0.21 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 135729,
|
||
|
|
|
||
|
|
debuff = "stealable_magic",
|
||
|
|
handler = function ()
|
||
|
|
removeDebuff( "target", "stealable_magic" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
supernova = {
|
||
|
|
id = 157980,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 25,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 1033912,
|
||
|
|
|
||
|
|
talent = "supernova",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
time_warp = {
|
||
|
|
id = 80353,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 300,
|
||
|
|
gcd = "off",
|
||
|
|
|
||
|
|
spend = function () return 0.04 * ( buff.arcane_power.up and ( talent.overpowered.enabled and 0.5 or 0.7 ) or 1 ) end,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
toggle = "cooldowns",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 458224,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "time_warp" )
|
||
|
|
applyDebuff( "player", "temporal_displacement" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
touch_of_the_magi = {
|
||
|
|
id = 321507,
|
||
|
|
cast = 1.5,
|
||
|
|
cooldown = 45,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 0.05,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 1033909,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "touch_of_the_magi")
|
||
|
|
if level > 45 then gain( 4, "arcane_charges" ) end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
-- Mage - Kyrian - 307443 - radiant_spark (Radiant Spark)
|
||
|
|
-- TODO: Increase vulnerability stack on direct damage spells.
|
||
|
|
radiant_spark = {
|
||
|
|
id = 307443,
|
||
|
|
cast = 1.5,
|
||
|
|
cooldown = 30,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 0.02,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 3565446,
|
||
|
|
|
||
|
|
toggle = "essences",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "radiant_spark" )
|
||
|
|
applyDebuff( "target", "radiant_spark_vulnerability" )
|
||
|
|
end,
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
radiant_spark = {
|
||
|
|
id = 307443,
|
||
|
|
duration = 8,
|
||
|
|
max_stack = 1
|
||
|
|
},
|
||
|
|
radiant_spark_vulnerability = {
|
||
|
|
id = 307454,
|
||
|
|
duration = 8,
|
||
|
|
max_stack = 4
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
-- Mage - Necrolord - 324220 - deathborne (Deathborne)
|
||
|
|
deathborne = {
|
||
|
|
id = 324220,
|
||
|
|
cast = 1.5,
|
||
|
|
cooldown = 180,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 0.05,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 3578226,
|
||
|
|
|
||
|
|
toggle = "essences", -- maybe should be cooldowns.
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "deathborne" )
|
||
|
|
end,
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
deathborne = {
|
||
|
|
id = 324220,
|
||
|
|
duration = function () return 20 + ( conduit.gift_of_the_lich.mod * 0.001 ) end,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
-- Mage - Night Fae - 314791 - shifting_power (Shifting Power)
|
||
|
|
shifting_power = {
|
||
|
|
id = 314791,
|
||
|
|
cast = function () return 4 * haste end,
|
||
|
|
channeled = true,
|
||
|
|
cooldown = 45,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 0.05,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 3636841,
|
||
|
|
|
||
|
|
toggle = "essences",
|
||
|
|
|
||
|
|
-- -action.shifting_power.execute_time%action.shifting_power.new_tick_time*(dbc.effect.815503.base_value%1000+conduit.discipline_of_the_grove.time_value)
|
||
|
|
cdr = function ()
|
||
|
|
return - action.shifting_power.execute_time / action.shifting_power.tick_time * ( -3 + conduit.discipline_of_the_grove.time_value )
|
||
|
|
end,
|
||
|
|
|
||
|
|
full_reduction = function ()
|
||
|
|
return - action.shifting_power.execute_time / action.shifting_power.tick_time * ( -3 + conduit.discipline_of_the_grove.time_value )
|
||
|
|
end,
|
||
|
|
|
||
|
|
start = function ()
|
||
|
|
applyBuff( "shifting_power" )
|
||
|
|
end,
|
||
|
|
|
||
|
|
tick = function ()
|
||
|
|
-- TODO: Identify which abilities have their CDs reduced.
|
||
|
|
end,
|
||
|
|
|
||
|
|
finish = function ()
|
||
|
|
removeBuff( "shifting_power" )
|
||
|
|
end,
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
shifting_power = {
|
||
|
|
id = 314791,
|
||
|
|
duration = function () return 4 * haste end,
|
||
|
|
tick_time = function () return haste end,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
heart_of_the_fae = {
|
||
|
|
id = 356881,
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 1,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
-- Mage - Venthyr - 314793 - mirrors_of_torment (Mirrors of Torment)
|
||
|
|
-- TODO: Get spell ID of the snare, root, silence.
|
||
|
|
mirrors_of_torment = {
|
||
|
|
id = 314793,
|
||
|
|
cast = 1.5,
|
||
|
|
cooldown = 90,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 0.04,
|
||
|
|
spendType = "mana",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 3565720,
|
||
|
|
|
||
|
|
toggle = "essences",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "mirrors_of_torment", nil, 3 )
|
||
|
|
end,
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
mirrors_of_torment = {
|
||
|
|
id = 314793,
|
||
|
|
duration = 20,
|
||
|
|
max_stack = 3, -- ???
|
||
|
|
},
|
||
|
|
-- Conduit
|
||
|
|
siphoned_malice = {
|
||
|
|
id = 337090,
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 3
|
||
|
|
}
|
||
|
|
},
|
||
|
|
},
|
||
|
|
} )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterSetting( "arcane_info", nil, {
|
||
|
|
type = "description",
|
||
|
|
name = "The Arcane Mage module treats combat as one of two phases. The 'Burn' phase begins when you have used Arcane Power and begun aggressively burning mana. The 'Conserve' phase starts when you've completed a burn phase and used Evocation to refill your mana bar. This phase is less " ..
|
||
|
|
"aggressive with mana expenditure, so that you will be ready when it is time to start another burn phase.",
|
||
|
|
width = "full",
|
||
|
|
fontSize = "medium",
|
||
|
|
order = 1,
|
||
|
|
} )
|
||
|
|
|
||
|
|
--[[ spec:RegisterSetting( "am_spam", 0, {
|
||
|
|
type = "toggle",
|
||
|
|
name = "Use |T136096:0|t Arcane Missiles Spam",
|
||
|
|
icon = 136096,
|
||
|
|
width = "full",
|
||
|
|
get = function () return Hekili.DB.profile.specs[ 62 ].settings.am_spam == 1 end,
|
||
|
|
set = function ( _, val )
|
||
|
|
Hekili.DB.profile.specs[ 62 ].settings.am_spam = val and 1 or 0
|
||
|
|
end,
|
||
|
|
order = 2,
|
||
|
|
} ) ]]
|
||
|
|
|
||
|
|
|
||
|
|
--[[ spec:RegisterSetting( "conserve_mana", 75, { -- NYI
|
||
|
|
type = "range",
|
||
|
|
name = "Minimum Mana (Conserve Phase)",
|
||
|
|
desc = "Specify the amount of mana (%) that should be conserved when conserving mana before a burn phase.",
|
||
|
|
|
||
|
|
min = 25,
|
||
|
|
max = 100,
|
||
|
|
step = 1,
|
||
|
|
|
||
|
|
width = "full",
|
||
|
|
order = 2,
|
||
|
|
}
|
||
|
|
} ) ]]
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterOptions( {
|
||
|
|
enabled = true,
|
||
|
|
|
||
|
|
aoe = 3,
|
||
|
|
|
||
|
|
nameplates = true,
|
||
|
|
nameplateRange = 8,
|
||
|
|
|
||
|
|
damage = true,
|
||
|
|
damageExpiration = 6,
|
||
|
|
|
||
|
|
potion = "spectral_intellect",
|
||
|
|
|
||
|
|
package = "Arcane",
|
||
|
|
} )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterPack( "Arcane", 20210707, [[da1k6gqiPK6rQQuUerfPKnrr(ecAuirNcjSkPeYRqOAwuuDlPKGDrYViImmIOogrPLruPNHqPPruHUgcfBJOI6BsjIXjLiDoPeyDeH6DevKsnpvv5EiP9ruLdkLOwOQQ6HQQKjsurkUirfXgjQiv(irfjgjrfjDsPKOvsr5LevKQMjri3ukHANeb)uvLQAOsjPLQQsLNsjtvvfxLOc6RevGXsuv7vv(lPgSshg1IrQhtyYaUm0MLQplfJMsDAqRwkj0RrGzRWTr0UP63IgofoUucA5cpxrtxLRd02jsFxvz8efNxk16vvPkZhHSFj)K99ZZcGp8jb5kz5kRKBjsULOKClqwjl3wWZ6ABGpldwqa3GplNjXNvlhc2XNLb3EKmW7NN1mbdb(SSVZykXsssnWZgKwjssjnHKGd(GPlcUFsAcjfs6zrdchxR0F0pla(WNeKRKLRSsULi5wIsYTazLSCL7ZAAGINeKZY9zzdbaq)r)SaWP4z1I5gS2woeSJLzMboAxBlX8ALRKLRSLzLz)YM9gCkXLzTc1khoXAV2gqbpQ1cs(RATzhya9MAZETcB2DCul0pmcqJdMETqFEiduB2RLqb7cCOzXbtNqvzwRqT)YM9gSwoeSJAO3Ho8Ax7L1YHGDuBZbz6TRLs4vRJsXO2p0VAhqPyT8SwoeSJAO3Ho8AtH6znGZB((5zLgOJX7NNeK99ZZcDMEGaV)FwIaEya5Nva6ypJgubaNcOXa6C0wlsss2buOZ0deOwt1sd27ka4uangqNJ2ArssYoGUh58uGgplwCW0FwDyGA6bpV39KGCF)8SqNPhiW7)NLiGhgq(zfGo2ZObvnbCoARHcOyGk0z6bcuRPAjzNvgIRw5vBlGyEwS4GP)S6ropTNs539KaX((5zXIdM(Zca5ZModhFwOZ0de49)7Esqo((5zHotpqG3)plrapmG8ZIKDwziUALxTYrj)SyXbt)zfmaK9tpn4GG39KaX8(5zXIdM(ZIegrgtD21xgKOFpl0z6bc8()DpjiNF)8SqNPhiW7)NLiGhgq(zrd27koeSJAJ8ddfq(51AQwrMdG8ZvCiyh1g5hgQajzOpFwS4GP)SM2W(b9gTr(HX7EsOL8(5zHotpqG3)plrapmG8ZsK5ai)Cfhc2rTr(HHkqgODTMQLgS3vCiyh1cBoAq18ybb1(xT0G9UIdb7OwyZrdQizz0ZJfe8SyXbt)zXHGDuNb97EsOL((5zHotpqG3)plrapmG8ZsKsrN9tjf9ZUDuRPAfzoaYpxrcJiJPo76lds0pvGKm0N1kVABPYXNfloy6ploeSJA6bpV39Kql49ZZIfhm9N1LGcBD21NnQj5g4ZcDMEGaV)F3tcYk53pplwCW0FwCiyh1g5hgpl0z6bc8()DpjiRSVFEwOZ0de49)ZseWddi)SOb7Dfhc2rTr(HHci)8Nfloy6pRa0rD21g5hgV7jbzL77NNf6m9abE))SyXbt)zze4eDbQZUMe6aplaCkcOXbt)zjhoXAB1Sfx7L1oBHGi(7H1YETOmxW12YHGDS2)h88QfamGEtTNnw7p51ILul3Q1(bDG8RwqFGZzTbO7qVP2woeSJ1kNiStvTTYETTCiyhRvoryN1cN1E8a9dbmV2pSwb7eE1coXAB1Sfx7h8SHETNnw7p51ILul3Q1(bDG8RwqFGZzTFyTq)WianUApBS2wUfxRWMDhhMx7mR9djCmQDYsXAHN6zjc4HbKFwTU2JhOFkoeSJAuyNk0z6bcuRPAbqAWExDjOWwND9zJAsUbQanQ1uTainyVRUeuyRZU(Srnj3avbsYqFw7FuRLYAzXbtxXHGDutp45Pqzqb4H6dsI12IQLgS3vgborxG6SRjHoGIKLrppwqqTu8UNeKLyF)8SqNPhiW7)Nfloy6plJaNOlqD21Kqh4zbGtranoy6pRwzV2wnBX1AZtNWRwAe9AbNiqTaGb0BQ9SXA)jVwCTFqhi)mV2pKWXOwWjwl8Q9YANTqqe)9WAzVwuMl4AB5qWow7)dEE1c9ApBS2Fx2QsQLB1A)Goq(PEwIaEya5NfnyVR4qWoQnYpmuGg1AQwAWExfGoQZU2i)Wqfijd9zT)rTwkRLfhmDfhc2rn9GNNcLbfGhQpijwBlQwAWExze4eDbQZUMe6akswg98ybb1sX7Esqw547NNf6m9abE))Seb8WaYplG8ubdaz)0tdoiqfijd9zTYRwIPwIiQwaKgS3vbdaz)0tdoiqlfC4yW0Wb8ARMhliOw5vRKFwS4GP)S4qWoQPh88E3tcYsmVFEwOZ0de49)ZIfhm9Nfhc2rnnhb3GplaCkcOXbt)z1YJpU9S2)5i4gSw(Q9SXArhO2SxBl3Q1(zJETbO7qVP2ZgRTLdb7yTYPYbz6TRDGnOdWr7NLiGhgq(zrd27koeSJAJ8ddfOrTMQLgS3vCiyh1g5hgQajzOpR9VABea1AQ2a0XEgnOIdb7O2MdY0BRqNPhiW7Esqw587NNf6m9abE))SyXbt)zXHGDutZrWn4ZcaNIaACW0FwT84JBpR9FocUbRLVApBSw0bQn71E2yT)USvR9d6a5xTF2OxBa6o0BQ9SXAB5qWowRCQCqME7Ahyd6aC0(zjc4HbKFw0G9UkaDuNDTr(HHc0Owt1sd27koeSJAJ8ddfq(51AQwAWExfGoQZU2i)Wqfijd9zT)rT2gbqTMQnaDSNrdQ4qWoQT5Gm92k0z6bc8UNeKTL8(5zHotpqG3)plHnd9NLSplKJrBTWMHUg2Fw0G9Usmqoe88GEJwyZUJdfq(5MOKgS3vCiyh1g5hgkqdIiIYwF8a9tLsXWi)WabmrjnyVRcqh1zxBKFyOaniIirMdG8ZvO0uWhmDvGmqBkOGINLiGhgq(zbG0G9U6sqHTo76Zg1KCdubAuRPApEG(P4qWoQrHDQqNPhiqTMQLYAPb7DfaYNnDgoQaYpVwIiQwwCqPOgDKeIZAPwRS1srTMQfaPb7D1LGcBD21NnQj5gOkqsg6ZALxTS4GPR4qWoQjHZjCGtfkdkapuFqs8zXIdM(ZIdb7OMeoNWboF3tcY2sF)8SqNPhiW7)NLiGhgq(zrd27kXa5qWZd6nQ5XccQLAT0G9Usmqoe88GEJIKLrppwqqTMQvKsrN9tjf9ZUD8SyXbt)zXHGDutcNt4aNV7jbzBbVFEwOZ0de49)ZIfhm9Nfhc2rnjCoHdC(Se2m0FwY(Seb8WaYplAWExjgihcEEqVrfilUAnvRiZbq(5koeSJAJ8ddvGKm0N1AQwkRLgS3vbOJ6SRnYpmuGg1ser1sd27koeSJAJ8ddfOrTu8UNeKRKF)8SqNPhiW7)NLiGhgq(zrd27koeSJAHnhnOAESGGA)JATs5aY0duD5rQjzz0cBoAW5ZIfhm9Nfhc2rDg0V7jb5k77NNf6m9abE))Seb8WaYplAWExfGoQZU2i)WqbAulrevlj7SYqC1kVALLyEwS4GP)S4qWoQPh88E3tcYvUVFEwOZ0de49)ZIfhm9Nfknf8bt)zb9dJa040W(ZIKDwzio5rTLsmplOFyeGgNgssIaq(WNLSplrapmG8ZIgS3vbOJ6SRnYpmua5NxRPAPb7Dfhc2rTr(HHci)839KGCj23pplwCW0FwCiyh10CeCd(SqNPhiW7)39UNvhoTHEJonqhJ3ppji77NNf6m9abE))SyXbt)zHstbFW0Fwa4ueqJdM(ZsoWg9Adq3HEtTi8SXO2ZgR1YQ2mQ9h5GAhyd6aCaXP51(H1(X(v7L1kNinRLg7zG1E2yT)KxlwsTCRw7h0bYpvTYHtSw4vlpRDMPxlpR93LTAT28S2o0HtBeO2emQ9djukw70a9R2emQvyZrdoFwIaEya5NfL1gGo2ZObvhsAKbp0FCyOqNPhiqTeruTuwBa6ypJgunHg2PRNxgKk0z6bcuRPABDTs5aY0duzeOb4yOrPzTuRv2APOwkQ1uTuwlnyVRcqh1zxBKFyOaYpVwIiQwJaLQBeakzvCiyh10CeCdwlf1AQwrMdG8ZvbOJ6SRnYpmubsYqF(U
|
||
|
|
|
||
|
|
|
||
|
|
end
|