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.
2094 lines
88 KiB
2094 lines
88 KiB
-- WarriorProtection.lua
|
|
-- August 2024
|
|
-- 11.0.2
|
|
|
|
if UnitClassBase( "player" ) ~= "WARRIOR" then return end
|
|
|
|
local addon, ns = ...
|
|
local Hekili = _G[ addon ]
|
|
local class, state = Hekili.Class, Hekili.State
|
|
|
|
local FindPlayerAuraByID, RangeType = ns.FindPlayerAuraByID, ns.RangeType
|
|
|
|
local strformat = string.format
|
|
|
|
local spec = Hekili:NewSpecialization( 73 )
|
|
|
|
local base_rage_gen = 2
|
|
|
|
spec:RegisterResource( Enum.PowerType.Rage, {
|
|
mainhand = {
|
|
swing = "mainhand",
|
|
|
|
last = function ()
|
|
local swing = state.swings.mainhand
|
|
local t = state.query_time
|
|
|
|
return ( swing + floor( ( t - swing ) / state.swings.mainhand_speed ) * state.swings.mainhand_speed )
|
|
end,
|
|
|
|
interval = "mainhand_speed",
|
|
|
|
stop = function () return state.time == 0 or state.swings.mainhand == 0 end,
|
|
value = function ()
|
|
if state.talent.devastator.enabled then -- 1 Rage for instigate with devastator, 2 rage for instigate with devastate
|
|
return ( base_rage_gen * ( state.talent.war_machine.enabled and 1.5 or 1 ) ) + ( state.talent.instigate.enabled and 1 or 0 ) -- 1 Rage for instigate
|
|
else
|
|
return ( base_rage_gen * ( state.talent.war_machine.enabled and 1.5 or 1 ) ) + ( state.talent.instigate.enabled and 2 or 0 ) -- 2 Rage for instigate
|
|
end
|
|
end
|
|
},
|
|
|
|
conquerors_banner = {
|
|
aura = "conquerors_banner",
|
|
|
|
last = function ()
|
|
local app = state.buff.conquerors_banner.applied
|
|
local t = state.query_time
|
|
|
|
return app + floor( t - app )
|
|
end,
|
|
|
|
interval = 1,
|
|
|
|
value = 4,
|
|
},
|
|
|
|
ravager = {
|
|
aura = "ravager",
|
|
|
|
last = function ()
|
|
local app = state.buff.ravager.applied
|
|
local t = state.query_time
|
|
|
|
return app + floor( ( t - app ) / state.haste ) * state.haste
|
|
end,
|
|
|
|
interval = function () return state.haste end,
|
|
|
|
value = function () return state.talent.storm_of_steel.enabled and 20 or 10 end,
|
|
},
|
|
} )
|
|
|
|
-- Talents
|
|
spec:RegisterTalents( {
|
|
-- Warrior
|
|
armored_to_the_teeth = { 90259, 394855, 2 }, -- Gain Strength equal to 2% of your Armor.
|
|
avatar = { 92639, 401150, 1 }, -- Transform into a colossus for 20 sec, causing you to deal 20% increased damage and removing all roots and snares. Generates 10 Rage.
|
|
barbaric_training = { 95954, 390675, 1 }, -- Revenge deals 25% increased damage but now costs 10 more rage.
|
|
battle_stance = { 90261, 386164, 1 }, -- A balanced combat state that increases the critical strike chance of your abilities by 3% and reduces the duration of movement impairing effects by 10%. Lasts until canceled.
|
|
berserker_shout = { 90348, 384100, 1 }, -- Go berserk, removing and granting immunity to Fear, Sap, and Incapacitate effects for 6 sec. Also remove fear effects from group members within 12 yds.
|
|
bitter_immunity = { 90356, 383762, 1 }, -- Restores 20% health instantly and removes all diseases, poisons and curses affecting you.
|
|
bounding_stride = { 90355, 202163, 1 }, -- Reduces the cooldown of Heroic Leap by 15 sec, and Heroic Leap now also increases your movement speed by 70% for 3 sec.
|
|
cacophonous_roar = { 90383, 382954, 1 }, -- Intimidating Shout can withstand 200% more damage before breaking.
|
|
champions_might = { 90323, 386284, 1 }, -- The duration of Champion's Spear is increased by 2 sec. You deal 25% increased critical strike damage to targets chained to your Spear.
|
|
champions_spear = { 90380, 376079, 1 }, -- Throw a spear at the target location, dealing 109,239 Physical damage instantly and an additional 114,148 damage over 4 sec. Deals reduced damage beyond 5 targets. Enemies hit are chained to the spear's location for the duration. Generates 10 Rage.
|
|
concussive_blows = { 90354, 383115, 1 }, -- Cooldown of Pummel reduced by 1.0 sec. Successfully interrupting an enemy increases the damage you deal to them by 5% for 10 sec.
|
|
crackling_thunder = { 95959, 203201, 1 }, -- Thunder Clap's radius is increased by 50%, and it reduces movement speed by an additional 20%.
|
|
cruel_strikes = { 90381, 392777, 2 }, -- Critical strike chance increased by 1% and critical strike damage of Execute increased by 5%.
|
|
crushing_force = { 90369, 390642, 2 }, -- Shield Slam deals an additional 5% damage and deals 5% increased critical strike damage.
|
|
defensive_stance = { 90330, 386208, 1 }, -- A defensive combat state that reduces all damage you take by 16%. Lasts until canceled.
|
|
double_time = { 90382, 103827, 1 }, -- Increases the maximum number of charges on Charge by 1, and reduces its cooldown by 3 sec.
|
|
endurance_training = { 90339, 382940, 2 }, -- Stamina increased by 5% and the duration of Fear, Sap and Incapacitate effects on you is reduced by 10.0%.
|
|
fast_footwork = { 90344, 382260, 1 }, -- Movement speed increased by 5%.
|
|
frothing_berserker = { 90370, 392790, 1 }, -- Revenge has a 20% chance to immediately refund 25% of the Rage spent.
|
|
heroic_leap = { 90346, 6544 , 1 }, -- Leap through the air toward a target location, slamming down with destructive force to deal 15,558 Physical damage to all enemies within 8 yards, and resetting the remaining cooldown on Taunt.
|
|
honed_reflexes = { 95956, 391271, 1 }, -- Cooldown of Shield Wall, Pummel, Intervene, Spell Reflection, and Storm Bolt reduced by 5%.
|
|
immovable_object = { 90364, 394307, 1 }, -- Activating Avatar or Shield Wall grants 4 sec of the other.
|
|
impending_victory = { 90326, 202168, 1 }, -- Instantly attack the target, causing 39,061 damage and healing you for 30% of your maximum health. Killing an enemy that yields experience or honor resets the cooldown of Impending Victory and makes it cost no Rage.
|
|
intervene = { 90329, 3411 , 1 }, -- Run at high speed toward an ally, intercepting all melee and ranged attacks against them for 6 sec while they remain within 10 yds.
|
|
intimidating_shout = { 90384, 5246 , 1 }, -- Causes the targeted enemy to cower in fear, and up to 5 additional enemies within 8 yards to flee. Targets are disoriented for 8 sec.
|
|
leeching_strikes = { 90371, 382258, 1 }, -- Leech increased by 3%.
|
|
menace = { 90383, 275338, 1 }, -- Intimidating Shout will knock back all nearby enemies except your primary target, and cause them all to cower in fear for 15 sec instead of fleeing.
|
|
onehanded_weapon_specialization = { 90324, 382895, 1 }, -- Damage with one-handed weapons and Leech increased by 5%.
|
|
overwhelming_rage = { 90378, 382767, 2 }, -- Maximum Rage increased by 15.
|
|
pain_and_gain = { 90353, 382549, 1 }, -- When you take any damage, heal for 2% of your maximum health. This can only occur once every 10 sec.
|
|
piercing_challenge = { 90379, 382948, 1 }, -- Champion's Spear's damage increased by 50% and its Rage generation is increased by 100%.
|
|
piercing_howl = { 90348, 12323 , 1 }, -- Snares all enemies within 12 yards, reducing their movement speed by 70% for 8 sec.
|
|
rallying_cry = { 90331, 97462 , 1 }, -- Lets loose a rallying cry, granting all party or raid members within 40 yards 10% temporary and maximum health for 10 sec.
|
|
reinforced_plates = { 90368, 382939, 1 }, -- Armor increased by 10%.
|
|
rumbling_earth = { 90374, 275339, 1 }, -- Shockwave's range increased by 6 yards and when Shockwave strikes at least 3 targets, its cooldown is reduced by 15 sec.
|
|
second_wind = { 90332, 29838 , 1 }, -- Restores 6% health every 1 sec when you have not taken damage for 5 sec. While you are below 35% health, restores 1.0% health every 1 sec. The amount restored increases the closer you are to death.
|
|
seismic_reverberation = { 90354, 382956, 1 }, -- If Whirlwind or Revenge hits 3 or more enemies, it hits them 1 additional time for 30% damage.
|
|
shattering_throw = { 90351, 64382 , 1 }, -- Hurl your weapon at the enemy, causing 63,053 Physical damage, ignoring armor, and removing any magical immunities. Deals up to 500% increased damage to absorb shields.
|
|
shockwave = { 90375, 46968 , 1 }, -- Sends a wave of force in a frontal cone, causing 19,862 damage and stunning all enemies within 16 yards for 2 sec.
|
|
sidearm = { 95954, 384404, 1 }, -- Your auto-attacks have a 20% chance to hurl weapons at your target and 3 other enemies in front of you, dealing an additional 16,551 Physical damage.
|
|
spell_reflection = { 90385, 23920 , 1 }, -- Raise your shield, reflecting the first spell cast on you, and reduce magic damage you take by 25% for 5 sec.
|
|
storm_bolt = { 90337, 107570, 1 }, -- Hurls your weapon at an enemy, causing 18,868 Physical damage and stunning for 4 sec.
|
|
thunder_clap = { 90343, 6343 , 1 }, -- Blasts all enemies within 8 yards for 32,507 Physical damage and reduces their movement speed by 20% for 10 sec. Deals reduced damage beyond 5 targets. Generates 5 Rage. If you have Rend, Thunder Clap affects 5 nearby targets with Rend.
|
|
thunderous_roar = { 90359, 384318, 1 }, -- Roar explosively, dealing 114,403 Physical damage to enemies within 12 yds and cause them to bleed for 131,423 physical damage over 8 sec.
|
|
thunderous_words = { 90358, 384969, 1 }, -- Increases the duration of Thunderous Roar's Bleed effect by 2.0 sec and Thunderous Roar's Bleed effect causes enemies to take 30% increased damage from all your bleeds.
|
|
unstoppable_force = { 90364, 275336, 1 }, -- Avatar increases the damage of Thunder Clap and Shockwave by 50% and reduces the cooldown of Thunder Clap by 50%.
|
|
uproar = { 90357, 391572, 1 }, -- Thunderous Roar's cooldown reduced by 45 sec.
|
|
war_machine = { 90345, 316733, 1 }, -- Your auto attacks generate 50% more Rage. Killing an enemy instantly generates 5 Rage, and increases your movement speed by 30% for 8 sec.
|
|
wild_strikes = { 90360, 382946, 2 }, -- Haste increased by 1% and your auto-attack critical strikes increase your auto-attack speed by 10% for 10 sec.
|
|
wrecking_throw = { 90351, 384110, 1 }, -- Hurl your weapon at the enemy, causing 63,053 Physical damage, ignoring armor. Deals up to 500% increased damage to absorb shields.
|
|
|
|
-- Protection
|
|
anger_management = { 90311, 152278, 1 }, -- Every 10 Rage you spend reduces the remaining cooldown on Avatar and Shield Wall by 1 sec.
|
|
battering_ram = { 90262, 394312, 1 }, -- Shield Charge critical strike chance and critical strike damage increased by 20%, and Shield Charge increases your auto-attack damage and speed by 10% for 20 sec.
|
|
battlescarred_veteran = { 90435, 386394, 1 }, -- When your health is brought below 30%, you take 80% less damage for 8 sec and healing you receive is increased by 100%. Cannot occur more than once every 3 min.
|
|
best_served_cold = { 90304, 202560, 1 }, -- Revenge deals 10% more damage, or 20% more damage when your successful dodges or parries have made it cost no Rage.
|
|
bloodborne = { 90448, 385704, 2 }, -- Deep Wounds, Rend and Thunderous Roar's Bleed effects deal 10% increased damage.
|
|
bloodsurge = { 90300, 384361, 1 }, -- Damage from your Bleed effects have a 10% chance to grant you 5 Rage.
|
|
bolster = { 90264, 280001, 1 }, -- Last Stand's cooldown is reduced by 60 sec, and it grants you the Shield Block effect for its duration.
|
|
booming_voice = { 90314, 202743, 1 }, -- Demoralizing Shout also generates 30 Rage, and increases damage you deal to affected targets by 20%.
|
|
brace_for_impact = { 90296, 386030, 1 }, -- Using Shield Slam increases the damage of Shield Slam by 5% for 16 sec, and it increases the block value of your shield by 3%. Stacking up to 5 times.
|
|
brutal_vitality = { 90451, 384036, 1 }, -- 10% of damage you deal adds to your active Ignore Pain.
|
|
challenging_shout = { 90309, 1161 , 1 }, -- Taunts all enemies within 10 yds to attack you for 6 sec.
|
|
champions_bulwark = { 90316, 386328, 1 }, -- Shield Charge deals 20% increased damage, grants you Shield Block, makes your next Revenge cost no Rage, and generates an additional 20 Rage.
|
|
dance_of_death = { 90260, 390713, 1 }, -- When an enemy dies while affected by your Ravager, its duration is extended by 2 sec. This effect can trigger a maximum of 3 times per use of Ravager.
|
|
defenders_aegis = { 90310, 397103, 1 }, -- Shield Wall gains 1 additional charge, and its cooldown is reduced by 60 sec.
|
|
demoralizing_shout = { 90305, 1160 , 1 }, -- Demoralizes all enemies within 15 yards, reducing the damage they deal to you by 20% for 8 sec. Generates 30 Rage.
|
|
devastator = { 90299, 236279, 1 }, -- Your auto attacks deal an additional 23,172 Physical damage and have a 20% chance to reset the remaining cooldown on Shield Slam.
|
|
disrupting_shout = { 90307, 386071, 1 }, -- Taunts all enemies within 14 yds to attack you for 6 sec, interrupts all spellcasting within 14 yds and prevents any spell in that school from being cast for 6 sec.
|
|
enduring_alacrity = { 90433, 384063, 1 }, -- Increases Stamina and Armor by 8% and your Haste by 2%.
|
|
enduring_defenses = { 90313, 386027, 1 }, -- Shield Block lasts 2 sec longer.
|
|
fight_through_the_flames = { 90306, 452494, 1 }, -- Defensive Stance additionally reduces magic damage you take by 6%.
|
|
focused_vigor = { 90318, 384067, 1 }, -- Increases Strength and Armor by 5% and your critical strike chance by 1%.
|
|
fueled_by_violence = { 90451, 383103, 1 }, -- You are healed for 110% of the damage dealt by Deep Wounds.
|
|
heavy_repercussions = { 90319, 203177, 1 }, -- Shield Slam generates 2 more Rage and extends the duration of Shield Block by 1.0 sec.
|
|
ignore_pain = { 90295, 190456, 1 }, -- Fight through the pain, ignoring 50% of damage taken, up to 1.8 million total damage prevented.
|
|
impenetrable_wall = { 90310, 384072, 1 }, -- Shield Slam generates an additional 4 Rage and reduces the remaining cooldown of Shield Wall by 6 sec.
|
|
indomitable = { 90434, 202095, 1 }, -- Your maximum health is increased by 6%, and every 20 Rage you spend heals you for 1% of your maximum health.
|
|
instigate = { 90301, 394311, 1 }, -- Devastate deals 20% increased damage and generates 2 Rage. Devastator deals 10% increased damage and generates 1 Rage.
|
|
into_the_fray = { 90319, 202603, 1 }, -- You gain 2% Haste for each enemy or ally within 10 yards, up to 8% Haste.
|
|
juggernaut = { 90449, 393967, 1 }, -- Execute increases Execute's damage dealt by 3% for 20 sec, stacking up to 15 times.
|
|
last_stand = { 90297, 12975 , 1 }, -- Increases maximum health by 30% for 15 sec, and instantly heals you for that amount.
|
|
massacre = { 90313, 281001, 1 }, -- Execute is now usable on targets below 35% health.
|
|
punish = { 90449, 275334, 1 }, -- Shield Slam deals 10% increased damage, and reduces enemies' damage against you by 2% for 9 sec. Multiple punishments may overlap.
|
|
ravager = { 90432, 228920, 1 }, -- Throws a whirling weapon at the target location that chases nearby enemies, inflicting 327,423 Physical damage to all enemies over 10.4 sec. Deals reduced damage beyond 8 targets. Generates 10 Rage each time it deals damage.
|
|
rend = { 90302, 394062, 1 }, -- Wounds the target, causing 25,927 Physical damage instantly and an additional 80,044 Bleed damage over 15 sec. Thunder Clap affects 5 nearby targets with Rend.
|
|
revenge = { 90298, 6572 , 1 }, -- Swing in a wide arc, dealing 37,983 Physical damage to all enemies in front of you. Deals reduced damage beyond 5 targets. Your successful dodges and parries have a chance to make your next Revenge cost no Rage.
|
|
shield_charge = { 90317, 385952, 1 }, -- Charge to an enemy with your shield, dealing 222,120 Physical damage to it and 88,848 Physical damage to all enemies within 10 yards. Also stuns the primary target for 4 sec. Generates 20 Rage.
|
|
shield_specialization = { 90315, 386011, 2 }, -- Increases Block chance by 6% and your Block value by 12%.
|
|
shield_wall = { 90312, 871 , 1 }, -- Reduces all damage you take by 40% for 8 sec.
|
|
show_of_force = { 90320, 385843, 1 }, -- Revenge damage increased by 10% and Revenge increases the damage of your next Thunder Clap by 20%.
|
|
spell_block = { 90450, 392966, 1 }, -- You are able to block spells for 30 sec.
|
|
storm_of_steel = { 90260, 382953, 1 }, -- Ravager's damage is reduced by 30% but it now has 2 charges and generates 10 additional Rage each time it deals damage.
|
|
strategist = { 90303, 384041, 1 }, -- Devastate, Thunder Clap, Revenge, and Execute have a 30% chance to reset the remaining cooldown on Shield Slam.
|
|
sudden_death = { 90320, 29725 , 1 }, -- Your attacks have a chance to make your next Execute cost no Rage, be usable on any target regardless of their health, and deal damage as if you spent 40 Rage.
|
|
thunderlord = { 90308, 385840, 1 }, -- Increases the radius of Demoralizing Shout by 5 yards. Each enemy hit by Thunder Clap reduces the remaining cooldown on Demoralizing Shout by 1.5 sec, up to 4.5 sec.
|
|
tough_as_nails = { 90450, 385888, 1 }, -- Blocking an attack deals 18,915 Physical damage to the attacker, ignoring armor. Generates high threat.
|
|
unnerving_focus = { 90452, 384042, 1 }, -- Last Stand increases your Rage generation by 50%.
|
|
violent_outburst = { 90265, 386477, 1 }, -- Consuming 30 rage grants a stack of Seeing Red, which transforms at 8 stacks into Violent Outburst, causing your next Shield Slam or Thunder Clap to deal 200% increased damage, generate 100% more Rage and grant Ignore Pain.
|
|
|
|
-- Colossus
|
|
arterial_bleed = { 94799, 440995, 1 }, -- Colossal Might increases the damage of your Rend and Deep Wounds by 2% per stack.
|
|
boneshaker = { 94789, 429639, 1 }, -- Shockwave's stun duration is increased by 1 sec and reduces the movement speed of affected enemies by 40% for 3 sec after the stun ends.
|
|
colossal_might = { 94819, 429634, 1 }, -- Colossal Might increases damage dealt by your next Demolish by 10%, stacking up to 5 times. Shield Slam and Execute grant a stack of Colossal Might and Revenge grants a stack of Colossal Might when it strikes 3 or more targets.
|
|
demolish = { 94818, 436358, 1, "colossus" }, -- Unleash a series of precise and powerful strikes against your target, dealing 515,611 damage to it, and 343,741 damage to enemies within 8 yds of it. Deals reduced damage beyond 8 targets. While channeling Demolish, you take 10% less damage and are immune to stuns, knockbacks, and forced movement effects. You can block, parry, dodge, and use certain defensive abilities while channeling Demolish.
|
|
dominance_of_the_colossus = { 94793, 429636, 1 }, -- Colossal Might now stacks up to 10 times. If you would gain a stack of Colossal Might and are at max stacks, the cooldown of Demolish is reduced by 2 sec. Enemies affected by Demolish take up to 10% more damage from you and deal up to 5% less damage to you for 10 sec based on the number of stacks of Colossal Might consumed by Demolish.
|
|
earthquaker = { 94789, 440992, 1 }, -- Shockwave also knocks enemies into the air, and its cooldown is reduced by 5 sec.
|
|
martial_expert = { 94812, 429638, 1 }, -- Critical strike damage of your abilities is increased by 10% and the amount of damage blocked by your critical blocks is increased by 20%.
|
|
mountain_of_muscle_and_scars = { 94806, 429642, 1 }, -- You deal 5% more damage and take 2.5% less damage. Size increased by 5%.
|
|
no_stranger_to_pain = { 94815, 429644, 1 }, -- Total damage prevented by Ignore Pain increased by 15%.
|
|
one_against_many = { 94799, 429637, 1 }, -- Shockwave, Revenge, and Whirlwind deal 5% more damage per target affected up to 5.
|
|
practiced_strikes = { 94796, 429647, 1 }, -- Shield Slam and Revenge damage increased by 20%.
|
|
precise_might = { 94794, 431548, 1 }, -- Shield Slam critical strikes grant an additional stack of Colossal Might.
|
|
tide_of_battle = { 94811, 429641, 1 }, -- Colossal Might increases the damage of your Revenge by 5% per stack.
|
|
veteran_vitality = { 94815, 440993, 1 }, -- When your health is brought below 35%, you gain a Second Wind, healing you for 12% of your max health over 2 sec. This effect cannot occur more than once every 60 sec.
|
|
|
|
-- Mountain Thane
|
|
avatar_of_the_storm = { 94805, 437134, 1 }, -- Casting Avatar grants you 2 charges of Thunder Blast and resets the cooldown of Thunder Clap. While Avatar is not active, Lightning Strikes have a 10% chance to grant you Avatar for 4 secs. Thunder Blast Your next Thunder Clap becomes a Thunder Blast that deals Stormstrike damage.
|
|
burst_of_power = { 94807, 437118, 1 }, -- Lightning Strikes have a 15% chance to make your next 2 Shield Slams have no cooldown.
|
|
crashing_thunder = { 94816, 436707, 1 }, -- Stormstrike or Nature damage your abilities deal is increased by 5%. Stormstrike damage ignores Armor. Thunder Clap damage increased by 40%. Seismic Reverberations now affects Thunder Clap in addition to Whirlwind.
|
|
flashing_skies = { 94797, 437079, 1 }, -- Thunder Blast calls down a Lightning Strike on an enemy it hits.
|
|
gathering_clouds = { 94792, 436201, 1 }, -- Your attacks trigger Lightning Strikes 30% more often.
|
|
ground_current = { 94800, 436148, 1 }, -- Lightning Strikes also deal 19,862 to enemies near their target. Damage reduced beyond 5 targets.
|
|
keep_your_feet_on_the_ground = { 94798, 438590, 1 }, -- Physical damage taken reduced by 2%. Thunder Blast reduces damage you take by 8% for 5 sec.
|
|
lightning_strikes = { 94803, 434969, 1, "mountain_thane" }, -- Damaging enemies with Thunder Clap, Revenge, or Execute has a 25% chance to also strike one with a lightning bolt, dealing 39,723 Nature damage. Lightning Strikes occur 30% more often during Avatar.
|
|
snap_induction = { 94797, 456270, 1 }, -- Activating Demoralizing Shout grants a charge of Thunder Blast.
|
|
steadfast_as_the_peaks = { 94798, 434970, 1 }, -- Stamina increased by 5%. Victory Rush increases your maximum health by 10% for 5 sec. When this health increase expires, you heal for any amount of the original Victory Rush that healed you in excess of your full health.
|
|
storm_bolts = { 94817, 436162, 1 }, -- Storm Bolt also hits 2 additional nearby targets, stunning them for 2 sec, but its cooldown is increased by 10 sec.
|
|
storm_shield = { 94817, 438597, 1 }, -- Intervening a target grants them a shield for 5 sec that absorbs magic damage equal to 3 times your Armor.
|
|
strength_of_the_mountain = { 94808, 437068, 1 }, -- Shield Slam damage increased by 10%. Demoralizing Shout reduces damage enemies deal to you by an additional 5%
|
|
thorims_might = { 94792, 436152, 1 }, -- Lightning Strikes generate 5 Rage. Revenge and Execute damage increased by 15%.
|
|
thunder_blast = { 94785, 435607, 1 }, -- Shield Slam and Bloodthirst have a 35% chance to grant you Thunder Blast, stacking up to 2 charges. Thunder Blast Your next Thunder Clap becomes a Thunder Blast that deals 40% increased damage as Stormstrike and generates 10 Rage.
|
|
} )
|
|
|
|
-- PvP Talents
|
|
spec:RegisterPvpTalents( {
|
|
battlefield_commander = 5629, -- (424742) Your Shout abilities have additional effects. Battle Shout: Increases Stamina by 3%. Piercing Howl: Radius increased by 50% Berserker Shout: Range increased by 8 yds. Intimidating Shout: Cooldown reduced by 15 sec. Rallying Cry: Removes movement impairing effects and grants 30% movement speed to allies. Thunderous Roar: Targets receive 5% more damage from all sources while bleeding.
|
|
bodyguard = 168 , -- (213871) Protect an ally, causing 40% of all Physical damage they take to be transfered to you. When the target takes Physical damage, your Shield Slam cooldown has a 30% chance to be reset. Bodyguard is cancelled if the target is further than 20 yards from you. Lasts 1 min. Only one target can be Bodyguarded at a time.
|
|
demolition = 5374, -- (329033) Reduces the cooldown of your Shattering Throw or Wrecking Throw by 50% and increases its damage to absorb shields by an additional 250%.
|
|
disarm = 24 , -- (236077) Disarm the enemy's weapons and shield for 5 sec. Disarmed creatures deal significantly reduced damage.
|
|
dragon_charge = 831 , -- (206572) Run at high speed at a distance in front of you. All enemies in your path will take 46,344 Physical damage and be knocked back.
|
|
morale_killer = 171 , -- (199023)
|
|
oppressor = 845 , -- (205800)
|
|
rebound = 833 , -- (213915) Spell Reflection reflects the next 2 incoming spells cast on you and reflected spells deal 50% extra damage to the attacker. Spell Reflection's cooldown is increased by 10 sec.
|
|
safeguard = 5626, -- (424654) Intervene now has 2 charges and reduces the ally's damage taken by 20% for 5 sec. Intervene's cooldown is increased by 10 sec.
|
|
shield_bash = 173 , -- (198912)
|
|
storm_of_destruction = 5627, -- (236308) Bladestorm and Ravager now snare all targets you hit by 60% for 6 sec and decrease their healing taken by 50 for 10 sec.
|
|
thunderstruck = 175 , -- (199045)
|
|
warbringer = 5432, -- (356353) Charge roots enemies for 2 sec and emanates a shockwave past the target, rooting enemies and dealing 33,102 Physical damage in a 20 yd cone.
|
|
warpath = 178 , -- (199086)
|
|
} )
|
|
|
|
|
|
-- Auras
|
|
spec:RegisterAuras( {
|
|
avatar = {
|
|
id = 401150,
|
|
duration = 20,
|
|
max_stack = 1,
|
|
copy = 107574
|
|
},
|
|
battering_ram = {
|
|
id = 394313,
|
|
duration = 20,
|
|
max_stack = 1,
|
|
},
|
|
battle_stance = {
|
|
id = 386164,
|
|
duration = 3600,
|
|
max_stack = 1
|
|
},
|
|
battlescarred_veteran = {
|
|
id = 386397,
|
|
duration = 8,
|
|
max_stack = 1
|
|
},
|
|
berserker_rage = {
|
|
id = 18499,
|
|
duration = 6,
|
|
max_stack = 1
|
|
},
|
|
berserker_shout = {
|
|
id = 384100,
|
|
duration = 6,
|
|
max_stack = 1
|
|
},
|
|
bodyguard = {
|
|
id = 213871,
|
|
duration = 60,
|
|
tick_time = 1,
|
|
max_stack = 1
|
|
},
|
|
bounding_stride = {
|
|
id = 202164,
|
|
duration = 3,
|
|
max_stack = 1,
|
|
},
|
|
brace_for_impact = {
|
|
id = 386029,
|
|
duration = 16,
|
|
max_stack = 5
|
|
},
|
|
burst_of_power = {
|
|
id = 437121,
|
|
duration = 12,
|
|
max_stack = 2,
|
|
},
|
|
challenging_shout = {
|
|
id = 1161,
|
|
duration = 6,
|
|
max_stack = 1
|
|
},
|
|
charge = {
|
|
id = 105771,
|
|
duration = 1,
|
|
max_stack = 1,
|
|
},
|
|
colossal_might = {
|
|
id = 440989,
|
|
duration = 24,
|
|
max_stack = function() return 5 + ( talent.dominance_of_the_colossus.enabled and 5 or 10 ) end
|
|
},
|
|
concussive_blows = {
|
|
id = 383116,
|
|
duration = 10,
|
|
max_stack = 1
|
|
},
|
|
dance_of_death = {
|
|
id = 393966,
|
|
duration = 120,
|
|
max_stack = 1,
|
|
},
|
|
deep_wounds = {
|
|
id = 115767,
|
|
duration = 15,
|
|
tick_time = 3,
|
|
max_stack = 1
|
|
},
|
|
defensive_stance = {
|
|
id = 386208,
|
|
duration = 3600,
|
|
max_stack = 1
|
|
},
|
|
demoralizing_shout = {
|
|
id = 1160,
|
|
duration = 8,
|
|
max_stack = 1
|
|
},
|
|
disarm = {
|
|
id = 236077,
|
|
duration = 6,
|
|
max_stack = 1
|
|
},
|
|
disrupting_shout = {
|
|
id = 386071,
|
|
duration = 6,
|
|
max_stack = 1
|
|
},
|
|
dragon_charge = {
|
|
id = 206572,
|
|
duration = 1.2,
|
|
max_stack = 1
|
|
},
|
|
champions_spear = {
|
|
id = 376080,
|
|
duration = function() return 4 + ( talent.champions_might.enabled and 2 or 0 ) end,
|
|
max_stack = 1
|
|
},
|
|
champions_might = {
|
|
id = 386286,
|
|
duration = 6,
|
|
max_stack = 1
|
|
},
|
|
-- Target Swapping
|
|
execute_ineligible = {
|
|
duration = 3600,
|
|
max_stack = 1,
|
|
generate = function( t )
|
|
if buff.sudden_death.down and target.health_pct > ( talent.massacre.enabled and 35 or 20 ) then
|
|
t.count = 1
|
|
t.expires = query_time + 3600
|
|
t.applied = query_time
|
|
t.duration = 3600
|
|
t.caster = "player"
|
|
return
|
|
end
|
|
t.count = 0
|
|
t.expires = 0
|
|
t.applied = 0
|
|
t.caster = "nobody"
|
|
end
|
|
},
|
|
focused_assault = {
|
|
id = 206891,
|
|
duration = 6,
|
|
max_stack = 5
|
|
},
|
|
hamstring = {
|
|
id = 1715,
|
|
duration = 15,
|
|
max_stack = 1
|
|
},
|
|
ignore_pain = {
|
|
id = 190456,
|
|
duration = 12,
|
|
max_stack = 1
|
|
},
|
|
indelible_victory = {
|
|
id = 336642,
|
|
duration = 8,
|
|
max_stack = 1
|
|
},
|
|
intimidating_shout = {
|
|
id = function () return talent.menace.enabled and 316593 or 5246 end,
|
|
duration = function () return talent.menace.enabled and 15 or 8 end,
|
|
max_stack = 1
|
|
},
|
|
into_the_fray = {
|
|
id = 202602,
|
|
duration = 3600,
|
|
max_stack = 5
|
|
},
|
|
juggernaut = {
|
|
id = 393968,
|
|
duration = 12,
|
|
max_stack = 15,
|
|
copy = 383290
|
|
},
|
|
keep_your_feet_on_the_ground = {
|
|
id = 438591,
|
|
duration = 5,
|
|
max_stack = 1
|
|
},
|
|
last_stand = {
|
|
id = 12975,
|
|
duration = 15,
|
|
max_stack = 1
|
|
},
|
|
piercing_howl = {
|
|
id = 12323,
|
|
duration = 8,
|
|
max_stack = 1
|
|
},
|
|
punish = {
|
|
id = 275335,
|
|
duration = 9,
|
|
max_stack = 5
|
|
},
|
|
rallying_cry = {
|
|
id = 97463,
|
|
duration = 10,
|
|
max_stack = 1,
|
|
shared = "player",
|
|
},
|
|
ravager = {
|
|
id = 228920,
|
|
duration = function () return ( buff.dance_of_death.up and 14 or 12 ) * haste end,
|
|
tick_time = 2,
|
|
max_stack = 1
|
|
},
|
|
rend = {
|
|
id = 388539,
|
|
duration = 15,
|
|
tick_time = 3,
|
|
max_stack = 1
|
|
},
|
|
revenge = {
|
|
id = 5302,
|
|
duration = 6,
|
|
max_stack = 1
|
|
},
|
|
-- Damage taken reduced by $w1%.
|
|
safeguard = {
|
|
id = 424655,
|
|
duration = 5.0,
|
|
max_stack = 1,
|
|
},
|
|
seeing_red = {
|
|
id = 386486,
|
|
duration = 30,
|
|
max_stack = 8
|
|
},
|
|
shield_bash = {
|
|
id = 198912,
|
|
duration = 8,
|
|
max_stack = 1
|
|
},
|
|
shield_block = {
|
|
id = 132404,
|
|
duration = function () return ( talent.enduring_defenses.enabled and 8 or 6 ) + ( talent.heavy_repercussions.enabled and 1 or 0 ) end,
|
|
max_stack = 1
|
|
},
|
|
shield_charge = {
|
|
id = 385954,
|
|
duration = 4,
|
|
max_stack = 1,
|
|
},
|
|
shield_wall = {
|
|
id = 871,
|
|
duration = 8,
|
|
max_stack = 1
|
|
},
|
|
shockwave = {
|
|
id = 132168,
|
|
duration = function() return 2 + ( talent.boneshaker.enabled and 1 or 0 ) end,
|
|
max_stack = 1
|
|
},
|
|
show_of_force = {
|
|
id = 385842,
|
|
duration = 12,
|
|
max_stack = 1
|
|
},
|
|
spell_block = {
|
|
id = 392966,
|
|
duration = 30,
|
|
max_stack = 1
|
|
},
|
|
spell_reflection = {
|
|
id = 23920,
|
|
duration = function () return legendary.misshapen_mirror.enabled and 8 or 5 end,
|
|
max_stack = 1
|
|
},
|
|
spell_reflection_defense = {
|
|
id = 385391,
|
|
duration = 5,
|
|
max_stack = 1
|
|
},
|
|
stance = {
|
|
alias = { "battle_stance", "berserker_stance", "defensive_stance" },
|
|
aliasMode = "first",
|
|
aliasType = "buff",
|
|
duration = 3600,
|
|
},
|
|
storm_bolt = {
|
|
id = 107570,
|
|
duration = 4,
|
|
max_stack = 1
|
|
},
|
|
-- Movement slowed by $s1%.
|
|
storm_of_destruction = {
|
|
id = 424597,
|
|
duration = 6.0,
|
|
max_stack = 1,
|
|
},
|
|
sudden_death = {
|
|
id = 52437,
|
|
duration = 10,
|
|
max_stack = 2
|
|
},
|
|
taunt = {
|
|
id = 355,
|
|
duration = 3,
|
|
max_stack = 1
|
|
},
|
|
thunder_blast = {
|
|
id = 435615,
|
|
duration = 15,
|
|
max_stack = 2
|
|
},
|
|
thunder_clap = {
|
|
id = 6343,
|
|
duration = 10,
|
|
max_stack = 1
|
|
},
|
|
thunderous_roar = {
|
|
id = 397364,
|
|
duration = function () return talent.thunderous_words.enabled and 10 or 8 end,
|
|
tick_time = 2,
|
|
max_stack = 1
|
|
},
|
|
unnerving_focus = {
|
|
id = 384043,
|
|
duration = 15,
|
|
max_stack = 1
|
|
},
|
|
victorious = {
|
|
id = 32216,
|
|
duration = 20,
|
|
max_stack = 1
|
|
},
|
|
violent_outburst = { -- Renamed from Outburst to violent Outburst in build 45779
|
|
id = 386478,
|
|
duration = 30,
|
|
max_stack = 1
|
|
},
|
|
war_machine = {
|
|
id = 262232,
|
|
duration = 8,
|
|
max_stack = 1
|
|
},
|
|
wild_strikes = {
|
|
id = 392778,
|
|
duration = 10,
|
|
max_stack = 1
|
|
},
|
|
wrecked = {
|
|
id = 447513,
|
|
duration = 10,
|
|
max_stack = 1
|
|
}
|
|
} )
|
|
|
|
|
|
-- Dragonflight Season 1
|
|
spec:RegisterGear( "tier29", 200426, 200428, 200423, 200425, 200427 )
|
|
spec:RegisterSetBonuses( "tier29_2pc", 393710, "tier29_4pc", 393711 ) -- Dragonflight Season 1
|
|
-- 2-Set - Revenge grants you Vanguard's Determination, increasing your damage done and reducing damage you take by 4% for 5 sec seconds.
|
|
-- 4-Set - During Vanguard's Determination, gain Ignore Pain equal to 5% of damage you deal.
|
|
spec:RegisterAura( "vanguards_determination", {
|
|
id = 394056,
|
|
duration = 5,
|
|
max_stack = 1,
|
|
} )
|
|
|
|
spec:RegisterGear( "tier30", 202446, 202444, 202443, 202442, 202441 )
|
|
spec:RegisterSetBonuses( "tier30_2pc", 405581, "tier30_4pc", 405582 )
|
|
--(2) Shield Slam deals 15% increased damage and reduces the cooldown of Last Stand by 1 sec. During Last Stand these effects are doubled.
|
|
--(4) For 10 sec after Last Stand ends, Shield Slam unleashes a wave of force dealing (45% of Attack power) Physical damage to enemies in front of you and reducing damage they deal to you by 5% for 5 sec.
|
|
spec:RegisterAura( "earthen_tenacity", {
|
|
id = 410218,
|
|
duration = 5,
|
|
max_stack = 1
|
|
} )
|
|
|
|
spec:RegisterGear( "tier31", 207180, 207181, 207182, 207183, 207185, 217218, 217220, 217216, 217217, 217219 )
|
|
spec:RegisterSetBonuses( "tier31_2pc", 422927, "tier31_4pc", 422928 )
|
|
-- (2) Spending Rage has a chance to cause your next Shield Slam to consume your bleeds on a target, instantly dealing 40% of the remaining damage of your Deep Wounds and Rend and 100% of Thunderous Roar's, and reducing your damage taken by 10% for 5 sec.
|
|
-- (4) For each bleed effect consumed from a target, your damage taken is reduced by an additional 2%. When Shield Slam consumes a bleed, the cooldown of Thunder Clap is reset and the cooldown of Thunderous Roar is reduced by 3.0 sec.
|
|
spec:RegisterAuras( {
|
|
fervid = {
|
|
id = 425517,
|
|
duration = 10,
|
|
max_stack = 1
|
|
},
|
|
fervid_opposition = {
|
|
id = 427413,
|
|
duration = 5,
|
|
max_stack = 1
|
|
},
|
|
} )
|
|
|
|
|
|
local rageSpent_10 = 0
|
|
local rageSpent_20 = 0
|
|
local rageSpent_30 = 0
|
|
|
|
spec:RegisterStateExpr( "rageSpent_10", function () return rageSpent_10 end ) -- Glory (Shadowlands) and Anger Management talent
|
|
spec:RegisterStateExpr( "rageSpent_20", function () return rageSpent_20 end ) -- Indomitable talent
|
|
spec:RegisterStateExpr( "rageSpent_30", function () return rageSpent_30 end ) -- Outburst talent
|
|
|
|
local RAGE = Enum.PowerType.Rage
|
|
local lastRage = -1
|
|
|
|
spec:RegisterUnitEvent( "UNIT_POWER_FREQUENT", "player", nil, function( event, unit, powerType )
|
|
if powerType == "RAGE" then
|
|
local current = UnitPower( "player", RAGE )
|
|
if current < lastRage - 3 then -- Spent Rage, -3 is used as a Hack to avoid Rage decaying
|
|
if state.talent.anger_management.enabled or ( state.legendary.glory.enabled and FindPlayerAuraByID( 324143 ) ) then -- Glory and Anger Management
|
|
rageSpent_10 = ( rageSpent_10 + lastRage - current ) % 10
|
|
end
|
|
if state.talent.indomitable.enabled then -- Indomitable
|
|
rageSpent_20 = ( rageSpent_20 + lastRage - current ) % 20
|
|
end
|
|
if state.talent.violent_outburst.enabled then -- Outburst T28 or Violent Outburst
|
|
rageSpent_30 = ( rageSpent_30 + lastRage - current ) % 30
|
|
end
|
|
end
|
|
lastRage = current
|
|
end
|
|
end )
|
|
|
|
-- model rage expenditure and special effects
|
|
spec:RegisterHook( "spend", function( amt, resource )
|
|
if resource == "rage" and amt < 0 then
|
|
if talent.anger_management.enabled or ( legendary.glory.enabled and buff.conquerors_banner.up ) then
|
|
rageSpent_10 = rageSpent_10 + amt
|
|
local rage10activations = floor( rageSpent_10 / 10 )
|
|
rageSpent_10 = rageSpent_10 % 10
|
|
|
|
if rage10activations > 0 then
|
|
if legendary.glory.enabled and buff.conquerors_banner.up then
|
|
buff.conquerors_banner.expires = buff.conquerors_banner.expires + ( rage10activations * 0.5 )
|
|
end
|
|
if talent.anger_management.enabled then
|
|
if talent.shield_wall.enabled then cooldown.shield_wall.expires = cooldown.shield_wall.expires - rage10activations end
|
|
if talent.avatar.enabled then cooldown.avatar.expires = cooldown.avatar.expires - rage10activations end
|
|
end
|
|
end
|
|
end
|
|
|
|
if talent.indomitable.enabled then
|
|
rageSpent_20 = rageSpent_20 + amt
|
|
local rage20activations = floor( rageSpent_20 / 20 )
|
|
rageSpent_20 = rageSpent_20 % 20
|
|
|
|
if rage20activations > 0 then
|
|
gain( ( 0.01 * rage20activations ) * health.max, "health" ) -- Restores 1% max health
|
|
end
|
|
end
|
|
|
|
if talent.violent_outburst.enabled then
|
|
rageSpent_30 = rageSpent_30 + amt
|
|
local rage30activations = floor( rageSpent_30 / 30 )
|
|
rageSpent_30 = rageSpent_30 % 30
|
|
|
|
if rage30activations > 0 then
|
|
addStack( "seeing_red", nil, rage30activations )
|
|
if buff.seeing_red.stack > 7 then
|
|
applyBuff( "violent_outburst" )
|
|
removeBuff( "seeing_red" )
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end )
|
|
|
|
spec:RegisterCombatLogEvent( function( _, subtype, _, sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, school, amount, interrupt, a, b, c, d, critical )
|
|
--TODO: Deepdive to see if beneficial or not.
|
|
if sourceGUID == state.GUID then
|
|
if state.talent.colossal_might.enabled and spellID == 440989 and ( subtype == "SPELL_AURA_APPLIED" or subtype == "SPELL_AURA_REMOVED" or subtype == "SPELL_AURA_REFRESH" or subtype == "SPELL_AURA_APPLIED_DOSE" or subtype == "SPELL_AURA_REMOVED_DOSE" ) then
|
|
Hekili:ForceUpdate( "COLOSSALMIGHT_CHANGED", true )
|
|
elseif state.talent.thunder_blast.enabled and spellID == 435615 and ( subtype == "SPELL_AURA_APPLIED" or subtype == "SPELL_AURA_REMOVED" or subtype == "SPELL_AURA_REFRESH" or subtype == "SPELL_AURA_APPLIED_DOSE" or subtype == "SPELL_AURA_REMOVED_DOSE" ) then
|
|
Hekili:ForceUpdate( "THUNDERBLAST_CHANGED", true )
|
|
elseif state.talent.burst_of_power.enabled and spellID == 437121 and ( subtype == "SPELL_AURA_APPLIED" or subtype == "SPELL_AURA_REMOVED" or subtype == "SPELL_AURA_REFRESH" or subtype == "SPELL_AURA_APPLIED_DOSE" or subtype == "SPELL_AURA_REMOVED_DOSE" ) then
|
|
Hekili:ForceUpdate( "BURSTOFPOWER_CHANGED", true )
|
|
end
|
|
end
|
|
end )
|
|
|
|
spec:RegisterStateExpr( "cycle_for_execute", function ()
|
|
if active_enemies == 1 or target.health_pct < ( talent.massacre.enabled and 35 or 20 ) or not settings.cycle or buff.execute_ineligible.down or buff.sudden_death.up then return false end
|
|
return Hekili:GetNumTargetsBelowHealthPct( talent.massacre.enabled and 35 or 20, false, max( settings.cycle_min, offset + delay ) ) > 0
|
|
end )
|
|
|
|
local TriggerEarthenTenacity = setfenv( function()
|
|
applyBuff( "earthen_tenacity" )
|
|
end, state )
|
|
|
|
spec:RegisterHook( "reset_precast", function ()
|
|
if set_bonus.tier30_4pc > 0 and buff.last_stand.up then
|
|
state:QueueAuraExpiration( "last_stand_earthen_tenacity", TriggerEarthenTenacity, buff.last_stand.expires )
|
|
end
|
|
end )
|
|
|
|
-- Abilities
|
|
spec:RegisterAbilities( {
|
|
avatar = {
|
|
id = 401150,
|
|
cast = 0,
|
|
cooldown = 90,
|
|
gcd = "off",
|
|
|
|
spend = function () return buff.unnerving_focus.up and -15 or -10 end,
|
|
spendType = "rage",
|
|
|
|
talent = "avatar",
|
|
startsCombat = false,
|
|
texture = 613534,
|
|
|
|
toggle = "cooldowns",
|
|
|
|
handler = function ()
|
|
applyBuff( "avatar" )
|
|
if talent.immovable_object.enabled then
|
|
applyBuff( "shield_wall", 4 )
|
|
end
|
|
if talent.violent_outburst.enabled then
|
|
applyBuff( "violent_outburst" )
|
|
end
|
|
end,
|
|
},
|
|
|
|
|
|
battle_shout = {
|
|
id = 6673,
|
|
cast = 0,
|
|
cooldown = 15,
|
|
gcd = "spell",
|
|
|
|
startsCombat = false,
|
|
texture = 132333,
|
|
|
|
nobuff = "battle_shout",
|
|
essential = true,
|
|
|
|
handler = function ()
|
|
applyBuff( "battle_shout" )
|
|
end,
|
|
},
|
|
|
|
|
|
battle_stance = {
|
|
id = 386164,
|
|
cast = 0,
|
|
cooldown = 3,
|
|
gcd = "off",
|
|
|
|
talent = "battle_stance",
|
|
startsCombat = false,
|
|
nobuff = function() return settings.stance_weaving and "battle_stance" or "stance" end,
|
|
|
|
handler = function ()
|
|
applyBuff( "battle_stance" )
|
|
removeBuff( "defensive_stance" )
|
|
end,
|
|
},
|
|
|
|
|
|
berserker_rage = {
|
|
id = 18499,
|
|
cast = 0,
|
|
cooldown = 60,
|
|
gcd = "off",
|
|
|
|
startsCombat = false,
|
|
texture = 136009,
|
|
|
|
--Not yet Implemented in LossOfControl via Classes.lua
|
|
--toggle = "defensives",
|
|
--usable = function () return ( debuff.sap.up or debuff.incapacitate.up or debuff.fear.up ) , "requires fear/incapacitate/sap debuff" end,
|
|
|
|
handler = function ()
|
|
applyBuff( "berserker_rage" )
|
|
end,
|
|
},
|
|
|
|
|
|
berserker_shout = {
|
|
id = 384100,
|
|
cast = 0,
|
|
cooldown = 60,
|
|
gcd = "off",
|
|
|
|
talent = "berserker_shout",
|
|
startsCombat = false,
|
|
texture = 136009,
|
|
|
|
--Not yet Implemented in LossOfControl via Classes.lua
|
|
--toggle = "defensives",
|
|
--usable = function () return ( debuff.sap.up or debuff.incapacitate.up or debuff.fear.up ) , "requires fear/incapacitate/sap debuff" end,
|
|
|
|
handler = function ()
|
|
applyBuff( "berserker_shout" )
|
|
end,
|
|
},
|
|
|
|
|
|
bitter_immunity = {
|
|
id = 383762,
|
|
cast = 0,
|
|
cooldown = 180,
|
|
gcd = "off",
|
|
|
|
talent = "bitter_immunity",
|
|
startsCombat = false,
|
|
texture = 136088,
|
|
|
|
toggle = "cooldowns",
|
|
|
|
handler = function ()
|
|
removeBuff( "dispellable_disease" )
|
|
removeBuff( "dispellable_poison" )
|
|
removeBuff( "dispellable_curse" )
|
|
gain( 0.2 * health.max, "health" )
|
|
end,
|
|
},
|
|
|
|
|
|
bodyguard = {
|
|
id = 213871,
|
|
cast = 0,
|
|
cooldown = 15,
|
|
gcd = "spell",
|
|
|
|
pvptalent = "bodyguard",
|
|
startsCombat = false,
|
|
texture = 132359,
|
|
|
|
handler = function ()
|
|
applyBuff( "bodyguard" )
|
|
end,
|
|
},
|
|
|
|
|
|
challenging_shout = {
|
|
id = 1161,
|
|
cast = 0,
|
|
cooldown = 120,
|
|
gcd = "off",
|
|
|
|
talent = "challenging_shout",
|
|
notalent = "disrupting_shout",
|
|
startsCombat = true,
|
|
texture = 132091,
|
|
|
|
toggle = "cooldowns",
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "challenging_shout" )
|
|
active_dot.challenging_shout = active_enemies
|
|
end,
|
|
},
|
|
|
|
champions_spear = {
|
|
id = function() return talent.champions_spear.enabled and 376079 or 307865 end,
|
|
cast = 0,
|
|
cooldown = 90,
|
|
gcd = "spell",
|
|
|
|
spend = function () return ( -10 * ( talent.piercing_challenge.enabled and 2 or 1 ) ) * ( 1 + conduit.piercing_verdict.mod * 0.01 ) end,
|
|
spendType = "rage",
|
|
|
|
startsCombat = true,
|
|
toggle = "cooldowns",
|
|
velocity = 30,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "champions_spear" )
|
|
if talent.champions_might.enabled or legendary.elysian_might.enabled then applyBuff( "champions_might" ) end
|
|
end,
|
|
|
|
copy = { "spear_of_bastion", 307865, 376079 }
|
|
},
|
|
|
|
charge = {
|
|
id = 100,
|
|
cast = 0,
|
|
charges = function () return talent.double_time.enabled and 2 or 1 end,
|
|
cooldown = function () return talent.double_time.enabled and 17 or 20 end,
|
|
recharge = function () return talent.double_time.enabled and 17 or 20 end,
|
|
gcd = "off",
|
|
icd = 1,
|
|
|
|
spend = function () return -20 * ( buff.unnerving_focus.up and 1.5 or 1 ) end,
|
|
spendType = "rage",
|
|
|
|
startsCombat = true,
|
|
texture = 132337,
|
|
|
|
usable = function () return target.minR > 8 and ( query_time - action.charge.lastCast > gcd.execute ), "target too close" end,
|
|
handler = function ()
|
|
applyDebuff( "target", "charge" )
|
|
if legendary.reprisal.enabled then
|
|
applyBuff( "shield_block", 4 )
|
|
applyBuff( "revenge" )
|
|
gain( 20, "rage" )
|
|
end
|
|
end,
|
|
},
|
|
|
|
|
|
defensive_stance = {
|
|
id = 386208,
|
|
cast = 0,
|
|
cooldown = 3,
|
|
gcd = "off",
|
|
|
|
talent = "defensive_stance",
|
|
startsCombat = false,
|
|
essential = true,
|
|
nobuff = function() return settings.stance_weaving and "defensive_stance" or "stance" end,
|
|
|
|
handler = function ()
|
|
removeBuff( "battle_stance" )
|
|
applyBuff( "defensive_stance" )
|
|
end,
|
|
},
|
|
|
|
demolish = {
|
|
id = 436358,
|
|
cast = function () return 2 * haste end,
|
|
channeled = true,
|
|
breakable = false,
|
|
cooldown = 45,
|
|
gcd = "spell",
|
|
|
|
startsCombat = true,
|
|
|
|
handler = function()
|
|
removeBuff( "colossal_might" )
|
|
active_dot.wrecked = active_enemies
|
|
end,
|
|
},
|
|
|
|
|
|
demoralizing_shout = {
|
|
id = 1160,
|
|
cast = 0,
|
|
cooldown = 45,
|
|
gcd = "spell",
|
|
|
|
spend = function () return ( talent.booming_voice.enabled and -30 or 0 ) * ( buff.unnerving_focus.up and 1.5 or 1 ) end,
|
|
spendType = "rage",
|
|
|
|
talent = "demoralizing_shout",
|
|
startsCombat = false,
|
|
texture = 132366,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "demoralizing_shout" )
|
|
active_dot.demoralizing_shout = max( active_dot.demoralizing_shout, active_enemies )
|
|
end,
|
|
},
|
|
|
|
|
|
devastate = {
|
|
id = 20243,
|
|
cast = 0,
|
|
cooldown = 0,
|
|
gcd = "spell",
|
|
|
|
spend = function() return ( talent.instigate.enabled and -2 or 0 ) * ( buff.unnerving_focus.up and 1.5 or 1) end,
|
|
spendType = "rage",
|
|
|
|
startsCombat = true,
|
|
notalent = "devastator",
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "deep_wounds" )
|
|
end,
|
|
},
|
|
|
|
|
|
disarm = {
|
|
id = 236077,
|
|
cast = 0,
|
|
cooldown = 45,
|
|
gcd = "spell",
|
|
|
|
pvptalent = "disarm",
|
|
startsCombat = false,
|
|
texture = 132343,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "disarm" )
|
|
end,
|
|
},
|
|
|
|
|
|
disrupting_shout = {
|
|
id = 386071,
|
|
cast = 0,
|
|
cooldown = 90,
|
|
gcd = "off",
|
|
|
|
talent = "disrupting_shout",
|
|
startsCombat = false,
|
|
texture = 132091,
|
|
|
|
toggle = "cooldowns",
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "disrupting_shout" )
|
|
active_dot.disrupting_shout = active_enemies
|
|
end,
|
|
},
|
|
|
|
|
|
dragon_charge = {
|
|
id = 206572,
|
|
cast = 0,
|
|
cooldown = 20,
|
|
gcd = "off",
|
|
|
|
pvptalent = "dragon_charge",
|
|
startsCombat = false,
|
|
texture = 1380676,
|
|
|
|
handler = function ()
|
|
end,
|
|
},
|
|
|
|
|
|
execute = {
|
|
id = function () return talent.massacre.enabled and 281000 or 163201 end,
|
|
known = 163201,
|
|
copy = { 163201, 281000 },
|
|
noOverride = 317485, -- Condemn
|
|
cast = 0,
|
|
cooldown = 0,
|
|
gcd = "spell",
|
|
hasteCD = true,
|
|
|
|
spend = 0,
|
|
spendType = "rage",
|
|
|
|
startsCombat = true,
|
|
texture = 135358,
|
|
|
|
usable = function ()
|
|
if buff.sudden_death.up then return true end
|
|
if cycle_for_execute then return true end
|
|
return target.health_pct < ( talent.massacre.enabled and 35 or 20 ), "requires < " .. ( talent.massacre.enabled and 35 or 20 ) .. "% health"
|
|
end,
|
|
|
|
cycle = "execute_ineligible",
|
|
|
|
indicator = function () if cycle_for_execute then return "cycle" end end,
|
|
|
|
timeToReady = function()
|
|
if buff.sudden_death.up then return 0 end
|
|
local threshold = settings.reserve_rage + 40
|
|
if rage.current >= threshold or ( buff.shield_block.remains > 3 and buff.ignore_pain.remains > 3 ) or not tanking then return 0 end
|
|
return rage[ "time_to_" .. ( settings.reserve_rage + 40 ) ]
|
|
end,
|
|
|
|
handler = function()
|
|
if not buff.sudden_death.up then
|
|
local cost = min( rage.current, 40 )
|
|
spend( cost, "rage", nil, true )
|
|
else
|
|
removeBuff( "sudden_death" )
|
|
end
|
|
if talent.juggernaut.enabled then addStack( "juggernaut" ) end
|
|
|
|
if talent.dominance_of_the_colossus.enabled and buff.colossal_might.stack == 10 then reduceCooldown( "demolish", 2 ) end
|
|
if talent.colossal_might.enabled then addStack( "colossal_might" ) end
|
|
end,
|
|
},
|
|
|
|
|
|
hamstring = {
|
|
id = 1715,
|
|
cast = 0,
|
|
cooldown = 0,
|
|
gcd = "spell",
|
|
|
|
spend = 10,
|
|
spendType = "rage",
|
|
|
|
startsCombat = true,
|
|
texture = 132316,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "hamstring" )
|
|
end,
|
|
},
|
|
|
|
|
|
heroic_leap = {
|
|
id = 6544,
|
|
cast = 0,
|
|
cooldown = function () return talent.bounding_stride.enabled and 30 or 45 end,
|
|
charges = function () return legendary.leaper.enabled and 3 or nil end,
|
|
recharge = function () return legendary.leaper.enabled and ( talent.bounding_stride.enabled and 30 or 45 ) or nil end,
|
|
gcd = "off",
|
|
icd = 0.8,
|
|
|
|
talent = "heroic_leap",
|
|
startsCombat = false,
|
|
texture = 236171,
|
|
|
|
handler = function ()
|
|
if talent.bounding_stride.enabled then applyBuff( "bounding_stride" ) end
|
|
end,
|
|
},
|
|
|
|
|
|
heroic_throw = {
|
|
id = 57755,
|
|
cast = 0,
|
|
cooldown = 1,
|
|
gcd = "spell",
|
|
|
|
startsCombat = true,
|
|
|
|
usable = function () return target.minR > 7, "requires 8 yard range or more" end,
|
|
handler = function ()
|
|
end,
|
|
},
|
|
|
|
|
|
ignore_pain = {
|
|
id = 190456,
|
|
cast = 0,
|
|
cooldown = 1,
|
|
gcd = "off",
|
|
|
|
spend = 35,
|
|
spendType = "rage",
|
|
|
|
talent = "ignore_pain",
|
|
startsCombat = false,
|
|
texture = 1377132,
|
|
|
|
toggle = "defensives",
|
|
|
|
readyTime = function ()
|
|
if settings.overlap_ignore_pain then return end
|
|
if buff.ignore_pain.up and buff.ignore_pain.v1 >= 0.3 * health.max then
|
|
return buff.ignore_pain.remains - gcd.max
|
|
end
|
|
end,
|
|
|
|
handler = function ()
|
|
if buff.ignore_pain.up then
|
|
buff.ignore_pain.expires = query_time + class.auras.ignore_pain.duration
|
|
buff.ignore_pain.v1 = min( 0.3 * health.max, buff.ignore_pain.v1 + stat.attack_power * 4.375 * ( 1 + stat.versatility_atk_mod / 100 ) )
|
|
else
|
|
applyBuff( "ignore_pain" )
|
|
buff.ignore_pain.v1 = min( 0.3 * health.max, stat.attack_power * 4.375 * ( 1 + stat.versatility_atk_mod / 100 ) )
|
|
end
|
|
end,
|
|
},
|
|
|
|
|
|
impending_victory = {
|
|
id = 202168,
|
|
cast = 0,
|
|
cooldown = 25,
|
|
gcd = "spell",
|
|
|
|
spend = function() return buff.victorious.up and 0 or 10 end,
|
|
spendType = "rage",
|
|
|
|
talent = "impending_victory",
|
|
startsCombat = true,
|
|
|
|
handler = function ()
|
|
removeBuff( "victorious" )
|
|
gain( health.max * 0.2, "health" )
|
|
if conduit.indelible_victory.enabled then applyBuff( "indelible_victory" ) end
|
|
if talent.steadfast_as_the_peaks.enabled then
|
|
gain( health.max * 0.1, "health" )
|
|
applyBuff( "steadfast_as_the_peaks" )
|
|
end
|
|
end,
|
|
},
|
|
|
|
|
|
intervene = {
|
|
id = 3411,
|
|
cast = 0,
|
|
cooldown = function ()
|
|
if pvptalent.safeguard.enabled then return 40 - ( talent.honed_reflexes.enabled and 40*0.05 or 0 ) end
|
|
return 30 - ( talent.honed_reflexes.enabled and 30*0.05 or 0 )
|
|
end,
|
|
charges = function () if pvptalent.safeguard.enabled then return 2 end end,
|
|
recharge = function () if pvptalent.safeguard.enabled then return 40 - ( talent.honed_reflexes.enabled and 40*0.05 or 0 ) end end,
|
|
gcd = "off",
|
|
icd = 1.5,
|
|
|
|
talent = "intervene",
|
|
startsCombat = false,
|
|
|
|
handler = function ()
|
|
if legendary.reprisal.enabled then
|
|
applyBuff( "shield_block", 4 )
|
|
applyBuff( "revenge" )
|
|
gain( 20, "rage" )
|
|
end
|
|
|
|
if pvptalent.safeguard.enabled then
|
|
applyBuff( "safeguard" )
|
|
end
|
|
end,
|
|
},
|
|
|
|
|
|
intimidating_shout = {
|
|
id = function() return talent.menace.enabled and 316593 or 5246 end,
|
|
cast = 0,
|
|
cooldown = 90,
|
|
gcd = "spell",
|
|
|
|
talent = "intimidating_shout",
|
|
startsCombat = true,
|
|
texture = 132154,
|
|
|
|
toggle = "interrupts",
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "intimidating_shout" )
|
|
active_dot.intimidating_shout = max( active_dot.intimidating_shout, active_enemies )
|
|
end,
|
|
|
|
copy = { 316593, 5246 },
|
|
},
|
|
|
|
|
|
last_stand = {
|
|
id = 12975,
|
|
cast = 0,
|
|
cooldown = function() return 180 - ( talent.bolster.enabled and 60 or 0 ) end,
|
|
gcd = "off",
|
|
|
|
talent = "last_stand",
|
|
startsCombat = false,
|
|
texture = 135871,
|
|
|
|
toggle = function()
|
|
return settings.last_stand_offensively and "cooldowns" or "defensives"
|
|
end,
|
|
|
|
usable = function()
|
|
if settings.last_stand_offensively and ( talent.unnerving_focus.enabled or conduit.unnerving_focus.enabled or set_bonus.tier30_2pc > 0 ) then return true end
|
|
|
|
local dmg_required = ( ( settings.last_stand_amount or 10 ) * 0.01 ) * health.max * ( solo and 0.5 or 1 )
|
|
local hp_required = ( ( settings.last_stand_health or 10 ) * 0.01 )
|
|
local hp = health.percent or 10
|
|
|
|
if settings.last_stand_condition then
|
|
if incoming_damage_5s < dmg_required then return false, format( "incoming_damage_5s[%.2f] < dmg_required[%.2f] setting", incoming_damage_5s, dmg_required ) end
|
|
if health.percent > hp_required then return false, format( "health.percent[%.2f] > hp_required[%.2f] setting", health.percent, hp_required ) end
|
|
return true
|
|
end
|
|
|
|
if incoming_damage_5s >= dmg_required or hp <= hp_required then return true end
|
|
if incoming_damage_5s < dmg_required then return false, format( "incoming_damage_5s[%.2f] < dmg_required[%.2f] setting", incoming_damage_5s, dmg_required ) end
|
|
if hp > hp_required then return false, format( "health.percent[%.2f] > hp_required[%.2f] setting", hp, hp_required ) end
|
|
return false
|
|
end,
|
|
|
|
handler = function ()
|
|
applyBuff( "last_stand" )
|
|
|
|
if talent.bolster.enabled then
|
|
applyBuff( "shield_block", buff.last_stand.duration )
|
|
end
|
|
|
|
if talent.unnerving_focus.enabled then
|
|
applyBuff( "unnerving_focus" )
|
|
end
|
|
|
|
if set_bonus.tier30_4pc > 0 then
|
|
state:QueueAuraExpiration( "last_stand_earthen_tenacity", TriggerEarthenTenacity, buff.last_stand.expires )
|
|
end
|
|
end,
|
|
},
|
|
|
|
|
|
oppressor = {
|
|
id = 205800,
|
|
cast = 0,
|
|
cooldown = 20,
|
|
gcd = "spell",
|
|
|
|
pvptalent = "oppressor",
|
|
startsCombat = false,
|
|
texture = 136080,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "focused_assault" )
|
|
end
|
|
},
|
|
|
|
|
|
piercing_howl = {
|
|
id = 12323,
|
|
cast = 0,
|
|
cooldown = 30,
|
|
gcd = "spell",
|
|
|
|
talent = "piercing_howl",
|
|
startsCombat = false,
|
|
texture = 136147,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "piercing_howl" )
|
|
active_dot.piercing_howl = max( active_dot.piercing_howl, active_enemies )
|
|
end,
|
|
},
|
|
|
|
|
|
pummel = {
|
|
id = 6552,
|
|
cast = 0,
|
|
cooldown = function () return 15 - ( talent.concussive_blows.enabled and 1 or 0 ) - ( talent.honed_reflexes.enabled and 15*0.05 or 0 ) end,
|
|
gcd = "off",
|
|
|
|
startsCombat = true,
|
|
texture = 132938,
|
|
|
|
toggle = "interrupts",
|
|
interrupt = true,
|
|
|
|
debuff = "casting",
|
|
readyTime = state.timeToInterrupt,
|
|
|
|
handler = function ()
|
|
interrupt()
|
|
if talent.concussive_blows.enabled then applyDebuff( "target", "concussive_blows" ) end
|
|
end,
|
|
},
|
|
|
|
|
|
rallying_cry = {
|
|
id = 97462,
|
|
cast = 0,
|
|
cooldown = 180,
|
|
gcd = "spell",
|
|
|
|
talent = "rallying_cry",
|
|
startsCombat = false,
|
|
texture = 132351,
|
|
|
|
toggle = "defensives",
|
|
|
|
usable = function()
|
|
local dmg_required = ( settings.rallying_cry_amount * 0.01 ) * health.max * ( solo and 0.5 or 1 )
|
|
local hp_required = ( settings.rallying_cry_health * 0.01 )
|
|
|
|
if settings.rallying_cry_condition then
|
|
if incoming_damage_5s < dmg_required then return false, format( "incoming_damage_5s[%.2f] < dmg_required[%.2f] setting", incoming_damage_5s, dmg_required ) end
|
|
if health.percent > hp_required then return false, format( "health.percent[%.2f] > hp_required[%.2f] setting", health.percent, hp_required ) end
|
|
return true
|
|
end
|
|
|
|
if incoming_damage_5s >= dmg_required or ( health.percent or 50 ) <= hp_required then return true end
|
|
if incoming_damage_5s < dmg_required then return false, format( "incoming_damage_5s[%.2f] < dmg_required[%.2f] setting", incoming_damage_5s, dmg_required ) end
|
|
if health.percent > hp_required then return false, format( "health.percent[%.2f] > hp_required[%.2f] setting", health.percent, hp_required ) end
|
|
return false
|
|
end,
|
|
|
|
handler = function ()
|
|
applyBuff( "rallying_cry" )
|
|
gain( 0.10 * health.max, "health" )
|
|
end,
|
|
},
|
|
|
|
|
|
ravager = {
|
|
id = 228920,
|
|
cast = 0,
|
|
charges = function () return ( talent.storm_of_steel.enabled and 2 or 1 ) end,
|
|
cooldown = 90,
|
|
recharge = 90,
|
|
gcd = "spell",
|
|
|
|
talent = "ravager",
|
|
startsCombat = true,
|
|
toggle = "cooldowns",
|
|
|
|
handler = function ()
|
|
applyBuff( "ravager" )
|
|
end,
|
|
},
|
|
|
|
|
|
rend = {
|
|
id = 394062,
|
|
cast = 0,
|
|
cooldown = 0,
|
|
gcd = "spell",
|
|
|
|
spend = 20,
|
|
spendType = "rage",
|
|
|
|
talent = "rend",
|
|
startsCombat = true,
|
|
texture = 132155,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "rend" )
|
|
end,
|
|
},
|
|
|
|
|
|
revenge = {
|
|
id = 6572,
|
|
cast = 0,
|
|
cooldown = 0,
|
|
gcd = "spell",
|
|
|
|
spend = function ()
|
|
if buff.revenge.up then return 0 end
|
|
return talent.barbaric_training.enabled and 30 or 20
|
|
end,
|
|
spendType = "rage",
|
|
|
|
talent = "revenge",
|
|
startsCombat = true,
|
|
texture = 132353,
|
|
|
|
readyTime = function()
|
|
if buff.revenge.up then return 0 end
|
|
local threshold = action.revenge.cost + ( settings.reserve_rage or 40 )
|
|
if rage.current >= threshold or ( buff.shield_block.remains > 3 and buff.ignore_pain.remains > 3 ) or not tanking then return 0 end
|
|
return rage[ "time_to_" .. threshold ]
|
|
end,
|
|
|
|
handler = function ()
|
|
if set_bonus.tier29_2pc > 0 then applyBuff( "vanguards_determination" ) end
|
|
if buff.revenge.up then removeBuff( "revenge" ) end
|
|
if talent.show_of_force.enabled then applyBuff( "show_of_force" ) end
|
|
applyDebuff( "target", "deep_wounds" )
|
|
|
|
if talent.demolish.enabled and active_enemies > 2 then
|
|
if talent.dominance_of_the_colossus.enabled and buff.colossal_might.stack == 10 then reduceCooldown( "demolish", 2 ) end
|
|
if talent.colossal_might.enabled then addStack( "colossal_might" ) end
|
|
end
|
|
end,
|
|
},
|
|
|
|
|
|
shattering_throw = {
|
|
id = 64382,
|
|
cast = 1.5,
|
|
cooldown = 180,
|
|
gcd = "spell",
|
|
|
|
talent = "shattering_throw",
|
|
startsCombat = true,
|
|
toggle = "cooldowns",
|
|
|
|
handler = function ()
|
|
removeDebuff( "target", "all_absorbs" )
|
|
end,
|
|
},
|
|
|
|
|
|
shield_bash = {
|
|
id = 198912,
|
|
cast = 0,
|
|
cooldown = 10,
|
|
gcd = "spell",
|
|
spend = -3,
|
|
spendType = "rage",
|
|
|
|
pvptalent = "shield_bash",
|
|
startsCombat = false,
|
|
texture = 132357,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "shield_bash" )
|
|
end,
|
|
},
|
|
|
|
|
|
shield_block = {
|
|
id = 2565,
|
|
cast = 0,
|
|
charges = 2,
|
|
cooldown = 16,
|
|
recharge = 16,
|
|
hasteCD = true,
|
|
gcd = "off",
|
|
|
|
toggle = "defensives",
|
|
equipped = "shield",
|
|
defensive = true,
|
|
|
|
spend = 30,
|
|
spendType = "rage",
|
|
|
|
startsCombat = false,
|
|
texture = 132110,
|
|
|
|
nobuff = function()
|
|
if not settings.stack_shield_block then return "shield_block" end
|
|
end,
|
|
|
|
handler = function ()
|
|
applyBuff( "shield_block" )
|
|
end,
|
|
},
|
|
|
|
|
|
shield_charge = {
|
|
id = 385952,
|
|
cast = 0,
|
|
cooldown = 45,
|
|
gcd = "spell",
|
|
|
|
spend = -20,
|
|
spendType = "rage",
|
|
|
|
talent = "shield_charge",
|
|
equipped = "shield",
|
|
startsCombat = true,
|
|
|
|
handler = function ()
|
|
if talent.battering_ram.enabled then
|
|
applyBuff( "battering_ram" )
|
|
end
|
|
if talent.champions_bulwark.enabled then
|
|
applyBuff( "shield_block" )
|
|
applyBuff( "revenge" )
|
|
gain( 20, "rage" )
|
|
end
|
|
end,
|
|
},
|
|
|
|
|
|
shield_slam = {
|
|
id = 23922,
|
|
cast = 0,
|
|
cooldown = function () return 9 - ( talent.honed_reflexes.enabled and 1 or 0 ) end,
|
|
hasteCD = true,
|
|
gcd = "spell",
|
|
|
|
spend = function ()
|
|
local reduction = 0
|
|
-- The Wall Legendary overtakes the new Impenetrable Wall talent, they do not stack in 10.0
|
|
if legendary.the_wall.enabled then reduction = reduction - 5
|
|
elseif talent.impenetrable_wall.enabled then reduction = reduction - 4
|
|
end
|
|
|
|
return
|
|
( -15 + reduction + ( talent.heavy_repercussions.enabled and -2 or 0 ) )
|
|
* ( buff.violent_outburst.up and 1.5 or 1 ) -- Build 45969
|
|
* ( buff.unnerving_focus.up and 1.5 or 1 )
|
|
end,
|
|
spendType = "rage",
|
|
|
|
equipped = "shield",
|
|
startsCombat = true,
|
|
texture = 134951,
|
|
|
|
readyTime = function()
|
|
if buff.burst_of_power.up then return 0 end
|
|
end,
|
|
|
|
handler = function ()
|
|
if buff.violent_outburst.up then
|
|
applyBuff( "ignore_pain" )
|
|
removeBuff( "violent_outburst" )
|
|
end
|
|
|
|
if talent.brace_for_impact.enabled then applyBuff( "brace_for_impact" ) end
|
|
|
|
if talent.heavy_repercussions.enabled and buff.shield_block.up then
|
|
buff.shield_block.expires = buff.shield_block.expires + 1
|
|
end
|
|
|
|
if talent.punish.enabled then applyDebuff( "target", "punish" ) end
|
|
|
|
if ( legendary.the_wall.enabled or talent.impenetrable_wall.enabled ) and cooldown.shield_wall.remains > 0 then
|
|
reduceCooldown( "shield_wall", 6 )
|
|
end
|
|
|
|
if set_bonus.tier30_2pc > 0 then
|
|
reduceCooldown( "last_stand", buff.last_stand.up and 4 or 2 )
|
|
end
|
|
|
|
if buff.fervid.up then
|
|
removeDebuff( "target", "deep_wounds" )
|
|
removeDebuff( "target", "rend" )
|
|
removeDebuff( "target", "thunderous_roar" )
|
|
if set_bonus.tier31_4pc > 0 then applyBuff( "fervid_opposition" ) end
|
|
end
|
|
|
|
if talent.dominance_of_the_colossus.enabled and buff.colossal_might.stack == 10 then reduceCooldown( "demolish", 2 ) end
|
|
if talent.colossal_might then addStack( "colossal_might" ) end
|
|
end,
|
|
},
|
|
|
|
|
|
shield_wall = {
|
|
id = 871,
|
|
cast = 0,
|
|
charges = function () return 1 + ( talent.defenders_aegis.enabled and 1 or 0 ) + ( legendary.unbreakable_will.enabled and 1 or 0 ) end,
|
|
cooldown = function() return 210 - ( talent.honed_reflexes.enabled and 210*0.05 or 0 ) - ( conduit.stalwart_guardian.enabled and 20 or 0 ) - ( talent.defenders_aegis.enabled and 60 or 0 ) end,
|
|
recharge = function() return 210 - ( talent.honed_reflexes.enabled and 210*0.05 or 0 ) - ( conduit.stalwart_guardian.enabled and 20 or 0 ) - ( talent.defenders_aegis.enabled and 60 or 0 ) end,
|
|
gcd = "off",
|
|
|
|
talent = "shield_wall",
|
|
startsCombat = false,
|
|
texture = 132362,
|
|
|
|
toggle = "defensives",
|
|
|
|
usable = function()
|
|
local dmg_required = ( ( settings.shield_wall_amount or 10 ) * 0.01 ) * health.max * ( solo and 0.5 or 1 )
|
|
local hp_required = ( ( settings.shield_wall_health or 10 ) * 0.01 )
|
|
|
|
if settings.shield_wall_condition then
|
|
if incoming_damage_5s < dmg_required then return false, format( "incoming_damage_5s[%.2f] < dmg_required[%.2f] setting", incoming_damage_5s, dmg_required ) end
|
|
if health.percent > hp_required then return false, format( "health.percent[%.2f] > hp_required[%.2f] setting", health.percent, hp_required ) end
|
|
return true
|
|
end
|
|
|
|
if incoming_damage_5s >= dmg_required or ( health.percent or 50 ) <= hp_required then return true end
|
|
if incoming_damage_5s < dmg_required then return false, format( "incoming_damage_5s[%.2f] < dmg_required[%.2f] setting", incoming_damage_5s, dmg_required ) end
|
|
if health.percent > hp_required then return false, format( "health.percent[%.2f] > hp_required[%.2f] setting", health.percent, hp_required ) end
|
|
return false
|
|
end,
|
|
|
|
handler = function ()
|
|
applyBuff( "shield_wall" )
|
|
if talent.immovable_object.enabled then applyBuff( "avatar", 4 ) end
|
|
end,
|
|
},
|
|
|
|
|
|
shockwave = {
|
|
id = 46968,
|
|
cast = 0,
|
|
cooldown = function () return
|
|
( ( ( talent.rumbling_earth.enabled and active_enemies >= 3 ) and 25 or 40 )
|
|
- ( conduit.disturb_the_peace.enabled and 5 or 0 )
|
|
- ( talent.earthquaker.enabled and 5 or 0 )
|
|
) end,
|
|
gcd = "spell",
|
|
|
|
talent = "shockwave",
|
|
startsCombat = true,
|
|
texture = 236312,
|
|
|
|
toggle = "interrupts",
|
|
debuff = function () return settings.shockwave_interrupt and "casting" or nil end,
|
|
readyTime = function () return settings.shockwave_interrupt and timeToInterrupt() or nil end,
|
|
|
|
usable = function () return not target.is_boss end,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "shockwave" )
|
|
active_dot.shockwave = max( active_dot.shockwave, active_enemies )
|
|
if not target.is_boss then interrupt() end
|
|
end,
|
|
},
|
|
|
|
|
|
slam = {
|
|
id = 1464,
|
|
cast = 0,
|
|
cooldown = 0,
|
|
gcd = "spell",
|
|
|
|
spend = 20,
|
|
spendType = "rage",
|
|
|
|
startsCombat = true,
|
|
texture = 132340,
|
|
|
|
handler = function ()
|
|
end,
|
|
},
|
|
|
|
|
|
spell_block = {
|
|
id = 392966,
|
|
cast = 0,
|
|
cooldown = 90,
|
|
gcd = "off",
|
|
|
|
talent = "spell_block",
|
|
startsCombat = false,
|
|
|
|
toggle = "defensives",
|
|
|
|
handler = function ()
|
|
applyBuff( "spell_block" )
|
|
end,
|
|
},
|
|
|
|
spell_reflection = {
|
|
id = 23920,
|
|
cast = 0,
|
|
cooldown = function() return 25 - ( talent.honed_reflexes.enabled and 25 * 0.05 or 0 ) end,
|
|
gcd = "off",
|
|
|
|
talent = "spell_reflection",
|
|
|
|
toggle = "defensives",
|
|
debuff = "casting",
|
|
|
|
handler = function()
|
|
applyBuff( "spell_reflection" )
|
|
applyBuff( "spell_reflection_defense" )
|
|
end,
|
|
},
|
|
|
|
storm_bolt = {
|
|
id = 107570,
|
|
cast = 0,
|
|
cooldown = function() return 30 - ( talent.honed_reflexes.enabled and 30 * 0.05 or 0 ) + ( talent.storm_bolts.enabled and 10 or 0 ) end,
|
|
gcd = "spell",
|
|
|
|
talent = "storm_bolt",
|
|
startsCombat = true,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "storm_bolt" )
|
|
end,
|
|
},
|
|
|
|
|
|
taunt = {
|
|
id = 355,
|
|
cast = 0,
|
|
cooldown = 8,
|
|
gcd = "off",
|
|
|
|
startsCombat = true,
|
|
texture = 136080,
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "taunt" )
|
|
end,
|
|
},
|
|
|
|
|
|
thunder_clap = {
|
|
id = 6343,
|
|
cast = 0,
|
|
cooldown = function () return haste * ( ( buff.avatar.up and talent.unstoppable_force.enabled ) and 3 or 6 ) end,
|
|
gcd = "spell",
|
|
hasteCD = true,
|
|
|
|
spend = function () return -5
|
|
* ( buff.violent_outburst.up and 2 or 1 )
|
|
* ( buff.unnerving_focus.up and 1.5 or 1 ) end,
|
|
spendType = "rage",
|
|
|
|
talent = "thunder_clap",
|
|
startsCombat = true,
|
|
texture = 136105,
|
|
bind = "thunder_blast",
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "thunder_clap" )
|
|
active_dot.thunder_clap = max( active_dot.thunder_clap, active_enemies )
|
|
removeBuff( "show_of_force" )
|
|
|
|
if ( talent.thunderlord.enabled or legendary.thunderlord.enabled ) and cooldown.demoralizing_shout.remains > 0 then
|
|
reduceCooldown( "demoralizing_shout", min( 3, active_enemies ) )
|
|
end
|
|
|
|
if talent.rend.enabled then
|
|
applyDebuff( "target", "rend" )
|
|
active_dot.rend = min( active_enemies, 5 )
|
|
end
|
|
|
|
if buff.violent_outburst.up then
|
|
applyBuff( "ignore_pain" )
|
|
removeBuff( "violent_outburst" )
|
|
end
|
|
end,
|
|
},
|
|
|
|
thunder_blast = {
|
|
id = 435222,
|
|
flash = 6343,
|
|
cast = 0,
|
|
cooldown = function () return haste * ( ( buff.avatar.up and talent.unstoppable_force.enabled ) and 3 or 6 ) end,
|
|
gcd = "spell",
|
|
hasteCD = true,
|
|
|
|
spend = function () return -15
|
|
* ( buff.violent_outburst.up and 2 or 1 )
|
|
* ( buff.unnerving_focus.up and 1.5 or 1 ) end,
|
|
spendType = "rage",
|
|
|
|
talent = "thunder_clap",
|
|
startsCombat = true,
|
|
texture = 136105,
|
|
bind = "thunder_clap",
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "thunder_clap" )
|
|
active_dot.thunder_clap = max( active_dot.thunder_clap, active_enemies )
|
|
removeBuff( "show_of_force" )
|
|
|
|
if ( talent.thunderlord.enabled or legendary.thunderlord.enabled ) and cooldown.demoralizing_shout.remains > 0 then
|
|
reduceCooldown( "demoralizing_shout", min( 3, active_enemies ) )
|
|
end
|
|
|
|
if talent.rend.enabled then
|
|
applyDebuff( "target", "rend" )
|
|
active_dot.rend = min( active_enemies, 5 )
|
|
end
|
|
|
|
if buff.violent_outburst.up then
|
|
applyBuff( "ignore_pain" )
|
|
removeBuff( "violent_outburst" )
|
|
end
|
|
end,
|
|
copy = { 6343 }
|
|
},
|
|
|
|
|
|
thunderous_roar = {
|
|
id = 384318,
|
|
cast = 0,
|
|
cooldown = function() return talent.uproar.enabled and 90 or 45 end,
|
|
gcd = "spell",
|
|
|
|
spend = -10,
|
|
spendType = "rage",
|
|
|
|
talent = "thunderous_roar",
|
|
startsCombat = true,
|
|
|
|
toggle = "cooldowns",
|
|
|
|
handler = function ()
|
|
applyDebuff( "target", "thunderous_roar" )
|
|
active_dot.thunderous_roar = max( active_dot.thunderous_roar, active_enemies )
|
|
end,
|
|
},
|
|
|
|
victory_rush = {
|
|
id = 34428,
|
|
cast = 0,
|
|
cooldown = 0,
|
|
gcd = "spell",
|
|
|
|
startsCombat = true,
|
|
buff = "victorious",
|
|
|
|
handler = function ()
|
|
removeBuff( "victorious" )
|
|
gain( health.max * 0.2, "health" )
|
|
if conduit.indelible_victory.enabled then applyBuff( "indelible_victory" ) end
|
|
end,
|
|
},
|
|
|
|
whirlwind = {
|
|
id = 1680,
|
|
cast = 0,
|
|
cooldown = 0,
|
|
gcd = "spell",
|
|
|
|
spend = 20,
|
|
spendType = "rage",
|
|
|
|
startsCombat = false,
|
|
texture = 132369,
|
|
|
|
handler = function ()
|
|
end,
|
|
},
|
|
|
|
wrecking_throw = {
|
|
id = 384110,
|
|
cast = 0,
|
|
cooldown = 45,
|
|
gcd = "spell",
|
|
|
|
talent = "wrecking_throw",
|
|
startsCombat = true,
|
|
|
|
handler = function ()
|
|
end,
|
|
},
|
|
} )
|
|
|
|
spec:RegisterSetting( "shockwave_interrupt", true, {
|
|
name = "Only |T236312:0|t Shockwave as Interrupt",
|
|
desc = "If checked, |T236312:0|t Shockwave will only be recommended when your target is casting (and talented).",
|
|
type = "toggle",
|
|
width = "full"
|
|
} )
|
|
|
|
spec:RegisterSetting( "overlap_ignore_pain", false, {
|
|
name = "Overlap |T1377132:0|t Ignore Pain",
|
|
desc = "If checked, |T1377132:0|t Ignore Pain can be recommended while it is already active even if its remaining absorb is greater than 30% of your maximum health. This setting may cause you to spend more Rage on mitigation.",
|
|
type = "toggle",
|
|
width = "full"
|
|
} )
|
|
|
|
spec:RegisterSetting( "stack_shield_block", false, {
|
|
name = "Overlap |T132110:0|t Shield Block",
|
|
desc = function()
|
|
return "If checked, the addon can recommend overlapping |T132110:0|t Shield Block usage. \n\n" ..
|
|
"This setting avoids leaving Shield Block at 2 charges, which wastes cooldown recovery time."
|
|
end,
|
|
type = "toggle",
|
|
width = "full"
|
|
} )
|
|
|
|
spec:RegisterSetting( "stance_weaving", false, {
|
|
name = "Allow Stance Changes",
|
|
desc = function()
|
|
return "If checked, custom priorities can be written to recommend changing between stances. For example, Battle Stance could be recommended when "
|
|
.. "using offensive cooldowns, then Defensive Stance can be recommended when tanking resumes.\n\n"
|
|
.. "If left unchecked, the addon will not recommend changing your stance as long as you are already in a stance. This choice prevents the addon "
|
|
.. "from endlessly recommending that you change your stance when you do not want to change it."
|
|
end,
|
|
type = "toggle",
|
|
width = "full"
|
|
} )
|
|
|
|
spec:RegisterSetting( "reserve_rage", 35, { -- Ignore Pain cost is 35, Shield Block is 30.
|
|
name = "|T135726:0|t Reserve Rage for Mitigation",
|
|
desc = "If set above 0, the addon will not recommend |T132353:0|t Revenge or |T135358:0|t Execute unless you'll be still have this much Rage afterward.\n\n"
|
|
.. "When set to |cFFFFD10035|r or higher, this feature ensures that you can always use |T1377132:0|t Ignore Pain and |T132110:0|t Shield Block when following recommendations for damage and threat.",
|
|
type = "range",
|
|
min = 0,
|
|
max = 100,
|
|
step = 1,
|
|
width = "full",
|
|
} )
|
|
|
|
spec:RegisterSetting( "shield_wall_amount", 50, {
|
|
name = "|T132362:0|t Shield Wall Damage Required",
|
|
desc = "If set above 0, the addon will not recommend |T132362:0|t Shield Wall unless you have taken this much damage in the past 5 seconds, as a percentage of your maximum health.\n\n"
|
|
.. "If set to |cFFFFD10050%|r and your maximum health is 50,000, then the addon will only recommend Shield Wall when you've taken 25,000 damage in the past 5 seconds.\n\n"
|
|
.. "This value is reduced by 50% when playing solo.",
|
|
type = "range",
|
|
min = 0,
|
|
max = 200,
|
|
step = 1,
|
|
width = "full",
|
|
} )
|
|
|
|
spec:RegisterSetting( "shield_wall_health", 50, {
|
|
name = "|T132362:0|t Shield Wall Health Percentage",
|
|
desc = "If set below 100, the addon will not recommend |T132362:0|t Shield Wall unless your current health has fallen below this percentage.",
|
|
type = "range",
|
|
min = 0,
|
|
max = 100,
|
|
step = 1,
|
|
width = "full",
|
|
} )
|
|
|
|
spec:RegisterSetting( "shield_wall_condition", false, {
|
|
name = "Require |T132362:0|t Shield Wall Damage and Health",
|
|
desc = "If checked, |T132362:0|t Shield Wall will not be recommended unless both the Damage Required |cFFFFD100and|r Health Percentage requirements are met.\n\n"
|
|
.. "Otherwise, Shield Wall can be recommended when |cFFFFD100either|r requirement is met.",
|
|
type = "toggle",
|
|
width = "full"
|
|
} )
|
|
|
|
spec:RegisterSetting( "rallying_cry_amount", 50, {
|
|
name = "|T132351:0|t Rallying Cry Damage Required",
|
|
desc = "If set above 0, the addon will not recommend |T132351:0|t Rallying Cry unless you have taken this much damage in the past 5 seconds, as a percentage of your maximum health.\n\n"
|
|
.. "If set to |cFFFFD10050%|r and your maximum health is 50,000, then the addon will only recommend Rallying Cry when you've taken 25,000 damage in the past 5 seconds.\n\n"
|
|
.. "This value is reduced by 50% when playing solo.",
|
|
type = "range",
|
|
min = 0,
|
|
max = 200,
|
|
step = 1,
|
|
width = "full",
|
|
} )
|
|
|
|
spec:RegisterSetting( "rallying_cry_health", 50, {
|
|
name = "|T132351:0|t Rallying Cry Health Percentage",
|
|
desc = "If set below 100, the addon will not recommend |T132351:0|t Rallying Cry unless your current health has fallen below this percentage.",
|
|
type = "range",
|
|
min = 0,
|
|
max = 100,
|
|
step = 1,
|
|
width = "full",
|
|
} )
|
|
|
|
spec:RegisterSetting( "rallying_cry_condition", false, {
|
|
name = "Require |T132351:0|t Rallying Cry Damage and Health",
|
|
desc = "If checked, |T132351:0|t Rallying Cry will not be recommended unless both the Damage Required |cFFFFD100and|r Health Percentage requirements are met.\n\n"
|
|
.. "Otherwise, Rallying Cry can be recommended when |cFFFFD100either|r requirement is met.",
|
|
type = "toggle",
|
|
width = "full"
|
|
} )
|
|
|
|
spec:RegisterSetting( "last_stand_offensively", false, {
|
|
name = "Use |T135871:0|t Last Stand Offensively",
|
|
desc = function()
|
|
return "If checked, the addon will recommend using |T135871:0|t Last Stand to generate rage.\n\n"
|
|
.. "If unchecked, the addon will only recommend |T135871:0|t Last Stand defensively after taking significant damage.\n\n"
|
|
.. "Requires " .. ( state.set_bonus.tier30_2pc > 0 and "|cFF00FF00" or "|cFFFF0000" ) .. "2-piece Tier 30|r or "
|
|
.. "|W|T571316:0|t " .. ( ( state.talent.unnerving_focus.enabled or state.conduit.unnerving_focus.enabled ) and "|cFF00FF00" or "|cFFFF0000" ) .. " Unnerving Focus|r|w"
|
|
end,
|
|
type = "toggle",
|
|
width = "full"
|
|
} )
|
|
|
|
spec:RegisterSetting( "last_stand_amount", 50, {
|
|
name = "|T135871:0|t Last Stand Damage Required",
|
|
desc = "If set above 0, the addon will not recommend |T135871:0|t Last Stand unless you have taken this much damage in the past 5 seconds, as a percentage of your maximum health.\n\n"
|
|
.. "If set to |cFFFFD10050%|r and your maximum health is 50,000, then the addon will only recommend Last Stand when you've taken 25,000 damage in the past 5 seconds.\n\n"
|
|
.. "This value is reduced by 50% when playing solo.",
|
|
type = "range",
|
|
min = 0,
|
|
max = 200,
|
|
step = 1,
|
|
width = "full",
|
|
disabled = function() return state.settings.last_stand_offensively end,
|
|
} )
|
|
|
|
spec:RegisterSetting( "last_stand_health", 50, {
|
|
name = "|T135871:0|t Last Stand Health Percentage",
|
|
desc = "If set below 100, the addon will not recommend |T135871:0|t Last Stand unless your current health has fallen below this percentage.",
|
|
type = "range",
|
|
min = 0,
|
|
max = 100,
|
|
step = 1,
|
|
width = "full",
|
|
disabled = function() return state.settings.last_stand_offensively end,
|
|
} )
|
|
|
|
spec:RegisterSetting( "last_stand_condition", false, {
|
|
name = "Require |T135871:0|t Last Stand Damage and Health",
|
|
desc = "If checked, |T135871:0|t Last Stand will not be recommended unless both the Damage Required |cFFFFD100and|r Health Percentage requirements are met.\n\n"
|
|
.. "Otherwise, Last Stand can be recommended when |cFFFFD100either|r requirement is met.",
|
|
type = "toggle",
|
|
width = "full",
|
|
disabled = function() return state.settings.last_stand_offensively end,
|
|
} )
|
|
|
|
|
|
local LSR = LibStub( "SpellRange-1.0" )
|
|
|
|
spec:RegisterRanges( "hamstring", "devastate", "execute", "storm_bolt", "charge", "heroic_throw", "taunt" )
|
|
|
|
spec:RegisterRangeFilter( strformat( "Can %s but cannot %s (8 yards)", Hekili:GetSpellLinkWithTexture( spec.abilities.taunt.id ), Hekili:GetSpellLinkWithTexture( spec.abilities.charge.id ) ), function()
|
|
return LSR.IsSpellInRange( spec.abilities.taunt.name ) == 1 and LSR.IsSpellInRange( class.abilities.charge.name ) ~= 0
|
|
end )
|
|
|
|
|
|
spec:RegisterOptions( {
|
|
enabled = true,
|
|
|
|
aoe = 2,
|
|
|
|
nameplates = true,
|
|
nameplateRange = 10,
|
|
rangeFilter = true,
|
|
|
|
damage = true,
|
|
damageExpiration = 8,
|
|
|
|
potion = "potion_of_spectral_strength",
|
|
|
|
package = "Protection Warrior",
|
|
} )
|
|
|
|
|
|
spec:RegisterPack( "Protection Warrior", 20240815, [[Hekili:nRv3UTTos4NLZngXytDK)l29G4CXEU60lkwaxG9ojtlrBRtKefOOC2SWWp77qkkjsAszz30Dx0I0gPHZ8ndN)i14p2)h(RJqmS)3N4nzM3YXZh5nF2Yjt9xZ(ih7Vohf(gAp8FYqPWp)hucdhYIjzN38pruAmHYP5JeckIZRcsjneO7aJLx87p90(y2HYTJcjPpveNwMG4lnKI2X4)E4t(R3wgNW(Zm)T2aYZZNa8mhh6)9faKoehfHRifxe6VMt6x8w(LXZ)9ZBwhN(hN3KZHum7JZBkZ58R483o)Tk6w8LjZa6(XbSa7WpaWfNb4Ns2fNaOgj0SIr5umG4Ti2FB1tWpzj4Gcgkle)iJSFFcEfO(FRlIpqkzCblPbEtEzAkor9jHhq094hJ3TIfNIx5D6uk5iofNXgffxjUxxQUGYcCqmdNwO(q0red0fLNuCigNef8okjrWCucNLXPa3rBbWr2(xWo4iCg)3IgSTC3UrvCzue59mvwTnHqIc2vs)q7PyAbM(wC2EnGqdrz4agHsb5P(MK49hyfb)vz0(uJxTlMIfcrJtGMxWOOKGqqh0KmAFazxaJgh(MMviNW)FC1vvDkZpDs)3hW42C2Odyuc7WO8q2lRM4PYP49zekoihfNvz9mO)vG(bpqHqIrr4DXHXahgpFqiHKWTEJKw)Ieu6ikgf9XPt6epZ7cIR8eQiFGC)cEwAohtbBltEhrFREdZKFt6MFMKpvH8iCkbmZX)ByRSYNvhdBjKu(RosIdX9r(s7SD9E(pPGR8utqfmrWyu12PG(YSmm9iFf7iHLfUG6uhq9NNZt86X2CRprLapgt4Yiau)TL0cMIyb)TJFeqX5yki1crEMAZqtaDooddHj8yAEWUlSnVlVt3i5MTj)kW(4fDH9RlWl43YEWpNOB4PtIi)xxTWtMzPaJ5gckoAeyMcFB1IbvumD(qxIkfYTuayPYelFhKfm8T6x(6QzdkWSGTKmW(YIX0PJdMKh(iVeaz3UG9HrRgRLJTzJIN16blPT(Q3v9PTMC8kRAiFzYG2KcgM2YodnWJRbwE6S8qvnHcrM7XAv0UmDHsHnR5kmQZkZKcnsGUGXjXfhAkCessiffqLNuEnRQTuyVuDnq)mzrykPSiGsmR8c7HVJoIvGhTmDBchFGObJADGaaLKKGkdEXOMfAilT85wEHWPPb8AEsrLurVwGFMw9nAzwq1VfaAo7rEBDRqe8Jf8QQSvJ5SthDsnoimbLBaqEb6lz3Ei8byMsdqJaj0A7aicURCbfr4z(HSlTrfUwdx634sAeJZKCwv0k9CYGlADqghuWi55IKd7iul(Coa(9aIz3kiAAFGIa3bWTtYU2OY7agpFROW0uqXhXzv96wN)SMhf44I04WaojuOZsHtRJWejBu9bLcqjbBTqEz1ZE3J2cLUVMrSt)TUCdUQDzQSpIx59puNGdrH)cMiOIuCgaNwy0YpziNnN)he2aThlRvjDXf2eEF15K3bLu8UMYt9FtFyf0FrzZTo)6LgUw8AS19GtivdxlAcGw3B13jUW)lCyjtZNTP8V7M7ePKCjM6925DV8H19wuYpTBqegbfoA3a0EC)mS9Yp5YeRtC0DO2XeTWs3PQVxo26m3rPjWhOZDLFZPhsFuM)7jzLScs)TLExEW1xNuNEtsVZJ3oOY93DVVcq2dMbISTfyRyA68EWg4GyZ)8WeVrBzKrkc6DlKAPm0fH1xXURjMxvUHG713C11CrUjpKBX38ZvYr4JG2YVNU1q9A(zTQVWoV5(RFhr5fOk8x)NP5ekd2c2m78Mk2CEdVdXIrN)M)Auj7a)Mdx3CNG)b)ob9xliHFrIqbs4F(U4ckLBN()D)1H0y4mgXi)1MjxoV5LvN3mU(s88xRT)4ZaC(ZZlUfLZQPozLlR55ndoVXzthN38kiWjcI0l7kE01k92Hsp7xcsNDVivLiNTxT50jjZVh4DEZZ3l6CVHp3PzKNiRYOSWtviD2yRfLqM9PIvtBrI85Cq88vab3P9zVFoZ3ln7UxzxQfHkjv4OCHi81Q)Oc4bcxAJqHbxNUV2dB)uPA3(KzA7goBI2MHgaQmJx3PGEqAMT0r65n6XZ2AOvML5EDwpVzOQo)YfEGMTFExPgFOtfqxjTAhK6y3(K3TMy475oVSEykxypyXBPRcLDbitNV59HDdvSkg96RLiXs)(Tgaz)mnP6Tzy0dNCNkZEzqLnyR9T3HBL7ewFwIQo)8IUCGD3DKOCH078Q79)wNEWDygw()HGR2W5o5Qw8XY64rJ2VfyCIAnN2M1DTcXoDf)Ad4hVShrm3GqKWAOLy9o1LPZVjXWHoFj)Q1fUmgQMvW8SowByySNAkH6uf6Pdg7U(MguKMu7YPZ6hD6HVQ)U43K)DtW3y31e(Ff2QJ9gRLXw5OvQBqm(B2HktynnJuVIQzkWy)09wbFmdeLSLHRxmUbIT4LT8V67o0uxT(XnZHGHK10MQEz6DPNMp9M9Pu4IEK0Rgi3v4FRUMYo1VRDggmaJwFQTZ0qxnPQpJd2AtTMsJzEWmMtlUSziiSgz2iBTPIWK0jAkJ6ysys5vo6QspOnzOm7l1rgDfhtX4y06IRiUAsuMZcNPCKz)AlxitJx)9CLzBN3v2wu0hTnNPVqh98Po9eQzCDorgU4)K(WF7lDQXsDnWeQ4Z(hcTNytDCiCAVM)PbQ6OzT5lqDDo(AZ91EPRoF2sBI3n6sP6l2zXIwi1XqnOsMZzvWfcNF9OLRHW70w(Rx3gVOp6wFaHd(3zFDg8Vd0BRP0fQ9qBovjIQ2vkNYvE00sy3DNyCjdfQtjqdrTxQNT5oPQMVCWt4nHWZS7Uy(d27IfeXx96LRc3q09bhUghgwZezwiTrtP6D2gpfhVzg3e0uAVXZxyg0A2qo8kM1CDF60UstQ2AOzMwbB16nXymxmHG7Z5j8kSn4lxCvK136HOntTwyKD2wpumMTK21rme6V9PKPYF0(KYCb4AEJqIA9dPv41eBxPFiTWL6HQrgu5DHieKjyR77D)Ah5a0PQzXHhO16zPp3ovFPKGQHYM)Ts4Y0mISX1WykD0wC9nDkoPrZSm3CwJQbE2FnjtT)sLrI22Xpmju4XACQMQ)4)F(d]] )
|