Scripts/ET:

* moved Nozdormu's script to a seperate file
* scripted Moruzond's respawn mechanism
This commit is contained in:
Ovahlord
2020-08-04 21:22:38 +02:00
parent f42d242996
commit 1fbd50db16
6 changed files with 323 additions and 97 deletions

View File

@@ -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

View File

@@ -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<Milliseconds, 4> DistortionBombIntervals =
@@ -145,17 +129,23 @@ std::array<Milliseconds, 4> 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);

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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);
}

View File

@@ -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

View File

@@ -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 <array>
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<Position const, 2> 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;
};

View File

@@ -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