Scripts/ScarletMonastery: Headless Horseman Rewrite (#25614)

This commit is contained in:
Keader
2020-10-26 14:04:36 -03:00
committed by GitHub
parent 28a1132211
commit a93abcf803
5 changed files with 1129 additions and 848 deletions

View File

@@ -17,25 +17,32 @@
#include "scarlet_monastery.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "EventMap.h"
#include "GameObject.h"
#include "InstanceScript.h"
#include "Map.h"
#include "ScriptMgr.h"
#include "TemporarySummon.h"
ObjectData const creatureData[] =
{
{ NPC_HEAD, DATA_HEAD },
{ NPC_HORSEMAN, DATA_HORSEMAN },
{ NPC_MOGRAINE, DATA_MOGRAINE },
{ NPC_VORREL, DATA_VORREL },
{ NPC_WHITEMANE, DATA_WHITEMANE },
{ 0, 0 } // END
{ NPC_HEADLESS_HORSEMAN_HEAD, DATA_HORSEMAN_HEAD },
{ NPC_HEADLESS_HORSEMAN, DATA_HEADLESS_HORSEMAN },
{ NPC_FLAME_BUNNY, DATA_FLAME_BUNNY },
{ NPC_EARTH_BUNNY, DATA_EARTH_BUNNY },
{ NPC_SIR_THOMAS, DATA_THOMAS },
{ NPC_MOGRAINE, DATA_MOGRAINE },
{ NPC_VORREL, DATA_VORREL },
{ NPC_WHITEMANE, DATA_WHITEMANE },
{ 0, 0 } // END
};
ObjectData const gameObjectData[] =
{
{ GO_PUMPKIN_SHRINE, DATA_PUMPKIN_SHRINE },
{ GO_HIGH_INQUISITORS_DOOR, DATA_HIGH_INQUISITORS_DOOR },
{ GO_LOOSELY_TURNED_SOIL, DATA_LOOSELY_TURNED_SOIL },
{ 0, 0 } // END
};
@@ -51,52 +58,92 @@ class instance_scarlet_monastery : public InstanceMapScript
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadObjectData(creatureData, gameObjectData);
_horsemanState = NOT_STARTED;
}
void OnCreatureCreate(Creature* creature) override
void HandleStartEvent()
{
switch (creature->GetEntry())
{
case NPC_PUMPKIN:
HorsemanAdds.insert(creature->GetGUID());
break;
default:
break;
}
_horsemanState = IN_PROGRESS;
for (uint32 data : {DATA_PUMPKIN_SHRINE, DATA_LOOSELY_TURNED_SOIL})
if (GameObject* gob = GetGameObject(data))
gob->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
InstanceScript::OnCreatureCreate(creature);
instance->SummonCreature(NPC_HEADLESS_HORSEMAN_HEAD, HeadlessHorsemanHeadSpawnPosition);
instance->SummonCreature(NPC_FLAME_BUNNY, BunnySpawnPosition);
instance->SummonCreature(NPC_EARTH_BUNNY, EarthBunnySpawnPosition);
_events.ScheduleEvent(EVENT_ACTIVE_EARTH_EXPLOSION, 1s + 500ms);
_events.ScheduleEvent(EVENT_SPAWN_HEADLESS_HORSEMAN, 3s);
_events.ScheduleEvent(EVENT_DESPAWN_OBJECTS, 10s);
if (Creature* thomas = GetCreature(DATA_THOMAS))
thomas->DespawnOrUnsummon();
}
bool SetBossState(uint32 type, EncounterState state) override
void SetData(uint32 type, uint32 data) override
{
if (!InstanceScript::SetBossState(type, state))
return false;
switch (type)
{
case DATA_HORSEMAN_EVENT:
if (state == DONE || state == FAIL || state == NOT_STARTED)
{
for (ObjectGuid const& guid : HorsemanAdds)
{
Creature* add = instance->GetCreature(guid);
if (add)
add->DespawnOrUnsummon();
}
HorsemanAdds.clear();
if (state == DONE)
HandleGameObject(ObjectGuid::Empty, false, GetGameObject(DATA_PUMPKIN_SHRINE));
}
case DATA_START_HORSEMAN_EVENT:
if (_horsemanState != IN_PROGRESS)
HandleStartEvent();
break;
case DATA_HORSEMAN_EVENT_STATE:
_horsemanState = data;
break;
case DATA_PREPARE_RESET:
_horsemanState = NOT_STARTED;
for (uint32 data : {DATA_FLAME_BUNNY, DATA_EARTH_BUNNY})
if (Creature* bunny = GetCreature(data))
bunny->DespawnOrUnsummon();
break;
default:
break;
}
return true;
}
protected:
GuidUnorderedSet HorsemanAdds;
uint32 GetData(uint32 type) const override
{
switch (type)
{
case DATA_HORSEMAN_EVENT_STATE:
return _horsemanState;
default:
return 0;
}
}
void Update(uint32 diff) override
{
if (_events.Empty())
return;
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ACTIVE_EARTH_EXPLOSION:
if (Creature* earthBunny = GetCreature(DATA_EARTH_BUNNY))
earthBunny->CastSpell(earthBunny, SPELL_EARTH_EXPLOSION);
break;
case EVENT_SPAWN_HEADLESS_HORSEMAN:
if (TempSummon* horseman = instance->SummonCreature(NPC_HEADLESS_HORSEMAN, HeadlessHorsemanSpawnPosition))
horseman->AI()->DoAction(ACTION_HORSEMAN_EVENT_START);
break;
case EVENT_DESPAWN_OBJECTS:
for (uint32 data : {DATA_PUMPKIN_SHRINE, DATA_LOOSELY_TURNED_SOIL})
if (GameObject* gob = GetGameObject(data))
gob->RemoveFromWorld();
break;
default:
break;
}
}
}
private:
EventMap _events;
uint32 _horsemanState;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override

