Files
TrinityCore/src/server/scripts/Spells/spell_hunter.cpp

1038 lines
38 KiB
C++

/*
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Scripts for spells with SPELLFAMILY_HUNTER, SPELLFAMILY_PET and SPELLFAMILY_GENERIC spells used by hunter players.
* Ordered alphabetically using scriptname.
* Scriptnames of files in this file should be prefixed with "spell_hun_".
*/
#include "Pet.h"
#include "ScriptMgr.h"
#include "Cell.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "SpellHistory.h"
enum HunterSpells
{
SPELL_HUNTER_BESTIAL_WRATH = 19574,
SPELL_HUNTER_CHIMERA_SHOT_HEAL = 53353,
SPELL_HUNTER_FIRE = 82926,
SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS = 91954,
SPELL_HUNTER_IMPROVED_MEND_PET = 24406,
SPELL_HUNTER_INSANITY = 95809,
SPELL_HUNTER_INVIGORATION_TRIGGERED = 53398,
SPELL_HUNTER_LOCK_AND_LOAD = 56453,
SPELL_HUNTER_MASTERS_CALL_TRIGGERED = 62305,
SPELL_HUNTER_MISDIRECTION_PROC = 35079,
SPELL_HUNTER_PET_LAST_STAND_TRIGGERED = 53479,
SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX = 55709,
SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED = 54114,
SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF = 55711,
SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED = 54045,
SPELL_HUNTER_RAPID_RECUPERATION = 58883,
SPELL_HUNTER_READINESS = 23989,
SPELL_HUNTER_SERPENT_STING = 1978,
SPELL_HUNTER_SNIPER_TRAINING_R1 = 53302,
SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 = 64418,
SPELL_HUNTER_STEADY_SHOT_FOCUS = 77443,
SPELL_HUNTER_THRILL_OF_THE_HUNT = 34720
};
enum MiscSpells
{
SPELL_DRAENEI_GIFT_OF_THE_NAARU = 59543,
SPELL_MAGE_TEMPORAL_DISPLACEMENT = 80354,
SPELL_SHAMAN_EXHAUSTION = 57723,
SPELL_SHAMAN_SATED = 57724
};
// 90355 - Ancient Hysteria
class spell_hun_ancient_hysteria : public SpellScriptLoader
{
public:
spell_hun_ancient_hysteria() : SpellScriptLoader("spell_hun_ancient_hysteria") { }
class spell_hun_ancient_hysteria_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_ancient_hysteria_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_INSANITY)
|| !sSpellMgr->GetSpellInfo(SPELL_MAGE_TEMPORAL_DISPLACEMENT)
|| !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EXHAUSTION)
|| !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_SATED))
return false;
return true;
}
void RemoveInvalidTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HUNTER_INSANITY));
targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_MAGE_TEMPORAL_DISPLACEMENT));
targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_EXHAUSTION));
targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_SATED));
}
void ApplyDebuff()
{
if (Unit* target = GetHitUnit())
target->CastSpell(target, SPELL_HUNTER_INSANITY, true);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hun_ancient_hysteria_SpellScript::RemoveInvalidTargets, EFFECT_ALL, TARGET_UNIT_CASTER_AREA_RAID);
AfterHit += SpellHitFn(spell_hun_ancient_hysteria_SpellScript::ApplyDebuff);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_ancient_hysteria_SpellScript();
}
};
// 53209 - Chimera Shot
class spell_hun_chimera_shot : public SpellScriptLoader
{
public:
spell_hun_chimera_shot() : SpellScriptLoader("spell_hun_chimera_shot") { }
class spell_hun_chimera_shot_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_chimera_shot_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_HEAL) ||
!sSpellMgr->GetSpellInfo(SPELL_HUNTER_SERPENT_STING))
return false;
return true;
}
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
GetCaster()->CastSpell(GetCaster(), SPELL_HUNTER_CHIMERA_SHOT_HEAL, true);
if (Aura* aur = GetHitUnit()->GetAura(SPELL_HUNTER_SERPENT_STING, GetCaster()->GetGUID()))
aur->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hun_chimera_shot_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_chimera_shot_SpellScript();
}
};
// 77767 - Cobra Shot
class spell_hun_cobra_shot : public SpellScriptLoader
{
public:
spell_hun_cobra_shot() : SpellScriptLoader("spell_hun_cobra_shot") { }
class spell_hun_cobra_shot_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_cobra_shot_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS) ||
!sSpellMgr->GetSpellInfo(SPELL_HUNTER_SERPENT_STING))
return false;
return true;
}
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
GetCaster()->CastSpell(GetCaster(), SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS, true);
if (Aura* aur = GetHitUnit()->GetAura(SPELL_HUNTER_SERPENT_STING, GetCaster()->GetGUID()))
{
int32 newDuration = aur->GetDuration() + GetEffectValue() * IN_MILLISECONDS;
aur->SetDuration(std::min(newDuration, aur->GetMaxDuration()), true);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hun_cobra_shot_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_cobra_shot_SpellScript();
}
};
// 781 - Disengage
class spell_hun_disengage : public SpellScriptLoader
{
public:
spell_hun_disengage() : SpellScriptLoader("spell_hun_disengage") { }
class spell_hun_disengage_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_disengage_SpellScript);
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (caster->GetTypeId() == TYPEID_PLAYER && !caster->IsInCombat())
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
return SPELL_CAST_OK;
}
void Register() override
{
OnCheckCast += SpellCheckCastFn(spell_hun_disengage_SpellScript::CheckCast);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_disengage_SpellScript();
}
};
// -19572 - Improved Mend Pet
class spell_hun_improved_mend_pet : public SpellScriptLoader
{
public:
spell_hun_improved_mend_pet() : SpellScriptLoader("spell_hun_improved_mend_pet") { }
class spell_hun_improved_mend_pet_AuraScript : public AuraScript
{
PrepareAuraScript(spell_hun_improved_mend_pet_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_IMPROVED_MEND_PET))
return false;
return true;
}
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
return roll_chance_i(GetEffect(EFFECT_0)->GetAmount());
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
PreventDefaultAction();
GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_IMPROVED_MEND_PET, true, NULL, aurEff);
}
void Register() override
{
DoCheckProc += AuraCheckProcFn(spell_hun_improved_mend_pet_AuraScript::CheckProc);
OnEffectProc += AuraEffectProcFn(spell_hun_improved_mend_pet_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_hun_improved_mend_pet_AuraScript();
}
};
// 53412 - Invigoration
class spell_hun_invigoration : public SpellScriptLoader
{
public:
spell_hun_invigoration() : SpellScriptLoader("spell_hun_invigoration") { }
class spell_hun_invigoration_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_invigoration_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_INVIGORATION_TRIGGERED))
return false;
return true;
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (Unit* unitTarget = GetHitUnit())
if (AuraEffect* aurEff = unitTarget->GetDummyAuraEffect(SPELLFAMILY_HUNTER, 3487, 0))
if (roll_chance_i(aurEff->GetAmount()))
unitTarget->CastSpell(unitTarget, SPELL_HUNTER_INVIGORATION_TRIGGERED, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hun_invigoration_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_invigoration_SpellScript();
}
};
// 53478 - Last Stand Pet
class spell_hun_last_stand_pet : public SpellScriptLoader
{
public:
spell_hun_last_stand_pet() : SpellScriptLoader("spell_hun_last_stand_pet") { }
class spell_hun_last_stand_pet_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_last_stand_pet_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_PET_LAST_STAND_TRIGGERED))
return false;
return true;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
int32 healthModSpellBasePoints0 = int32(caster->CountPctFromMaxHealth(30));
caster->CastCustomSpell(caster, SPELL_HUNTER_PET_LAST_STAND_TRIGGERED, &healthModSpellBasePoints0, NULL, NULL, true, NULL);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hun_last_stand_pet_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_last_stand_pet_SpellScript();
}
};
// 53271 - Masters Call
class spell_hun_masters_call : public SpellScriptLoader
{
public:
spell_hun_masters_call() : SpellScriptLoader("spell_hun_masters_call") { }
class spell_hun_masters_call_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_masters_call_SpellScript);
bool Validate(SpellInfo const* spellInfo) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_MASTERS_CALL_TRIGGERED) ||
!sSpellMgr->GetSpellInfo(spellInfo->GetEffect(EFFECT_0)->CalcValue()))
return false;
return true;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Unit* ally = GetHitUnit())
if (Player* caster = GetCaster()->ToPlayer())
if (Pet* target = caster->GetPet())
{
TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE);
target->CastSpell(ally, GetEffectValue(), castMask);
}
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
{
// Cannot be processed while pet is dead
TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE);
target->CastSpell(target, SPELL_HUNTER_MASTERS_CALL_TRIGGERED, castMask);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
OnEffectHitTarget += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_masters_call_SpellScript();
}
};
// 34477 - Misdirection
class spell_hun_misdirection : public SpellScriptLoader
{
public:
spell_hun_misdirection() : SpellScriptLoader("spell_hun_misdirection") { }
class spell_hun_misdirection_AuraScript : public AuraScript
{
PrepareAuraScript(spell_hun_misdirection_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_MISDIRECTION_PROC))
return false;
return true;
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT || !GetTarget()->HasAura(SPELL_HUNTER_MISDIRECTION_PROC))
GetTarget()->ResetRedirectThreat();
}
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
return GetTarget()->GetRedirectThreatTarget() != nullptr;
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
PreventDefaultAction();
GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_MISDIRECTION_PROC, true, NULL, aurEff);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
DoCheckProc += AuraCheckProcFn(spell_hun_misdirection_AuraScript::CheckProc);
OnEffectProc += AuraEffectProcFn(spell_hun_misdirection_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_hun_misdirection_AuraScript();
}
};
// 35079 - Misdirection (Proc)
class spell_hun_misdirection_proc : public SpellScriptLoader
{
public:
spell_hun_misdirection_proc() : SpellScriptLoader("spell_hun_misdirection_proc") { }
class spell_hun_misdirection_proc_AuraScript : public AuraScript
{
PrepareAuraScript(spell_hun_misdirection_proc_AuraScript);
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
GetTarget()->ResetRedirectThreat();
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_proc_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_hun_misdirection_proc_AuraScript();
}
};
// 54044 - Pet Carrion Feeder
class spell_hun_pet_carrion_feeder : public SpellScriptLoader
{
public:
spell_hun_pet_carrion_feeder() : SpellScriptLoader("spell_hun_pet_carrion_feeder") { }
class spell_hun_pet_carrion_feeder_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_pet_carrion_feeder_SpellScript);
bool Load() override
{
if (!GetCaster()->IsPet())
return false;
return true;
}
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED))
return false;
return true;
}
SpellCastResult CheckIfCorpseNear()
{
Unit* caster = GetCaster();
float max_range = GetSpellInfo()->GetMaxRange(false);
WorldObject* result = NULL;
// search for nearby enemy corpse in range
Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_CHECK_ENEMY);
Trinity::WorldObjectSearcher<Trinity::AnyDeadUnitSpellTargetInRangeCheck> searcher(caster, result, check);
caster->GetMap()->VisitFirstFound(caster->m_positionX, caster->m_positionY, max_range, searcher);
if (!result)
return SPELL_FAILED_NO_EDIBLE_CORPSES;
return SPELL_CAST_OK;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
caster->CastSpell(caster, SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED, false);
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_hun_pet_carrion_feeder_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
OnCheckCast += SpellCheckCastFn(spell_hun_pet_carrion_feeder_SpellScript::CheckIfCorpseNear);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_pet_carrion_feeder_SpellScript();
}
};
// 55709 - Pet Heart of the Phoenix
class spell_hun_pet_heart_of_the_phoenix : public SpellScriptLoader
{
public:
spell_hun_pet_heart_of_the_phoenix() : SpellScriptLoader("spell_hun_pet_heart_of_the_phoenix") { }
class spell_hun_pet_heart_of_the_phoenix_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_pet_heart_of_the_phoenix_SpellScript);
bool Load() override
{
if (!GetCaster()->IsPet())
return false;
return true;
}
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF))
return false;
return true;
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
if (Unit* owner = caster->GetOwner())
if (!caster->HasAura(SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF))
{
owner->CastCustomSpell(SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED, SPELLVALUE_BASE_POINT0, 100, caster, true);
caster->CastSpell(caster, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF, true);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hun_pet_heart_of_the_phoenix_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_pet_heart_of_the_phoenix_SpellScript();
}
};
// -53228 - Rapid Recuperation
class spell_hun_rapid_recuperation : public SpellScriptLoader
{
public:
spell_hun_rapid_recuperation() : SpellScriptLoader("spell_hun_rapid_recuperation") { }
class spell_hun_rapid_recuperation_AuraScript : public AuraScript
{
PrepareAuraScript(spell_hun_rapid_recuperation_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_RAPID_RECUPERATION))
return false;
return true;
}
void HandleAbilityCast(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
{
// This effect only from Rapid Fire (ability cast)
if (!(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[0] & 0x20))
PreventDefaultAction();
}
void HandleFocusRegen(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
// This effect only from Rapid Killing (focus regen)
if (!(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x01000000))
return;
int32 focus = aurEff->GetAmount();
GetTarget()->CastCustomSpell(SPELL_HUNTER_RAPID_RECUPERATION, SPELLVALUE_BASE_POINT0, focus, GetTarget(), true, NULL, aurEff);
}
void Register() override
{
OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_AuraScript::HandleAbilityCast, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_AuraScript::HandleFocusRegen, EFFECT_1, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_hun_rapid_recuperation_AuraScript();
}
};
// 23989 - Readiness
class spell_hun_readiness : public SpellScriptLoader
{
public:
spell_hun_readiness() : SpellScriptLoader("spell_hun_readiness") { }
class spell_hun_readiness_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_readiness_SpellScript);
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
// immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath
GetCaster()->GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr)
{
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first);
///! If spellId in cooldown map isn't valid, the above will return a null pointer.
if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER &&
spellInfo->Id != SPELL_HUNTER_READINESS &&
spellInfo->Id != SPELL_HUNTER_BESTIAL_WRATH &&
spellInfo->Id != SPELL_DRAENEI_GIFT_OF_THE_NAARU &&
spellInfo->GetRecoveryTime() > 0)
return true;
return false;
}, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hun_readiness_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_readiness_SpellScript();
}
};
// 82925 - Ready, Set, Aim...
class spell_hun_ready_set_aim : public SpellScriptLoader
{
public:
spell_hun_ready_set_aim() : SpellScriptLoader("spell_hun_ready_set_aim") { }
class spell_hun_ready_set_aim_AuraScript : public AuraScript
{
PrepareAuraScript(spell_hun_ready_set_aim_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_FIRE))
return false;
return true;
}
void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (GetStackAmount() == 5)
{
GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_FIRE, true, NULL, aurEff);
GetTarget()->RemoveAura(GetId());
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_hun_ready_set_aim_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_hun_ready_set_aim_AuraScript();
}
};
// 37506 - Scatter Shot
class spell_hun_scatter_shot : public SpellScriptLoader
{
public:
spell_hun_scatter_shot() : SpellScriptLoader("spell_hun_scatter_shot") { }
class spell_hun_scatter_shot_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_scatter_shot_SpellScript);
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
Player* caster = GetCaster()->ToPlayer();
// break Auto Shot and autohit
caster->InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
caster->AttackStop();
caster->SendAttackSwingCancelAttack();
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hun_scatter_shot_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_scatter_shot_SpellScript();
}
};
// -53302 - Sniper Training
class spell_hun_sniper_training : public SpellScriptLoader
{
public:
spell_hun_sniper_training() : SpellScriptLoader("spell_hun_sniper_training") { }
class spell_hun_sniper_training_AuraScript : public AuraScript
{
PrepareAuraScript(spell_hun_sniper_training_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_R1) ||
!sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1))
return false;
return true;
}
void HandlePeriodic(AuraEffect const* aurEff)
{
PreventDefaultAction();
if (aurEff->GetAmount() <= 0)
{
Unit* target = GetTarget();
uint32 spellId = SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 + GetId() - SPELL_HUNTER_SNIPER_TRAINING_R1;
target->CastSpell(target, spellId, true, 0, aurEff);
if (Player* playerTarget = GetUnitOwner()->ToPlayer())
{
int32 baseAmount = aurEff->GetBaseAmount();
int32 amount = playerTarget->CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff->GetEffIndex(), &baseAmount);
GetEffect(EFFECT_0)->SetAmount(amount);
}
}
}
void HandleUpdatePeriodic(AuraEffect* aurEff)
{
if (Player* playerTarget = GetUnitOwner()->ToPlayer())
{
int32 baseAmount = aurEff->GetBaseAmount();
int32 amount = playerTarget->isMoving() ?
playerTarget->CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff->GetEffIndex(), &baseAmount) :
aurEff->GetAmount() - 1;
aurEff->SetAmount(amount);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_hun_sniper_training_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_hun_sniper_training_AuraScript::HandleUpdatePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_hun_sniper_training_AuraScript();
}
};
// 56641 - Steady Shot
class spell_hun_steady_shot : public SpellScriptLoader
{
public:
spell_hun_steady_shot() : SpellScriptLoader("spell_hun_steady_shot") { }
class spell_hun_steady_shot_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_steady_shot_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_STEADY_SHOT_FOCUS))
return false;
return true;
}
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void HandleOnHit()
{
GetCaster()->CastSpell(GetCaster(), SPELL_HUNTER_STEADY_SHOT_FOCUS, true);
}
void Register() override
{
OnHit += SpellHitFn(spell_hun_steady_shot_SpellScript::HandleOnHit);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_steady_shot_SpellScript();
}
};
// 1515 - Tame Beast
class spell_hun_tame_beast : public SpellScriptLoader
{
public:
spell_hun_tame_beast() : SpellScriptLoader("spell_hun_tame_beast") { }
class spell_hun_tame_beast_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_tame_beast_SpellScript);
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (caster->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_DONT_REPORT;
if (!GetExplTargetUnit())
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
if (Creature* target = GetExplTargetUnit()->ToCreature())
{
if (target->getLevel() > caster->getLevel())
return SPELL_FAILED_HIGHLEVEL;
// use SMSG_PET_TAME_FAILURE?
if (!target->GetCreatureTemplate()->IsTameable(caster->ToPlayer()->CanTameExoticPets()))
return SPELL_FAILED_BAD_TARGETS;
if (!caster->GetPetGUID().IsEmpty())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
if (!caster->GetCharmGUID().IsEmpty())
return SPELL_FAILED_ALREADY_HAVE_CHARM;
}
else
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
return SPELL_CAST_OK;
}
void Register() override
{
OnCheckCast += SpellCheckCastFn(spell_hun_tame_beast_SpellScript::CheckCast);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_tame_beast_SpellScript();
}
};
// 53434 - Call of the Wild
class spell_hun_target_only_pet_and_owner : public SpellScriptLoader
{
public:
spell_hun_target_only_pet_and_owner() : SpellScriptLoader("spell_hun_target_only_pet_and_owner") { }
class spell_hun_target_only_pet_and_owner_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_target_only_pet_and_owner_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.clear();
targets.push_back(GetCaster());
if (Unit* owner = GetCaster()->GetOwner())
targets.push_back(owner);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hun_target_only_pet_and_owner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hun_target_only_pet_and_owner_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_PARTY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hun_target_only_pet_and_owner_SpellScript();
}
};
// 34497 - Thrill of the Hunt
class spell_hun_thrill_of_the_hunt : public SpellScriptLoader
{
public:
spell_hun_thrill_of_the_hunt() : SpellScriptLoader("spell_hun_thrill_of_the_hunt") { }
class spell_hun_thrill_of_the_hunt_AuraScript : public AuraScript
{
PrepareAuraScript(spell_hun_thrill_of_the_hunt_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_THRILL_OF_THE_HUNT))
return false;
return true;
}
void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
std::vector<SpellInfo::CostData> costs = eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), SpellSchoolMask(eventInfo.GetDamageInfo()->GetSchoolMask()));
auto m = std::find_if(costs.begin(), costs.end(), [](SpellInfo::CostData const& cost) { return cost.Power == POWER_FOCUS; });
if (m != costs.end())
{
int32 focus = CalculatePct(m->Amount, aurEff->GetAmount());
if (focus > 0)
GetTarget()->CastCustomSpell(GetTarget(), SPELL_HUNTER_THRILL_OF_THE_HUNT, &focus, NULL, NULL, true, NULL, aurEff);
}
}
void Register() override
{
OnEffectProc += AuraEffectProcFn(spell_hun_thrill_of_the_hunt_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_hun_thrill_of_the_hunt_AuraScript();
}
};
// -56333 - T.N.T.
class spell_hun_tnt : public SpellScriptLoader
{
public:
spell_hun_tnt() : SpellScriptLoader("spell_hun_tnt") { }
class spell_hun_tnt_AuraScript : public AuraScript
{
PrepareAuraScript(spell_hun_tnt_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_LOCK_AND_LOAD))
return false;
return true;
}
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
return roll_chance_i(GetEffect(EFFECT_0)->GetAmount());
}
void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
PreventDefaultAction();
GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_LOCK_AND_LOAD, true, NULL, aurEff);
}
void Register() override
{
DoCheckProc += AuraCheckProcFn(spell_hun_tnt_AuraScript::CheckProc);
OnEffectProc += AuraEffectProcFn(spell_hun_tnt_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_hun_tnt_AuraScript();
}
};
void AddSC_hunter_spell_scripts()
{
new spell_hun_ancient_hysteria();
new spell_hun_chimera_shot();
new spell_hun_cobra_shot();
new spell_hun_disengage();
new spell_hun_improved_mend_pet();
new spell_hun_invigoration();
new spell_hun_last_stand_pet();
new spell_hun_masters_call();
new spell_hun_misdirection();
new spell_hun_misdirection_proc();
new spell_hun_pet_carrion_feeder();
new spell_hun_pet_heart_of_the_phoenix();
new spell_hun_rapid_recuperation();
new spell_hun_readiness();
new spell_hun_ready_set_aim();
new spell_hun_scatter_shot();
new spell_hun_sniper_training();
new spell_hun_steady_shot();
new spell_hun_tame_beast();
new spell_hun_target_only_pet_and_owner();
new spell_hun_thrill_of_the_hunt();
new spell_hun_tnt();
}