From 48ce9575973f639ff99463b7981965edf52760e0 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Sun, 12 Feb 2023 12:27:25 +0100 Subject: [PATCH] fix(Scripts/BlackMorass): Adds should walk towards Medivh. (#14945) --- .../rev_1676119703739192300.sql | 2 + src/server/game/Movement/MotionMaster.cpp | 4 +- src/server/game/Movement/MotionMaster.h | 2 +- .../HomeMovementGenerator.cpp | 2 +- .../HomeMovementGenerator.h | 3 +- .../TheBlackMorass/the_black_morass.cpp | 562 +++++++++--------- .../TheBlackMorass/the_black_morass.h | 2 + 7 files changed, 290 insertions(+), 287 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1676119703739192300.sql diff --git a/data/sql/updates/pending_db_world/rev_1676119703739192300.sql b/data/sql/updates/pending_db_world/rev_1676119703739192300.sql new file mode 100644 index 000000000..8c3c75827 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1676119703739192300.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `ScriptName`='npc_black_morass_summoned_add' WHERE `entry` IN (17835,21818,17892,18994,18995,21137,21136,21138,21139); diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index fe8075ddb..27daa3196 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -248,14 +248,14 @@ void MotionMaster::MoveRandom(float wanderDistance) } } -void MotionMaster::MoveTargetedHome() +void MotionMaster::MoveTargetedHome(bool walk /*= false*/) { Clear(false); if (_owner->GetTypeId() == TYPEID_UNIT && !_owner->ToCreature()->GetCharmerOrOwnerGUID()) { LOG_DEBUG("movement.motionmaster", "Creature ({}) targeted home", _owner->GetGUID().ToString()); - Mutate(new HomeMovementGenerator(), MOTION_SLOT_ACTIVE); + Mutate(new HomeMovementGenerator(walk), MOTION_SLOT_ACTIVE); } else if (_owner->GetTypeId() == TYPEID_UNIT && _owner->ToCreature()->GetCharmerOrOwnerGUID()) { diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 73d8144c6..4693025de 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -197,7 +197,7 @@ public: } void MoveIdle(); - void MoveTargetedHome(); + void MoveTargetedHome(bool walk = false); void MoveRandom(float wanderDistance = 0.0f); void MoveFollow(Unit* target, float dist, float angle, MovementSlot slot = MOTION_SLOT_ACTIVE); void MoveChase(Unit* target, std::optional dist = {}, std::optional angle = {}); diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp index 818342744..ee8c9dfcc 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -65,7 +65,7 @@ void HomeMovementGenerator::_setTargetLocation(Creature* owner) owner->UpdateAllowedPositionZ(x, y, z); init.MoveTo(x, y, z, DisableMgr::IsPathfindingEnabled(owner->FindMap()), true); - init.SetWalk(false); + init.SetWalk(_walk); init.Launch(); arrived = false; diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h index 1b4395d36..82da2b0f2 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h @@ -29,7 +29,7 @@ template <> class HomeMovementGenerator : public MovementGeneratorMedium< Creature, HomeMovementGenerator > { public: - HomeMovementGenerator() : arrived(false), i_recalculateTravel(false) {} + HomeMovementGenerator(bool walk) : arrived(false), i_recalculateTravel(false), _walk(walk) {} ~HomeMovementGenerator() {} void DoInitialize(Creature*); @@ -43,5 +43,6 @@ private: void _setTargetLocation(Creature*); bool arrived : 1; bool i_recalculateTravel : 1; + bool _walk; }; #endif diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp index b1d88ca83..b3a27299b 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp @@ -17,6 +17,7 @@ #include "the_black_morass.h" #include "MoveSplineInit.h" +#include "SmartAI.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" @@ -82,195 +83,194 @@ private: Creature& _owner; }; -class npc_medivh_bm : public CreatureScript +struct npc_medivh_bm : public ScriptedAI { -public: - npc_medivh_bm() : CreatureScript("npc_medivh_bm") { } - - CreatureAI* GetAI(Creature* creature) const override + npc_medivh_bm(Creature* creature) : ScriptedAI(creature) { - return GetTheBlackMorassAI(creature); + _instance = creature->GetInstanceScript(); + + _groundArray.clear(); + _airArray.clear(); + + _groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f, creature->GetPositionY(), creature->GetPositionZ())); + _airArray.push_back(G3D::Vector3(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ())); + + for (uint8 i = 0; i < 10; ++i) + { + _groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + 8.0f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ())); + } + + for (uint8 i = 0; i < 40; ++i) + { + _airArray.push_back(G3D::Vector3(creature->GetPositionX() + i * 0.25f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + i * 0.25f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ() + i / 4.0f)); + } + + for (uint8 i = 40; i < 80; ++i) + { + _airArray.push_back(G3D::Vector3(creature->GetPositionX() + 10.0f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + 10.0f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ() + i / 4.0f)); + } } - struct npc_medivh_bmAI : public ScriptedAI + void Reset() override { - npc_medivh_bmAI(Creature* creature) : ScriptedAI(creature) + events.Reset(); + me->CastSpell(me, SPELL_MANA_SHIELD, true); + + if (_instance->GetData(TYPE_AEONUS) != DONE) { - instance = creature->GetInstanceScript(); + me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false); + } + } - groundArray.clear(); - airArray.clear(); + void JustSummoned(Creature* summon) override + { + _instance->SetGuidData(DATA_SUMMONED_NPC, summon->GetGUID()); - groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f, creature->GetPositionY(), creature->GetPositionZ())); - airArray.push_back(G3D::Vector3(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ())); - for (uint8 i = 0; i < 10; ++i) - groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + 8.0f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ())); + if (summon->GetEntry() == NPC_DP_CRYSTAL_STALKER) + { + summon->DespawnOrUnsummon(25000); + summon->CastSpell(summon, RAND(SPELL_BANISH_PURPLE, SPELL_BANISH_GREEN), true); + summon->GetMotionMaster()->MoveSplinePath(&_airArray); + } + else if (summon->GetEntry() == NPC_DP_EMITTER_STALKER) + { + summon->CastSpell(summon, SPELL_BLACK_CRYSTAL, true); + Movement::MoveSplineInit init(summon); + init.MovebyPath(_groundArray); + init.SetCyclic(); + init.Launch(); + } + } - for (uint8 i = 0; i < 40; ++i) - airArray.push_back(G3D::Vector3(creature->GetPositionX() + i * 0.25f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + i * 0.25f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ() + i / 4.0f)); - for (uint8 i = 40; i < 80; ++i) - airArray.push_back(G3D::Vector3(creature->GetPositionX() + 10.0f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + 10.0f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ() + i / 4.0f)); + void SummonedCreatureDespawn(Creature* summon) override + { + _instance->SetGuidData(DATA_DELETED_NPC, summon->GetGUID()); + } + + void MoveInLineOfSight(Unit* who) override + { + if (!events.Empty() || _instance->GetData(TYPE_AEONUS) == DONE) + { + return; } - InstanceScript* instance; - EventMap events; - Movement::PointsArray groundArray; - Movement::PointsArray airArray; + if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 20.0f)) + { + Talk(SAY_ENTER); + _instance->SetData(DATA_MEDIVH, 1); - void Reset() override + me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false); + + events.ScheduleEvent(EVENT_CHECK_HEALTH_75, 500); + events.ScheduleEvent(EVENT_CHECK_HEALTH_50, 500); + events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 500); + events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 2000); + events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 4000); + events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 6000); + events.ScheduleEvent(EVENT_SUMMON_FLYING_CRYSTAL, 8000); + } + } + + void AttackStart(Unit* ) override { } + + void DoAction(int32 param) override + { + if (param == ACTION_OUTRO) { events.Reset(); - me->CastSpell(me, SPELL_MANA_SHIELD, true); + events.ScheduleEvent(EVENT_OUTRO_1, 4000); + me->InterruptNonMeleeSpells(true); - if (instance && instance->GetData(TYPE_AEONUS) != DONE) - me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false); + me->SummonGameObject(GO_DARK_PORTAL, -2086.0f, 7125.6215f, 30.5f, 6.148f, 0.0f, 0.0f, 0.0f, 0.0f, 0); } + } - void JustSummoned(Creature* summon) override + void JustDied(Unit* /*killer*/) override + { + me->SetRespawnTime(DAY); + events.Reset(); + Talk(SAY_DEATH); + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + switch (uint32 eventId = events.ExecuteEvent()) { - if (instance) - instance->SetGuidData(DATA_SUMMONED_NPC, summon->GetGUID()); - - if (summon->GetEntry() == NPC_DP_CRYSTAL_STALKER) - { - summon->DespawnOrUnsummon(25000); - summon->CastSpell(summon, RAND(SPELL_BANISH_PURPLE, SPELL_BANISH_GREEN), true); - summon->GetMotionMaster()->MoveSplinePath(&airArray); - } - else if (summon->GetEntry() == NPC_DP_EMITTER_STALKER) - { - summon->CastSpell(summon, SPELL_BLACK_CRYSTAL, true); - Movement::MoveSplineInit init(summon); - init.MovebyPath(groundArray); - init.SetCyclic(); - init.Launch(); - } - } - - void SummonedCreatureDespawn(Creature* summon) override - { - if (instance) - instance->SetGuidData(DATA_DELETED_NPC, summon->GetGUID()); - } - - void MoveInLineOfSight(Unit* who) override - { - if (!events.Empty() || (instance && instance->GetData(TYPE_AEONUS) == DONE)) - return; - - if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 20.0f)) - { - Talk(SAY_ENTER); - if (instance) - instance->SetData(DATA_MEDIVH, 1); - - me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false); - - events.ScheduleEvent(EVENT_CHECK_HEALTH_75, 500); - events.ScheduleEvent(EVENT_CHECK_HEALTH_50, 500); - events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 500); - events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 2000); - events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 4000); - events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 6000); - events.ScheduleEvent(EVENT_SUMMON_FLYING_CRYSTAL, 8000); - } - } - - void AttackStart(Unit* ) override { } - - void DoAction(int32 param) override - { - if (param == ACTION_OUTRO) - { - events.Reset(); - events.ScheduleEvent(EVENT_OUTRO_1, 4000); - me->InterruptNonMeleeSpells(true); - - me->SummonGameObject(GO_DARK_PORTAL, -2086.0f, 7125.6215f, 30.5f, 6.148f, 0.0f, 0.0f, 0.0f, 0.0f, 0); - } - } - - void JustDied(Unit* /*killer*/) override - { - me->SetRespawnTime(DAY); - events.Reset(); - Talk(SAY_DEATH); - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - switch (uint32 eventId = events.ExecuteEvent()) - { - case EVENT_CHECK_HEALTH_25: - case EVENT_CHECK_HEALTH_50: - case EVENT_CHECK_HEALTH_75: - if (instance && instance->GetData(DATA_SHIELD_PERCENT) <= eventId * 25) - { - Talk(eventId + 1); - break; - } - events.ScheduleEvent(eventId, 500); - break; - case EVENT_SUMMON_CRYSTAL: - me->SummonCreature(NPC_DP_EMITTER_STALKER, me->GetPositionX() + 8.0f, me->GetPositionY(), me->GetPositionZ()); - break; - case EVENT_SUMMON_FLYING_CRYSTAL: - me->CastSpell(me, SPELL_PORTAL_CRYSTALS, true); - events.ScheduleEvent(EVENT_SUMMON_FLYING_CRYSTAL, 1000); - break; - case EVENT_OUTRO_1: - me->SetFacingTo(6.21f); - Talk(SAY_WIN); - events.ScheduleEvent(EVENT_OUTRO_2, 17000); - break; - case EVENT_OUTRO_2: - me->SetFacingTo(3.07f); - events.ScheduleEvent(EVENT_OUTRO_3, 2000); - break; - case EVENT_OUTRO_3: - SummonOrcs(-2046.158f, -3.0f, 37000, 30000, true); - events.ScheduleEvent(EVENT_OUTRO_4, 2000); - break; - case EVENT_OUTRO_4: - SummonOrcs(-2055.97f, -2.0f, 33000, 28000, false); - events.ScheduleEvent(EVENT_OUTRO_5, 2000); - break; - case EVENT_OUTRO_5: - SummonOrcs(-2064.0f, -1.5f, 29000, 26000, false); - events.ScheduleEvent(EVENT_OUTRO_6, 2000); - break; - case EVENT_OUTRO_6: - SummonOrcs(-2074.35f, -0.1f, 26000, 24000, false); - events.ScheduleEvent(EVENT_OUTRO_7, 7000); - break; - case EVENT_OUTRO_7: - Talk(SAY_ORCS_ENTER); - events.ScheduleEvent(EVENT_OUTRO_8, 7000); - break; - case EVENT_OUTRO_8: - if (Creature* cr = me->FindNearestCreature(NPC_SHADOW_COUNCIL_ENFORCER, 20.0f)) - { - cr->SetFacingTo(3.07f); - cr->AI()->Talk(SAY_ORCS_ANSWER); - } - break; - } - } - - void SummonOrcs(float x, float y, uint32 duration, uint32 homeTime, bool first) - { - for (uint8 i = 0; i < 6; ++i) - { - if (Creature* cr = me->SummonCreature(NPC_SHADOW_COUNCIL_ENFORCER, -2091.731f, 7133.083f - 3.0f * i, 34.589f, 0.0f)) + case EVENT_CHECK_HEALTH_25: + case EVENT_CHECK_HEALTH_50: + case EVENT_CHECK_HEALTH_75: + if (_instance->GetData(DATA_SHIELD_PERCENT) <= eventId * 25) { - cr->GetMotionMaster()->MovePoint(0, (first && i == 3) ? x + 2.0f : x, cr->GetPositionY() + y, cr->GetMapHeight(x, cr->GetPositionY() + y, cr->GetPositionZ(), true)); - cr->m_Events.AddEvent(new NpcRunToHome(*cr), cr->m_Events.CalculateTime(homeTime + urand(0, 2000))); - cr->DespawnOrUnsummon(duration + urand(0, 2000)); + Talk(eventId + 1); + break; } + events.ScheduleEvent(eventId, 500); + break; + case EVENT_SUMMON_CRYSTAL: + me->SummonCreature(NPC_DP_EMITTER_STALKER, me->GetPositionX() + 8.0f, me->GetPositionY(), me->GetPositionZ()); + break; + case EVENT_SUMMON_FLYING_CRYSTAL: + me->CastSpell(me, SPELL_PORTAL_CRYSTALS, true); + events.ScheduleEvent(EVENT_SUMMON_FLYING_CRYSTAL, 1000); + break; + case EVENT_OUTRO_1: + me->SetFacingTo(6.21f); + Talk(SAY_WIN); + events.ScheduleEvent(EVENT_OUTRO_2, 17000); + break; + case EVENT_OUTRO_2: + me->SetFacingTo(3.07f); + events.ScheduleEvent(EVENT_OUTRO_3, 2000); + break; + case EVENT_OUTRO_3: + SummonOrcs(-2046.158f, -3.0f, 37000, 30000, true); + events.ScheduleEvent(EVENT_OUTRO_4, 2000); + break; + case EVENT_OUTRO_4: + SummonOrcs(-2055.97f, -2.0f, 33000, 28000, false); + events.ScheduleEvent(EVENT_OUTRO_5, 2000); + break; + case EVENT_OUTRO_5: + SummonOrcs(-2064.0f, -1.5f, 29000, 26000, false); + events.ScheduleEvent(EVENT_OUTRO_6, 2000); + break; + case EVENT_OUTRO_6: + SummonOrcs(-2074.35f, -0.1f, 26000, 24000, false); + events.ScheduleEvent(EVENT_OUTRO_7, 7000); + break; + case EVENT_OUTRO_7: + Talk(SAY_ORCS_ENTER); + events.ScheduleEvent(EVENT_OUTRO_8, 7000); + break; + case EVENT_OUTRO_8: + if (Creature* cr = me->FindNearestCreature(NPC_SHADOW_COUNCIL_ENFORCER, 20.0f)) + { + cr->SetFacingTo(3.07f); + cr->AI()->Talk(SAY_ORCS_ANSWER); + } + break; + } + } + + void SummonOrcs(float x, float y, uint32 duration, uint32 homeTime, bool first) + { + for (uint8 i = 0; i < 6; ++i) + { + if (Creature* cr = me->SummonCreature(NPC_SHADOW_COUNCIL_ENFORCER, -2091.731f, 7133.083f - 3.0f * i, 34.589f, 0.0f)) + { + cr->GetMotionMaster()->MovePoint(0, (first && i == 3) ? x + 2.0f : x, cr->GetPositionY() + y, cr->GetMapHeight(x, cr->GetPositionY() + y, cr->GetPositionZ(), true)); + cr->m_Events.AddEvent(new NpcRunToHome(*cr), cr->m_Events.CalculateTime(homeTime + urand(0, 2000))); + cr->DespawnOrUnsummon(duration + urand(0, 2000)); } } - }; + } + +private: + InstanceScript* _instance; + EventMap _events; + Movement::PointsArray _groundArray; + Movement::PointsArray _airArray; }; enum timeRift @@ -279,151 +279,149 @@ enum timeRift EVENT_CHECK_DEATH = 2 }; -class npc_time_rift : public CreatureScript +struct npc_time_rift : public NullCreatureAI { -public: - npc_time_rift() : CreatureScript("npc_time_rift") { } - - CreatureAI* GetAI(Creature* creature) const override + npc_time_rift(Creature* creature) : NullCreatureAI(creature) { - return GetTheBlackMorassAI(creature); + _instance = creature->GetInstanceScript(); } - struct npc_time_riftAI : public NullCreatureAI + void Reset() override { - npc_time_riftAI(Creature* creature) : NullCreatureAI(creature) + if (_instance->GetData(DATA_RIFT_NUMBER) >= 18) { - instance = creature->GetInstanceScript(); + me->DespawnOrUnsummon(30000); + return; } - EventMap events; - InstanceScript* instance; - ObjectGuid riftKeeperGUID; + events.ScheduleEvent(EVENT_SUMMON_AT_RIFT, 16000); + events.ScheduleEvent(EVENT_CHECK_DEATH, 8000); + } - void Reset() override - { - if (instance && instance->GetData(DATA_RIFT_NUMBER) >= 18) + void SetGUID(ObjectGuid guid, int32) override + { + _riftKeeperGUID = guid; + } + + void DoSummonAtRift(uint32 entry) + { + Position pos = me->GetNearPosition(10.0f, 2 * M_PI * rand_norm()); + + if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 150000)) + if (_instance) { - me->DespawnOrUnsummon(30000); - return; - } - - events.ScheduleEvent(EVENT_SUMMON_AT_RIFT, 16000); - events.ScheduleEvent(EVENT_CHECK_DEATH, 8000); - } - - void SetGUID(ObjectGuid guid, int32) override - { - riftKeeperGUID = guid; - } - - void DoSummonAtRift(uint32 entry) - { - Position pos = me->GetNearPosition(10.0f, 2 * M_PI * rand_norm()); - - if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 150000)) - if (instance) + if (Unit* medivh = ObjectAccessor::GetUnit(*me, _instance->GetGuidData(DATA_MEDIVH))) { - if (Unit* medivh = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_MEDIVH))) + float o = medivh->GetAngle(summon) + frand(-1.0f, 1.0f); + summon->SetHomePosition(medivh->GetPositionX() + 14.0f * cos(o), medivh->GetPositionY() + 14.0f * std::sin(o), medivh->GetPositionZ(), summon->GetAngle(medivh)); + summon->GetMotionMaster()->MoveTargetedHome(true); + summon->SetReactState(REACT_DEFENSIVE); + } + } + } + + void DoSelectSummon() + { + uint32 entry = RAND(NPC_INFINITE_ASSASIN, NPC_INFINITE_WHELP, NPC_INFINITE_CRONOMANCER, NPC_INFINITE_EXECUTIONER, NPC_INFINITE_VANQUISHER); + if (entry == NPC_INFINITE_WHELP) + { + DoSummonAtRift(entry); + DoSummonAtRift(entry); + DoSummonAtRift(entry); + } + else + { + DoSummonAtRift(entry); + } + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + switch (events.ExecuteEvent()) + { + case EVENT_SUMMON_AT_RIFT: + DoSelectSummon(); + events.ScheduleEvent(EVENT_SUMMON_AT_RIFT, 15000); + break; + case EVENT_CHECK_DEATH: + if (!me->HasUnitState(UNIT_STATE_CASTING)) + { + Creature* riftKeeper = ObjectAccessor::GetCreature(*me, _riftKeeperGUID); + if (!riftKeeper || !riftKeeper->IsAlive()) { - float o = medivh->GetAngle(summon) + frand(-1.0f, 1.0f); - summon->SetHomePosition(medivh->GetPositionX() + 14.0f * cos(o), medivh->GetPositionY() + 14.0f * std::sin(o), medivh->GetPositionZ(), summon->GetAngle(medivh)); - summon->GetMotionMaster()->MoveTargetedHome(); - summon->SetReactState(REACT_DEFENSIVE); + _instance->SetData(DATA_RIFT_KILLED, 1); + + me->DespawnOrUnsummon(0); + break; + } + else + { + me->CastSpell(riftKeeper, SPELL_RIFT_CHANNEL, false); } } + events.ScheduleEvent(EVENT_CHECK_DEATH, 500); + break; } + } - void DoSelectSummon() - { - uint32 entry = RAND(NPC_INFINITE_ASSASIN, NPC_INFINITE_WHELP, NPC_INFINITE_CRONOMANCER, NPC_INFINITE_EXECUTIONER, NPC_INFINITE_VANQUISHER); - if (entry == NPC_INFINITE_WHELP) - { - DoSummonAtRift(entry); - DoSummonAtRift(entry); - DoSummonAtRift(entry); - } - else - DoSummonAtRift(entry); - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - switch (events.ExecuteEvent()) - { - case EVENT_SUMMON_AT_RIFT: - DoSelectSummon(); - events.ScheduleEvent(EVENT_SUMMON_AT_RIFT, 15000); - break; - case EVENT_CHECK_DEATH: - if (!me->HasUnitState(UNIT_STATE_CASTING)) - { - Creature* riftKeeper = ObjectAccessor::GetCreature(*me, riftKeeperGUID); - if (!riftKeeper || !riftKeeper->IsAlive()) - { - if (instance) - instance->SetData(DATA_RIFT_KILLED, 1); - - me->DespawnOrUnsummon(0); - break; - } - else - me->CastSpell(riftKeeper, SPELL_RIFT_CHANNEL, false); - } - events.ScheduleEvent(EVENT_CHECK_DEATH, 500); - break; - } - } - }; +private: + EventMap _events; + InstanceScript* _instance; + ObjectGuid _riftKeeperGUID; }; -class spell_black_morass_corrupt_medivh : public SpellScriptLoader +struct npc_black_morass_summoned_add : public SmartAI { -public: - spell_black_morass_corrupt_medivh() : SpellScriptLoader("spell_black_morass_corrupt_medivh") { } - - class spell_black_morass_corrupt_medivh_AuraScript : public AuraScript + npc_black_morass_summoned_add(Creature* creature) : SmartAI(creature) { - PrepareAuraScript(spell_black_morass_corrupt_medivh_AuraScript); + } - bool Load() override + void EnterEvadeMode(EvadeReason why) override + { + SmartAI::EnterEvadeMode(why); + + me->GetMotionMaster()->MoveTargetedHome(true); + } +}; + +class spell_black_morass_corrupt_medivh : public AuraScript +{ + PrepareAuraScript(spell_black_morass_corrupt_medivh); + + bool Load() override + { + _ticks = 0; + return true; + } + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + if (++_ticks >= 3) { _ticks = 0; - return true; - } - void PeriodicTick(AuraEffect const* /*aurEff*/) - { - if (++_ticks >= 3) + if (InstanceScript* instance = GetUnitOwner()->GetInstanceScript()) { - _ticks = 0; - - if (InstanceScript* instance = GetUnitOwner()->GetInstanceScript()) - { - instance->SetData(DATA_DAMAGE_SHIELD, m_scriptSpellId == SPELL_CORRUPT_AEONUS ? 2 : 1); - } + instance->SetData(DATA_DAMAGE_SHIELD, m_scriptSpellId == SPELL_CORRUPT_AEONUS ? 2 : 1); } } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_black_morass_corrupt_medivh_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - - private: - uint8 _ticks = 0; - }; - - AuraScript* GetAuraScript() const override - { - return new spell_black_morass_corrupt_medivh_AuraScript(); } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_black_morass_corrupt_medivh::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + +private: + uint8 _ticks = 0; }; void AddSC_the_black_morass() { - new npc_medivh_bm(); - new npc_time_rift(); - new spell_black_morass_corrupt_medivh(); + RegisterTheBlackMorassCreatureAI(npc_medivh_bm); + RegisterTheBlackMorassCreatureAI(npc_time_rift); + RegisterTheBlackMorassCreatureAI(npc_black_morass_summoned_add); + + RegisterSpellScript(spell_black_morass_corrupt_medivh); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h index 2666034bc..73874f7c0 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h @@ -94,4 +94,6 @@ inline AI* GetTheBlackMorassAI(T* obj) return GetInstanceAI(obj, TheBlackMorassScriptName); } +#define RegisterTheBlackMorassCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetTheBlackMorassAI) + #endif