Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
instance_halls_of_reflection.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "ScriptMgr.h"
7#include "ScriptedCreature.h"
8#include "InstanceScript.h"
9#include "Player.h"
10#include "WorldPacket.h"
11#include "halls_of_reflection.h"
12
13Position const JainaSpawnPos = {5236.659f, 1929.894f, 707.7781f, 0.8726646f}; // Jaina Spawn Position
14Position const SylvanasSpawnPos = {5236.667f, 1929.906f, 707.7781f, 0.8377581f}; // Sylvanas Spawn Position
15Position const GeneralSpawnPos = {5415.538f, 2117.842f, 707.7781f, 3.944444f}; // Frostsworn General
16Position const JainaSpawnPos2 = {5549.011f, 2257.041f, 733.0120f, 1.153993f}; // Jaina Spawn Position 2
17Position const SylvanasSpawnPos2 = {5549.011f, 2257.041f, 733.0120f, 1.153993f}; // Sylvanas Spawn Position 2
18
20{
21 {5309.577f, 2042.668f, 707.7781f, 4.694936f},
22 {5295.885f, 2040.342f, 707.7781f, 5.078908f},
23 {5340.836f, 1992.458f, 707.7781f, 2.757620f},
24 {5325.072f, 1977.597f, 707.7781f, 2.076942f},
25 {5277.365f, 1993.229f, 707.7781f, 0.401426f},
26 {5275.479f, 2001.135f, 707.7781f, 0.174533f},
27 {5302.448f, 2042.222f, 707.7781f, 4.904375f},
28 {5343.293f, 1999.384f, 707.7781f, 2.914700f},
29 {5295.635f, 1973.757f, 707.7781f, 1.186824f},
30 {5311.031f, 1972.229f, 707.7781f, 1.640610f},
31 {5275.076f, 2008.724f, 707.7781f, 6.213372f},
32 {5316.701f, 2041.550f, 707.7781f, 4.502949f},
33 {5344.150f, 2007.168f, 707.7781f, 3.159046f},
34 {5319.158f, 1973.998f, 707.7781f, 1.919862f},
35 {5302.247f, 1972.415f, 707.7781f, 1.378810f},
36 {5277.739f, 2016.882f, 707.7781f, 5.969026f},
37 {5322.964f, 2040.288f, 707.7781f, 4.345870f},
38 {5343.467f, 2015.951f, 707.7781f, 3.490659f},
39 {5313.820f, 1978.146f, 707.7781f, 1.745329f},
40 {5279.649f, 2004.656f, 707.7781f, 0.069814f},
41 {5306.057f, 2037.002f, 707.7781f, 4.817109f},
42 {5337.865f, 2003.403f, 707.7781f, 2.984513f},
43 {5299.434f, 1979.009f, 707.7781f, 1.239184f},
44 {5312.752f, 2037.122f, 707.7781f, 4.590216f},
45 {5335.724f, 1996.859f, 707.7781f, 2.740167f},
46 {5280.632f, 2012.156f, 707.7781f, 6.056293f},
47 {5320.369f, 1980.125f, 707.7781f, 2.007129f},
48 {5306.572f, 1977.474f, 707.7781f, 1.500983f},
49 {5336.599f, 2017.278f, 707.7781f, 3.473205f},
50 {5282.897f, 2019.597f, 707.7781f, 5.881760f},
51 {5318.704f, 2036.108f, 707.7781f, 4.223697f},
52 {5280.513f, 1997.842f, 707.7781f, 0.296706f},
53 {5337.833f, 2010.057f, 707.7781f, 3.228859f},
54 {5299.250f, 2035.998f, 707.7781f, 5.026548f},
55};
56
58{
59public:
60 instance_halls_of_reflection() : InstanceMapScript("instance_halls_of_reflection", 668) { }
61
63 {
65
92
94 {
95 if (!_teamInInstance)
96 _teamInInstance = player->GetTeam();
97 }
98
100 {
101 Map::PlayerList const& players = instance->GetPlayers();
102 if (!players.isEmpty())
103 if (Player* player = players.begin()->GetSource())
104 _teamInInstance = player->GetTeam();
105
106 switch (creature->GetEntry())
107 {
108 case NPC_JAINA_PART1:
110 _jainaOrSylvanasPart1GUID = creature->GetGUID();
111 break;
112 case NPC_FALRIC:
113 _falricGUID = creature->GetGUID();
114 break;
115 case NPC_MARWYN:
116 _marwynGUID = creature->GetGUID();
117 break;
119 _frostwornGeneralGUID = creature->GetGUID();
121 if (Creature* general = instance->GetCreature(_frostwornGeneralGUID))
122 general->SetPhaseMask(1, true);
123 break;
124 case NPC_JAINA_PART2:
126 _jainaOrSylvanasPart2GUID = creature->GetGUID();
127 break;
128 }
129 }
130
132 {
133 switch (creature->GetEntry())
134 {
136 case NPC_WAVE_FOOTMAN:
138 case NPC_WAVE_PRIEST:
139 case NPC_WAVE_MAGE:
140 {
141 uint32 internalWaveId = creature->AI()->GetData(0);
142 waveGuidList[internalWaveId].erase(creature->GetGUID());
143 break;
144 }
145 }
146 }
147
149 {
150 switch (go->GetEntry())
151 {
152 case GO_FROSTMOURNE:
153 _frostmourneGUID = go->GetGUID();
155 HandleGameObject(0, false, go);
157 go->SetPhaseMask(2, true);
158 break;
159 case GO_ENTRANCE_DOOR:
160 _entranceDoorGUID = go->GetGUID();
162 HandleGameObject(0, true, go);
163 break;
165 _frostwornDoorGUID = go->GetGUID();
168 HandleGameObject(0, true, go);
169 else
170 HandleGameObject(0, false, go);
171 break;
172 case GO_ARTHAS_DOOR:
173 _arthasDoorGUID = go->GetGUID();
176 HandleGameObject(0, true, go);
177 else
178 HandleGameObject(0, false, go);
179 break;
180 case GO_CAVE:
181 _caveGUID = go->GetGUID();
183 break;
184 }
185 }
186
188 {
189 builder.AppendState(WORLD_STATE_HOR_WAVES_ENABLED, 0);
190 builder.AppendState(WORLD_STATE_HOR_WAVE_COUNT, 0);
191 }
192
194 {
195 if (!InstanceScript::SetBossState(type, state))
196 return false;
197
198 switch (type)
199 {
201 if (state == DONE)
202 {
203 ++_waveCount;
204 events.ScheduleEvent(EVENT_NEXT_WAVE, 60000);
205 }
206 break;
208 if (state == DONE)
209 {
213 if (Creature* general = instance->GetCreature(_frostwornGeneralGUID))
214 general->SetPhaseMask(1, true);
215 }
216 break;
218 default:
219 break;
220 }
221
222 return true;
223 }
224
225 void SetData(uint32 type, uint32 data) OVERRIDE
226 {
227 switch (type)
228 {
229 case DATA_INTRO_EVENT:
230 if (data == IN_PROGRESS)
231 {
232 if (!_introEvent)
233 {
235 instance->SummonCreature(NPC_JAINA_PART1, JainaSpawnPos);
236 else
238 }
239 }
240 _introEvent = data;
241 break;
242 case DATA_WAVE_COUNT:
243 if (_waveCount && data == NOT_STARTED)
245 break;
247 if (data == DONE)
248 {
251 instance->SummonCreature(NPC_JAINA_PART2, JainaSpawnPos2);
252 else
254 }
255 _frostwornGeneral = data;
256 break;
258 if (data == IN_PROGRESS)
259 {
260 if (!_escapeevent)
261 if (Creature* jaina_or_sylvanas = instance->GetCreature(_jainaOrSylvanasPart2GUID))
262 jaina_or_sylvanas->AI()->DoAction(ACTION_START_ESCAPING);
263 }
264 else if (data == NOT_STARTED)
265 {
266 if (Creature* jaina_or_sylvanas = instance->GetCreature(_jainaOrSylvanasPart2GUID))
267 jaina_or_sylvanas->DespawnOrUnsummon(1);
269 instance->SummonCreature(NPC_JAINA_PART2, JainaSpawnPos2);
270 else
273 }
274 _escapeevent = data;
275 break;
276 case DATA_SUMMONS:
277 if (data == 0)
278 {
280 if (_mobsaticewall == 0)
281 {
282 if (Creature* jaina_or_sylvanas = instance->GetCreature(_jainaOrSylvanasPart2GUID))
283 jaina_or_sylvanas->AI()->DoAction(ACTION_WALL_BROKEN);
284 }
285 }
286 else if (data == 1)
288 break;
289 }
290
291 SaveToDB();
292 }
293
294
295 // wave scheduling,checked when wave npcs die
297 {
298 Creature* creature = unit->ToCreature();
299 if (!creature)
300 return;
301
302 switch (creature->GetEntry())
303 {
305 case NPC_WAVE_FOOTMAN:
307 case NPC_WAVE_PRIEST:
308 case NPC_WAVE_MAGE:
309 {
310 uint32 deadNpcs = 0;
311 uint32 waveId = creature->AI()->GetData(0);
312 for (std::set<uint64>::const_iterator itr = waveGuidList[waveId].begin(); itr != waveGuidList[waveId].end(); ++itr)
313 {
314 Creature* npc = instance->GetCreature(*itr);
315 if (!npc || !npc->IsAlive())
316 ++deadNpcs;
317 }
318 // because the current npc returns IsAlive when OnUnitDeath happens
319 // we check if the number of dead npcs is equal to the list-1
320 if (deadNpcs == waveGuidList[waveId].size() - 1)
321 {
322 ++_waveCount;
323 events.ScheduleEvent(EVENT_NEXT_WAVE, 3000);
324 }
325 break;
326 }
327 }
328 }
329
331 {
332 if (!instance->HavePlayers())
333 return;
334
335 events.Update(diff);
336
337 switch (events.ExecuteEvent())
338 {
339 case EVENT_NEXT_WAVE:
341 break;
342 }
343 }
344
346 {
347 switch (eventId)
348 {
349 // spawning all wave npcs at once
351 _waveCount = 1;
354 {
355 std::list<uint32> possibilityList, tempList;
356 uint32 posIndex = 0;
357
358 possibilityList.push_back(NPC_WAVE_MERCENARY);
359 possibilityList.push_back(NPC_WAVE_FOOTMAN);
360 possibilityList.push_back(NPC_WAVE_RIFLEMAN);
361 possibilityList.push_back(NPC_WAVE_PRIEST);
362 possibilityList.push_back(NPC_WAVE_MAGE);
363
364 // iterate each wave
365 for (uint8 i = 0; i < 8; ++i)
366 {
367 tempList = possibilityList;
368
369 uint64 bossGuid = i <= 3 ? _falricGUID : _marwynGUID;
370
371 if (!i)
373 else if (i < 6 && i != 3)
375
376 for (std::list<uint32>::const_iterator itr = tempList.begin(); itr != tempList.end(); ++itr)
377 {
378 if (Creature* boss = instance->GetCreature(bossGuid))
379 {
381 {
382 temp->AI()->SetData(0, i);
383 waveGuidList[i].insert(temp->GetGUID());
384 }
385 }
386
387 ++posIndex;
388 }
389 }
390 }
391 events.ScheduleEvent(EVENT_NEXT_WAVE, 5000);
392 break;
393 case EVENT_ADD_WAVE:
397
398 if (_waveCount % 5)
399 {
400 uint32 internalWaveId = _waveCount - ((_waveCount < 5) ? 1 : 2);
401 for (std::set<uint64>::const_iterator itr = waveGuidList[internalWaveId].begin(); itr != waveGuidList[internalWaveId].end(); ++itr)
402 {
403 if (Creature* temp = instance->GetCreature(*itr))
404 {
405 temp->CastSpell(temp, SPELL_SPIRIT_ACTIVATE, true);
407 temp->AI()->DoZoneInCombat(temp, 100.00f);
408 }
409 }
410 }
411 else
412 {
413 uint32 bossIndex = (_waveCount / 5) - 1;
414 if (GetBossState(DATA_FALRIC_EVENT + bossIndex) != DONE)
415 {
416 if (Creature* boss = instance->GetCreature(bossIndex ? _marwynGUID : _falricGUID))
417 boss->AI()->DoAction(ACTION_ENTER_COMBAT);
418 }
419 else if (_waveCount != 10)
420 {
421 ++_waveCount;
422 events.ScheduleEvent(EVENT_NEXT_WAVE, 5000);
423 }
424 }
425 break;
426 case EVENT_DO_WIPE:
427 _waveCount = 0;
428 events.Reset();
432
433 if (Creature* falric = instance->GetCreature(_falricGUID))
434 falric->SetVisible(false);
435 if (Creature* marwyn = instance->GetCreature(_marwynGUID))
436 marwyn->SetVisible(false);
437 //despawn wave npcs
438 for (uint8 i = 0; i < 8; ++i)
439 {
440 for (std::set<uint64>::const_iterator itr = waveGuidList[i].begin(); itr != waveGuidList[i].end(); ++itr)
441 if (Creature* creature = instance->GetCreature(*itr))
442 creature->DespawnOrUnsummon(1);
443 waveGuidList[i].clear();
444 }
445 break;
446 }
447 }
448
450 {
451 switch (type)
452 {
453 case DATA_WAVE_COUNT:
454 return _waveCount;
456 return _teamInInstance;
457 case DATA_INTRO_EVENT:
458 return _introEvent;
460 return _frostwornGeneral;
462 return _escapeevent;
463 case DATA_SUMMONS:
464 return _mobsaticewall;
465 default:
466 break;
467 }
468
469 return 0;
470 }
471
473 {
474 switch (type)
475 {
477 return _falricGUID;
479 return _marwynGUID;
483 return _frostwornDoorGUID;
484 case DATA_FROSTMOURNE:
485 return _frostmourneGUID;
488 case DATA_CAVE_IN:
489 return _caveGUID;
490 default:
491 break;
492 }
493
494 return 0;
495 }
496
497 std::string GetSaveData() OVERRIDE
498 {
500
501 std::ostringstream saveStream;
502 saveStream << "H R " << GetBossSaveData() << _introEvent << ' ' << _frostwornGeneral << _escapeevent;
503
505 return saveStream.str();
506 }
507
508 void Load(char const* in) OVERRIDE
509 {
510 if (!in)
511 {
513 return;
514 }
515
517
518 char dataHead1, dataHead2;
519
520 std::istringstream loadStream(in);
521 loadStream >> dataHead1 >> dataHead2;
522
523 if (dataHead1 == 'H' && dataHead2 == 'R')
524 {
525 for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
526 {
527 uint32 tmpState;
528 loadStream >> tmpState;
529 if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
530 tmpState = NOT_STARTED;
531
532 SetBossState(i, EncounterState(tmpState));
533 }
534
535 uint32 temp = 0;
536 loadStream >> temp;
537 if (temp == DONE)
539 else
541
542 loadStream >> temp;
543 if (temp == DONE)
545 else
547
548 loadStream >> temp;
549 if (temp == DONE)
551 else
553 }
554 else
556
558 }
559
560 private:
567
574
581
583
584 std::set<uint64> waveGuidList[8];
585 };
586
591};
592
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
#define OUT_LOAD_INST_DATA_FAIL
EncounterState
@ IN_PROGRESS
@ DONE
@ SPECIAL
@ NOT_STARTED
#define OUT_SAVE_INST_DATA_COMPLETE
#define OUT_LOAD_INST_DATA_COMPLETE
#define OUT_SAVE_INST_DATA
#define OUT_LOAD_INST_DATA(a)
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:74
@ ALLIANCE
@ GO_FLAG_INTERACT_COND
@ UNIT_FLAG_IMMUNE_TO_NPC
Definition Unit.h:634
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ UNIT_FIELD_FLAGS
@ GAMEOBJECT_FIELD_FLAGS
CreatureAI * AI() const
Definition Creature.h:483
InstanceMapScript(const char *name, uint32 mapId)
InstanceScript(Map *map)
void SetBossNumber(uint32 number)
virtual bool SetBossState(uint32 id, EncounterState state)
std::string GetBossSaveData()
EncounterState GetBossState(uint32 id) const
void HandleGameObject(uint64 guid, bool open, GameObject *go=NULL)
void DoUpdateWorldState(uint32 worldstateId, uint32 worldstateValue)
bool isEmpty() const
Definition LinkedList.h:86
Definition Map.h:238
MapRefManager PlayerList
Definition Map.h:406
iterator begin()
uint32 GetEntry() const
Definition Object.h:125
Creature * ToCreature()
Definition Object.h:207
FROM * GetSource() const
Definition Reference.h:83
virtual uint32 GetData(uint32) const
Definition UnitAI.h:127
Definition Unit.h:1367
TempSummon * SummonCreature(uint32 id, Position const &pos, TempSummonType spwtype=TempSummonType::TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0) const
Definition Object.cpp:2703
InstanceScript * GetInstanceScript(InstanceMap *map) const OVERRIDE
@ NPC_JAINA_PART1
@ NPC_JAINA_PART2
@ NPC_SYLVANAS_PART2
@ NPC_SYLVANAS_PART1
@ DATA_TEAM_IN_INSTANCE
@ GO_FROSTWORN_DOOR
@ GO_FROSTMOURNE
@ GO_ENTRANCE_DOOR
@ GO_ARTHAS_DOOR
@ ACTION_START_ESCAPING
@ ACTION_WALL_BROKEN
@ ACTION_ENTER_COMBAT
@ NPC_WAVE_FOOTMAN
@ NPC_WAVE_PRIEST
@ NPC_FALRIC
@ NPC_WAVE_MAGE
@ NPC_WAVE_MERCENARY
@ NPC_FROSTWORN_GENERAL
@ NPC_WAVE_RIFLEMAN
@ NPC_MARWYN
@ WORLD_STATE_HOR_WAVES_ENABLED
@ WORLD_STATE_HOR_WAVE_COUNT
@ EVENT_SPAWN_WAVES
@ EVENT_NEXT_WAVE
@ EVENT_ADD_WAVE
@ EVENT_DO_WIPE
@ SPELL_SPIRIT_ACTIVATE
@ DATA_MARWYN_EVENT
@ DATA_INTRO_EVENT
@ DATA_FROSWORN_EVENT
@ DATA_ESCAPE_EVENT
@ DATA_ESCAPE_LEADER
@ DATA_SUMMONS
@ DATA_FALRIC_EVENT
@ DATA_WAVE_COUNT
@ DATA_CAVE_IN
@ DATA_FROSTMOURNE
@ DATA_LICHKING_EVENT
@ DATA_FROSTWORN_DOOR
#define MAX_ENCOUNTER
void AddSC_instance_halls_of_reflection()
Position const SpawnPos[]
Position const JainaSpawnPos2
Position const SylvanasSpawnPos
Position const GeneralSpawnPos
Position const SylvanasSpawnPos2
Position const JainaSpawnPos
void RandomResizeList(std::list< T > &list, uint32 size)
Definition Containers.h:19