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.
1122 lines
46 KiB
1122 lines
46 KiB
|
5 years ago
|
-- WarriorFury.lua
|
||
|
|
-- June 2018
|
||
|
|
|
||
|
|
local addon, ns = ...
|
||
|
|
local Hekili = _G[ addon ]
|
||
|
|
|
||
|
|
local class = Hekili.Class
|
||
|
|
local state = Hekili.State
|
||
|
|
|
||
|
|
local IsActiveSpell = ns.IsActiveSpell
|
||
|
|
|
||
|
|
|
||
|
|
-- Conduits
|
||
|
|
-- [x] depths_of_insanity
|
||
|
|
-- [-] hack_and_slash
|
||
|
|
-- [-] vicious_contempt
|
||
|
|
|
||
|
|
|
||
|
|
if UnitClassBase( 'player' ) == 'WARRIOR' then
|
||
|
|
local spec = Hekili:NewSpecialization( 72 )
|
||
|
|
|
||
|
|
local base_rage_gen, fury_rage_mult = 1.75, 1.00
|
||
|
|
local offhand_mod = 0.50
|
||
|
|
|
||
|
|
spec:RegisterResource( Enum.PowerType.Rage, {
|
||
|
|
mainhand_fury = {
|
||
|
|
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 ()
|
||
|
|
return ( state.talent.war_machine.enabled and 1.1 or 1 ) * base_rage_gen * fury_rage_mult * state.swings.mainhand_speed / state.haste
|
||
|
|
end
|
||
|
|
},
|
||
|
|
|
||
|
|
offhand_fury = {
|
||
|
|
swing = "offhand",
|
||
|
|
|
||
|
|
last = function ()
|
||
|
|
local swing = state.swings.offhand
|
||
|
|
local t = state.query_time
|
||
|
|
|
||
|
|
return swing + ( floor( ( t - swing ) / state.swings.offhand_speed ) * state.swings.offhand_speed )
|
||
|
|
end,
|
||
|
|
|
||
|
|
interval = "offhand_speed",
|
||
|
|
|
||
|
|
stop = function () return state.time == 0 or state.swings.offhand == 0 end,
|
||
|
|
value = function ()
|
||
|
|
return ( state.talent.war_machine.enabled and 1.1 or 1 ) * base_rage_gen * fury_rage_mult * state.swings.offhand_speed * offhand_mod / state.haste
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
bladestorm = {
|
||
|
|
aura = "bladestorm",
|
||
|
|
|
||
|
|
last = function ()
|
||
|
|
local app = state.buff.bladestorm.applied
|
||
|
|
local t = state.query_time
|
||
|
|
|
||
|
|
return app + ( floor( ( t - app ) / ( 1 * state.haste ) ) * ( 1 * state.haste ) )
|
||
|
|
end,
|
||
|
|
|
||
|
|
interval = function () return 1 * state.haste end,
|
||
|
|
|
||
|
|
value = 5,
|
||
|
|
},
|
||
|
|
|
||
|
|
battle_trance = {
|
||
|
|
aura = "battle_trance",
|
||
|
|
|
||
|
|
last = function ()
|
||
|
|
local app = state.buff.battle_trance.applied
|
||
|
|
local t = state.query_time
|
||
|
|
|
||
|
|
return app + ( floor( ( t - app ) / state.haste ) * state.haste )
|
||
|
|
end,
|
||
|
|
|
||
|
|
interval = 3,
|
||
|
|
|
||
|
|
value = 5,
|
||
|
|
},
|
||
|
|
|
||
|
|
conquerors_banner = {
|
||
|
|
aura = "conquerors_banner",
|
||
|
|
|
||
|
|
last = function ()
|
||
|
|
local app = state.buff.conquerors_banner.applied
|
||
|
|
local t = state.query_time
|
||
|
|
|
||
|
|
return app + ( floor( ( t - app ) / ( 1 * state.haste ) ) * ( 1 * state.haste ) )
|
||
|
|
end,
|
||
|
|
|
||
|
|
interval = 1,
|
||
|
|
|
||
|
|
value = 4,
|
||
|
|
},
|
||
|
|
} )
|
||
|
|
|
||
|
|
-- Talents
|
||
|
|
spec:RegisterTalents( {
|
||
|
|
war_machine = 22632, -- 262231
|
||
|
|
sudden_death = 22633, -- 280721
|
||
|
|
fresh_meat = 22491, -- 215568
|
||
|
|
|
||
|
|
double_time = 19676, -- 103827
|
||
|
|
impending_victory = 22625, -- 202168
|
||
|
|
storm_bolt = 23093, -- 107570
|
||
|
|
|
||
|
|
massacre = 22379, -- 206315
|
||
|
|
frenzy = 22381, -- 335077
|
||
|
|
onslaught = 23372, -- 315720
|
||
|
|
|
||
|
|
furious_charge = 23097, -- 202224
|
||
|
|
bounding_stride = 22627, -- 202163
|
||
|
|
warpaint = 22382, -- 208154
|
||
|
|
|
||
|
|
seethe = 22383, -- 335091
|
||
|
|
frothing_berserker = 22393, -- 215571
|
||
|
|
cruelty = 19140, -- 335070
|
||
|
|
|
||
|
|
meat_cleaver = 22396, -- 280392
|
||
|
|
dragon_roar = 22398, -- 118000
|
||
|
|
bladestorm = 22400, -- 46924
|
||
|
|
|
||
|
|
anger_management = 22405, -- 152278
|
||
|
|
reckless_abandon = 22402, -- 202751
|
||
|
|
siegebreaker = 16037, -- 280772
|
||
|
|
} )
|
||
|
|
|
||
|
|
-- PvP Talents
|
||
|
|
spec:RegisterPvpTalents( {
|
||
|
|
barbarian = 166, -- 280745
|
||
|
|
battle_trance = 170, -- 213857
|
||
|
|
bloodrage = 172, -- 329038
|
||
|
|
death_sentence = 25, -- 198500
|
||
|
|
death_wish = 179, -- 199261
|
||
|
|
demolition = 5373, -- 329033
|
||
|
|
disarm = 3533, -- 236077
|
||
|
|
enduring_rage = 177, -- 198877
|
||
|
|
master_and_commander = 3528, -- 235941
|
||
|
|
slaughterhouse = 3735, -- 352998
|
||
|
|
warbringer = 5431, -- 356353
|
||
|
|
} )
|
||
|
|
|
||
|
|
|
||
|
|
-- Auras
|
||
|
|
spec:RegisterAuras( {
|
||
|
|
battle_shout = {
|
||
|
|
id = 6673,
|
||
|
|
duration = 3600,
|
||
|
|
max_stack = 1,
|
||
|
|
shared = "player", -- check for anyone's buff on the player.
|
||
|
|
},
|
||
|
|
berserker_rage = {
|
||
|
|
id = 18499,
|
||
|
|
duration = 6,
|
||
|
|
type = "",
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
bladestorm = {
|
||
|
|
id = 46924,
|
||
|
|
duration = function () return 4 * haste end,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
bounding_stride = {
|
||
|
|
id = 202164,
|
||
|
|
duration = 3,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
charge = {
|
||
|
|
id = 105771,
|
||
|
|
duration = 1,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
enrage = {
|
||
|
|
id = 184362,
|
||
|
|
duration = 4,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
enraged_regeneration = {
|
||
|
|
id = 184364,
|
||
|
|
duration = 8,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
frenzy = {
|
||
|
|
id = 335082,
|
||
|
|
duration = 12,
|
||
|
|
max_stack = 4,
|
||
|
|
},
|
||
|
|
furious_charge = {
|
||
|
|
id = 202225,
|
||
|
|
duration = 5,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
hamstring= {
|
||
|
|
id = 1715,
|
||
|
|
duration = 15,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
ignore_pain = {
|
||
|
|
id = 190456,
|
||
|
|
duration = 12,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
intimidating_shout = {
|
||
|
|
id = 5246,
|
||
|
|
duration = 8,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
piercing_howl = {
|
||
|
|
id = 12323,
|
||
|
|
duration = 8,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
rallying_cry = {
|
||
|
|
id = 97463,
|
||
|
|
duration = function () return ( azerite.moment_of_glory.enabled and 12 or 10 ) * ( 1 + conduit.inspiring_presence.mod * 0.01 ) end,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
recklessness = {
|
||
|
|
id = 1719,
|
||
|
|
duration = function () return ( level > 51 and 12 or 10 ) * ( 1 + conduit.depths_of_insanity.mod * 0.01 ) end,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
siegebreaker = {
|
||
|
|
id = 280773,
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
spell_reflection = {
|
||
|
|
id = 23920,
|
||
|
|
duration = function () return legendary.misshapen_mirror.enabled and 8 or 5 end,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
storm_bolt = {
|
||
|
|
id = 132169,
|
||
|
|
duration = 4,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
sudden_death = {
|
||
|
|
id = 280776,
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
taunt = {
|
||
|
|
id = 355,
|
||
|
|
duration = 3,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
victorious = {
|
||
|
|
id = 32216,
|
||
|
|
duration = 20,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
whirlwind = {
|
||
|
|
id = 85739,
|
||
|
|
duration = 20,
|
||
|
|
max_stack = function () return talent.meat_cleaver.enabled and 4 or 2 end,
|
||
|
|
copy = "meat_cleaver"
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
-- Azerite Powers
|
||
|
|
gathering_storm = {
|
||
|
|
id = 273415,
|
||
|
|
duration = 6,
|
||
|
|
max_stack = 5,
|
||
|
|
},
|
||
|
|
|
||
|
|
-- Cold Steel, Hot Blood
|
||
|
|
gushing_wound = {
|
||
|
|
id = 288091,
|
||
|
|
duration = 6,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
|
||
|
|
intimidating_presence = {
|
||
|
|
id = 288644,
|
||
|
|
duration = 12,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
|
||
|
|
moment_of_glory = {
|
||
|
|
id = 280210,
|
||
|
|
duration = 12,
|
||
|
|
max_stack = 1,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
-- PvP Talents
|
||
|
|
battle_trance = {
|
||
|
|
id = 213858,
|
||
|
|
duration = 18,
|
||
|
|
max_stack = 1
|
||
|
|
},
|
||
|
|
} )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterGear( 'tier20', 147187, 147188, 147189, 147190, 147191, 147192 )
|
||
|
|
spec:RegisterAura( "raging_thirst", {
|
||
|
|
id = 242300,
|
||
|
|
duration = 8
|
||
|
|
} ) -- fury 2pc.
|
||
|
|
spec:RegisterAura( "bloody_rage", {
|
||
|
|
id = 242952,
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 10
|
||
|
|
} ) -- fury 4pc.
|
||
|
|
|
||
|
|
spec:RegisterGear( 'tier21', 152178, 152179, 152180, 152181, 152182, 152183 )
|
||
|
|
spec:RegisterAura( "slaughter", {
|
||
|
|
id = 253384,
|
||
|
|
duration = 4
|
||
|
|
} ) -- fury 2pc dot.
|
||
|
|
spec:RegisterAura( "outrage", {
|
||
|
|
id = 253385,
|
||
|
|
duration = 8
|
||
|
|
} ) -- fury 4pc.
|
||
|
|
|
||
|
|
spec:RegisterGear( "ceannar_charger", 137088 )
|
||
|
|
spec:RegisterGear( "timeless_stratagem", 143728 )
|
||
|
|
spec:RegisterGear( "kazzalax_fujiedas_fury", 137053 )
|
||
|
|
spec:RegisterAura( "fujiedas_fury", {
|
||
|
|
id = 207776,
|
||
|
|
duration = 10,
|
||
|
|
max_stack = 4
|
||
|
|
} )
|
||
|
|
spec:RegisterGear( "mannoroths_bloodletting_manacles", 137107 ) -- NYI.
|
||
|
|
spec:RegisterGear( "najentuss_vertebrae", 137087 )
|
||
|
|
spec:RegisterGear( "valarjar_berserkers", 151824 )
|
||
|
|
spec:RegisterGear( "ayalas_stone_heart", 137052 )
|
||
|
|
spec:RegisterAura( "stone_heart", { id = 225947,
|
||
|
|
duration = 10
|
||
|
|
} )
|
||
|
|
spec:RegisterGear( "the_great_storms_eye", 151823 )
|
||
|
|
spec:RegisterAura( "tornados_eye", {
|
||
|
|
id = 248142,
|
||
|
|
duration = 6,
|
||
|
|
max_stack = 6
|
||
|
|
} )
|
||
|
|
spec:RegisterGear( "archavons_heavy_hand", 137060 )
|
||
|
|
spec:RegisterGear( "weight_of_the_earth", 137077 ) -- NYI.
|
||
|
|
|
||
|
|
spec:RegisterGear( "soul_of_the_battlelord", 151650 )
|
||
|
|
|
||
|
|
state.IsActiveSpell = IsActiveSpell
|
||
|
|
|
||
|
|
local whirlwind_consumers = {
|
||
|
|
bloodthirst = 1,
|
||
|
|
execute = 1,
|
||
|
|
impending_victory = 1,
|
||
|
|
raging_blow = 1,
|
||
|
|
rampage = 1,
|
||
|
|
siegebreaker = 1,
|
||
|
|
victory_rush = 1
|
||
|
|
}
|
||
|
|
|
||
|
|
local whirlwind_gained = 0
|
||
|
|
local whirlwind_stacks = 0
|
||
|
|
|
||
|
|
local rageSpent = 0
|
||
|
|
local gloryRage = 0
|
||
|
|
|
||
|
|
local fresh_meat_actual = {}
|
||
|
|
local fresh_meat_virtual = {}
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterEvent( "COMBAT_LOG_EVENT_UNFILTERED", function( event )
|
||
|
|
local _, subtype, _, sourceGUID, sourceName, _, _, destGUID, destName, destFlags, _, spellID, spellName = CombatLogGetCurrentEventInfo()
|
||
|
|
|
||
|
|
if sourceGUID == state.GUID then
|
||
|
|
if subtype == "SPELL_CAST_SUCCESS" then
|
||
|
|
local ability = class.abilities[ spellID ]
|
||
|
|
|
||
|
|
if not ability then return end
|
||
|
|
|
||
|
|
if ability.key == "whirlwind" then
|
||
|
|
whirlwind_gained = GetTime()
|
||
|
|
whirlwind_stacks = state.talent.meat_cleaver.enabled and 4 or 2
|
||
|
|
|
||
|
|
elseif whirlwind_consumers[ ability.key ] and whirlwind_stacks > 0 then
|
||
|
|
whirlwind_stacks = whirlwind_stacks - 1
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
if ability.key == "conquerors_banner" then
|
||
|
|
rageSinceBanner = 0
|
||
|
|
end
|
||
|
|
|
||
|
|
elseif state.talent.fresh_meat.enabled and spellID == 23881 and subtype == "SPELL_DAMAGE" and not fresh_meat_actual[ destGUID ] and UnitGUID( "target" ) == destGUID then
|
||
|
|
fresh_meat_actual[ destGUID ] = true
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
local wipe = table.wipe
|
||
|
|
|
||
|
|
spec:RegisterEvent( "PLAYER_REGEN_ENABLED", function()
|
||
|
|
wipe( fresh_meat_actual )
|
||
|
|
end )
|
||
|
|
|
||
|
|
spec:RegisterHook( "UNIT_ELIMINATED", function( id )
|
||
|
|
fresh_meat_actual[ id ] = nil
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
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 then
|
||
|
|
rageSpent = ( rageSpent + lastRage - current ) % 20 -- Recklessness.
|
||
|
|
|
||
|
|
if state.legendary.glory.enabled and FindUnitBuffByID( "player", 324143 ) then
|
||
|
|
gloryRage = ( gloryRage + lastRage - current ) % 20 -- Glory.
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
lastRage = current
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
spec:RegisterStateExpr( "rage_spent", function ()
|
||
|
|
return rageSpent
|
||
|
|
end )
|
||
|
|
|
||
|
|
spec:RegisterStateExpr( "glory_rage", function ()
|
||
|
|
return gloryRage
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterHook( "spend", function( amt, resource )
|
||
|
|
if resource == "rage" then
|
||
|
|
if talent.recklessness.enabled then
|
||
|
|
rage_spent = rage_spent + amt
|
||
|
|
cooldown.recklessness.expires = cooldown.recklessness.expires - floor( rage_spent / 20 )
|
||
|
|
rage_spent = rage_spent % 20
|
||
|
|
end
|
||
|
|
|
||
|
|
if legendary.glory.enabled and buff.conquerors_banner.up then
|
||
|
|
glory_rage = glory_rage + amt
|
||
|
|
local reduction = floor( glory_rage / 20 ) * 0.5
|
||
|
|
glory_rage = glory_rage % 20
|
||
|
|
|
||
|
|
buff.conquerors_banner.expires = buff.conquerors_banner.expires + reduction
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
local WillOfTheBerserker = setfenv( function()
|
||
|
|
applyBuff( "will_of_the_berserker" )
|
||
|
|
end, state )
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterHook( "TimeToReady", function( wait, action )
|
||
|
|
local id = class.abilities[ action ].id
|
||
|
|
if buff.bladestorm.up and ( id < -99 or id > 0 ) then
|
||
|
|
wait = max( wait, buff.bladestorm.remains )
|
||
|
|
end
|
||
|
|
return wait
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterHook( "reset_precast", function ()
|
||
|
|
rage_spent = nil
|
||
|
|
rage_since_banner = nil
|
||
|
|
|
||
|
|
if buff.bladestorm.up and buff.gathering_storm.up then
|
||
|
|
applyBuff( "gathering_storm", buff.bladestorm.remains + 6, 5 )
|
||
|
|
end
|
||
|
|
|
||
|
|
if buff.whirlwind.up then
|
||
|
|
if whirlwind_stacks == 0 then removeBuff( "whirlwind" )
|
||
|
|
elseif whirlwind_stacks < buff.whirlwind.stack then
|
||
|
|
applyBuff( "whirlwind", buff.whirlwind.remains, whirlwind_stacks )
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
if legendary.will_of_the_berserker.enabled and buff.recklessness.up then
|
||
|
|
state:QueueAuraExpiration( "recklessness", WillOfTheBerserker, buff.recklessness.expires )
|
||
|
|
end
|
||
|
|
|
||
|
|
wipe( fresh_meat_virtual )
|
||
|
|
active_dot.hit_by_fresh_meat = 0
|
||
|
|
|
||
|
|
for k, v in pairs( fresh_meat_actual ) do
|
||
|
|
fresh_meat_virtual[ k ] = v
|
||
|
|
|
||
|
|
if k == target.unit then
|
||
|
|
applyDebuff( "target", "hit_by_fresh_meat" )
|
||
|
|
else
|
||
|
|
active_dot.hit_by_fresh_meat = active_dot.hit_by_fresh_meat + 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end )
|
||
|
|
|
||
|
|
|
||
|
|
-- Abilities
|
||
|
|
spec:RegisterAbilities( {
|
||
|
|
battle_shout = {
|
||
|
|
id = 6673,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 15,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 132333,
|
||
|
|
|
||
|
|
essential = true,
|
||
|
|
nobuff = "battle_shout",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "battle_shout" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
berserker_rage = {
|
||
|
|
id = 18499,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 60,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
toggle = "cooldowns",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 136009,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "berserker_rage" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
bladestorm = {
|
||
|
|
id = 46924,
|
||
|
|
cast = function () return 4 * haste end,
|
||
|
|
channeled = true,
|
||
|
|
cooldown = 60,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
toggle = "cooldowns",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 236303,
|
||
|
|
|
||
|
|
talent = "bladestorm",
|
||
|
|
range = 8,
|
||
|
|
|
||
|
|
start = function ()
|
||
|
|
applyBuff( "bladestorm" )
|
||
|
|
gain( 5, "rage" )
|
||
|
|
|
||
|
|
if azerite.gathering_storm.enabled then
|
||
|
|
applyBuff( "gathering_storm", 6 + ( 4 * haste ), 5 )
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
bloodthirst = {
|
||
|
|
id = function () return talent.reckless_abandon.enabled and buff.recklessness.up and 335096 or 23881 end,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 4.5,
|
||
|
|
hasteCD = true,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = function () return ( talent.seethe.enabled and ( stat.crit >= 100 and -4 or -2 ) or 0 ) - 8 end,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
cycle = function () return talent.fresh_meat.enabled and "hit_by_fresh_meat" or nil end,
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = function () return talent.reckless_abandon.enabled and buff.recklessness.up and 236304 or 136012 end,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
gain( health.max * ( buff.enraged_regeneration.up and 0.23 or 0.03 ), "health" )
|
||
|
|
|
||
|
|
removeBuff( "bloody_rage" )
|
||
|
|
removeStack( "whirlwind" )
|
||
|
|
|
||
|
|
if azerite.cold_steel_hot_blood.enabled and stat.crit >= 100 then
|
||
|
|
applyDebuff( "target", "gushing_wound" )
|
||
|
|
gain( 4, "rage" )
|
||
|
|
end
|
||
|
|
|
||
|
|
if legendary.cadence_of_fujieda.enabled then
|
||
|
|
if buff.cadence_of_fujieda.stack < 5 then stat.haste = stat.haste + 0.01 end
|
||
|
|
addStack( "cadence_of_fujieda", nil, 1 )
|
||
|
|
end
|
||
|
|
|
||
|
|
if talent.fresh_meat.enabled and debuff.hit_by_fresh_meat.down then
|
||
|
|
applyBuff( "enrage" )
|
||
|
|
applyDebuff( "target", "hit_by_fresh_meat" )
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
cadence_of_fujieda = {
|
||
|
|
id = 335558,
|
||
|
|
duration = 12,
|
||
|
|
max_stack = 5,
|
||
|
|
},
|
||
|
|
hit_by_fresh_meat = {
|
||
|
|
duration = 3600,
|
||
|
|
max_stack = 1,
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
copy = { "bloodbath", 335096, 23881 }
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
charge = {
|
||
|
|
id = 100,
|
||
|
|
cast = 0,
|
||
|
|
charges = function () return talent.double_time.enabled and 2 or nil 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",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 132337,
|
||
|
|
|
||
|
|
usable = function () return target.distance > 10 and ( query_time - action.charge.lastCast > gcd.execute ) end,
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "charge" )
|
||
|
|
if talent.furious_charge.enabled then applyBuff( "furious_charge" ) end
|
||
|
|
setDistance( 5 )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
dragon_roar = {
|
||
|
|
id = 118000,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 35,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = -10,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 642418,
|
||
|
|
|
||
|
|
talent = "dragon_roar",
|
||
|
|
range = 12,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
enraged_regeneration = {
|
||
|
|
id = 184364,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = function () return 120 - conduit.stalwart_guardian.mod * 0.001 end,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
toggle = "defensives",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 132345,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "enraged_regeneration" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
execute = {
|
||
|
|
id = function () return IsActiveSpell( 280735 ) and 280735 or 5308 end,
|
||
|
|
known = 5308,
|
||
|
|
noOverride = 317485,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 6,
|
||
|
|
hasteCD = true,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = -20,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 135358,
|
||
|
|
|
||
|
|
usable = function () return buff.sudden_death.up or buff.stone_heart.up or target.health.pct < ( IsActiveSpell( 280735 ) and 35 or 20 ) end,
|
||
|
|
handler = function ()
|
||
|
|
if buff.stone_heart.up then removeBuff( "stone_heart" )
|
||
|
|
elseif buff.sudden_death.up then removeBuff( "sudden_death" ) end
|
||
|
|
removeStack( "whirlwind" )
|
||
|
|
end,
|
||
|
|
|
||
|
|
copy = { 280735, 5308 }
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
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",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 236171,
|
||
|
|
|
||
|
|
usable = function () return ( query_time - action.heroic_leap.lastCast > gcd.execute ) end,
|
||
|
|
handler = function ()
|
||
|
|
setDistance( 15 ) -- probably heroic_leap + charge combo.
|
||
|
|
if talent.bounding_stride.enabled then applyBuff( "bounding_stride" ) end
|
||
|
|
end,
|
||
|
|
|
||
|
|
copy = 52174
|
||
|
|
},
|
||
|
|
|
||
|
|
ignore_pain = {
|
||
|
|
id = 190456,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 12,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
toggle = "defensives",
|
||
|
|
|
||
|
|
spend = 80,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 1377132,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "ignore_pain" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
impending_victory = {
|
||
|
|
id = 202168,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 30,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 10,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 589768,
|
||
|
|
|
||
|
|
talent = "impending_victory",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
gain( health.max * 0.3, "health" )
|
||
|
|
removeStack( "whirlwind" )
|
||
|
|
if conduit.indelible_victory.enabled then applyBuff( "indelible_victory" ) end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
intimidating_shout = {
|
||
|
|
id = 5246,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 90,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
toggle = "cooldowns",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 132154,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "intimidating_shout" )
|
||
|
|
--if azerite.intimidating_presence.enabled then applyDebuff( "target", "intimidating_presence" ) end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
onslaught = {
|
||
|
|
id = 315720,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 12,
|
||
|
|
hasteCD = true,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = -15,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 132364,
|
||
|
|
|
||
|
|
buff = "enrage",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
removeStack( "whirlwind" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
piercing_howl = {
|
||
|
|
id = 12323,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = function () return 30 + conduit.disturb_the_peace.mod * 0.001 end,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 136147,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "piercing_howl" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
pummel = {
|
||
|
|
id = 6552,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 15,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 132938,
|
||
|
|
|
||
|
|
toggle = "interrupts",
|
||
|
|
|
||
|
|
debuff = "casting",
|
||
|
|
readyTime = state.timeToInterrupt,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
interrupt()
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
raging_blow = {
|
||
|
|
id = function () return talent.reckless_abandon.enabled and buff.recklessness.up and 335097 or 85288 end,
|
||
|
|
cast = 0,
|
||
|
|
charges = 2,
|
||
|
|
cooldown = 8,
|
||
|
|
recharge = 8,
|
||
|
|
hasteCD = true,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = -12,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = function () return talent.reckless_abandon.enabled and buff.recklessness.up and 132215 or 589119 end,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
removeStack( "whirlwind" )
|
||
|
|
|
||
|
|
if buff.will_of_the_berserker.up then buff.will_of_the_berserker.expires = query_time + 12 end
|
||
|
|
end,
|
||
|
|
|
||
|
|
copy = { "crushing_blow", 335097, 85288 }
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
rallying_cry = {
|
||
|
|
id = 97462,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 180,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
toggle = "defensives",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 132351,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "rallying_cry" )
|
||
|
|
|
||
|
|
if azerite.moment_of_glory.enabled then applyBuff( "moment_of_glory" ) end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
rampage = {
|
||
|
|
id = 184367,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 80,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 132352,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
if talent.frenzy.enabled then addStack( "frenzy", nil, 1 ) end
|
||
|
|
applyBuff( "enrage" )
|
||
|
|
removeStack( "whirlwind" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
recklessness = {
|
||
|
|
id = 1719,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 90,
|
||
|
|
gcd = "off",
|
||
|
|
|
||
|
|
toggle = "cooldowns",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 458972,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "recklessness" )
|
||
|
|
if talent.reckless_abandon.enabled then
|
||
|
|
gain( 50, "rage" )
|
||
|
|
end
|
||
|
|
if legendary.will_of_the_berserker.enabled then
|
||
|
|
state:QueueAuraExpiration( "recklessness", WillOfTheBerserker, buff.recklessness.expires )
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
|
||
|
|
auras = {
|
||
|
|
will_of_the_berserker = {
|
||
|
|
id = 335597,
|
||
|
|
duration = 12,
|
||
|
|
max_stack = 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
shattering_throw = {
|
||
|
|
id = 64382,
|
||
|
|
cast = 1.5,
|
||
|
|
cooldown = 180,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 311430,
|
||
|
|
|
||
|
|
range = 30,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
siegebreaker = {
|
||
|
|
id = 280772,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 30,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = -10,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 294382,
|
||
|
|
|
||
|
|
talent = "siegebreaker",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "siegebreaker" )
|
||
|
|
removeStack( "whirlwind" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
slam = {
|
||
|
|
id = 1464,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 30,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
spend = 20,
|
||
|
|
spendType = "rage",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 132340,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
removeStack( "whirlwind" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
spell_reflection = {
|
||
|
|
id = 23920,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 25,
|
||
|
|
gcd = "off",
|
||
|
|
|
||
|
|
toggle = "interrupts",
|
||
|
|
|
||
|
|
startsCombat = false,
|
||
|
|
texture = 132361,
|
||
|
|
|
||
|
|
debuff = "casting",
|
||
|
|
readyTime = state.timeToInterrupt,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyBuff( "spell_reflection" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
storm_bolt = {
|
||
|
|
id = 107570,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 30,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 613535,
|
||
|
|
|
||
|
|
talent = "storm_bolt",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "storm_bolt" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
taunt = {
|
||
|
|
id = 355,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 8,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 136080,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
applyDebuff( "target", "taunt" )
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
victory_rush = {
|
||
|
|
id = 34428,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 132342,
|
||
|
|
|
||
|
|
notalent = "impending_victory",
|
||
|
|
buff = "victorious",
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
removeBuff( "victorious" )
|
||
|
|
removeStack( "whirlwind" )
|
||
|
|
if conduit.indelible_victory.enabled then applyBuff( "indelible_victory" ) end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
whirlwind = {
|
||
|
|
id = 190411,
|
||
|
|
cast = 0,
|
||
|
|
cooldown = 0,
|
||
|
|
gcd = "spell",
|
||
|
|
|
||
|
|
startsCombat = true,
|
||
|
|
texture = 132369,
|
||
|
|
|
||
|
|
usable = function ()
|
||
|
|
if settings.check_ww_range and target.outside7 then return false, "target is outside of whirlwind range" end
|
||
|
|
return true
|
||
|
|
end,
|
||
|
|
|
||
|
|
handler = function ()
|
||
|
|
if level > 36 then
|
||
|
|
applyBuff ( "whirlwind", nil, talent.meat_cleaver.enabled and 4 or 2 )
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
} )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterOptions( {
|
||
|
|
enabled = true,
|
||
|
|
|
||
|
|
aoe = 2,
|
||
|
|
|
||
|
|
nameplates = true,
|
||
|
|
nameplateRange = 8,
|
||
|
|
|
||
|
|
damage = true,
|
||
|
|
damageExpiration = 8,
|
||
|
|
|
||
|
|
potion = "potion_of_phantom_fire",
|
||
|
|
|
||
|
|
package = "Fury",
|
||
|
|
} )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterSetting( "check_ww_range", false, {
|
||
|
|
name = "Check |T132369:0|t Whirlwind Range",
|
||
|
|
desc = "If checked, when your target is outside of |T132369:0|t Whirlwind's range, it will not be recommended.",
|
||
|
|
type = "toggle",
|
||
|
|
width = "full"
|
||
|
|
} )
|
||
|
|
|
||
|
|
spec:RegisterSetting( "heroic_charge", false, {
|
||
|
|
name = "Use Heroic Charge Combo",
|
||
|
|
desc = "If checked, the default priority will check |cFFFFD100settings.heroic_charge|r to determine whether to use Heroic Leap + Charge together.\n\n" ..
|
||
|
|
"This is generally a DPS increase but the erratic movement can be disruptive to smooth gameplay.",
|
||
|
|
type = "toggle",
|
||
|
|
width = "full",
|
||
|
|
} )
|
||
|
|
|
||
|
|
|
||
|
|
spec:RegisterPack( "Fury", 20210705, [[d400kbqiOu5rOKAtePprPyuevDkkOvbbu5vuGzrPYTiQ0Ui8lkHHruCmvWYGs6zukzAOK01Ou12OuQ6BqagheOohkHADOempOuUhk1(ikDqOe1cPe9qOu1eHaYfHsKnIsi8rucrJeLq6KqG0kvHMjkjUjLsPANuO(jeqvdfcOSukLINIIPsHCvkLsSvkLkFfceJfkH9sYFHQbd6Wswms9yrMSOUSYMH0NvPrdrNgy1ukLYRHqZMu3MI2nv)gvdxfDCuIwUQEoIPlCDKSDI47usJNOIZdbTEkLsA(qX(LA1bLrkMCftzmwLbRhKbbiJ9czyX2cR2YEftGWZPyoReI1DkgVmNIHfb1JqfZzHqnVYkJumeo1NMIbzeNewWclUGajfTiXnTGamP0va4E6l0WccWmzHIHMcOdeuxrRyYvmLXyvgSEqgeGm2lKHfBlSAlBPykQaj)vmmatSVHw0qS8NqcmdWZjkgKGCEUIwXKhjPyyrq9iSHii1)a(3hpsPrydT3UgIvzW6H(yFe7rw(DewOpk3gILZ5LBicmktZPf9r52qeiaPO1l3qtUKzopAOfnKfDphKAiRS6SHPsRBO8opAOVLxUHO8VHaxU3YCnmX9yYjmu0hLBdTTZLSCdTux5rc(B2WYZneb6Rl3BOTHxFdlAUK1ql1CEoqcEs0WG3qG55ZLSgI(JLuZtiSHC0g(lXnnNNRaWDsdLNamjn85uxKAe2WXsQsBOOpk3gILZ5LBOLve61qgKCQOHbVHN)sCt6kAiwgbgRi6JYTHy5CE5gABHSgIGgZKi6JYTHgzDfIneL)nebbj41wbEUH0dL)RH6jz6gAleGOpk3gABMjxYYnelriZtJi6JYTHiqC3MOHuK1qgWUJ(xH4(gcqBiiSH0Ws)RYiSHuNnuEeOvbsZcX9gk6JYTHmlOoBiAH4AizSKAEAKgIY)gYaU(IgYpNVxOy0asqugPyk(ugPm(GYifZ8IwVSYsft6bXEqPyUPS4NzbCsdz3qzAO0gs4uAAGNfOGNe4K4bioX8IwVCdL2qAkuubk4jbojEaIt8ZSaoPHsBinfkQy(x3j(zwaN0qS1WBkRyQua4UIjvEAACAkuufdnfkkUxMtXqRR8ib)nvHYySQmsXmVO1lRSuXKEqShukgAkuuX8VUtqD2qPnmX56m3Ql(LqupcXhHi(zwaN0qzBO9kMkfaURykpbMh4fASNGKNqufkJTLYifZ8IwVSYsft6bXEqPyOPqrfZ)6ob1zdL2WVURHyRHSQmkMkfaURyiNRECokoDrca3vHYywvzKIzErRxwzPIj9GypOum0uOOI5FDNG6SHsBi5CAnEu)Dbryfj41wbEUHY2qSQyQua4UIHwx5rc(BQyaES)PodCaQI5MYIFMfWjSLrkHtPPbEwGcEsGtIhG4KstHIkqbpjWjXdqCIFMfWjsPPqrfZ)6oXpZc4eSDtzvOm2ELrkM5fTEzLLkM0dI9GsXiFdPPqrfZ)6ob1zdXGPH0uOOIFje1Jq8ricQZgkTHpLpu(FNGaCuknoH6VtmVO1l3qdBO0gkPEqrRNyYzjQy4NilYumvkaCxXK4EEMUkugB7vgPyQua4UIHa2D0)ke3RyMx06LvwQcLXiaLrkMkfaURy(Y8SUtXmVO1lRSufkJrWkJumZlA9YklvmPhe7bLIHMcfvm)R7euNnuAdtCUoZT6IFje1Jq8riIFMfWjnu2gAVIPsbG7kgY5QhNJItxKaWDvOmMfRmsXmVO1lRSuXKEqShukgAkuuX8VUt8ZSaoPHY2WBk3qe4Aiwf2RyQua4UIHwx5rc(BQcvOyia)QhEu)DHYiLXhugPyMx06LvwQyspi2dkfZt5dL)3jSc0ACokEGC407j7rCVySKcCEUCdL2qAkuuHvGwJZrXdKdNEpzpI7f)mlGtAi2A4nLvmvkaCxX81f4xCAn3QkugJvLrkM5fTEzLLkM0dI9GsX8u(q5)DcRaTgNJIhiho9EYEe3lglPaNNl3qPnKMcfvyfO14Cu8a5WP3t2J4EXpZc4KgITgEtzftLca3vmFDb(fNwZTQcLX2szKIzErRxwzPIj9GypOumKZP14r93feHvKGxBf45gYUHhAO0gEtzXpZc4KgYUHY0qPnu(ggLEEimlcPs)eZlA9YnedMgM4sMxEiKmpqIWVHg2qPnus9GIwpXKZsuXWprwK1qPnu(g(1Dnu2gYILPHyW0qSRHjoxN5wDrI75z6IFMfWjn0qftLca3vmPYttJttHIQyOPqrX9YCkgADLhj4VPkugZQkJumZlA9YklvmPhe7bLIr(gstHIkM)1DcQZgIbtdPPqrf)siQhH4JqeuNnuAdFkFO8)obb4OuACc1FNyErRxUHg2qPnus9GIwpXKZsuXWprwKPyQua4UIjX98mDvOm2ELrkM5fTEzLLkM0dI9GsXqtHIkM)1DcQZgkTHsQhu06jMCwIkg(jYImftLca3vmjUNNPRcLX2ELrkM5fTEzLLkM0dI9GsXKhnfkQGa2D0)ke3lYCREdL2q5Bi5CAnEu)Dbryfj41wbEUHY2WdnedMg(fiJpjZdrLZebWBOSn8G9n0qftLca3vmeWUJ(xH4EvOmgbOmsXmVO1lRSuXKEqShukg5BinfkQ4xcr9ieFeIG6SHyW0qAkuuH5m5pcX5O4AQeiJN)vMeb1zdnSHyW0q5BinfkQy(x3j(zwaN0qS1WBk3qmyA4x31qzBilwMgAydXGPH0uOOc0FUTvek(zwaN0qS1Wdc7vmvkaCxX8L5zDNkugJGvgPyQua4UIjX98mDfZ8IwVSYsvOmMfRmsXmVO1lRSuXKEqShukgAkuuX8VUtqD2qPnu(gsoNwJh1FxqewrcETvGNBOSn8qdXGPHFbY4tY8qu5mra8gkBdra23qdvmvkaCxXuEcmpWl0ypbjpHOkugFqgLrkM5fTEzLLkM0dI9GsXqtHIkM)1DcQZgkTHY3qY50A8O(7cIWksWRTc8CdLTHhAigmn8lqgFsMhIkNjcG3qzBiRAFdnuXuPaWDfd5C1JZrXPlsa4UkugF4GYiftLca3vmtolrftXmVO1lRSufkJpGvLrkM5fTEzLLkM0dI9GsXqtHIkM)1DcQZgkTHY3qSRH0uOOIFje1Jq8riIFMfWjnedMg(1DneBn0EzAOHnuAdLVHKZP14r93feHvKGxBf45gYUHhAO0g(fiJpjZdrLZebWBOSnKvTVHyW0qY50A8O(7cIWksWRTc8Cdz3qS2qdvmvkaCxXqRR8ib)nvHY4d2szKIzErRxwzPIPsbG7kgAnNNdKGNekM0dI9GsXqtHIkM)1DIm3Q3qmyAyI7zkqiKasaofbpX9yMNH4lhXgkBdTVHsByu)DHa5kDGuCMIgITgAl7vmjeM0dpQ)UGOm(GkugFGvvgPyMx06LvwQyspi2dkfdnfkQy(x3jYCREdXGPHjUNPaHqcib4ue8e3JzEgIVCeBOSn0(gkTHr93fcKR0bsXzkAi2AOTSVHsBi21WO0Zdr6PMoqOyErRxwXuPaWDfdTMZZbsWtcvOm(G9kJumZlA9YklvmPhe7bLIHMcfvm)R7euNnuAdLVHKZP14r93feHvKGxBf45gkBdp0qmyA4xGm(KmpevoteaVHY2Wd23qdvmvkaCxXK)6YD8NxVkugFW2RmsXuPaWDfd3j6I6ImumZlA9YklvHY4diaLrkM5fTEzLLkM0dI9GsXqtHIkm3Na6ri40CF3h459cQZgkTHKZP14r93feHvKGxBf45gkBdTLIPsbG7kgRibV2kWZQqz8beSYifZ8IwVSYsft6bXEqPysiR)osdz3qS2qmyAinfkQ4xcr9ieFeIG6SHsBOK6bfTEIjNLOIHFISiRHsByu65HWSiKk9tmVO1lRyQua4UI5RlWV40AUvvOm(alwzKIzErRxwzPIj9GypOumjK1FhPHSBiwBigmnKMcfv8lHOEeIpcrqD2qPnus9GIwpXKZsuXWprwK1qPnmk98qywesL(jMx06LvmvkaCxX81f4xCAn3QkugJvzugPyMx06LvwQyQua4UI
|
||
|
|
|
||
|
|
|
||
|
|
end
|