TrinityCore
instance_culling_of_stratholme.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
19#include "Creature.h"
20#include "CreatureAI.h"
21#include "EventMap.h"
22#include "GameObject.h"
23#include "GameTime.h"
24#include "InstanceScript.h"
25#include "Map.h"
26#include "Log.h"
27#include "Player.h"
28#include "ScriptMgr.h"
29#include "TemporarySummon.h"
30#include <array>
31#include <sstream>
32#include <unordered_map>
33#include <unordered_set>
34#include <vector>
35
36/*
37 * Culling of Stratholme encounters:
38 * 0 - Meathook
39 * 1 - Salramm the Fleshcrafter
40 * 2 - Chrono-Lord Epoch
41 * 3 - Mal'Ganis
42 * 4 - Infinite Corruptor (Heroic only)
43 */
44
46{
52};
53
55{
58 NPC_CHROMIE = 26527, // first chromie - we don't need the other two for anything
67 NPC_ACOLYTE = 27731,
70 NPC_MEATHOOK = 26529,
71 NPC_SALRAMM = 26530,
72
74 GO_EXIT_GATE = 191788,
75
77};
78
80{
87
91};
92
94{
106
108{
114
116{
121 WAVE_SALRAMM = 10
123
125{
129};
130
132{
133 { DATA_MEATHOOK, {{ 2002 }} },
134 { DATA_SALRAMM, {{ 2004 }} },
135 { DATA_EPOCH, {{ 2003 }} },
136 { DATA_MAL_GANIS, {{ 2005 }} }
137};
138
140{
141 switch (state)
142 {
143 case JUST_STARTED:
144 default:
145 return JUST_STARTED;
147 return CRATES_IN_PROGRESS;
148 case CRATES_DONE:
149 return CRATES_DONE;
150 case UTHER_TALK:
151 case PURGE_PENDING:
152 case PURGE_STARTING:
154 return PURGE_PENDING;
155 case WAVES_DONE:
157 case TOWN_HALL:
158 return TOWN_HALL_PENDING;
161 case GAUNTLET_PENDING:
163 return GAUNTLET_PENDING;
166 return GAUNTLET_COMPLETE;
167 case COMPLETE:
168 return COMPLETE;
169 }
170}
171
172static Position const CorruptorPos = { 2331.642f, 1273.273f, 132.9524f, 3.717551f };
173static Position const GuardianPos = { 2321.489f, 1268.383f, 132.8507f, 0.418879f };
174static Position const CorruptorRiftPos = { 2443.626f, 1280.450f, 133.0066f, 1.727876f };
175
176static std::array<std::array<uint32, MAX_SPAWNS_PER_WAVE>, NUM_SCOURGE_WAVES> const HeroicWaves =
177{
178 {
183 { { 0 } }, // wave 5, meathook (special)
188 { { 0 } } // wave 10, salramm (special)
189 }
190};
191
193{
195 std::array<Position, MAX_SPAWNS_PER_WAVE> SpawnPoints;
196};
197
198static const std::array<WaveLocation, WAVE_LOC_MAX - WAVE_LOC_MIN + 1> WaveLocations =
199{
200 {
201 { // King's Square
203 {
204 {
205 { 2131.474f, 1352.615f, 131.372f, 6.10960f },
206 { 2131.463f, 1357.127f, 131.587f, 5.95173f },
207 { 2129.795f, 1345.093f, 131.194f, 0.17905f },
208 { 2136.235f, 1347.894f, 131.628f, 0.20262f },
209 { 2138.219f, 1356.240f, 132.169f, 5.95173f },
210 { 2140.584f, 1351.624f, 132.142f, 6.08525f }
211 }
212 }
213 },
214 { // Market Row
216 {
217 {
218 { 2226.364f, 1331.808f, 127.0193f, 3.298672f },
219 { 2229.934f, 1329.146f, 127.057f, 3.24605f },
220 { 2225.028f, 1327.269f, 127.791f, 3.03792f },
221 { 2223.844f, 1335.282f, 127.749f, 3.47774f },
222 { 2222.192f, 1330.859f, 127.526f, 3.18793f },
223 { 2225.865f, 1331.029f, 127.007f, 3.18793f }
224 }
225 }
226 },
227 { // Festival Lane
229 {
230 {
231 { 2183.596f, 1238.823f, 136.551f, 2.16377f },
232 { 2181.420f, 1237.357f, 136.565f, 2.16377f },
233 { 2178.692f, 1237.446f, 136.694f, 1.99098f },
234 { 2184.980f, 1242.458f, 136.772f, 2.59181f },
235 { 2176.873f, 1240.463f, 136.420f, 2.10094f },
236 { 2181.523f, 1244.298f, 136.338f, 2.38997f }
237 }
238 }
239 },
240 { // Elders' Square
242 {
243 {
244 { 2267.003f, 1168.055f, 137.821f, 2.79050f },
245 { 2264.392f, 1162.145f, 137.910f, 2.39937f },
246 { 2262.785f, 1166.648f, 138.053f, 2.71353f },
247 { 2265.214f, 1170.771f, 137.972f, 2.80385f },
248 { 2259.745f, 1159.360f, 138.198f, 2.34047f },
249 { 2264.222f, 1171.708f, 138.047f, 2.82742f }
250 }
251 }
252 },
253 { // Town Hall
255 {
256 {
257 { 2351.656f, 1218.682f, 130.062f, 4.63383f },
258 { 2354.921f, 1218.425f, 130.280f, 4.63383f },
259 { 2347.516f, 1216.976f, 130.491f, 5.02496f },
260 { 2356.508f, 1216.656f, 130.445f, 4.29061f },
261 { 2346.674f, 1216.739f, 130.576f, 5.32341f },
262 { 2351.728f, 1214.561f, 130.255f, 4.61891f }
263 }
264 }
265 }
266 }
267};
268
270{
271 public:
272 instance_culling_of_stratholme() : InstanceMapScript("instance_culling_of_stratholme", 595) { }
273
275 {
277 _currentState(*this, "currentState", JUST_STARTED),
278 _infiniteGuardianTimeout(*this, "infiniteGuardianTimeout", 0),
279 _waveCount(0),
281 {
286
289 }
290
291 void AfterDataLoad() override
292 {
294 SetInstanceProgress(loadState, true);
295
298
299 time_t timediff = (_infiniteGuardianTimeout - GameTime::GetGameTime());
301 timediff = -1;
302
303 TC_LOG_DEBUG("scripts.cos", "instance_culling_of_stratholme::ReadSaveDataMore: Loaded with state {} and guardian timeout at {} minutes {} seconds from now", (uint32)loadState, timediff / MINUTE, timediff % MINUTE);
304 }
305
306 void SetData(uint32 type, uint32 data) override
307 {
308 switch (type)
309 {
310 case DATA_GM_OVERRIDE:
312 break;
313 case DATA_ARTHAS_DIED:
314 // Respawn everything, then regress to last stable state
317 break;
321 break;
323 if (uint32 missingCrates = MissingPlagueCrates())
325 else
327 break;
331 break;
335 break;
336 case DATA_START_WAVES:
339 break;
343 break;
347 break;
351 break;
355 break;
359 break;
360 default:
361 break;
362 }
363 }
364
365 void OnUnitDeath(Unit* unit) override
366 {
368 return;
369
370 // if this is a wave spawn...
371 auto it = _waveSpawns.find(unit->GetGUID());
372 if (it == _waveSpawns.end())
373 return;
374
375 // ... then erase it from our list, then check if there are no more spawns alive...
376 _waveSpawns.erase(it);
377 if (!_waveSpawns.empty())
378 return;
379
380 // ... and if there are none, the wave is done and we progress
381
382 // clear existing world markers
383 for (uint32 marker = WAVE_MARKER_MIN; marker <= WAVE_MARKER_MAX; ++marker)
385
386 // schedule next wave if applicable
389 else
391 }
392
393 void SetGuidData(uint32 type, ObjectGuid guid) override
394 {
395 switch (type)
396 {
397 case DATA_GM_RECALL:
398 {
400 Position const& target = arthas ? arthas->GetPosition() : GetArthasSnapbackFor(_currentState);
401
402 for (auto itr = instance->GetPlayers().begin(); itr != instance->GetPlayers().end(); ++itr)
403 {
404 if (Player* player = itr->GetSource())
405 if (player->GetGUID() == guid || !player->IsGameMaster())
406 {
407 player->CombatStop(true);
408 constexpr float offsetDist = 10.0f;
409 float myAngle = rand_norm() * static_cast<float>(2.0f * M_PI);
410 Position myTarget(target.GetPositionX() + std::sin(myAngle) * offsetDist, target.GetPositionY() + std::sin(myAngle) * offsetDist, target.GetPositionZ(), myAngle + M_PI);
411 player->NearTeleportTo(myTarget);
412 }
413 }
414 break;
415 }
416 case DATA_UTHER_START:
419 break;
420 case DATA_START_PURGE:
422 break;
425 break;
426 case DATA_TO_GAUNTLET:
428 break;
431 break;
434 break;
435 default:
436 break;
437 }
438 }
439
440 uint32 GetData(uint32 type) const override
441 {
442 if (type == DATA_INSTANCE_PROGRESS)
443 return _currentState;
444 return 0;
445 }
446
447 bool SetBossState(uint32 type, EncounterState state) override
448 {
449 if (type == DATA_INFINITE_CORRUPTOR && state == DONE)
450 {
454 }
455
456 if (!InstanceScript::SetBossState(type, state))
457 return false;
458
459 return true;
460 }
461
462 void Update(uint32 diff) override
463 {
464 events.Update(diff);
465 while (uint32 eventId = events.ExecuteEvent())
466 {
467 switch (eventId)
468 {
469 case EVENT_GUARDIAN_TICK: // regular ticks at :00 seconds on the timer, and then at 04:30 remaining for the chromie whisper
470 { // we do the whisper as a guardian tick because i don't want to duplicate the real-time code
471 if (!instance->IsHeroic())
472 return;
473
474 time_t secondsToGuardianDeath = _infiniteGuardianTimeout - GameTime::GetGameTime();
475 if (secondsToGuardianDeath <= 0)
476 {
480
481 if (Creature* corruptor = instance->GetCreature(_corruptorGUID))
482 {
483 corruptor->AI()->DoAction(-ACTION_CORRUPTOR_LEAVE);
484 if (Creature* guardian = instance->GetCreature(_guardianGUID))
485 Unit::Kill(corruptor, guardian); // @todo is there some spell for this?
486 }
488 }
489 else
490 {
491 time_t minutes = (secondsToGuardianDeath - 1) / MINUTE;
492 time_t seconds = ((secondsToGuardianDeath - 1) % MINUTE) + 1;
493
494 // chromie whispers - we only ever tick at :00 and :30, but give some leeway in case of slow tick rate
495 if (minutes == 24 && seconds >= 45)
496 if (Creature* chromie = instance->GetCreature(_chromieGUID))
497 chromie->AI()->Talk(CHROMIE_WHISPER_GUARDIAN_1);
498 if (minutes == 4 && seconds < 45)
499 if (Creature* chromie = instance->GetCreature(_chromieGUID))
500 chromie->AI()->Talk(CHROMIE_WHISPER_GUARDIAN_2);
501 if (minutes == 0)
502 if (Creature* chromie = instance->GetCreature(_chromieGUID))
503 chromie->AI()->Talk(CHROMIE_WHISPER_GUARDIAN_3);
504
505 // update the timer state
508 if (minutes == 4 && seconds > 30)
509 events.Repeat(Seconds(seconds - 30));
510 else
511 events.Repeat(Seconds(seconds));
512 }
513 break;
514 }
516 TC_LOG_DEBUG("scripts.cos", "instance_culling_of_stratholme::Update: Spawning new Arthas for instance...");
518 events.CancelEvent(EVENT_RESPAWN_ARTHAS); // make sure we don't have two scheduled
519 break;
523 crier->AI()->Talk(CRIER_SAY_CALL_TO_GATES);
524 break;
526 {
528 break;
529
530 ++_waveCount;
532
534 while (spawnLoc == _currentSpawnLoc) // don't allow repeats
535 spawnLoc = urand(WAVE_LOC_MIN, WAVE_LOC_MAX);
536 WaveLocation const& spawnLocation = WaveLocations[spawnLoc - WAVE_LOC_MIN];
537
538 switch (_waveCount)
539 {
540 case WAVE_MEATHOOK:
541 if (Creature* spawn = instance->SummonCreature(NPC_MEATHOOK, spawnLocation.SpawnPoints[0]))
542 _waveSpawns.insert(spawn->GetGUID());
543 break;
544 case WAVE_SALRAMM:
545 if (Creature* spawn = instance->SummonCreature(NPC_SALRAMM, spawnLocation.SpawnPoints[0]))
546 _waveSpawns.insert(spawn->GetGUID());
547 break;
548 default:
549 if (instance->IsHeroic())
550 {
551 for (uint32 i = 0; i < MAX_SPAWNS_PER_WAVE; ++i)
552 if (uint32 entry = HeroicWaves[_waveCount - 1][i])
553 if (Creature* spawn = instance->SummonCreature(entry, spawnLocation.SpawnPoints[i]))
554 _waveSpawns.insert(spawn->GetGUID());
555 }
556 else
557 {
558 for (uint32 i = 0; i <= 1; ++i)
559 if (Creature* spawn = instance->SummonCreature(NPC_DEVOURING_GHOUL, spawnLocation.SpawnPoints[i]))
560 _waveSpawns.insert(spawn->GetGUID());
561 }
562 break;
563 }
564
565 for (uint32 marker = WAVE_MARKER_MIN; marker <= WAVE_MARKER_MAX; ++marker)
567 DoUpdateWorldState(spawnLocation.WorldState, 1);
568
570 _currentSpawnLoc = spawnLoc;
571 break;
572 }
576 crier->AI()->Talk(_currentSpawnLoc);
577 break;
578 default:
579 break;
580 }
581 }
582 }
583
584 void OnCreatureCreate(Creature* creature) override
585 {
586 switch (creature->GetEntry())
587 {
588 case NPC_CHROMIE:
589 _chromieGUID = creature->GetGUID();
590 creature->setActive(true);
591 break;
593 _corruptorGUID = creature->GetGUID();
594 creature->setActive(true);
595 break;
597 _guardianGUID = creature->GetGUID();
598 creature->setActive(true);
599 break;
601 _genericBunnyGUID = creature->GetGUID();
602 creature->setActive(true);
603 break;
604 case NPC_CRATE_HELPER:
605 _plagueCrates.push_back(creature->GetGUID());
606 break;
607 case NPC_ARTHAS:
608 TC_LOG_DEBUG("scripts.cos", "instance_culling_of_stratholme::OnCreatureCreate: Arthas spawned at {}", creature->GetPosition().ToString());
609 _arthasGUID = creature->GetGUID();
610 creature->setActive(true);
611 break;
613 _crierGUID = creature->GetGUID();
614 creature->setActive(true);
615 break;
616 default:
617 break;
618 }
619 }
620
621 void OnGameObjectCreate(GameObject* object) override
622 {
623 switch (object->GetEntry())
624 {
626 _passageGUID = object->GetGUID();
627 object->setActive(true);
629 break;
630 default:
631 break;
632 }
633 }
634
636 {
637 if (_currentState != fromState)
638 return;
639 SetInstanceProgress(toState, false);
641 arthas->AI()->SetGUID(starterGUID, -startAction);
642 }
643
645 {
646 TC_LOG_DEBUG("scripts.cos", "instance_culling_of_stratholme::SetInstanceProgress: Instance progress is now 0x{:X}", (uint32)state);
647 _currentState = state;
648
649 /* Spawn group management */
655
656 /* Arthas management */
657 if (state > CRATES_DONE)
658 { // there might be an Arthas instance in the dungeon somewhere
659 // notify him of the change so he can adjust
661 if (arthas)
662 {
663 if (force)
664 {
665 arthas->DespawnOrUnsummon();
666 arthas = nullptr;
667 }
668 else
670 }
671
672 if (!arthas) // if there is currently no arthas, then we need to spawn one
674 }
675 else if (Creature* arthas = instance->GetCreature(_arthasGUID)) // there shouldn't be any Arthas around
676 arthas->DespawnOrUnsummon();
677
678 /* World state management */
679 // Plague crates
680 if (state == CRATES_IN_PROGRESS)
681 {
684 }
685 else if (state == CRATES_DONE)
686 {
689 }
690 else
691 {
694 }
695 // Scourge wave counter
696 if (state == WAVES_DONE)
698 else
700
701 // Hidden Passage status handling
703 passage->SetGoState(state <= GAUNTLET_TRANSITION ? GO_STATE_READY : GO_STATE_ACTIVE);
704
705 switch (state)
706 {
707 case CRATES_DONE:
709 bunny->CastSpell(nullptr, SPELL_CRATES_KILL_CREDIT, TRIGGERED_FULL_MASK);
711 break;
713 _waveCount = 0;
715 _waveSpawns.clear();
718 break;
719 default:
720 break;
721 }
722
723 if (force)
724 {
725 // Forced transitions are regressions (event failures) or GM overrides; respawn all dead creatures, and despawn any temporary summons
726 events.Reset();
728
729 // Reset respawn time on all permanent spawns, despawn all temporary spawns
730 // @todo dynspawn, this won't work
731 std::vector<Creature*> toDespawn;
732 std::unordered_map<ObjectGuid, Creature*> const& objects = instance->GetObjectsStore().GetElements()._elements._element;
733 for (std::unordered_map<ObjectGuid, Creature*>::const_iterator itr = objects.cbegin(); itr != objects.cend(); ++itr)
734 {
735 if (itr->second && (itr->second->isDead() || !itr->second->GetSpawnId() || itr->second->GetOriginalEntry() != itr->second->GetEntry()))
736 {
737 if (itr->second->getDeathState() == DEAD) // despawned, not corpse
738 itr->second->SetRespawnTime(1);
739 else
740 toDespawn.push_back(itr->second);
741 }
742 }
743
744 for (Creature* creature : toDespawn)
745 {
746 if (creature->GetSpawnId())
747 creature->SetRespawnTime(1);
748 creature->DespawnOrUnsummon(0s, 1s);
749 }
750
753 }
754 }
755
756 private:
757
759 {
760 uint32 returnValue = 0;
761 for (ObjectGuid const& crateHelperGUID : _plagueCrates)
762 if (Creature* crateHelper = instance->GetCreature(crateHelperGUID))
763 if (crateHelper->IsAlive() && !crateHelper->AI()->GetData(DATA_CRATE_REVEALED))
764 ++returnValue;
765 return returnValue;
766 }
767
769 {
771 {
777 }
778 }
779
780 void SetSpawnGroupState(COSInstanceEntries group, bool state, bool force)
781 {
782 if (state)
783 instance->SpawnGroupSpawn(group, true);
784 else if (force)
785 instance->SpawnGroupDespawn(group, true);
786 else
788 }
789
792 std::unordered_map<uint32, uint32> _currentWorldStates;
794
795 // Generic
800 std::vector<ObjectGuid> _plagueCrates;
801
804
805 // Scourge Waves
808 std::unordered_set<ObjectGuid> _waveSpawns;
809
810 // Gauntlet
812 };
813
815 {
817 }
818};
819
821{
823}
@ MINUTE
Definition: Common.h:29
#define M_PI
Definition: Common.h:115
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
EncounterState
@ FAIL
@ DONE
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
float rand_norm()
Definition: Random.cpp:75
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
@ GO_STATE_READY
@ GO_STATE_ACTIVE
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
@ DEAD
Definition: Unit.h:249
#define DataHeader
uint32 const EncounterCount
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
CreatureAI * AI() const
Definition: Creature.h:214
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void Repeat(Milliseconds time)
Definition: EventMap.cpp:63
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
void CancelEvent(uint32 eventId)
Definition: EventMap.cpp:131
void RescheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:52
void Reset()
Definition: EventMap.cpp:21
void SetBossNumber(uint32 number)
virtual bool SetBossState(uint32 id, EncounterState state)
void LoadDungeonEncounterData(T const &encounters)
void DoUpdateWorldState(int32 worldStateId, int32 value)
InstanceMap * instance
EncounterState GetBossState(uint32 id) const
void LoadDoorData(DoorData const *data)
void SetHeaders(std::string const &dataHeaders)
iterator end()
Definition: MapRefManager.h:35
iterator begin()
Definition: MapRefManager.h:34
void SetSpawnGroupInactive(uint32 groupId)
Definition: Map.h:713
MapStoredObjectTypesContainer & GetObjectsStore()
Definition: Map.h:422
bool SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn=false, bool force=false, std::vector< WorldObject * > *spawnedObjects=nullptr)
Definition: Map.cpp:2348
void DeleteRespawnTimes()
Definition: Map.h:493
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, Milliseconds duration=0ms, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty, SmoothPhasingInfo const *smoothPhasingInfo=nullptr)
Definition: Object.cpp:1836
GameObject * GetGameObject(ObjectGuid const &guid)
Definition: Map.cpp:3489
bool SpawnGroupDespawn(uint32 groupId, bool deleteRespawnTimes=false, size_t *count=nullptr)
Definition: Map.cpp:2437
bool IsHeroic() const
Definition: Map.cpp:3282
PlayerList const & GetPlayers() const
Definition: Map.h:367
Creature * GetCreature(ObjectGuid const &guid)
Definition: Map.cpp:3479
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
ContainerUnorderedMap< OBJECT_TYPES, KEY_TYPE > & GetElements()
virtual void DoAction(int32)
Definition: UnitAI.h:72
Definition: Unit.h:627
static void Kill(Unit *attacker, Unit *victim, bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition: Unit.cpp:10591
void setActive(bool isActiveObject)
Definition: Object.cpp:922
InstanceScript * GetInstanceScript(InstanceMap *map) const override
Position const & GetArthasSnapbackFor(COSProgressStates state)
@ DATA_START_MALGANIS
@ DATA_SKIP_TO_PURGE
@ DATA_INSTANCE_PROGRESS
@ DATA_ARTHAS_DIED
@ DATA_GAUNTLET_DONE
@ DATA_MALGANIS_DONE
@ DATA_TO_GAUNTLET
@ DATA_START_GAUNTLET
@ DATA_START_WAVES
@ DATA_GM_OVERRIDE
@ DATA_UTHER_START
@ DATA_CRATES_START
@ DATA_TOWN_HALL_DONE
@ DATA_REACH_TOWN_HALL
@ DATA_START_TOWN_HALL
@ DATA_MEATHOOK
@ DATA_GM_RECALL
@ DATA_GAUNTLET_REACHED
@ DATA_START_PURGE
@ DATA_MAL_GANIS
@ DATA_INFINITE_CORRUPTOR
@ DATA_CRATE_REVEALED
@ DATA_UTHER_FINISHED
@ DATA_SALRAMM
COSInstanceActions
@ ACTION_START_RP_EVENT2
@ ACTION_CORRUPTOR_LEAVE
@ ACTION_PROGRESS_UPDATE
@ ACTION_START_RP_EVENT3
@ ACTION_START_RP_EVENT4_2
@ ACTION_START_RP_EVENT4_1
@ ACTION_START_RP_EVENT5
COSProgressStates
@ UTHER_TALK
@ JUST_STARTED
@ TOWN_HALL_COMPLETE
@ CRATES_IN_PROGRESS
@ GAUNTLET_IN_PROGRESS
@ TOWN_HALL_PENDING
@ CRATES_DONE
@ GAUNTLET_PENDING
@ WAVES_DONE
@ MALGANIS_IN_PROGRESS
@ WAVES_IN_PROGRESS
@ GAUNTLET_TRANSITION
@ PURGE_PENDING
@ PURGE_STARTING
@ GAUNTLET_COMPLETE
COSInstanceEntries
@ SPAWNGRP_UNDEAD_TRASH
@ GO_HIDDEN_PASSAGE
@ SPAWNGRP_RESIDENTS
@ SPAWNGRP_GAUNTLET_TRASH
@ SPAWNGRP_CHROMIE_MID
@ SPAWNGRP_CRATE_HELPERS
static Position const GuardianPos
static std::array< std::array< uint32, MAX_SPAWNS_PER_WAVE >, NUM_SCOURGE_WAVES > const HeroicWaves
DoorData const doorData[]
static const std::array< WaveLocation, WAVE_LOC_MAX - WAVE_LOC_MIN+1 > WaveLocations
static Position const CorruptorPos
COSProgressStates GetStableStateFor(COSProgressStates const state)
void AddSC_instance_culling_of_stratholme()
DungeonEncounterData const encounters[]
static Position const CorruptorRiftPos
time_t GetGameTime()
Definition: GameTime.cpp:44
std::unordered_map< KEY_TYPE, OBJECT * > _element
Definition: TypeContainer.h:57
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr float GetPositionZ() const
Definition: Position.h:78
COSWorldStates const WorldState
std::array< Position, MAX_SPAWNS_PER_WAVE > SpawnPoints
void InitiateArthasEvent(COSProgressStates fromState, COSProgressStates toState, COSInstanceActions startAction, ObjectGuid starterGUID)