From 1fbd50db166bfb11757219904431e6f6f064a602 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Tue, 4 Aug 2020 21:22:38 +0200 Subject: [PATCH] Scripts/ET: * moved Nozdormu's script to a seperate file * scripted Moruzond's respawn mechanism --- .../world/4.3.4/2020_08_04_00_world.sql | 31 ++++ .../CavernsOfTime/EndTime/boss_murozond.cpp | 107 ++---------- .../CavernsOfTime/EndTime/end_time.cpp | 158 ++++++++++++++++++ .../Kalimdor/CavernsOfTime/EndTime/end_time.h | 2 +- .../EndTime/instance_end_time.cpp | 116 ++++++++++++- .../Kalimdor/kalimdor_script_loader.cpp | 6 +- 6 files changed, 323 insertions(+), 97 deletions(-) create mode 100644 sql/updates/world/4.3.4/2020_08_04_00_world.sql create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/EndTime/end_time.cpp diff --git a/sql/updates/world/4.3.4/2020_08_04_00_world.sql b/sql/updates/world/4.3.4/2020_08_04_00_world.sql new file mode 100644 index 00000000000..e6f1493c29e --- /dev/null +++ b/sql/updates/world/4.3.4/2020_08_04_00_world.sql @@ -0,0 +1,31 @@ +UPDATE `creature_template` SET `ScriptName`= 'npc_end_time_nozdormu' WHERE `entry`= 54751; + +DELETE FROM `spawn_group_template` WHERE `groupId` IN (437, 438); +INSERT INTO `spawn_group_template` (`groupId`, `groupName`, `groupFlags`) VALUES +(437, 'End Time - Murozond Chest', 4), +(438, 'End Time - Murozond Trash Pack', 4); + +DELETE FROM `spawn_group` WHERE `groupId` IN (437, 438); +INSERT INTO `spawn_group` (`groupId`, `spawnType`, `spawnId`) VALUES +(437, 1, 212782), +(438, 0, 341660), +(438, 0, 341662), +(438, 0, 341661), +(438, 0, 341659), +(438, 0, 341673), +(438, 0, 341658), +(438, 0, 341656), +(438, 0, 341657); + +DELETE FROM `creature` WHERE `guid`= 320247; +DELETE FROM `creature_addon` WHERE `guid`= 320247; + +UPDATE `creature` SET `modelid`= 38754 WHERE `id`= 54751; + +DELETE FROM `creature_onkill_reward` WHERE `creature_id`= 54432; +INSERT INTO `creature_onkill_reward` (`creature_id`, `RewOnKillRepFaction1`, `MaxStanding1`, `RewOnKillRepValue1`, `CurrencyId1`, `CurrencyCount1`) VALUES +(54432, 1162, 7, 250, 395, 7000); + +DELETE FROM `instance_spawn_groups` WHERE `spawnGroupId`= 438; +INSERT INTO `instance_spawn_groups` (`instanceMapId`, `bossStateId`, `bossStates`, `spawnGroupId`, `flags`) VALUES +(938, 4, 17, 438, 1); -- Enable group when Murozond is not DONE diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/boss_murozond.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/boss_murozond.cpp index 68a4bc48e5b..d5566757c03 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/boss_murozond.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/boss_murozond.cpp @@ -79,14 +79,7 @@ enum Events // Mirror Image EVENT_UNROOT_SUMMONER, EVENT_MOVE_SUMMONER_BACK, - EVENT_TELEPORT_SUMMONER, - - // Nozdormu - EVENT_TALK_ENCOUNTER_INTRO, - EVENT_TALK_ENCOUNTER_OUTRO_1, - EVENT_TALK_ENCOUNTER_OUTRO_2, - EVENT_TALK_ENCOUNTER_OUTRO_3, - EVENT_TALK_ENCOUNTER_OUTRO_4 + EVENT_TELEPORT_SUMMONER }; enum Actions @@ -106,14 +99,7 @@ enum Texts SAY_INTRO_2 = 1, SAY_AGGRO = 2, SAY_REWIND_TIME = 3, // offset until group Id 7 - SAY_DEATH = 8, - - // Nozdormu - SAY_ENCOUNTER_INTRO = 0, - SAY_ENCOUNTER_OUTRO_1 = 1, - SAY_ENCOUNTER_OUTRO_2 = 2, - SAY_ENCOUNTER_OUTRO_3 = 3, - SAY_ENCOUNTER_OUTRO_4 = 4 + SAY_DEATH = 8 }; enum MovePoints @@ -131,8 +117,6 @@ enum Misc Position const ArenaFlightPosition = { 4181.117f, -420.21933f, 138.38057f }; Position const ArenaLandPosition = { 4181.117f, -420.21933f, 119.77462f }; -Position const NozdormuEncounterTeleportPosition = { 4033.37f, -294.457f, 181.613f, 5.8119464f }; -Position const NozdormuDefeatTeleportPosition = { 4138.48f, -429.436f, 122.259f, 5.8119464f }; constexpr float FlightPreFightOrientation = 3.1066861f; std::array DistortionBombIntervals = @@ -145,17 +129,23 @@ std::array DistortionBombIntervals = struct boss_murozond : public BossAI { - boss_murozond(Creature* creature) : BossAI(creature, DATA_MUROZOND), _rewindTimeCount(0), _defeated(false) - { - me->SetReactState(REACT_PASSIVE); - } + boss_murozond(Creature* creature) : BossAI(creature, DATA_MUROZOND), _rewindTimeCount(0), _defeated(false) { } void InitializeAI() override { + me->SetReactState(REACT_PASSIVE); me->SetDisableGravity(true); me->SetHover(true); } + void JustAppeared() override + { + if (instance->GetBossState(DATA_MUROZOND) == FAIL) + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + _Reset(); + } + void JustEngagedWith(Unit* who) override { _JustEngagedWith(who); @@ -178,9 +168,9 @@ struct boss_murozond : public BossAI instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SANDS_OF_THE_HOURGLASS); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TEMPORAL_BLAST); instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - _EnterEvadeMode(); + instance->SetBossState(DATA_MUROZOND, FAIL); summons.DespawnAll(); - _DespawnAtEvade(); + me->DespawnOrUnsummon(); } void MovementInform(uint32 type, uint32 pointId) override @@ -191,6 +181,7 @@ struct boss_murozond : public BossAI switch (pointId) { case POINT_ARENA: + me->setActive(false); me->SetFacingTo(FlightPreFightOrientation); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); break; @@ -228,6 +219,7 @@ struct boss_murozond : public BossAI else if (data == DONE) { Talk(SAY_INTRO_2); + me->setActive(true); me->GetMotionMaster()->MovePoint(POINT_ARENA, ArenaFlightPosition, false); } break; @@ -473,72 +465,6 @@ private: EventMap _events; }; -struct npc_murozond_nozdormu : public NullCreatureAI -{ - npc_murozond_nozdormu(Creature* creature) : NullCreatureAI(creature), _introDone(false) - { - me->SetDisplayId(me->GetCreatureTemplate()->Modelid1); - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_ENCOUNTER_INTRO: - if (!_introDone) - { - _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_INTRO, 8s + 400ms); - _introDone = true; - } - break; - case ACTION_ENCOUNTER_OUTRO: - me->NearTeleportTo(NozdormuDefeatTeleportPosition); - _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_OUTRO_1, 8s + 700ms); - break; - default: - break; - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_TALK_ENCOUNTER_INTRO: - Talk(SAY_ENCOUNTER_INTRO); - me->NearTeleportTo(NozdormuEncounterTeleportPosition); - break; - case EVENT_TALK_ENCOUNTER_OUTRO_1: - Talk(SAY_ENCOUNTER_OUTRO_1); - _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_OUTRO_2, 17s); - break; - case EVENT_TALK_ENCOUNTER_OUTRO_2: - Talk(SAY_ENCOUNTER_OUTRO_2); - _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_OUTRO_3, 17s); - break; - case EVENT_TALK_ENCOUNTER_OUTRO_3: - Talk(SAY_ENCOUNTER_OUTRO_3); - _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_OUTRO_4, 14s); - break; - case EVENT_TALK_ENCOUNTER_OUTRO_4: - Talk(SAY_ENCOUNTER_OUTRO_4); - me->SetFacingTo(3.1765f); - break; - default: - break; - } - } - } - -private: - EventMap _events; - bool _introDone; -}; - // 101590 - Rewind Time class spell_murozond_rewind_time_forcecast : public SpellScript { @@ -608,7 +534,6 @@ void AddSC_boss_murozond() { RegisterEndTimeCreatureAI(boss_murozond); RegisterEndTimeCreatureAI(npc_murozond_mirror_image); - RegisterEndTimeCreatureAI(npc_murozond_nozdormu); RegisterSpellScript(spell_murozond_rewind_time_forcecast); RegisterSpellScript(spell_murozond_rewind_time); RegisterSpellScript(spell_murozond_clone_master_health); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/end_time.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/end_time.cpp new file mode 100644 index 00000000000..e91a8b0f416 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/end_time.cpp @@ -0,0 +1,158 @@ +/* + * 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 . + */ + +#include "end_time.h" +#include "InstanceScript.h" +#include "PassiveAI.h" +#include "Player.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptMgr.h" + +enum Events +{ + // Nozdormu + EVENT_TALK_ENCOUNTER_INTRO = 1, + EVENT_TALK_ENCOUNTER_OUTRO_1, + EVENT_TALK_ENCOUNTER_OUTRO_2, + EVENT_TALK_ENCOUNTER_OUTRO_3, + EVENT_TALK_ENCOUNTER_OUTRO_4 +}; + +enum Actions +{ + // Nozdormu + ACTION_ENCOUNTER_INTRO = 1, + ACTION_ENCOUNTER_OUTRO = 2 +}; + +enum Texts +{ + // Nozdormu + SAY_ENCOUNTER_INTRO = 0, + SAY_ENCOUNTER_OUTRO_1 = 1, + SAY_ENCOUNTER_OUTRO_2 = 2, + SAY_ENCOUNTER_OUTRO_3 = 3, + SAY_ENCOUNTER_OUTRO_4 = 4 +}; + +enum GossipMenus +{ + GOSSIP_MENU_ID_NOZDORMU = 13360, + GOSSIP_MENU_OPTION_ID_WELL_OF_ETERNITY = 0 +}; + +Position const NozdormuEncounterTeleportPosition = { 4033.37f, -294.457f, 181.613f, 5.8119464f }; +Position const NozdormuDefeatTeleportPosition = { 4138.48f, -429.436f, 122.259f, 5.8119464f }; + +struct npc_end_time_nozdormu : public NullCreatureAI +{ + npc_end_time_nozdormu(Creature* creature) : NullCreatureAI(creature), _instance(nullptr), _introDone(false) { } + + void InitializeAI() override + { + _instance = me->GetInstanceScript(); + } + + bool GossipHello(Player* player) override + { + if (!_instance) + return true; + + if (_instance->GetBossState(DATA_MUROZOND) == DONE) + AddGossipItemFor(player, GOSSIP_MENU_ID_NOZDORMU, GOSSIP_MENU_OPTION_ID_WELL_OF_ETERNITY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + SendGossipMenuFor(player, player->GetGossipTextId(GOSSIP_MENU_ID_NOZDORMU, me), me->GetGUID()); + + return true; + } + + bool GossipSelect(Player* /*player*/, uint32 menuId, uint32 /*gossipListId*/) override + { + // Todo: Well of Eternity teleport + + return true; + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_ENCOUNTER_INTRO: + if (!_introDone) + { + _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_INTRO, 8s + 400ms); + _introDone = true; + } + break; + case ACTION_ENCOUNTER_OUTRO: + me->setActive(true); + me->NearTeleportTo(NozdormuDefeatTeleportPosition); + _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_OUTRO_1, 8s + 700ms); + me->setActive(false); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_TALK_ENCOUNTER_INTRO: + Talk(SAY_ENCOUNTER_INTRO); + me->setActive(true); + me->NearTeleportTo(NozdormuEncounterTeleportPosition); + me->setActive(false); + break; + case EVENT_TALK_ENCOUNTER_OUTRO_1: + Talk(SAY_ENCOUNTER_OUTRO_1); + _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_OUTRO_2, 17s); + break; + case EVENT_TALK_ENCOUNTER_OUTRO_2: + Talk(SAY_ENCOUNTER_OUTRO_2); + _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_OUTRO_3, 17s); + break; + case EVENT_TALK_ENCOUNTER_OUTRO_3: + Talk(SAY_ENCOUNTER_OUTRO_3); + _events.ScheduleEvent(EVENT_TALK_ENCOUNTER_OUTRO_4, 14s); + break; + case EVENT_TALK_ENCOUNTER_OUTRO_4: + Talk(SAY_ENCOUNTER_OUTRO_4); + me->SetFacingTo(3.1765f); + break; + default: + break; + } + } + } + +private: + EventMap _events; + InstanceScript* _instance; + bool _introDone; +}; + +void AddSC_end_time() +{ + RegisterEndTimeCreatureAI(npc_end_time_nozdormu); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/end_time.h b/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/end_time.h index 28f6fb38647..6e135aa3c0d 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/end_time.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/end_time.h @@ -52,7 +52,7 @@ enum ETCreatures /*Murozond*/ NPC_INFINITE_WARDEN = 54923, NPC_INFINITE_SUPRESSOR = 54920, - NPC_NOZDORMU_BRONZE_DRAGON_SHRINE = 54751 + NPC_NOZDORMU_DRAGON_SHRINES = 54751 }; enum ETGameObjectIds diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/instance_end_time.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/instance_end_time.cpp index eeb93b40f3f..a218caadd0a 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/instance_end_time.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EndTime/instance_end_time.cpp @@ -16,16 +16,19 @@ */ #include "end_time.h" +#include "EventMap.h" #include "Creature.h" #include "CreatureAI.h" #include "InstanceScript.h" +#include "Map.h" #include "ScriptMgr.h" +#include + ObjectData const creatureData[] = { - { BOSS_MUROZOND, DATA_MUROZOND }, - { NPC_NOZDORMU_BRONZE_DRAGON_SHRINE, DATA_NOZDORMU_BRONZE_DRAGON_SHRINE }, - { 0, 0 } // END + { BOSS_MUROZOND, DATA_MUROZOND }, + { 0, 0 } // END }; ObjectData const gameobjectData[] = @@ -38,6 +41,27 @@ DoorData const doorData[] = { 0, 0, DOOR_TYPE_ROOM } // END }; +enum Events +{ + EVENT_RESPAWN_MUROZOND = 1 +}; + +enum SpawnGroups +{ + SPAWN_GROUP_ID_MUROZOND_CHEST = 437 +}; + +enum AreaIds +{ + AREA_ID_BRONZE_DRAGON_SHRINE = 5795 +}; + +std::array MurozondSpawnPositions = +{ + Position(4288.125f, -456.40277f, 160.4989f, 2.98451f), // Initial spawn position + Position(4181.117f, -420.21933f, 138.38057f, 3.10668f) // Respawn position +}; + class instance_end_time : public InstanceMapScript { public: @@ -53,6 +77,23 @@ public: LoadObjectData(creatureData, gameobjectData); } + void Create() override + { + InstanceScript::Create(); + + // The instance has been created without save data, just spawn Murozond at his initial position. + instance->SummonCreature(BOSS_MUROZOND, MurozondSpawnPositions[0]); + } + + void Load(char const* data) override + { + InstanceScript::Load(data); + + // The instance has been created from existing save data, but Murozond has not been defeated yet. Spawn him at his initial position. + if (GetBossState(DATA_MUROZOND) != DONE) + instance->SummonCreature(BOSS_MUROZOND, MurozondSpawnPositions[0]); + } + void OnUnitDeath(Unit* unit) override { if (!unit->IsCreature()) @@ -72,7 +113,76 @@ public: break; } } + + void OnCreatureCreate(Creature* creature) override + { + InstanceScript::OnCreatureCreate(creature); + + switch (creature->GetEntry()) + { + case NPC_NOZDORMU_DRAGON_SHRINES: + if (creature->GetAreaId() == AREA_ID_BRONZE_DRAGON_SHRINE) + AddObject(creature, DATA_NOZDORMU_BRONZE_DRAGON_SHRINE, true); + break; + default: + break; + } + } + + void OnCreatureRemove(Creature* creature) override + { + InstanceScript::OnCreatureRemove(creature); + + switch (creature->GetEntry()) + { + case NPC_NOZDORMU_DRAGON_SHRINES: + if (creature->GetAreaId() == AREA_ID_BRONZE_DRAGON_SHRINE) + AddObject(creature, DATA_NOZDORMU_BRONZE_DRAGON_SHRINE, false); + break; + default: + break; + } + } + + bool SetBossState(uint32 type, EncounterState state) override + { + if (!InstanceScript::SetBossState(type, state)) + return false; + + switch (type) + { + case DATA_MUROZOND: + if (state == FAIL) + _events.ScheduleEvent(EVENT_RESPAWN_MUROZOND, 30s); + else if (state == DONE) + instance->SpawnGroupSpawn(SPAWN_GROUP_ID_MUROZOND_CHEST); + break; + default: + break; + } + + return true; + } + + void Update(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_RESPAWN_MUROZOND: + instance->SummonCreature(BOSS_MUROZOND, MurozondSpawnPositions[1]); + break; + default: + break; + } + } + } + private: + EventMap _events; uint8 _killedInfiniteDragonkins; }; diff --git a/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp index 4669419d614..8dc472552cb 100644 --- a/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp +++ b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp @@ -47,7 +47,8 @@ void AddSC_boss_mal_ganis(); void AddSC_boss_meathook(); void AddSC_culling_of_stratholme(); void AddSC_instance_culling_of_stratholme(); -void AddSC_boss_murozond(); //CoT End Time +void AddSC_end_time(); //CoT End Time +void AddSC_boss_murozond(); void AddSC_instance_end_time(); void AddSC_instance_well_of_eternity(); //CoT Well of Eternity void AddSC_instance_hour_of_twilight(); //CoT Hour of Twilight @@ -180,7 +181,8 @@ void AddKalimdorScripts() AddSC_boss_meathook(); AddSC_culling_of_stratholme(); AddSC_instance_culling_of_stratholme(); - AddSC_boss_murozond(); //CoT End Time + AddSC_end_time(); //CoT End Time + AddSC_boss_murozond(); AddSC_instance_end_time(); AddSC_instance_well_of_eternity(); //CoT Well of Eternity AddSC_instance_hour_of_twilight(); //CoT Hour of Twilight