diff options
author | offl <11556157+offl@users.noreply.github.com> | 2021-07-11 14:55:47 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-11 14:55:47 +0300 |
commit | 51c94fed9a87652b6c0372b20a54ecd51beb1a06 (patch) | |
tree | 80ab9a168e789cfa7bcbe0ff6612f170379fccc5 | |
parent | 40f4b141bd602d6285c3d2d21315a29b2ab3cce1 (diff) |
Scripts/Pet: Update pet scripts to new register model (1/2) (#26661)
-rw-r--r-- | src/server/scripts/Pet/pet_dk.cpp | 162 | ||||
-rw-r--r-- | src/server/scripts/Pet/pet_generic.cpp | 119 | ||||
-rw-r--r-- | src/server/scripts/Pet/pet_hunter.cpp | 445 |
3 files changed, 319 insertions, 407 deletions
diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp index 59b6f564886..33d08e8be1c 100644 --- a/src/server/scripts/Pet/pet_dk.cpp +++ b/src/server/scripts/Pet/pet_dk.cpp @@ -36,107 +36,85 @@ enum DeathKnightSpells SPELL_DK_SANCTUARY = 54661 }; -class npc_pet_dk_ebon_gargoyle : public CreatureScript +struct npc_pet_dk_ebon_gargoyle : CasterAI { - public: - npc_pet_dk_ebon_gargoyle() : CreatureScript("npc_pet_dk_ebon_gargoyle") { } + npc_pet_dk_ebon_gargoyle(Creature* creature) : CasterAI(creature) { } - struct npc_pet_dk_ebon_gargoyleAI : CasterAI + void InitializeAI() override + { + CasterAI::InitializeAI(); + ObjectGuid ownerGuid = me->GetOwnerGUID(); + if (!ownerGuid) + return; + + // Find victim of Summon Gargoyle spell + std::list<Unit*> targets; + Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30.0f); + Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check); + Cell::VisitAllObjects(me, searcher, 30.0f); + for (Unit* target : targets) { - npc_pet_dk_ebon_gargoyleAI(Creature* creature) : CasterAI(creature) { } - - void InitializeAI() override - { - CasterAI::InitializeAI(); - ObjectGuid ownerGuid = me->GetOwnerGUID(); - if (!ownerGuid) - return; - - // Find victim of Summon Gargoyle spell - std::list<Unit*> targets; - Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30.0f); - Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check); - Cell::VisitAllObjects(me, searcher, 30.0f); - for (Unit* target : targets) - { - if (target->HasAura(SPELL_DK_SUMMON_GARGOYLE_1, ownerGuid)) - { - me->Attack(target, false); - break; - } - } - } - - void JustDied(Unit* /*killer*/) override + if (target->HasAura(SPELL_DK_SUMMON_GARGOYLE_1, ownerGuid)) { - // Stop Feeding Gargoyle when it dies - if (Unit* owner = me->GetOwner()) - owner->RemoveAurasDueToSpell(SPELL_DK_SUMMON_GARGOYLE_2); + me->Attack(target, false); + break; } + } + } - // Fly away when dismissed - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_DK_DISMISS_GARGOYLE || !me->IsAlive()) - return; - - Unit* owner = me->GetOwner(); - if (!owner || owner != caster) - return; - - // Stop Fighting - me->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, true); - - // Sanctuary - me->CastSpell(me, SPELL_DK_SANCTUARY, true); - me->SetReactState(REACT_PASSIVE); - - //! HACK: Creature's can't have MOVEMENTFLAG_FLYING - // Fly Away - me->SetCanFly(true); - me->SetSpeedRate(MOVE_FLIGHT, 0.75f); - me->SetSpeedRate(MOVE_RUN, 0.75f); - float x = me->GetPositionX() + 20 * std::cos(me->GetOrientation()); - float y = me->GetPositionY() + 20 * std::sin(me->GetOrientation()); - float z = me->GetPositionZ() + 40; - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(0, x, y, z); - - // Despawn as soon as possible - me->DespawnOrUnsummon(Seconds(4)); - } - }; + void JustDied(Unit* /*killer*/) override + { + // Stop Feeding Gargoyle when it dies + if (Unit* owner = me->GetOwner()) + owner->RemoveAurasDueToSpell(SPELL_DK_SUMMON_GARGOYLE_2); + } - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_pet_dk_ebon_gargoyleAI(creature); - } + // Fly away when dismissed + void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override + { + if (spellInfo->Id != SPELL_DK_DISMISS_GARGOYLE || !me->IsAlive()) + return; + + Unit* owner = me->GetOwner(); + if (!owner || owner != caster) + return; + + // Stop Fighting + me->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, true); + + // Sanctuary + me->CastSpell(me, SPELL_DK_SANCTUARY, true); + me->SetReactState(REACT_PASSIVE); + + //! HACK: Creature's can't have MOVEMENTFLAG_FLYING + // Fly Away + me->SetCanFly(true); + me->SetSpeedRate(MOVE_FLIGHT, 0.75f); + me->SetSpeedRate(MOVE_RUN, 0.75f); + float x = me->GetPositionX() + 20 * std::cos(me->GetOrientation()); + float y = me->GetPositionY() + 20 * std::sin(me->GetOrientation()); + float z = me->GetPositionZ() + 40; + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MovePoint(0, x, y, z); + + // Despawn as soon as possible + me->DespawnOrUnsummon(Seconds(4)); + } }; -class npc_pet_dk_guardian : public CreatureScript +struct npc_pet_dk_guardian : public AggressorAI { - public: - npc_pet_dk_guardian() : CreatureScript("npc_pet_dk_guardian") { } - - struct npc_pet_dk_guardianAI : public AggressorAI - { - npc_pet_dk_guardianAI(Creature* creature) : AggressorAI(creature) { } - - bool CanAIAttack(Unit const* target) const override - { - if (!target) - return false; - Unit* owner = me->GetOwner(); - if (owner && !target->IsInCombatWith(owner)) - return false; - return AggressorAI::CanAIAttack(target); - } - }; + npc_pet_dk_guardian(Creature* creature) : AggressorAI(creature) { } - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_pet_dk_guardianAI(creature); - } + bool CanAIAttack(Unit const* target) const override + { + if (!target) + return false; + Unit* owner = me->GetOwner(); + if (owner && !target->IsInCombatWith(owner)) + return false; + return AggressorAI::CanAIAttack(target); + } }; // 51963 - Gargoyle Strike @@ -164,7 +142,7 @@ class spell_pet_dk_gargoyle_strike : public SpellScript void AddSC_deathknight_pet_scripts() { - new npc_pet_dk_ebon_gargoyle(); - new npc_pet_dk_guardian(); + RegisterCreatureAI(npc_pet_dk_ebon_gargoyle); + RegisterCreatureAI(npc_pet_dk_guardian); RegisterSpellScript(spell_pet_dk_gargoyle_strike); } diff --git a/src/server/scripts/Pet/pet_generic.cpp b/src/server/scripts/Pet/pet_generic.cpp index 63c2b4bbb29..6e7b62f6451 100644 --- a/src/server/scripts/Pet/pet_generic.cpp +++ b/src/server/scripts/Pet/pet_generic.cpp @@ -22,7 +22,6 @@ /* ContentData npc_pet_gen_pandaren_monk 100% Pandaren Monk drinks and bows with you - npc_pet_gen_mojo 100% Mojo follows you when you kiss it EndContentData */ #include "ScriptMgr.h" @@ -40,86 +39,76 @@ enum PandarenMonkMisc EVENT_DRINK = 4 }; -class npc_pet_gen_pandaren_monk : public CreatureScript +struct npc_pet_gen_pandaren_monk : public NullCreatureAI { -public: - npc_pet_gen_pandaren_monk() : CreatureScript("npc_pet_gen_pandaren_monk") {} + npc_pet_gen_pandaren_monk(Creature* creature) : NullCreatureAI(creature) { } - struct npc_pet_gen_pandaren_monkAI : public NullCreatureAI + void Reset() override { - npc_pet_gen_pandaren_monkAI(Creature* creature) : NullCreatureAI(creature) { } + _events.Reset(); + _events.ScheduleEvent(EVENT_FOCUS, 1s); + } + + void EnterEvadeMode(EvadeReason why) override + { + if (!_EnterEvadeMode(why)) + return; + + Reset(); + } + + void ReceiveEmote(Player* /*player*/, uint32 emote) override + { + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + me->StopMoving(); - void Reset() override + switch (emote) { - _events.Reset(); + case TEXT_EMOTE_BOW: _events.ScheduleEvent(EVENT_FOCUS, 1s); + break; + case TEXT_EMOTE_DRINK: + _events.ScheduleEvent(EVENT_DRINK, 1s); + break; } + } - void EnterEvadeMode(EvadeReason why) override - { - if (!_EnterEvadeMode(why)) - return; + void UpdateAI(uint32 diff) override + { + _events.Update(diff); - Reset(); - } + if (Unit* owner = me->GetCharmerOrOwner()) + if (!me->IsWithinDist(owner, 30.f)) + me->InterruptSpell(CURRENT_CHANNELED_SPELL); - void ReceiveEmote(Player* /*player*/, uint32 emote) override + while (uint32 eventId = _events.ExecuteEvent()) { - me->InterruptSpell(CURRENT_CHANNELED_SPELL); - me->StopMoving(); - - switch (emote) + switch (eventId) { - case TEXT_EMOTE_BOW: - _events.ScheduleEvent(EVENT_FOCUS, 1s); + case EVENT_FOCUS: + if (Unit* owner = me->GetCharmerOrOwner()) + me->SetFacingToObject(owner); + _events.ScheduleEvent(EVENT_EMOTE, 1s); break; - case TEXT_EMOTE_DRINK: - _events.ScheduleEvent(EVENT_DRINK, 1s); + case EVENT_EMOTE: + me->HandleEmoteCommand(EMOTE_ONESHOT_BOW); + _events.ScheduleEvent(EVENT_FOLLOW, 1s); + break; + case EVENT_FOLLOW: + if (Unit* owner = me->GetCharmerOrOwner()) + me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + break; + case EVENT_DRINK: + me->CastSpell(me, SPELL_PANDAREN_MONK, false); + break; + default: break; } } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - if (Unit* owner = me->GetCharmerOrOwner()) - if (!me->IsWithinDist(owner, 30.f)) - me->InterruptSpell(CURRENT_CHANNELED_SPELL); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FOCUS: - if (Unit* owner = me->GetCharmerOrOwner()) - me->SetFacingToObject(owner); - _events.ScheduleEvent(EVENT_EMOTE, 1s); - break; - case EVENT_EMOTE: - me->HandleEmoteCommand(EMOTE_ONESHOT_BOW); - _events.ScheduleEvent(EVENT_FOLLOW, 1s); - break; - case EVENT_FOLLOW: - if (Unit* owner = me->GetCharmerOrOwner()) - me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - break; - case EVENT_DRINK: - me->CastSpell(me, SPELL_PANDAREN_MONK, false); - break; - default: - break; - } - } - } - private: - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_pet_gen_pandaren_monkAI(creature); } + +private: + EventMap _events; }; enum SoulTrader @@ -177,7 +166,7 @@ struct npc_pet_lich : public ScriptedAI void AddSC_generic_pet_scripts() { - new npc_pet_gen_pandaren_monk(); + RegisterCreatureAI(npc_pet_gen_pandaren_monk); RegisterCreatureAI(npc_pet_gen_soul_trader); RegisterCreatureAI(npc_pet_lich); } diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp index 779746b451c..8c7cb43811f 100644 --- a/src/server/scripts/Pet/pet_hunter.cpp +++ b/src/server/scripts/Pet/pet_hunter.cpp @@ -54,300 +54,245 @@ enum PetSpellsMisc PET_ICON_ID_SMACK = 473 }; -class npc_pet_hunter_snake_trap : public CreatureScript +struct npc_pet_hunter_snake_trap : public ScriptedAI { - public: - npc_pet_hunter_snake_trap() : CreatureScript("npc_pet_hunter_snake_trap") { } + npc_pet_hunter_snake_trap(Creature* creature) : ScriptedAI(creature), _isViper(false), _spellTimer(0) { } - struct npc_pet_hunter_snake_trapAI : public ScriptedAI - { - npc_pet_hunter_snake_trapAI(Creature* creature) : ScriptedAI(creature), _isViper(false), _spellTimer(0) { } + void JustEngagedWith(Unit* /*who*/) override { } - void JustEngagedWith(Unit* /*who*/) override { } + void JustAppeared() override + { + _isViper = me->GetEntry() == NPC_HUNTER_VIPER ? true : false; - void JustAppeared() override - { - _isViper = me->GetEntry() == NPC_HUNTER_VIPER ? true : false; + me->SetMaxHealth(uint32(107 * (me->GetLevel() - 40) * 0.025f)); + // Add delta to make them not all hit the same time + me->SetAttackTime(BASE_ATTACK, me->GetAttackTime(BASE_ATTACK) + urandms(0,6)); - me->SetMaxHealth(uint32(107 * (me->GetLevel() - 40) * 0.025f)); - // Add delta to make them not all hit the same time - me->SetAttackTime(BASE_ATTACK, me->GetAttackTime(BASE_ATTACK) + urandms(0,6)); + if (!_isViper && !me->HasAura(SPELL_HUNTER_DEADLY_POISON_PASSIVE)) + DoCast(me, SPELL_HUNTER_DEADLY_POISON_PASSIVE, true); + } - if (!_isViper && !me->HasAura(SPELL_HUNTER_DEADLY_POISON_PASSIVE)) - DoCast(me, SPELL_HUNTER_DEADLY_POISON_PASSIVE, true); - } + // Redefined for random target selection: + void MoveInLineOfSight(Unit* /*who*/) override { } - // Redefined for random target selection: - void MoveInLineOfSight(Unit* /*who*/) override { } - - void UpdateAI(uint32 diff) override - { - if (me->GetVictim() && me->GetVictim()->HasBreakableByDamageCrowdControlAura()) - { // don't break cc - me->GetThreatManager().ClearFixate(); - me->InterruptNonMeleeSpells(false); - me->AttackStop(); - return; - } - - if (me->IsSummon() && !me->GetThreatManager().GetFixateTarget()) - { // find new target - Unit* summoner = me->ToTempSummon()->GetSummonerUnit(); - - std::vector<Unit*> targets; - - auto addTargetIfValid = [this, &targets, summoner](CombatReference* ref) mutable - { - Unit* enemy = ref->GetOther(summoner); - if (!enemy->HasBreakableByDamageCrowdControlAura() && me->CanCreatureAttack(enemy) && me->IsWithinDistInMap(enemy, me->GetAttackDistance(enemy))) - targets.push_back(enemy); - }; - - for (std::pair<ObjectGuid const, PvPCombatReference*> const& pair : summoner->GetCombatManager().GetPvPCombatRefs()) - addTargetIfValid(pair.second); - - if (targets.empty()) - for (std::pair<ObjectGuid const, CombatReference*> const& pair : summoner->GetCombatManager().GetPvECombatRefs()) - addTargetIfValid(pair.second); - - for (Unit* target : targets) - me->EngageWithTarget(target); - - if (!targets.empty()) - { - Unit* target = Trinity::Containers::SelectRandomContainerElement(targets); - me->GetThreatManager().FixateTarget(target); - } - } - - if (!UpdateVictim()) - return; - - // Viper - if (_isViper) - { - if (_spellTimer <= diff) - { - if (!urand(0, 2)) // 33% chance to cast - DoCastVictim(RAND(SPELL_HUNTER_MIND_NUMBING_POISON, SPELL_HUNTER_CRIPPLING_POISON)); - - _spellTimer = 3000; - } - else - _spellTimer -= diff; - } - - DoMeleeAttackIfReady(); - } - - private: - bool _isViper; - uint32 _spellTimer; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_pet_hunter_snake_trapAI(creature); + void UpdateAI(uint32 diff) override + { + if (me->GetVictim() && me->GetVictim()->HasBreakableByDamageCrowdControlAura()) + { // don't break cc + me->GetThreatManager().ClearFixate(); + me->InterruptNonMeleeSpells(false); + me->AttackStop(); + return; } -}; -// 57627 - Charge -class spell_pet_charge : public SpellScriptLoader -{ - public: - spell_pet_charge() : SpellScriptLoader("spell_pet_charge") { } + if (me->IsSummon() && !me->GetThreatManager().GetFixateTarget()) + { // find new target + Unit* summoner = me->ToTempSummon()->GetSummonerUnit(); - class spell_pet_charge_AuraScript : public AuraScript - { - PrepareAuraScript(spell_pet_charge_AuraScript); + std::vector<Unit*> targets; - bool Validate(SpellInfo const* /*spellInfo*/) override + auto addTargetIfValid = [this, &targets, summoner](CombatReference* ref) mutable { - return ValidateSpellInfo( - { - SPELL_PET_SWOOP, - SPELL_PET_CHARGE - }); - } + Unit* enemy = ref->GetOther(summoner); + if (!enemy->HasBreakableByDamageCrowdControlAura() && me->CanCreatureAttack(enemy) && me->IsWithinDistInMap(enemy, me->GetAttackDistance(enemy))) + targets.push_back(enemy); + }; - void HandleDummy(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - // Remove +% AP aura - Unit* pet = eventInfo.GetActor(); - Aura* aura = pet->GetAura(SPELL_PET_SWOOP, pet->GetGUID()); - if (!aura) - aura = pet->GetAura(SPELL_PET_CHARGE, pet->GetGUID()); + for (std::pair<ObjectGuid const, PvPCombatReference*> const& pair : summoner->GetCombatManager().GetPvPCombatRefs()) + addTargetIfValid(pair.second); - if (!aura) - return; + if (targets.empty()) + for (std::pair<ObjectGuid const, CombatReference*> const& pair : summoner->GetCombatManager().GetPvECombatRefs()) + addTargetIfValid(pair.second); - aura->DropCharge(AURA_REMOVE_BY_EXPIRE); - } + for (Unit* target : targets) + me->EngageWithTarget(target); - void Register() override + if (!targets.empty()) { - OnEffectProc += AuraEffectProcFn(spell_pet_charge_AuraScript::HandleDummy, EFFECT_0, SPELL_AURA_DUMMY); + Unit* target = Trinity::Containers::SelectRandomContainerElement(targets); + me->GetThreatManager().FixateTarget(target); } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_pet_charge_AuraScript(); } -}; -// -53178 - Guard Dog -class spell_pet_guard_dog : public SpellScriptLoader -{ - public: - spell_pet_guard_dog() : SpellScriptLoader("spell_pet_guard_dog") { } + if (!UpdateVictim()) + return; - class spell_pet_guard_dog_AuraScript : public AuraScript + // Viper + if (_isViper) { - PrepareAuraScript(spell_pet_guard_dog_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override + if (_spellTimer <= diff) { - return ValidateSpellInfo({ SPELL_PET_GUARD_DOG_HAPPINESS }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - // Growl shares family flags with other spells - // filter by spellIcon instead - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL) - return false; + if (!urand(0, 2)) // 33% chance to cast + DoCastVictim(RAND(SPELL_HUNTER_MIND_NUMBING_POISON, SPELL_HUNTER_CRIPPLING_POISON)); - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - caster->CastSpell(nullptr, SPELL_PET_GUARD_DOG_HAPPINESS, aurEff); - - Unit* target = eventInfo.GetProcTarget(); - if (!target->CanHaveThreatList()) - return; - float addThreat = CalculatePct(ASSERT_NOTNULL(eventInfo.GetSpellInfo())->Effects[EFFECT_0].CalcValue(caster), aurEff->GetAmount()); - target->GetThreatManager().AddThreat(caster, addThreat, GetSpellInfo(), false, true); + _spellTimer = 3000; } + else + _spellTimer -= diff; + } - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pet_guard_dog_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pet_guard_dog_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; + DoMeleeAttackIfReady(); + } - AuraScript* GetAuraScript() const override - { - return new spell_pet_guard_dog_AuraScript(); - } +private: + bool _isViper; + uint32 _spellTimer; }; -// -62764 - Silverback -class spell_pet_silverback : public SpellScriptLoader +// 57627 - Charge +class spell_pet_charge : public AuraScript { - public: - spell_pet_silverback() : SpellScriptLoader("spell_pet_silverback") { } + PrepareAuraScript(spell_pet_charge); - class spell_pet_silverback_AuraScript : public AuraScript + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( { - PrepareAuraScript(spell_pet_silverback_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PET_GUARD_DOG_HAPPINESS }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - // Growl shares family flags with other spells - // filter by spellIcon instead - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL) - return false; - - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - static uint32 const triggerSpell[2] = { SPELL_PET_SILVERBACK_RANK_1, SPELL_PET_SILVERBACK_RANK_2 }; - - PreventDefaultAction(); - - uint32 spellId = triggerSpell[GetSpellInfo()->GetRank() - 1]; - eventInfo.GetActor()->CastSpell(nullptr, spellId, aurEff); - } + SPELL_PET_SWOOP, + SPELL_PET_CHARGE + }); + } + + void HandleDummy(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + // Remove +% AP aura + Unit* pet = eventInfo.GetActor(); + Aura* aura = pet->GetAura(SPELL_PET_SWOOP, pet->GetGUID()); + if (!aura) + aura = pet->GetAura(SPELL_PET_CHARGE, pet->GetGUID()); + + if (!aura) + return; + + aura->DropCharge(AURA_REMOVE_BY_EXPIRE); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pet_charge::HandleDummy, EFFECT_0, SPELL_AURA_DUMMY); + } +}; - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pet_silverback_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pet_silverback_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; +// -53178 - Guard Dog +class spell_pet_guard_dog : public AuraScript +{ + PrepareAuraScript(spell_pet_guard_dog); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PET_GUARD_DOG_HAPPINESS }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Growl shares family flags with other spells + // filter by spellIcon instead + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* caster = eventInfo.GetActor(); + caster->CastSpell(nullptr, SPELL_PET_GUARD_DOG_HAPPINESS, aurEff); + + Unit* target = eventInfo.GetProcTarget(); + if (!target->CanHaveThreatList()) + return; + float addThreat = CalculatePct(ASSERT_NOTNULL(eventInfo.GetSpellInfo())->Effects[EFFECT_0].CalcValue(caster), aurEff->GetAmount()); + target->GetThreatManager().AddThreat(caster, addThreat, GetSpellInfo(), false, true); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pet_guard_dog::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pet_guard_dog::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; - AuraScript* GetAuraScript() const override - { - return new spell_pet_silverback_AuraScript(); - } +// -62764 - Silverback +class spell_pet_silverback : public AuraScript +{ + PrepareAuraScript(spell_pet_silverback); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PET_GUARD_DOG_HAPPINESS }); + } + + bool CheckProc(ProcEventInfo& eventInfo) + { + // Growl shares family flags with other spells + // filter by spellIcon instead + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL) + return false; + + return true; + } + + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + { + static uint32 const triggerSpell[2] = { SPELL_PET_SILVERBACK_RANK_1, SPELL_PET_SILVERBACK_RANK_2 }; + + PreventDefaultAction(); + + uint32 spellId = triggerSpell[GetSpellInfo()->GetRank() - 1]; + eventInfo.GetActor()->CastSpell(nullptr, spellId, aurEff); + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pet_silverback::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_pet_silverback::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } }; // -61680 - Culling the Herd -class spell_pet_culling_the_herd : public SpellScriptLoader +class spell_pet_culling_the_herd : public AuraScript { - public: - spell_pet_culling_the_herd() : SpellScriptLoader("spell_pet_culling_the_herd") { } + PrepareAuraScript(spell_pet_culling_the_herd); - class spell_pet_culling_the_herd_AuraScript : public AuraScript - { - PrepareAuraScript(spell_pet_culling_the_herd_AuraScript); + bool CheckProc(ProcEventInfo& eventInfo) + { + // Claw, Bite and Smack share FamilyFlags with other spells + // filter by spellIcon instead + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return false; - bool CheckProc(ProcEventInfo& eventInfo) - { - // Claw, Bite and Smack share FamilyFlags with other spells - // filter by spellIcon instead - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return false; - - switch (spellInfo->SpellIconID) - { - case PET_ICON_ID_CLAW: - case PET_ICON_ID_BITE: - case PET_ICON_ID_SMACK: - break; - default: - return false; - } - - return true; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pet_culling_the_herd_AuraScript::CheckProc); - } - }; - - AuraScript* GetAuraScript() const override + switch (spellInfo->SpellIconID) { - return new spell_pet_culling_the_herd_AuraScript(); + case PET_ICON_ID_CLAW: + case PET_ICON_ID_BITE: + case PET_ICON_ID_SMACK: + break; + default: + return false; } + + return true; + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_pet_culling_the_herd::CheckProc); + } }; void AddSC_hunter_pet_scripts() { - new npc_pet_hunter_snake_trap(); - new spell_pet_charge(); - new spell_pet_guard_dog(); - new spell_pet_silverback(); - new spell_pet_culling_the_herd(); + RegisterCreatureAI(npc_pet_hunter_snake_trap); + RegisterSpellScript(spell_pet_charge); + RegisterSpellScript(spell_pet_guard_dog); + RegisterSpellScript(spell_pet_silverback); + RegisterSpellScript(spell_pet_culling_the_herd); } |