/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * 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 . */ /* * Ordered alphabetically using scriptname. * Scriptnames of files in this file should be prefixed with "npc_pet_dk_". */ #include "ScriptMgr.h" #include "CellImpl.h" #include "CombatAI.h" #include "GridNotifiersImpl.h" #include "MotionMaster.h" enum DeathKnightSpells { SPELL_DK_SUMMON_GARGOYLE_1 = 49206, SPELL_DK_SUMMON_GARGOYLE_2 = 50514, SPELL_DK_DISMISS_GARGOYLE = 50515, SPELL_DK_SANCTUARY = 54661 }; struct npc_pet_dk_ebon_gargoyle : CasterAI { npc_pet_dk_ebon_gargoyle(Creature* creature) : CasterAI(creature) { } void InitializeAI() override { CasterAI::InitializeAI(); ObjectGuid ownerGuid = me->GetOwnerGUID(); if (!ownerGuid) return; // Find victim of Summon Gargoyle spell std::list targets; Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30.0f); Trinity::UnitListSearcher 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 { // Stop Feeding Gargoyle when it dies if (Unit* owner = me->GetOwner()) owner->RemoveAurasDueToSpell(SPELL_DK_SUMMON_GARGOYLE_2); } // 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->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); // 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)); } }; struct npc_pet_dk_guardian : public AggressorAI { npc_pet_dk_guardian(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); } }; void AddSC_deathknight_pet_scripts() { RegisterCreatureAI(npc_pet_dk_ebon_gargoyle); RegisterCreatureAI(npc_pet_dk_guardian); }