View File

@@ -19,12 +19,18 @@
#define SCARLET_M_
#include "CreatureAIImpl.h"
#include "Position.h"
#define SMScriptName "instance_scarlet_monastery"
#define DataHeader "SM"
uint32 const EncounterCount = 10;
Position const BunnySpawnPosition = { 1776.27f, 1348.74f, 19.20f };
Position const EarthBunnySpawnPosition = { 1765.28f, 1347.46f, 18.55f, 6.17f };
Position const HeadlessHorsemanSpawnPosition = { 1765.00f, 1347.00f, 15.00f };
Position const HeadlessHorsemanHeadSpawnPosition = { 1788.54f, 1348.05f, 18.88f }; // Guessed
enum SMDataTypes
{
DATA_INTERROGATOR_VISHAS = 0,
@@ -37,32 +43,52 @@ enum SMDataTypes
DATA_AZSHIR,
DATA_SCORN,
DATA_HORSEMAN_EVENT, // Last defined encounter
DATA_HEAD,
DATA_HORSEMAN,
DATA_MOGRAINE,
DATA_VORREL,
DATA_WHITEMANE,
// Headless Horseman
DATA_HORSEMAN_HEAD,
DATA_HEADLESS_HORSEMAN,
DATA_PUMPKIN_SHRINE,
DATA_HIGH_INQUISITORS_DOOR,
DATA_LOOSELY_TURNED_SOIL,
DATA_START_HORSEMAN_EVENT,
DATA_FLAME_BUNNY,
DATA_EARTH_BUNNY,
DATA_HORSEMAN_EVENT_STATE,
DATA_PREPARE_RESET,
DATA_THOMAS
};
enum SMCreatureIds
{
NPC_MOGRAINE = 3976,
NPC_WHITEMANE = 3977,
NPC_VORREL = 3981,
NPC_HORSEMAN = 23682,
NPC_HEAD = 23775,
NPC_PUMPKIN = 23694
NPC_MOGRAINE = 3976,
NPC_WHITEMANE = 3977,
NPC_VORREL = 3981,
NPC_HEADLESS_HORSEMAN = 23682,
NPC_HEADLESS_HORSEMAN_HEAD = 23775,
NPC_PULSING_PUMPKIN = 23694,
NPC_PUMPKIN_FIEND = 23545,
NPC_FLAME_BUNNY = 23686,
NPC_EARTH_BUNNY = 23758,
NPC_SIR_THOMAS = 23904
};
enum SMCreatureMisc
{
SPELL_EARTH_EXPLOSION = 42373,
EVENT_ACTIVE_EARTH_EXPLOSION = 1,
EVENT_SPAWN_HEADLESS_HORSEMAN = 2,
EVENT_DESPAWN_OBJECTS = 3,
ACTION_HORSEMAN_EVENT_START = 101
};
enum SMGameObjectIds
{
GO_HIGH_INQUISITORS_DOOR = 104600,
GO_PUMPKIN_SHRINE = 186267
GO_PUMPKIN_SHRINE = 186267,
GO_LOOSELY_TURNED_SOIL = 186314
};
template <class AI, class T>