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.

1368 lines
61 KiB

5 years ago
-- HunterSurvival.lua
-- June 2018
local addon, ns = ...
local Hekili = _G[ addon ]
local class = Hekili.Class
local state = Hekili.State
local PTR = ns.PTR
-- Shadowlands Legendaries
-- [x] Wildfire Cluster
-- [-] Rylakstalker's Confounding Strikes (passive/reactive)
-- [x] Latent Poison Injectors
-- [x] Butcher's Bone Fragments
-- Conduits
-- [x] Deadly Tandem
-- [x] Flame Infusion
-- [-] Stinging Strike
-- [-] Strength of the Pack
if UnitClassBase( "player" ) == "HUNTER" then
local spec = Hekili:NewSpecialization( 255 )
spec:RegisterResource( Enum.PowerType.Focus, {
terms_of_engagement = {
aura = "terms_of_engagement",
last = function ()
local app = state.buff.terms_of_engagement.applied
local t = state.query_time
return app + floor( t - app )
end,
interval = 1,
value = 2,
},
death_chakram = {
resource = "focus",
aura = "death_chakram",
last = function ()
return state.buff.death_chakram.applied + floor( state.query_time - state.buff.death_chakram.applied )
end,
interval = function () return class.auras.death_chakram.tick_time end,
value = function () return state.conduit.necrotic_barrage.enabled and 5 or 3 end,
}
} )
-- Talents
spec:RegisterTalents( {
vipers_venom = 22275, -- 268501
terms_of_engagement = 22283, -- 265895
alpha_predator = 22296, -- 269737
guerrilla_tactics = 21997, -- 264332
hydras_bite = 22769, -- 260241
butchery = 22297, -- 212436
trailblazer = 19347, -- 199921
natural_mending = 19348, -- 270581
camouflage = 23100, -- 199483
bloodseeker = 22277, -- 260248
steel_trap = 19361, -- 162488
a_murder_of_crows = 22299, -- 131894
born_to_be_wild = 22268, -- 266921
posthaste = 22276, -- 109215
binding_shot = 22499, -- 109248
tip_of_the_spear = 22300, -- 260285
mongoose_bite = 22278, -- 259387
flanking_strike = 22271, -- 269751
birds_of_prey = 22272, -- 260331
wildfire_infusion = 22301, -- 271014
chakrams = 23105, -- 259391
} )
-- PvP Talents
spec:RegisterPvpTalents( {
chimaeral_sting = 3609, -- 356719
diamond_ice = 686, -- 203340
dragonscale_armor = 3610, -- 202589
hiexplosive_trap = 3606, -- 236776
hunting_pack = 661, -- 203235
mending_bandage = 662, -- 212640
roar_of_sacrifice = 663, -- 53480
sticky_tar = 664, -- 203264
survival_tactics = 3607, -- 202746
trackers_net = 665, -- 212638
tranquilizing_darts = 5420, -- 356015
wild_kingdom = 5443, -- 356707
} )
-- Auras
spec:RegisterAuras( {
a_murder_of_crows = {
id = 131894,
duration = 15,
max_stack = 1,
},
aspect_of_the_eagle = {
id = 186289,
duration = 15,
max_stack = 1,
},
aspect_of_the_turtle = {
id = 186265,
duration = 8,
max_stack = 1,
},
binding_shot = {
id = 117405,
duration = 3600,
max_stack = 1,
},
camouflage = {
id = 199483,
duration = 60,
max_stack = 1,
},
coordinated_assault = {
id = 266779,
duration = function () return 20 + ( conduit.deadly_tandem.mod * 0.001 ) end,
max_stack = 1,
},
eagle_eye = {
id = 6197,
},
feign_death = {
id = 5384,
duration = 360,
max_stack = 1,
},
freezing_trap = {
id = 3355,
duration = 60,
type = "Magic",
max_stack = 1,
},
growl = {
id = 2649,
duration = 3,
max_stack = 1,
},
harpoon = {
id = 190927,
duration = 3,
max_stack = 1,
},
hunters_mark = {
id = 257284,
duration = 3600,
type = "Magic",
max_stack = 1,
},
internal_bleeding = {
id = 270343,
duration = 9,
max_stack = 3
},
intimidation = {
id = 24394,
duration = 5,
max_stack = 1,
},
kill_command = {
id = 259277,
duration = 8,
max_stack = 1,
generate = function( t )
local name, _, count, _, duration, expires, caster = FindUnitDebuffByID( "target", 259277, "PLAYER" )
if name then
t.name = name
t.count = 1
t.expires = expires
t.applied = expires - duration
t.caster = caster
return
end
t.count = 0
t.expires = 0
t.applied = 0
t.caster = "nobody"
end,
copy = "bloodseeker"
},
masters_call = {
id = 54216,
duration = 4,
type = "Magic",
max_stack = 1,
},
misdirection = {
id = 35079,
duration = 8,
max_stack = 1,
},
mongoose_fury = {
id = 259388,
duration = 14,
max_stack = 5,
},
pathfinding = {
id = 264656,
duration = 3600,
max_stack = 1,
},
pheromone_bomb = {
id = 270332,
duration = 6,
max_stack = 1,
},
posthaste = {
id = 118922,
duration = 4,
max_stack = 1,
},
predator = {
id = 260249,
duratinon = 3600,
max_stack = 10,
},
serpent_sting = {
id = 259491,
duration = function () return 12 * haste end,
tick_time = function () return 3 * haste end,
type = "Poison",
max_stack = 1,
},
shrapnel_bomb = {
id = 270339,
duration = 6,
max_stack = 1,
},
steel_trap = {
id = 162487,
duration = 20,
max_stack = 1,
},
steel_trap_immobilize = {
id = 162480,
duration = 20,
max_stack = 1,
},
tar_trap = {
id = 135299,
duration = 3600,
max_stack = 1,
},
terms_of_engagement = {
id = 265898,
duration = 10,
max_stack = 1,
},
tip_of_the_spear = {
id = 260286,
duration = 10,
max_stack = 3,
},
trailblazer = {
id = 231390,
duration = 3600,
max_stack = 1,
},
vipers_venom = {
id = 268552,
duration = 8,
max_stack = 1,
},
volatile_bomb = {
id = 271049,
duration = 6,
max_stack = 1,
},
wildfire_bomb_dot = {
id = 269747,
duration = 6,
max_stack = 1,
},
wildfire_bomb = {
alias = { "wildfire_bomb_dot", "shrapnel_bomb", "pheromone_bomb", "volatile_bomb" },
aliasType = "debuff",
aliasMode = "longest"
},
wing_clip = {
id = 195645,
duration = 15,
max_stack = 1,
},
-- AZERITE POWERS
blur_of_talons = {
id = 277969,
duration = 6,
max_stack = 5,
},
latent_poison = {
id = 273286,
duration = 20,
max_stack = 10
},
primeval_intuition = {
id = 288573,
duration = 12,
max_stack = 5,
},
-- Legendaries
latent_poison_injection = {
id = 336903,
duration = 15,
max_stack = 10
},
nessingwarys_trapping_apparatus = {
id = 336744,
duration = 5,
max_stack = 1,
copy = { "nesingwarys_trapping_apparatus", "nesingwarys_apparatus", "nessingwarys_apparatus" }
},
-- Conduits
strength_of_the_pack = {
id = 341223,
duration = 4,
max_stack = 1
}
} )
spec:RegisterHook( "runHandler", function( action, pool )
if buff.camouflage.up and action ~= "camouflage" then removeBuff( "camouflage" ) end
if buff.feign_death.up and action ~= "feign_death" then removeBuff( "feign_death" ) end
end )
spec:RegisterStateExpr( "current_wildfire_bomb", function () return "wildfire_bomb" end )
local function IsActiveSpell( id )
local slot = FindSpellBookSlotBySpellID( id )
if not slot then return false end
local _, _, spellID = GetSpellBookItemName( slot, "spell" )
return id == spellID
end
state.IsActiveSpell = IsActiveSpell
local pheromoneReset = false
local FindUnitDebuffByID = ns.FindUnitDebuffByID
spec:RegisterEvent( "COMBAT_LOG_EVENT_UNFILTERED", function ()
local _, subtype, _, sourceGUID, sourceName, _, _, destGUID, destName, destFlags, _, spellID, spellName = CombatLogGetCurrentEventInfo()
if sourceGUID == state.GUID and spellID == 259489 and subtype == "SPELL_CAST_SUCCESS" then
pheromoneReset = FindUnitDebuffByID( "target", 270332 ) and true or false
end
end )
local ExpireNesingwarysTrappingApparatus = setfenv( function()
focus.regen = focus.regen * 0.5
forecastResources( "focus" )
end, state )
spec:RegisterHook( "reset_precast", function()
if talent.wildfire_infusion.enabled then
if IsActiveSpell( 270335 ) then current_wildfire_bomb = "shrapnel_bomb"
elseif IsActiveSpell( 270323 ) then current_wildfire_bomb = "pheromone_bomb"
elseif IsActiveSpell( 271045 ) then current_wildfire_bomb = "volatile_bomb"
else current_wildfire_bomb = "wildfire_bomb" end
else
current_wildfire_bomb = "wildfire_bomb"
end
if prev_gcd[1].kill_command and pheromoneReset and cooldown.kill_command.remains > 0 and ( now - action.kill_command.lastCast < 0.25 ) then
setCooldown( "kill_command", 0 )
end
if now - action.harpoon.lastCast < 1.5 then
setDistance( 5 )
end
if debuff.tar_trap.up then
debuff.tar_trap.expires = debuff.tar_trap.applied + 30
end
if buff.nesingwarys_apparatus.up then
state:QueueAuraExpiration( "nesingwarys_apparatus", ExpireCelestialAlignment, buff.nesingwarys_apparatus.expires )
end
if now - action.resonating_arrow.lastCast < 6 then applyBuff( "resonating_arrow", 10 - ( now - action.resonating_arrow.lastCast ) ) end
end )
spec:RegisterHook( "specializationChanged", function ()
current_wildfire_bomb = nil
end )
spec:RegisterStateTable( "next_wi_bomb", setmetatable( {}, {
__index = function( t, k )
if k == "shrapnel" then return current_wildfire_bomb == "shrapnel_bomb"
elseif k == "pheromone" then return current_wildfire_bomb == "pheromone_bomb"
elseif k == "volatile" then return current_wildfire_bomb == "volatile_bomb" end
return false
end
} ) )
spec:RegisterStateTable( "bloodseeker", setmetatable( {}, {
__index = function( t, k )
if k == "count" then
return active_dot.kill_command
end
return debuff.kill_command[ k ]
end,
} ) )
spec:RegisterStateExpr( "bloodseeker", function () return debuff.bloodseeker end )
-- Abilities
spec:RegisterAbilities( {
a_murder_of_crows = {
id = 131894,
cast = 0,
cooldown = 60,
gcd = "spell",
spend = 30,
spendType = "focus",
toggle = "cooldowns",
startsCombat = true,
texture = 645217,
talent = "a_murder_of_crows",
handler = function ()
applyDebuff( "target", "a_murder_of_crows" )
end,
},
aspect_of_the_cheetah = {
id = 186257,
cast = 0,
cooldown = function () return ( 180 * ( legendary.call_of_the_wild.enabled and 0.75 or 1 ) * ( talent.born_to_be_wild.enabled and 0.8 or 1 ) ) + ( conduit.cheetahs_vigor.mod * 0.001 ) end,
gcd = "spell",
startsCombat = false,
texture = 132242,
handler = function ()
applyBuff( "aspect_of_the_cheetah_sprint" )
applyBuff( "aspect_of_the_cheetah" )
end,
},
aspect_of_the_eagle = {
id = 186289,
cast = 0,
cooldown = function () return 90 * ( legendary.call_of_the_wild.enabled and 0.75 or 1 ) * ( talent.born_to_be_wild.enabled and 0.8 or 1 ) end,
gcd = "off",
toggle = "cooldowns",
startsCombat = false,
texture = 612363,
handler = function ()
applyBuff( "aspect_of_the_eagle" )
end,
},
aspect_of_the_turtle = {
id = 186265,
cast = 0,
cooldown = function () return ( 180 * ( legendary.call_of_the_wild.enabled and 0.75 or 1 ) * ( talent.born_to_be_wild.enabled and 0.8 or 1 ) ) + ( conduit.harmony_of_the_tortollan.mod * 0.001 ) end,
gcd = "spell",
toggle = "defensives",
startsCombat = false,
texture = 132199,
handler = function ()
applyBuff( "aspect_of_the_turtle" )
setCooldown( "global_cooldown", 8 )
end,
},
binding_shot = {
id = 109248,
cast = 0,
cooldown = 45,
gcd = "spell",
startsCombat = false,
texture = 462650,
handler = function ()
applyDebuff( "target", "binding_shot" )
end,
},
butchery = {
id = 212436,
cast = 0,
charges = 3,
cooldown = 9,
recharge = 9,
hasteCD = true,
gcd = "spell",
spend = 30,
spendType = "focus",
startsCombat = true,
texture = 999948,
aura = function () return debuff.shrapnel_bomb.up and "internal_bleeding" or nil end,
cycle = function () return debuff.shrapnel_bomb.up and "internal_bleeding" or nil end,
talent = "butchery",
usable = function () return charges > 1 or active_enemies > 1 or target.time_to_die < ( 9 * haste ) end,
handler = function ()
gainChargeTime( "wildfire_bomb", min( 5, active_enemies ) )
gainChargeTime( "shrapnel_bomb", min( 5, active_enemies ) )
gainChargeTime( "volatile_bomb", min( 5, active_enemies ) )
gainChargeTime( "pheromone_bomb", min( 5, active_enemies ) )
if talent.birds_of_prey.enabled and buff.coordinated_assault.up and UnitIsUnit( "pettarget", "target" ) then
buff.coordinated_assault.expires = buff.coordinated_assault.expires + 1.5
end
if debuff.shrapnel_bomb.up then applyDebuff( "target", "internal_bleeding", 9, min( 3, debuff.internal_bleeding.stack + 1 ) ) end
removeBuff( "butchers_bone_fragments" )
if conduit.flame_infusion.enabled then
addStack( "flame_infusion", nil, 1 )
end
end,
},
camouflage = {
id = 199483,
cast = 0,
cooldown = 60,
gcd = "spell",
startsCombat = false,
texture = 461113,
talent = "camouflage",
usable = function () return time == 0 end,
handler = function ()
applyBuff( "camouflage" )
end,
},
carve = {
id = 187708,
cast = 0,
cooldown = 6,
hasteCD = true,
gcd = "spell",
spend = 35,
spendType = "focus",
startsCombat = true,
texture = 1376039,
-- aura = function () return debuff.shrapnel_bomb.up and "internal_bleeding" or nil end,
-- cycle = function () return debuff.shrapnel_bomb.up and "internal_bleeding" or nil end,
notalent = "butchery",
handler = function ()
gainChargeTime( "wildfire_bomb", min( 5, active_enemies ) )
gainChargeTime( "shrapnel_bomb", min( 5, active_enemies ) )
gainChargeTime( "volatile_bomb", min( 5, active_enemies ) )
gainChargeTime( "pheromone_bomb", min( 5, active_enemies ) )
if debuff.shrapnel_bomb.up then applyDebuff( "target", "internal_bleeding", 9, min( 3, debuff.internal_bleeding.stack + 1 ) ) end
if talent.birds_of_prey.enabled and buff.coordinated_assault.up and UnitIsUnit( "pettarget", "target" ) then
buff.coordinated_assault.expires = buff.coordinated_assault.expires + 1.5
end
removeBuff( "butchers_bone_fragments" )
if conduit.flame_infusion.enabled then
addStack( "flame_infusion", nil, 1 )
end
end,
auras = {
-- Conduit
flame_infusion = {
id = 341401,
duration = 8,
max_stack = 2,
}
}
},
chakrams = {
id = 259391,
cast = 0,
cooldown = 20,
gcd = "spell",
spend = 15,
spendType = "focus",
startsCombat = true,
texture = 648707,
talent = "chakrams",
handler = function ()
end,
},
coordinated_assault = {
id = 266779,
cast = 0,
cooldown = function () return ( essence.vision_of_perfection.enabled and 0.87 or 1 ) * ( legendary.call_of_the_wild.enabled and 0.75 or 1 ) * 120 end,
gcd = "spell",
toggle = "cooldowns",
startsCombat = false,
texture = 2065565,
nobuff = function ()
if settings.ca_vop_overlap then return end
return "coordinated_assault"
end,
usable = function () return pet.alive end,
handler = function ()
applyBuff( "coordinated_assault" )
end,
},
disengage = {
id = 781,
cast = 0,
cooldown = 20,
gcd = "off",
startsCombat = false,
texture = 132294,
handler = function ()
setDistance( 15 )
if talent.posthaste.enabled then applyBuff( "posthaste" ) end
if conduit.tactical_retreat.enabled and target.within8 then applyDebuff( "target", "tactical_retreat" ) end
end,
},
--[[ eagle_eye = {
id = 6197,
cast = 0,
cooldown = 0,
gcd = "spell",
startsCombat = true,
texture = 132172,
handler = function ()
end,
}, ]]
exhilaration = {
id = 109304,
cast = 0,
cooldown = 120,
gcd = "spell",
toggle = "defensives",
startsCombat = false,
texture = 461117,
handler = function ()
gain( 0.3 * health.max, "health" )
if conduit.rejuvenating_wind.enabled then applyBuff( "rejuvenating_wind" ) end
end,
},
--[[ Using from BM module.
feign_death = {
id = 5384,
cast = 0,
cooldown = 30,
gcd = "off",
startsCombat = false,
texture = 132293,
handler = function ()
applyBuff( "feign_death" )
end,
}, ]]
flanking_strike = {
id = 269751,
cast = 0,
cooldown = 30,
gcd = "spell",
spend = -30,
spendType = "focus",
startsCombat = true,
texture = 236184,
talent = "flanking_strike",
usable = function () return pet.alive end,
},
--[[ flare = {
id = 1543,
cast = 0,
cooldown = 20,
gcd = "spell",
startsCombat = true,
texture = 135815,
handler = function ()
applyDebuff( "target", "flare" )
end,
}, ]]
freezing_trap = {
id = 187650,
cast = 0,
cooldown = 30,
gcd = "spell",
spend = function ()
if legendary.nessingwarys_trapping_apparatus.enabled then
return -45, "focus"
end
end,
startsCombat = false,
texture = 135834,
handler = function ()
applyDebuff( "target", "freezing_trap" )
end,
},
harpoon = {
id = 190925,
cast = 0,
charges = 1,
cooldown = 20,
recharge = 20,
gcd = "spell",
startsCombat = true,
texture = 1376040,
usable = function () return settings.use_harpoon and target.distance > 8, "harpoon disabled or target too close" end,
handler = function ()
applyDebuff( "target", "harpoon" )
if talent.terms_of_engagement.enabled then applyBuff( "terms_of_engagement" ) end
setDistance( 5 )
end,
},
hunters_mark = {
id = 257284,
cast = 0,
cooldown = 0,
gcd = "spell",
startsCombat = false,
texture = 236188,
handler = function ()
applyDebuff( "target", "hunters_mark" )
end,
},
intimidation = {
id = 19577,
cast = 0,
cooldown = 60,
gcd = "spell",
startsCombat = true,
texture = 132111,
usable = function () return pet.alive, "requires a living pet" end,
handler = function ()
applyDebuff( "target", "intimidation" )
end,
},
kill_command = {
id = 259489,
cast = 0,
charges = function () return talent.alpha_predator.enabled and 2 or nil end,
cooldown = 6,
recharge = 6,
hasteCD = true,
gcd = "spell",
spend = -15,
spendType = "focus",
startsCombat = true,
texture = 132176,
cycle = function () return talent.bloodseeker.enabled and "kill_command" or nil end,
usable = function () return pet.alive, "requires a living pet" end,
handler = function ()
if talent.bloodseeker.enabled then
applyBuff( "predator", 8 )
applyDebuff( "target", "kill_command", 8 )
end
if talent.tip_of_the_spear.enabled then addStack( "tip_of_the_spear", 20, 1 ) end
if debuff.pheromone_bomb.up then
if talent.alpha_predator.enabled then gainCharges( "kill_command", 1 )
else setCooldown( "kill_command", 0 ) end
end
if debuff.shrapnel_bomb.up then applyDebuff( "target", "internal_bleeding", 9, min( 3, debuff.internal_bleeding.stack + 1 ) ) end
end,
},
kill_shot = {
id = 320976,
cast = 0,
cooldown = 10,
gcd = "spell",
spend = function () return buff.flayers_mark.up and 0 or 10 end,
spendType = "focus",
startsCombat = true,
texture = 236174,
usable = function () return buff.flayers_mark.up or target.health_pct < 20, "requires target health below 20 percent" end,
handler = function ()
if buff.flayers_mark.up and legendary.pouch_of_razor_fragments.enabled then
applyDebuff( "target", "pouch_of_razor_fragments" )
removeBuff( "flayers_mark" )
end
end,
},
masters_call = {
id = 272682,
cast = 0,
cooldown = 45,
gcd = "off",
startsCombat = false,
texture = 236189,
usable = function () return pet.alive, "requires a living pet" end,
handler = function ()
applyBuff( "masters_call" )
end,
},
misdirection = {
id = 34477,
cast = 0,
cooldown = 30,
gcd = "off",
startsCombat = false,
texture = 132180,
usable = function () return pet.alive or group, "requires a living pet or ally" end,
handler = function ()
applyBuff( "misdirection" )
end,
},
mongoose_bite = {
id = 259387,
cast = 0,
cooldown = 0,
gcd = "spell",
spend = 30,
spendType = "focus",
startsCombat = true,
texture = 1376044,
aura = function () return debuff.shrapnel_bomb.up and "internal_bleeding" or nil end,
cycle = function () return debuff.shrapnel_bomb.up and "internal_bleeding" or nil end,
talent = "mongoose_bite",
handler = function ()
if buff.mongoose_fury.down then applyBuff( "mongoose_fury" )
else applyBuff( "mongoose_fury", buff.mongoose_fury.remains, min( 5, buff.mongoose_fury.stack + 1 ) ) end
if debuff.shrapnel_bomb.up then
if debuff.internal_bleeding.up then applyDebuff( "target", "internal_bleeding", 9, debuff.internal_bleeding.stack + 1 ) end
end
removeDebuff( "target", "latent_poison" )
removeDebuff( "target", "latent_poison_injection" )
if azerite.wilderness_survival.enabled then
gainChargeTime( "wildfire_bomb", 1 )
if talent.wildfire_infusion.enabled then
gainChargeTime( "shrapnel_bomb", 1 )
gainChargeTime( "pheromone_bomb", 1 )
gainChargeTime( "volatile_bomb", 1 )
end
end
if azerite.primeval_intuition.enabled then
addStack( "primeval_intuition", nil, 1 )
end
if azerite.blur_of_talons.enabled and buff.coordinated_assault.up then
addStack( "blur_of_talons", nil, 1)
end
if legendary.butchers_bone_fragments.enabled then
addStack( "butchers_bone_fragments", nil, 1 )
end
end,
copy = { 265888, "mongoose_bite_eagle" }
},
muzzle = {
id = 187707,
cast = 0,
cooldown = 15,
gcd = "off",
startsCombat = true,
texture = 1376045,
toggle = "interrupts",
debuff = "casting",
readyTime = state.timeToInterrupt,
handler = function ()
if conduit.reversal_of_fortune.enabled then
gain( conduit.reversal_of_fortune.mod, "focus" )
end
interrupt()
end,
},
pheromone_bomb = {
-- id = 270323,
known = 259495,
cast = 0,
charges = function () return talent.guerrilla_tactics.enabled and 2 or nil end,
cooldown = 18,
recharge = 18,
gcd = "spell",
startsCombat = true,
bind = "wildfire_bomb",
talent = "wildfire_infusion",
usable = function () return current_wildfire_bomb == "pheromone_bomb" end,
handler = function ()
applyDebuff( "target", "pheromone_bomb" )
current_wildfire_bomb = "wildfire_bomb"
end,
},
raptor_strike = {
id = 186270,
cast = 0,
cooldown = 0,
gcd = "spell",
spend = 30,
spendType = "focus",
startsCombat = true,
texture = 1376046,
aura = function () return debuff.shrapnel_bomb.up and "internal_bleeding" or nil end,
cycle = function () return debuff.shrapnel_bomb.up and "internal_bleeding" or nil end,
notalent = "mongoose_bite",
handler = function ()
removeBuff( "tip_of_the_spear" )
if debuff.shrapnel_bomb.up then
if debuff.internal_bleeding.up then applyDebuff( "target", "internal_bleeding", 9, debuff.internal_bleeding.stack + 1 ) end
end
if talent.birds_of_prey.enabled and buff.coordinated_assault.up and UnitIsUnit( "pettarget", "target" ) then
buff.coordinated_assault.expires = buff.coordinated_assault.expires + 1.5
end
removeDebuff( "target", "latent_poison" )
removeDebuff( "target", "latent_poison_injection" )
if azerite.wilderness_survival.enabled then
gainChargeTime( "wildfire_bomb", 1 )
if talent.wildfire_infusion.enabled then
gainChargeTime( "shrapnel_bomb", 1 )
gainChargeTime( "pheromone_bomb", 1 )
gainChargeTime( "volatile_bomb", 1 )
end
end
if azerite.primeval_intuition.enabled then
addStack( "primeval_intuition", nil, 1 )
end
if azerite.blur_of_talons.enabled and buff.coordinated_assault.up then
addStack( "blur_of_talons", nil, 1)
end
if legendary.butchers_bone_fragments.enabled then
addStack( "butchers_bone_fragments", nil, 1 )
end
end,
copy = { "raptor_strike_eagle", 265189 },
auras = {
butchers_bone_fragments = {
id = 336908,
duration = 12,
max_stack = 6,
},
}
},
serpent_sting = {
id = 259491,
cast = 0,
cooldown = 0,
gcd = "spell",
spend = function () return buff.vipers_venom.up and 0 or 20 end,
spendType = "focus",
startsCombat = true,
texture = 1033905,
handler = function ()
removeBuff( "vipers_venom" )
applyDebuff( "target", "serpent_sting" )
if azerite.latent_poison.enabled then
applyDebuff( "target", "latent_poison" )
end
if legendary.latent_poison_injectors.enabled then
applyDebuff( "target", "latent_poison_injection", nil, debuff.latent_poison_injection.stack + 1 )
end
end,
},
shrapnel_bomb = {
-- id = 270335,
known = 259495,
cast = 0,
charges = function () return talent.guerrilla_tactics.enabled and 2 or nil end,
cooldown = 18,
recharge = 18,
hasteCD = true,
gcd = "spell",
startsCombat = true,
bind = "wildfire_bomb",
usable = function () return current_wildfire_bomb == "shrapnel_bomb" end,
handler = function ()
applyDebuff( "target", "shrapnel_bomb" )
current_wildfire_bomb = "wildfire_bomb"
end,
},
steady_shot = {
id = 56641,
cast = 1.75,
cooldown = 0,
gcd = "spell",
startsCombat = true,
texture = 132213,
handler = function ()
end,
},
steel_trap = {
id = 162488,
cast = 0,
cooldown = 30,
gcd = "spell",
spend = function ()
if legendary.nessingwarys_trapping_apparatus.enabled then
return -45, "focus"
end
end,
startsCombat = false,
texture = 1467588,
handler = function ()
applyDebuff( "target", "steel_trap" )
end,
},
summon_pet = {
id = 883,
cast = 0,
cooldown = 0,
gcd = "spell",
spend = 0,
spendType = "focus",
startsCombat = false,
texture = 'Interface\\ICONS\\Ability_Hunter_BeastCall',
essential = true,
nomounted = true,
usable = function () return not pet.exists end,
handler = function ()
summonPet( "made_up_pet", 3600, "ferocity" )
end,
},
tar_trap = {
id = 187698,
cast = 0,
cooldown = function () return level > 55 and 25 or 30 end,
gcd = "spell",
spend = function ()
if legendary.nessingwarys_trapping_apparatus.enabled then
return -45, "focus"
end
end,
startsCombat = false,
texture = 576309,
handler = function ()
applyDebuff( "target", "tar_trap" )
end,
},
tranquilizing_shot = {
id = 19801,
cast = 0,
cooldown = 10,
gcd = "spell",
startsCombat = true,
texture = 136020,
toggle = "interrupts",
usable = function () return buff.dispellable_enrage.up or buff.dispellable_magic.up, "requires dispellable_enrage or dispellable_magic" end,
handler = function ()
removeBuff( "dispellable_enrage" )
removeBuff( "dispellable_magic" )
if level > 53 then gain( 10, "focus" ) end
end,
},
volatile_bomb = {
-- id = 271045,
known = 259495,
cast = 0,
charges = function () return talent.guerrilla_tactics.enabled and 2 or nil end,
cooldown = 18,
recharge = 18,
hasteCD = true,
gcd = "spell",
startsCombat = true,
bind = "wildfire_bomb",
usable = function () return current_wildfire_bomb == "volatile_bomb" end,
handler = function ()
if debuff.serpent_sting.up then applyDebuff( "target", "serpent_sting" ) end
current_wildfire_bomb = "wildfire_bomb"
end,
},
wildfire_bomb = {
id = function ()
if current_wildfire_bomb == "wildfire_bomb" then return 259495
elseif current_wildfire_bomb == "pheromone_bomb" then return 270323
elseif current_wildfire_bomb == "shrapnel_bomb" then return 270335
elseif current_wildfire_bomb == "volatile_bomb" then return 271045 end
return 259495
end,
flash = { 270335, 270323, 271045, 259495 },
known = 259495,
cast = 0,
charges = function () return talent.guerrilla_tactics.enabled and 2 or nil end,
cooldown = 18,
recharge = 18,
hasteCD = true,
gcd = "spell",
startsCombat = true,
--[[ texture = function ()
local a = current_wildfire_bomb and current_wildfire_bomb or "wildfire_bomb"
if a == "wildfire_bomb" or not action[ a ] then return 2065634 end
return action[ a ].texture
end, ]]
aura = "wildfire_bomb",
bind = function () return current_wildfire_bomb end,
usable = function () return current_wildfire_bomb ~= "pheromone_bomb" or debuff.serpent_sting.up end,
handler = function ()
if current_wildfire_bomb ~= "wildfire_bomb" then
runHandler( current_wildfire_bomb )
current_wildfire_bomb = "wildfire_bomb"
return
end
applyDebuff( "target", "wildfire_bomb_dot" )
removeBuff( "flame_infusion" )
end,
copy = { 271045, 270335, 270323, 259495 }
},
wing_clip = {
id = 195645,
cast = 0,
cooldown = 0,
gcd = "spell",
spend = 20,
spendType = "focus",
startsCombat = true,
texture = 132309,
handler = function ()
applyDebuff( "target", "wing_clip" )
end,
},
} )
spec:RegisterOptions( {
enabled = true,
aoe = 2,
nameplates = true,
nameplateRange = 8,
damage = true,
damageExpiration = 8,
potion = "spectral_agility",
package = "Survival"
} )
spec:RegisterSetting( "use_harpoon", true, {
name = "|T1376040:0|t Use Harpoon",
desc = "If checked, the addon will recommend |T1376040:0|t Harpoon when you are out of range and Harpoon is available.",
type = "toggle",
width = 1.49
} )
spec:RegisterSetting( "ca_vop_overlap", false, {
name = "|T2065565:0|t Coordinated Assault Overlap (Vision of Perfection)",
desc = "If checked, the addon will recommend |T2065565:0|t Coordinated Assault even if the buff is already applied due to a Vision of Perfection proc.\n" ..
"This may be preferred when delaying Coordinated Assault would cost you one or more uses of Coordinated Assault in a given fight.",
type = "toggle",
width = "full"
} )
spec:RegisterPack( "Survival", 20210703, [[d80uMbqisQ6rssPUKKuzta0NeIAuqqNccSkuj1RaWSqL6wac2Le)cv0WaK6ysILbr6zqeMgQeCnajBdquFdqOXHkjohQKuRdqK3HkHqZtiCpsY(iPYbLKclKKYdHiAIssr6IOsiyJOsi5JcrWirLqQtkerReq9sujuZuis3uskc7us1pLKIOHIkHOLIkj5PanvuHVkeHgRKuYEr8xsnyuomvlgjpgQjRWLj2SI(mQA0cvNw0QLKI61quZwWTrQDRYVLA4K44Os0Yv65QA6uUoK2UKY3fkJxsY5fsRxsQA(qO9dAsfcheWHBcPosbAKwbObIansuQGeanxPcsjGwufHaQ4yKDEHaEoTqabr3Aznpqav8OH2heoiGFJUyHawTHS4MP8ajo5KpT4OufCtZ5N0Ob3Y(WRpno)KgZjbKcndwK8iueWHBcPosbAKwbObIansuQGeanxbO5keqh1I3lbemPrscy8CmKJqrahYJjGGOBTSMhGmUOrptwiWaJgIczib3qgsbAKwHagY3EcheWZCchK6viCqaDSL9raFtKG2wxHakNtfKbrnIrQJucheq5CQGmiQraXBAYMobu9qgf6CwILHH(vYnTVScTN3dziIiKrHoNLyzyOFLCt7lRq759qgGqgU7WOJDfKZqqJBAA)gLvO98EcOJTSpc4CfP6ZJxBRRqmsDKGWbbuoNkidIAeq8MMSPtavpKrHoNLyzyOFLCt7lRq759qgIiczuOZzjwgg6xj30(Yk0EEpKbiKH7om6yxb5me04MM2VrzfApVNa6yl7JaA(QT1vigXiGdz6ObJWbPEfcheqhBzFeqA0QV6dcbuoNkidIAeJuhPeoiGY5ubzquJa6yl7JaARFCjAgYQppE9hVnc4qE8Mkw2hbmsOHmpU4diZVbKXX6hxIMHS6fiRoxKijKjNqNYZnKftGSrFr2GSrdzw88HSzVqMsWJk7dzuc2rFbYslYdiJsGmRBi7vCA6OqMFdilMazy)ISbzR4JmefY4y9JlHSxrW5mXqgf6C(fciEtt20jGQhYmF5fRKVwj4rLLyK6ibHdcOJTSpci6l60e6NakNtfKbrnIrQZfiCqaLZPcYGOgb0Xw2hbe7HG2Xw2NoKVrad5B6ZPfciE8eJuhOiCqaLZPcYGOgbeVPjB6eqhBznrlNqNYdzrazibKbiKzEqoRqL7419uRSs0ICovqgeqhBzFeqShcAhBzF6q(gbmKVPpNwiGuTcXi1bYeoiGY5ubzquJaI30KnDcOJTSMOLtOt5HSiGmKaYaeYupKzEqoRqL7419uRSs0ICovqgeqhBzFeqShcAhBzF6q(gbmKVPpNwiGVrmsDGiHdcOCovqge1iG4nnztNa6ylRjA5e6uEitDqgsjGo2Y(iGype0o2Y(0H8ncyiFtFoTqaXbXRjeJuNRq4Ga6yl7Ja6l2prB9UYzeq5CQGmiQrmIravwb30uUr4GuVcHdcOCovqge1iGTcb8flNeq8MMSPtanpiNvO7JV7x0uPjf5CQGmiGd5XBQyzFeqGrdrHmKGBidPansRqaR5R(CAHastP3xJ73iGo2Y(iG18nDQGqaR5burlHxiGo2Y(kRRy9QFBtKLcUFJawZdOcb0Xw2xHUp(UFrtLMuW9BeJuhPeoiGo2Y(iGpknDFAfXiGY5ubzquJyK6ibHdcOJTSpcivBwqg6zWJkJy5XRTUQ8iGY5ubzquJyK6CbcheqhBzFeWzq(441NgbuoNkidIAeJuhOiCqaLZPcYGOgbeVPjB6eWf9KzV8s5B0WSxErl0uY(fHlrtffzqaDSL9ranF126keJuhit4Ga6yl7Ja(MibTTUcbuoNkidIAeJyeW3iCqQxHWbbuoNkidIAeq8MMSPtaNng9HmaGmS)MEfE5GSiGSzJr)cTxfb0Xw2hbCiUfxJJ7iVonXi1rkHdcOCovqge1iGo2Y(iGVSkYz63YJNaI30KnDcO6HSrBLxwf5m9B5XxSeJCE8qgGqM5lVyflPfT16rkqM6GmGiKHiIqgf6CwQLkY(6AY10fufidqiJcDol1sfzFDn5A6Yk0EEpKfbKXJheqCuCq0MV8I9K6vigPosq4Ga6yl7JaodEuzO)4TraLZPcYGOgXi15ceoiGo2Y(iGR895wE8AF3ogbuoNkidIAeJuhOiCqaDSL9raJLHH(vYnTNakNtfKbrnIrQdKjCqaDSL9raXDVJ8CtgA)Fhnyeq5CQGmiQrmsDGiHdcOJTSpciYziO)4TraLZPcYGOgXi15keoiGY5ubzquJaI30KnDc4SXOpKbaKH930RWlhKfbKnBm6xO9QiGo2Y(iGZGFiNhV(TnrwigPoxnHdcOJTSpcORPr3HS6EQXBh7jGY5ubzquJyK6vaAcheq5CQGmiQraXBAYMobCIgc6vWX9Lx0wslqweqgpEaziIiKnBm6dzaazy)n9k8YbzrazZgJ(fAVkidqidHq2jvz6yPMQPPk16GBzqGmaHSrBLxwf5m9B5XxSeJCE8qgGq2OTYlRICM(T84lRmx5J7ubbYqeri7KQmDSut10ufL4Y209jqgGqM6Hmk05Sq3hF3VONOB0cQcKbiKnBm6dzaazy)n9k8YbzrazZgJ(fAVkidiazo2Y(kiNHGg300(nky)n9k8YbzCnKHeqgcGmereYSKw0wRhPazrazvaAcOJTSpcySmmM5kAQMMIyK6vQq4GakNtfKbrnciEtt20jGo2YAIwoHoLhYuhKvbYaeYupKTONm7LxkB0GJ8BEazzFnUVzJEJ841VTjYYxeUenvuKbb0Xw2hbe7BnHyK6vqkHdcOCovqge1iG4nnztNa6ylRjA5e6uEitDqwfidqit9q2IEYSxEPSrdoYV5bKL914(Mn6nYJx)2MilFr4s0urrgqgGqgU7WOJDLyzymZv0unnvzIgc6vWX9Lx0wslqM6GSxrcbT5lVypKbiKHqidh3xE51Z1Xw2NhGm1bziTauqgIiczJ2kF81vojOPAAQILyKZJhYqab0Xw2hbKc1WXLnkXi1RGeeoiGY5ubzquJaI30KnDc4SXOpKbaKH930RWlhKfbKnBm6xO9QiGo2Y(iGVjsqBRRqms9kCbcheq5CQGmiQraDSL9raP7JV7x0uPjeq8MMSPtanpiNv8GsCxRSYWTElY5ubzazaczieYOqNZcDF8D)IEIUrlOkqgGqgf6CwO7JV7x0t0nAzfApVhYIaYMng9HmoHmecz18nDQGuOP07RX9BqgqaYW(B6v4LdYqaKX1qgpEazaczQhYOqNZsSmm0VsUP9LvO98EidreHmk05Sq3hF3VONOB0Yk0EEpKbiKDsvMowQPAAQIsCzB6(eidbeqCuCq0MV8I9K6vigPEfGIWbbuoNkidIAeqhBzFeqKZqqJBAA)geq8MMSPtaNOHGEfCCF5fTL0cKfbKXJhqgGq2SXOpKbaKH930RWlhKfbKnBm6xO9QiG4O4GOnF5f7j1Rqms9kazcheq5CQGmiQraDSL9raxxX6v)2Mileq8MMSPtaPqNZILk6EQT4I(veFlV5yKHmvqgsaziIiKnAR8Xxx5KGMQPPkwIropEciokoiAZxEXEs9keJuVcqKWbbuoNkidIAeq8MMSPtahTv(4RRCsqt10uflXiNhpb0Xw2hbKUp(UFrtLMqms9kCfcheq5CQGmiQraDSL9raFzvKZ0VLhpbeVPjB6eWvMR8XDQGazaczMV8IvSKw0wRhPazQdYaIqgIiczuOZzPwQi7RRjxtxqviG4O4GOnF5f7j1Rqms9kC1eoiGY5ubzquJaI30KnDc4jvz6yPMQPPkF81vojazaczZgJ(qM6GSA(Movqk0u6914(niJRHmKczaczJ2kVSkYz63YJVScTN3dzQdYakiJRHmE8Ga6yl7JagldJzUIMQPPigPosbAcheqhBzFeqCCh51PFcOCovqge1igPosRq4GakNtfKbrncOJTSpciYziOXnnTFdciEtt20jGZgJ(qgaqg2FtVcVCqweq2SXOFH2RIaIJIdI28LxSNuVcXi1rksjCqaLZPcYGO
end