TrinityCore
Loading...
Searching...
No Matches
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 <unordered_map>
32#include <unordered_set>
33#include <vector>
34
35/*
36 * Culling of Stratholme encounters:
37 * 0 - Meathook
38 * 1 - Salramm the Fleshcrafter
39 * 2 - Chrono-Lord Epoch
40 * 3 - Mal'Ganis
41 * 4 - Infinite Corruptor (Heroic only)
42 */
43
52
54{
57 NPC_CHROMIE = 26527, // first chromie - we don't need the other two for anything
66 NPC_ACOLYTE = 27731,
69 NPC_MEATHOOK = 26529,
70 NPC_SALRAMM = 26530,
71
73 GO_EXIT_GATE = 191788,
74
76};
77
91
105
113
122
128
130{
131 { DATA_MEATHOOK, {{ 2002 }} },
132 { DATA_SALRAMM, {{ 2004 }} },
133 { DATA_EPOCH, {{ 2003 }} },
134 { DATA_MAL_GANIS, {{ 2005 }} }
135};
136
138{
139 switch (state)
140 {
141 case JUST_STARTED:
142 default:
143 return JUST_STARTED;
145 return CRATES_IN_PROGRESS;
146 case CRATES_DONE:
147 return CRATES_DONE;
148 case UTHER_TALK:
149 case PURGE_PENDING:
150 case PURGE_STARTING:
152 return PURGE_PENDING;
153 case WAVES_DONE:
155 case TOWN_HALL:
156 return TOWN_HALL_PENDING;
159 case GAUNTLET_PENDING:
161 return GAUNTLET_PENDING;
164 return GAUNTLET_COMPLETE;
165 case COMPLETE:
166 return COMPLETE;
167 }
168}
169
170static constexpr Position CorruptorPos = { 2331.642f, 1273.273f, 132.9524f, 3.717551f };
171static constexpr Position GuardianPos = { 2321.489f, 1268.383f, 132.8507f, 0.418879f };
172static constexpr Position CorruptorRiftPos = { 2443.626f, 1280.450f, 133.0066f, 1.727876f };
173
174static constexpr std::array<std::array<uint32, MAX_SPAWNS_PER_WAVE>, NUM_SCOURGE_WAVES> HeroicWaves =
175{
176 {
181 { { 0 } }, // wave 5, meathook (special)
186 { { 0 } } // wave 10, salramm (special)
187 }
188};
189
191{
193 std::array<Position, MAX_SPAWNS_PER_WAVE> SpawnPoints;
194};
195
196static constexpr std::array<WaveLocation, WAVE_LOC_MAX - WAVE_LOC_MIN + 1> WaveLocations =
197{
198 {
199 { // King's Square
201 {
202 {
203 { 2131.474f, 1352.615f, 131.372f, 6.10960f },
204 { 2131.463f, 1357.127f, 131.587f, 5.95173f },
205 { 2129.795f, 1345.093f, 131.194f, 0.17905f },
206 { 2136.235f, 1347.894f, 131.628f, 0.20262f },
207 { 2138.219f, 1356.240f, 132.169f, 5.95173f },
208 { 2140.584f, 1351.624f, 132.142f, 6.08525f }
209 }
210 }
211 },
212 { // Market Row
214 {
215 {
216 { 2226.364f, 1331.808f, 127.0193f, 3.298672f },
217 { 2229.934f, 1329.146f, 127.057f, 3.24605f },
218 { 2225.028f, 1327.269f, 127.791f, 3.03792f },
219 { 2223.844f, 1335.282f, 127.749f, 3.47774f },
220 { 2222.192f, 1330.859f, 127.526f, 3.18793f },
221 { 2225.865f, 1331.029f, 127.007f, 3.18793f }
222 }
223 }
224 },
225 { // Festival Lane
227 {
228 {
229 { 2183.596f, 1238.823f, 136.551f, 2.16377f },
230 { 2181.420f, 1237.357f, 136.565f, 2.16377f },
231 { 2178.692f, 1237.446f, 136.694f, 1.99098f },
232 { 2184.980f, 1242.458f, 136.772f, 2.59181f },
233 { 2176.873f, 1240.463f, 136.420f, 2.10094f },
234 { 2181.523f, 1244.298f, 136.338f, 2.38997f }
235 }
236 }
237 },
238 { // Elders' Square
240 {
241 {
242 { 2267.003f, 1168.055f, 137.821f, 2.79050f },
243 { 2264.392f, 1162.145f, 137.910f, 2.39937f },
244 { 2262.785f, 1166.648f, 138.053f, 2.71353f },
245 { 2265.214f, 1170.771f, 137.972f, 2.80385f },
246 { 2259.745f, 1159.360f, 138.198f, 2.34047f },
247 { 2264.222f, 1171.708f, 138.047f, 2.82742f }
248 }
249 }
250 },
251 { // Town Hall
253 {
254 {
255 { 2351.656f, 1218.682f, 130.062f, 4.63383f },
256 { 2354.921f, 1218.425f, 130.280f, 4.63383f },
257 { 2347.516f, 1216.976f, 130.491f, 5.02496f },
258 { 2356.508f, 1216.656f, 130.445f, 4.29061f },
259 { 2346.674f, 1216.739f, 130.576f, 5.32341f },
260 { 2351.728f, 1214.561f, 130.255f, 4.61891f }
261 }
262 }
263 }
264 }
265};
266
268{
269 public:
270 instance_culling_of_stratholme() : InstanceMapScript("instance_culling_of_stratholme", 595) { }
271
273 {
288
289 void AfterDataLoad() override
290 {
292 SetInstanceProgress(loadState, true);
293
296
297 time_t timediff = (_infiniteGuardianTimeout - GameTime::GetGameTime());
299 timediff = -1;
300
301 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);
302 }
303
304 void SetData(uint32 type, uint32 data) override
305 {
306 switch (type)
307 {
308 case DATA_GM_OVERRIDE:
310 break;
311 case DATA_ARTHAS_DIED:
312 // Respawn everything, then regress to last stable state
315 break;
319 break;
321 if (uint32 missingCrates = MissingPlagueCrates())
323 else
325 break;
329 break;
333 break;
334 case DATA_START_WAVES:
337 break;
341 break;
345 break;
349 break;
353 break;
357 break;
358 default:
359 break;
360 }
361 }
362
363 void OnUnitDeath(Unit* unit) override
364 {
366 return;
367
368 // if this is a wave spawn...
369 auto it = _waveSpawns.find(unit->GetGUID());
370 if (it == _waveSpawns.end())
371 return;
372
373 // ... then erase it from our list, then check if there are no more spawns alive...
374 _waveSpawns.erase(it);
375 if (!_waveSpawns.empty())
376 return;
377
378 // ... and if there are none, the wave is done and we progress
379
380 // clear existing world markers
381 for (uint32 marker = WAVE_MARKER_MIN; marker <= WAVE_MARKER_MAX; ++marker)
383
384 // schedule next wave if applicable
387 else
389 }
390
391 void SetGuidData(uint32 type, ObjectGuid guid) override
392 {
393 switch (type)
394 {
395 case DATA_GM_RECALL:
396 {
398 Position const& target = arthas ? arthas->GetPosition() : GetArthasSnapbackFor(_currentState);
399
400 for (auto itr = instance->GetPlayers().begin(); itr != instance->GetPlayers().end(); ++itr)
401 {
402 if (Player* player = itr->GetSource())
403 if (player->GetGUID() == guid || !player->IsGameMaster())
404 {
405 player->CombatStop(true);
406 player->NearTeleportTo(player->GetRandomPoint(target, 10.0f));
407 }
408 }
409 break;
410 }
411 case DATA_UTHER_START:
414 break;
415 case DATA_START_PURGE:
417 break;
420 break;
421 case DATA_TO_GAUNTLET:
423 break;
426 break;
429 break;
430 default:
431 break;
432 }
433 }
434
435 uint32 GetData(uint32 type) const override
436 {
437 if (type == DATA_INSTANCE_PROGRESS)
438 return _currentState;
439 return 0;
440 }
441
442 bool SetBossState(uint32 type, EncounterState state) override
443 {
444 if (type == DATA_INFINITE_CORRUPTOR && state == DONE)
445 {
449 }
450
451 if (!InstanceScript::SetBossState(type, state))
452 return false;
453
454 return true;
455 }
456
457 void Update(uint32 diff) override
458 {
459 events.Update(diff);
460 while (uint32 eventId = events.ExecuteEvent())
461 {
462 switch (eventId)
463 {
464 case EVENT_GUARDIAN_TICK: // regular ticks at :00 seconds on the timer, and then at 04:30 remaining for the chromie whisper
465 { // we do the whisper as a guardian tick because i don't want to duplicate the real-time code
466 if (!instance->IsHeroic())
467 return;
468
469 time_t secondsToGuardianDeath = _infiniteGuardianTimeout - GameTime::GetGameTime();
470 if (secondsToGuardianDeath <= 0)
471 {
475
476 if (Creature* corruptor = instance->GetCreature(_corruptorGUID))
477 {
478 corruptor->AI()->DoAction(-ACTION_CORRUPTOR_LEAVE);
479 if (Creature* guardian = instance->GetCreature(_guardianGUID))
480 Unit::Kill(corruptor, guardian); // @todo is there some spell for this?
481 }
483 }
484 else
485 {
486 time_t minutes = (secondsToGuardianDeath - 1) / MINUTE;
487 time_t seconds = ((secondsToGuardianDeath - 1) % MINUTE) + 1;
488
489 // chromie whispers - we only ever tick at :00 and :30, but give some leeway in case of slow tick rate
490 if (minutes == 24 && seconds >= 45)
491 if (Creature* chromie = instance->GetCreature(_chromieGUID))
492 chromie->AI()->Talk(CHROMIE_WHISPER_GUARDIAN_1);
493 if (minutes == 4 && seconds < 45)
494 if (Creature* chromie = instance->GetCreature(_chromieGUID))
495 chromie->AI()->Talk(CHROMIE_WHISPER_GUARDIAN_2);
496 if (minutes == 0)
497 if (Creature* chromie = instance->GetCreature(_chromieGUID))
498 chromie->AI()->Talk(CHROMIE_WHISPER_GUARDIAN_3);
499
500 // update the timer state
503 if (minutes == 4 && seconds > 30)
504 events.Repeat(Seconds(seconds - 30));
505 else
506 events.Repeat(Seconds(seconds));
507 }
508 break;
509 }
511 TC_LOG_DEBUG("scripts.cos", "instance_culling_of_stratholme::Update: Spawning new Arthas for instance...");
513 events.CancelEvent(EVENT_RESPAWN_ARTHAS); // make sure we don't have two scheduled
514 break;
518 crier->AI()->Talk(CRIER_SAY_CALL_TO_GATES);
519 break;
521 {
523 break;
524
525 ++_waveCount;
527
529 while (spawnLoc == _currentSpawnLoc) // don't allow repeats
530 spawnLoc = urand(WAVE_LOC_MIN, WAVE_LOC_MAX);
531 WaveLocation const& spawnLocation = WaveLocations[spawnLoc - WAVE_LOC_MIN];
532
533 switch (_waveCount)
534 {
535 case WAVE_MEATHOOK:
536 if (Creature* spawn = instance->SummonCreature(NPC_MEATHOOK, spawnLocation.SpawnPoints[0]))
537 _waveSpawns.insert(spawn->GetGUID());
538 break;
539 case WAVE_SALRAMM:
540 if (Creature* spawn = instance->SummonCreature(NPC_SALRAMM, spawnLocation.SpawnPoints[0]))
541 _waveSpawns.insert(spawn->GetGUID());
542 break;
543 default:
544 if (instance->IsHeroic())
545 {
546 for (uint32 i = 0; i < MAX_SPAWNS_PER_WAVE; ++i)
547 if (uint32 entry = HeroicWaves[_waveCount - 1][i])
548 if (Creature* spawn = instance->SummonCreature(entry, spawnLocation.SpawnPoints[i]))
549 _waveSpawns.insert(spawn->GetGUID());
550 }
551 else
552 {
553 for (uint32 i = 0; i <= 1; ++i)
554 if (Creature* spawn = instance->SummonCreature(NPC_DEVOURING_GHOUL, spawnLocation.SpawnPoints[i]))
555 _waveSpawns.insert(spawn->GetGUID());
556 }
557 break;
558 }
559
560 for (uint32 marker = WAVE_MARKER_MIN; marker <= WAVE_MARKER_MAX; ++marker)
562 DoUpdateWorldState(spawnLocation.WorldState, 1);
563
565 _currentSpawnLoc = spawnLoc;
566 break;
567 }
571 crier->AI()->Talk(_currentSpawnLoc);
572 break;
573 default:
574 break;
575 }
576 }
577 }
578
579 void OnCreatureCreate(Creature* creature) override
580 {
581 switch (creature->GetEntry())
582 {
583 case NPC_CHROMIE:
584 _chromieGUID = creature->GetGUID();
585 creature->setActive(true);
586 break;
588 _corruptorGUID = creature->GetGUID();
589 creature->setActive(true);
590 break;
592 _guardianGUID = creature->GetGUID();
593 creature->setActive(true);
594 break;
596 _genericBunnyGUID = creature->GetGUID();
597 creature->setActive(true);
598 break;
599 case NPC_CRATE_HELPER:
600 _plagueCrates.push_back(creature->GetGUID());
601 break;
602 case NPC_ARTHAS:
603 TC_LOG_DEBUG("scripts.cos", "instance_culling_of_stratholme::OnCreatureCreate: Arthas spawned at {}", creature->GetPosition());
604 _arthasGUID = creature->GetGUID();
605 creature->setActive(true);
606 break;
608 _crierGUID = creature->GetGUID();
609 creature->setActive(true);
610 break;
611 default:
612 break;
613 }
614 }
615
616 void OnGameObjectCreate(GameObject* object) override
617 {
618 switch (object->GetEntry())
619 {
621 _passageGUID = object->GetGUID();
622 object->setActive(true);
624 break;
625 default:
626 break;
627 }
628 }
629
631 {
632 if (_currentState != fromState)
633 return;
634 SetInstanceProgress(toState, false);
636 arthas->AI()->SetGUID(starterGUID, -startAction);
637 }
638
640 {
641 TC_LOG_DEBUG("scripts.cos", "instance_culling_of_stratholme::SetInstanceProgress: Instance progress is now 0x{:X}", (uint32)state);
642 _currentState = state;
643
644 /* Spawn group management */
650
651 /* Arthas management */
652 if (state > CRATES_DONE)
653 { // there might be an Arthas instance in the dungeon somewhere
654 // notify him of the change so he can adjust
656 if (arthas)
657 {
658 if (force)
659 {
660 arthas->DespawnOrUnsummon();
661 arthas = nullptr;
662 }
663 else
665 }
666
667 if (!arthas) // if there is currently no arthas, then we need to spawn one
669 }
670 else if (Creature* arthas = instance->GetCreature(_arthasGUID)) // there shouldn't be any Arthas around
671 arthas->DespawnOrUnsummon();
672
673 /* World state management */
674 // Plague crates
675 if (state == CRATES_IN_PROGRESS)
676 {
679 }
680 else if (state == CRATES_DONE)
681 {
684 }
685 else
686 {
689 }
690 // Scourge wave counter
691 if (state == WAVES_DONE)
693 else
695
696 // Hidden Passage status handling
698 passage->SetGoState(state <= GAUNTLET_TRANSITION ? GO_STATE_READY : GO_STATE_ACTIVE);
699
700 switch (state)
701 {
702 case CRATES_DONE:
704 bunny->CastSpell(nullptr, SPELL_CRATES_KILL_CREDIT, TRIGGERED_FULL_MASK);
706 break;
708 _waveCount = 0;
710 _waveSpawns.clear();
713 break;
714 default:
715 break;
716 }
717
718 if (force)
719 {
720 // Forced transitions are regressions (event failures) or GM overrides; respawn all dead creatures, and despawn any temporary summons
721 events.Reset();
723
724 // Reset respawn time on all permanent spawns, despawn all temporary spawns
725 // @todo dynspawn, this won't work
726 std::vector<Creature*> toDespawn;
727 std::unordered_map<ObjectGuid, Creature*> const& objects = instance->GetObjectsStore().Data.Head;
728 for (std::unordered_map<ObjectGuid, Creature*>::const_iterator itr = objects.cbegin(); itr != objects.cend(); ++itr)
729 {
730 if (itr->second && (itr->second->isDead() || !itr->second->GetSpawnId() || itr->second->GetOriginalEntry() != itr->second->GetEntry()))
731 {
732 if (itr->second->getDeathState() == DEAD) // despawned, not corpse
733 itr->second->SetRespawnTime(1);
734 else
735 toDespawn.push_back(itr->second);
736 }
737 }
738
739 for (Creature* creature : toDespawn)
740 {
741 if (creature->GetSpawnId())
742 creature->SetRespawnTime(1);
743 creature->DespawnOrUnsummon(0s, 1s);
744 }
745
748 }
749 }
750
751 private:
752
754 {
755 uint32 returnValue = 0;
756 for (ObjectGuid const& crateHelperGUID : _plagueCrates)
757 if (Creature* crateHelper = instance->GetCreature(crateHelperGUID))
758 if (crateHelper->IsAlive() && !crateHelper->AI()->GetData(DATA_CRATE_REVEALED))
759 ++returnValue;
760 return returnValue;
761 }
762
774
775 void SetSpawnGroupState(COSInstanceEntries group, bool state, bool force)
776 {
777 if (state)
778 instance->SpawnGroupSpawn(group, true);
779 else if (force)
780 instance->SpawnGroupDespawn(group, true);
781 else
783 }
784
787 std::unordered_map<uint32, uint32> _currentWorldStates;
789
790 // Generic
795 std::vector<ObjectGuid> _plagueCrates;
796
799
800 // Scourge Waves
803 std::unordered_set<ObjectGuid> _waveSpawns;
804
805 // Gauntlet
807 };
808
813};
814
@ MINUTE
Definition Common.h:32
uint8_t uint8
Definition Define.h:156
uint32_t uint32
Definition Define.h:154
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
EncounterState
@ FAIL
@ DONE
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
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.
@ DEAD
Definition Unit.h:255
#define DataHeader
uint32 const EncounterCount
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
CreatureAI * AI() const
Definition Creature.h:228
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void Update(uint32 time)
Definition EventMap.h:61
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:40
void CancelEvent(uint32 eventId)
Definition EventMap.cpp:135
void RescheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:56
void Reset()
Definition EventMap.cpp:25
void SetBossNumber(uint32 number)
virtual bool SetBossState(uint32 id, EncounterState state)
void DoUpdateWorldState(int32 worldStateId, int32 value)
InstanceMap * instance
void SetHeaders(std::string_view dataHeaders)
void LoadDungeonEncounterData(std::span< DungeonEncounterData const > encounters)
EncounterState GetBossState(uint32 id) const
void LoadDoorData(std::span< DoorData const > data)
void SetSpawnGroupInactive(uint32 groupId)
Definition Map.h:753
MapStoredObjectTypesContainer & GetObjectsStore()
Definition Map.h:458
bool SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn=false, bool force=false, std::vector< WorldObject * > *spawnedObjects=nullptr)
Definition Map.cpp:2350
void DeleteRespawnTimes()
Definition Map.h:532
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:1186
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:3552
bool SpawnGroupDespawn(uint32 groupId, bool deleteRespawnTimes=false, size_t *count=nullptr)
Definition Map.cpp:2439
bool IsHeroic() const
Definition Map.cpp:3311
PlayerList const & GetPlayers() const
Definition Map.h:403
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:3542
static ObjectGuid const Empty
Definition ObjectGuid.h:314
uint32 GetEntry() const
Definition Object.h:89
iterator end()
Definition RefManager.h:36
iterator begin()
Definition RefManager.h:35
virtual void DoAction(int32 param)
Definition UnitAI.h:73
Definition Unit.h:635
static void Kill(Unit *attacker, Unit *victim, bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition Unit.cpp:11225
void setActive(bool isActiveObject)
Definition Object.cpp:276
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_GAUNTLET_REACHED
@ DATA_START_PURGE
@ DATA_INFINITE_CORRUPTOR
@ DATA_CRATE_REVEALED
@ DATA_UTHER_FINISHED
@ 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
@ TOWN_HALL_COMPLETE
@ CRATES_IN_PROGRESS
@ GAUNTLET_IN_PROGRESS
@ TOWN_HALL_PENDING
@ GAUNTLET_PENDING
@ MALGANIS_IN_PROGRESS
@ WAVES_IN_PROGRESS
@ GAUNTLET_TRANSITION
@ PURGE_PENDING
@ PURGE_STARTING
@ GAUNTLET_COMPLETE
@ SPAWNGRP_UNDEAD_TRASH
@ GO_HIDDEN_PASSAGE
@ SPAWNGRP_RESIDENTS
@ SPAWNGRP_GAUNTLET_TRASH
@ SPAWNGRP_CHROMIE_MID
@ SPAWNGRP_CRATE_HELPERS
static constexpr std::array< std::array< uint32, MAX_SPAWNS_PER_WAVE >, NUM_SCOURGE_WAVES > HeroicWaves
static constexpr std::array< WaveLocation, WAVE_LOC_MAX - WAVE_LOC_MIN+1 > WaveLocations
static constexpr Position CorruptorPos
static constexpr DoorData doorData[]
COSProgressStates GetStableStateFor(COSProgressStates const state)
static constexpr Position GuardianPos
static constexpr Position CorruptorRiftPos
static constexpr DungeonEncounterData encounters[]
void AddSC_instance_culling_of_stratholme()
time_t GetGameTime()
Definition GameTime.cpp:52
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
TypeListContainerStorage< UnderlyingContainer, Types... > Data
COSWorldStates const WorldState
std::array< Position, MAX_SPAWNS_PER_WAVE > SpawnPoints
void InitiateArthasEvent(COSProgressStates fromState, COSProgressStates toState, COSInstanceActions startAction, ObjectGuid starterGUID)