Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
instance_naxxramas.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 "naxxramas.h"
10
12{
47};
48
59
60float const HeiganPos[2] = { 2796.0f, -3707.0f };
61float const HeiganEruptionSlope[3] =
62{
63 (-3685.0f - HeiganPos[1]) / (2724.0f - HeiganPos[0]),
64 (-3647.0f - HeiganPos[1]) / (2749.0f - HeiganPos[0]),
65 (-3637.0f - HeiganPos[1]) / (2771.0f - HeiganPos[0])
66};
67
68// 0 H x
69// 1 ^
70// 2 |
71// 3 y<--o
72inline uint32 GetEruptionSection(float x, float y)
73{
74 y -= HeiganPos[1];
75 if (y < 1.0f)
76 return 0;
77
78 x -= HeiganPos[0];
79 if (x > -1.0f)
80 return 3;
81
82 float slope = y/x;
83 for (uint32 i = 0; i < 3; ++i)
84 if (slope > HeiganEruptionSlope[i])
85 return i;
86 return 3;
87}
88
90{
91 public:
92 instance_naxxramas() : InstanceMapScript("instance_naxxramas", 533) { }
93
95 {
97 {
101
102 GothikGateGUID = 0;
104 FaerlinaGUID = 0;
105 ThaneGUID = 0;
106 LadyGUID = 0;
107 BaronGUID = 0;
108 SirGUID = 0;
109 ThaddiusGUID = 0;
110 HeiganGUID = 0;
111 FeugenGUID = 0;
112 StalaggGUID = 0;
113 SapphironGUID = 0;
114 KelthuzadGUID = 0;
116
117 playerDied = 0;
118
119 memset(PortalsGUID, 0, sizeof(PortalsGUID));
120 }
121
123 {
124 switch (creature->GetEntry())
125 {
126 case NPC_FAERLINA:
127 FaerlinaGUID = creature->GetGUID();
128 break;
129 case NPC_THANE:
130 ThaneGUID = creature->GetGUID();
131 break;
132 case NPC_LADY:
133 LadyGUID = creature->GetGUID();
134 break;
135 case NPC_BARON:
136 BaronGUID = creature->GetGUID();
137 break;
138 case NPC_SIR:
139 SirGUID = creature->GetGUID();
140 break;
141 case NPC_THADDIUS:
142 ThaddiusGUID = creature->GetGUID();
143 break;
144 case NPC_HEIGAN:
145 HeiganGUID = creature->GetGUID();
146 break;
147 case NPC_FEUGEN:
148 FeugenGUID = creature->GetGUID();
149 break;
150 case NPC_STALAGG:
151 StalaggGUID = creature->GetGUID();
152 break;
153 case NPC_SAPPHIRON:
154 SapphironGUID = creature->GetGUID();
155 break;
156 case NPC_KEL_THUZAD:
157 KelthuzadGUID = creature->GetGUID();
158 break;
159 default:
160 break;
161 }
162
163 AddMinion(creature, true);
164 }
165
167 {
168 AddMinion(creature, false);
169 }
170
172 {
173 if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287)
174 {
175 uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY());
176 HeiganEruptionGUID[section].insert(go->GetGUID());
177 return;
178 }
179
180 switch (go->GetEntry())
181 {
182 case GO_GOTHIK_GATE:
183 GothikGateGUID = go->GetGUID();
184 break;
187 HorsemenChestGUID = go->GetGUID();
188 break;
190 PortalsGUID[0] = go->GetGUID();
191 break;
193 PortalsGUID[1] = go->GetGUID();
194 break;
196 PortalsGUID[2] = go->GetGUID();
197 break;
199 PortalsGUID[3] = go->GetGUID();
200 break;
202 KelthuzadTriggerGUID = go->GetGUID();
203 break;
204 default:
205 break;
206 }
207
208 AddDoor(go, true);
209 }
210
212 {
213 if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287)
214 {
215 uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY());
216
217 HeiganEruptionGUID[section].erase(go->GetGUID());
218 return;
219 }
220
221 switch (go->GetEntry())
222 {
223 case GO_BIRTH:
224 if (SapphironGUID)
225 {
226 if (Creature* sapphiron = instance->GetCreature(SapphironGUID))
227 sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH);
228 return;
229 }
230 break;
231 default:
232 break;
233 }
234
235 AddDoor(go, false);
236 }
237
239 {
240 if (unit->GetTypeId() == TypeID::TYPEID_PLAYER && IsEncounterInProgress())
241 {
242 playerDied = 1;
243 SaveToDB();
244 }
245 }
246
248 {
249 switch (id)
250 {
252 HeiganErupt(value);
253 break;
254 case DATA_GOTHIK_GATE:
255 if (GameObject* gate = instance->GetGameObject(GothikGateGUID))
256 gate->SetGoState(GOState(value));
257 break;
258 case DATA_HORSEMEN0:
259 case DATA_HORSEMEN1:
260 case DATA_HORSEMEN2:
261 case DATA_HORSEMEN3:
262 if (value == NOT_STARTED)
263 {
266 }
267 else if (value == DONE)
268 {
269 time_t now = time(NULL);
270
271 if (minHorsemenDiedTime == 0)
273
275 }
276 break;
278 AbominationCount = value;
279 break;
280 }
281 }
282
284 {
285 switch (id)
286 {
288 return AbominationCount;
289 default:
290 break;
291 }
292
293 return 0;
294 }
295
297 {
298 switch (id)
299 {
300 case DATA_FAERLINA:
301 return FaerlinaGUID;
302 case DATA_THANE:
303 return ThaneGUID;
304 case DATA_LADY:
305 return LadyGUID;
306 case DATA_BARON:
307 return BaronGUID;
308 case DATA_SIR:
309 return SirGUID;
310 case DATA_THADDIUS:
311 return ThaddiusGUID;
312 case DATA_HEIGAN:
313 return HeiganGUID;
314 case DATA_FEUGEN:
315 return FeugenGUID;
316 case DATA_STALAGG:
317 return StalaggGUID;
318 case DATA_KELTHUZAD:
319 return KelthuzadGUID;
321 return PortalsGUID[0];
323 return PortalsGUID[1];
325 return PortalsGUID[2];
327 return PortalsGUID[3];
330 }
331
332 return 0;
333 }
334
336 {
337 if (!InstanceScript::SetBossState(id, state))
338 return false;
339
340 if (id == BOSS_HORSEMEN && state == DONE)
341 {
342 if (GameObject* horsemenChest = instance->GetGameObject(HorsemenChestGUID))
343 {
344 horsemenChest->SetRespawnTime(horsemenChest->GetRespawnDelay());
345 horsemenChest->RemoveFlag(GAMEOBJECT_FIELD_FLAGS, GO_FLAG_NOT_SELECTABLE);
346 }
347 }
348
349 return true;
350 }
351
352 void HeiganErupt(uint32 section)
353 {
354 for (uint32 i = 0; i < 4; ++i)
355 {
356 if (i == section)
357 continue;
358
359 for (std::set<uint64>::const_iterator itr = HeiganEruptionGUID[i].begin(); itr != HeiganEruptionGUID[i].end(); ++itr)
360 {
361 if (GameObject* heiganEruption = instance->GetGameObject(*itr))
362 {
363 heiganEruption->SendCustomAnim(heiganEruption->GetGoAnimProgress());
364 heiganEruption->CastSpell(NULL, SPELL_ERUPTION);
365 }
366 }
367 }
368 }
369
370 // This Function is called in CheckAchievementCriteriaMeet and CheckAchievementCriteriaMeet is called before SetBossState(bossId, DONE),
371 // so to check if all bosses are done the checker must exclude 1 boss, the last done, if there is at most 1 encouter in progress when is
372 // called this function then all bosses are done. The one boss that check is the boss that calls this function, so it is dead.
374 {
375 uint32 numBossAlive = 0;
376 for (uint32 i = 0; i < EncounterCount; ++i)
377 if (GetBossState(i) != DONE)
378 numBossAlive++;
379
380 if (numBossAlive > 1)
381 return false;
382 return true;
383 }
384
385 bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target = NULL*/, uint32 /*miscvalue1 = 0*/) OVERRIDE
386 {
387 switch (criteria_id)
388 {
389 case 7600: // Criteria for achievement 2176: And They Would All Go Down Together 15sec of each other 10-man
391 return true;
392 return false;
393 case 7601: // Criteria for achievement 2177: And They Would All Go Down Together 15sec of each other 25-man
395 return true;
396 return false;
397 // Difficulty checks are done on DB.
398 // Criteria for achievement 2186: The Immortal (25-man)
399 case 13233: // The Four Horsemen
400 case 13234: // Maexxna
401 case 13235: // Thaddius
402 case 13236: // Loatheb
403 case 7616: // Kel'Thuzad
404 // Criteria for achievement 2187: The Undying (10-man)
405 case 13237: // The Four Horsemen
406 case 13238: // Maexxna
407 case 13239: // Loatheb
408 case 13240: // Thaddius
409 case 7617: // Kel'Thuzad
411 return true;
412 return false;
413 }
414
415 return false;
416 }
417
418 std::string GetSaveData() OVERRIDE
419 {
421
422 std::ostringstream saveStream;
423 saveStream << "N X " << GetBossSaveData() << playerDied;
424
426 return saveStream.str();
427 }
428
429 void Load(const char* strIn) OVERRIDE
430 {
431 if (!strIn)
432 {
434 return;
435 }
436
437 OUT_LOAD_INST_DATA(strIn);
438
439 char dataHead1, dataHead2;
440
441 std::istringstream loadStream(strIn);
442 loadStream >> dataHead1 >> dataHead2;
443
444 if (dataHead1 == 'N' && dataHead2 == 'X')
445 {
446 for (uint8 i = 0; i < EncounterCount; ++i)
447 {
448 uint32 tmpState;
449 loadStream >> tmpState;
450 if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
451 tmpState = NOT_STARTED;
452
453 SetBossState(i, EncounterState(tmpState));
454 }
455
456 loadStream >> playerDied;
457 }
458
460 }
461
462 protected:
463 /* The Arachnid Quarter */
464 // Grand Widow Faerlina
466
467 /* The Plague Quarter */
468 // Heigan the Unclean
469 std::set<uint64> HeiganEruptionGUID[4];
471
472 /* The Military Quarter */
473 // Gothik the Harvester
475 // The Four Horsemen
484
485 /* The Construct Quarter */
486 // Thaddius
490
491 /* Frostwyrm Lair */
492 // Sapphiron
494 // Kel'Thuzad
499
500 /* The Immortal / The Undying */
502 };
503
508};
509
DifficultyID
Definition DBCEnums.h:330
@ DIFFICULTY_25MAN_NORMAL
Definition DBCEnums.h:335
@ DIFFICULTY_10MAN_NORMAL
Definition DBCEnums.h:334
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
GOState
Definition GameObject.h:575
#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)
@ DOOR_TYPE_ROOM
@ DOOR_TYPE_PASSAGE
@ BOUNDARY_NONE
@ BOUNDARY_SW
@ BOUNDARY_NE
@ BOUNDARY_W
@ BOUNDARY_NW
@ BOUNDARY_S
@ BOUNDARY_N
@ BOUNDARY_E
@ TYPEID_PLAYER
Definition Object.h:55
@ GO_FLAG_NOT_SELECTABLE
@ GAMEOBJECT_FIELD_FLAGS
uint32 const EncounterCount
@ SPELL_ERUPTION
Definition boss_garr.cpp:26
InstanceMapScript(const char *name, uint32 mapId)
InstanceScript(Map *map)
void SetBossNumber(uint32 number)
virtual bool SetBossState(uint32 id, EncounterState state)
std::string GetBossSaveData()
void AddMinion(Creature *minion, bool add)
EncounterState GetBossState(uint32 id) const
virtual bool IsEncounterInProgress() const
void AddDoor(GameObject *door, bool add)
void LoadMinionData(MinionData const *data)
void LoadDoorData(DoorData const *data)
Definition Map.h:238
Definition Unit.h:1367
InstanceScript * GetInstanceScript(InstanceMap *map) const OVERRIDE
DoorData const doorData[]
float const HeiganPos[2]
uint32 GetEruptionSection(float x, float y)
MinionData const minionData[]
DoorData const doorData[]
float const HeiganEruptionSlope[3]
void AddSC_instance_naxxramas()
@ NPC_FEUGEN
Definition naxxramas.h:71
@ NPC_THADDIUS
Definition naxxramas.h:69
@ NPC_LADY
Definition naxxramas.h:66
@ NPC_KEL_THUZAD
Definition naxxramas.h:74
@ NPC_FAERLINA
Definition naxxramas.h:64
@ NPC_SAPPHIRON
Definition naxxramas.h:73
@ NPC_STALAGG
Definition naxxramas.h:72
@ NPC_HEIGAN
Definition naxxramas.h:70
@ NPC_THANE
Definition naxxramas.h:65
@ NPC_SIR
Definition naxxramas.h:68
@ NPC_DK_UNDERSTUDY
Definition naxxramas.h:78
@ NPC_FOLLOWER_WORSHIPPER
Definition naxxramas.h:77
@ DATA_THANE
Definition naxxramas.h:46
@ DATA_HEIGAN
Definition naxxramas.h:51
@ DATA_SIR
Definition naxxramas.h:49
@ DATA_KELTHUZAD
Definition naxxramas.h:54
@ DATA_KELTHUZAD_PORTAL02
Definition naxxramas.h:56
@ DATA_FAERLINA
Definition naxxramas.h:45
@ DATA_KELTHUZAD_PORTAL01
Definition naxxramas.h:55
@ DATA_THADDIUS
Definition naxxramas.h:50
@ DATA_LADY
Definition naxxramas.h:47
@ DATA_FEUGEN
Definition naxxramas.h:52
@ DATA_KELTHUZAD_PORTAL04
Definition naxxramas.h:58
@ DATA_KELTHUZAD_TRIGGER
Definition naxxramas.h:59
@ DATA_STALAGG
Definition naxxramas.h:53
@ DATA_KELTHUZAD_PORTAL03
Definition naxxramas.h:57
@ BOSS_RAZUVIOUS
Definition naxxramas.h:23
@ BOSS_HEIGAN
Definition naxxramas.h:17
@ BOSS_GROBBULUS
Definition naxxramas.h:20
@ BOSS_LOATHEB
Definition naxxramas.h:18
@ BOSS_GLUTH
Definition naxxramas.h:21
@ BOSS_GOTHIK
Definition naxxramas.h:24
@ BOSS_SAPPHIRON
Definition naxxramas.h:26
@ BOSS_MAEXXNA
Definition naxxramas.h:15
@ BOSS_THADDIUS
Definition naxxramas.h:22
@ BOSS_KELTHUZAD
Definition naxxramas.h:27
@ BOSS_ANUBREKHAN
Definition naxxramas.h:13
@ BOSS_NOTH
Definition naxxramas.h:16
@ BOSS_PATCHWERK
Definition naxxramas.h:19
@ BOSS_HORSEMEN
Definition naxxramas.h:25
@ BOSS_FAERLINA
Definition naxxramas.h:14
@ DATA_HEIGAN_ERUPT
Definition naxxramas.h:32
@ DATA_HORSEMEN0
Definition naxxramas.h:36
@ DATA_HORSEMEN1
Definition naxxramas.h:37
@ DATA_SAPPHIRON_BIRTH
Definition naxxramas.h:34
@ DATA_HORSEMEN3
Definition naxxramas.h:39
@ DATA_GOTHIK_GATE
Definition naxxramas.h:33
@ DATA_ABOMINATION_KILLED
Definition naxxramas.h:40
@ DATA_HORSEMEN2
Definition naxxramas.h:38
@ GO_PASSAGE_SAPPHIRON
Definition naxxramas.h:106
@ GO_ARAC_EYE_RAMP
Definition naxxramas.h:112
@ GO_KELTHUZAD_TRIGGER
Definition naxxramas.h:90
@ GO_ROOM_HORSEMEN
Definition naxxramas.h:105
@ GO_MILI_EYE_RAMP
Definition naxxramas.h:114
@ GO_PASSAGE_ANUBREKHAN
Definition naxxramas.h:92
@ GO_GOTHIK_GATE
Definition naxxramas.h:85
@ GO_ROOM_LOATHEB
Definition naxxramas.h:99
@ GO_CONS_EYE_RAMP
Definition naxxramas.h:115
@ GO_ROOM_HEIGAN
Definition naxxramas.h:97
@ GO_PASSAGE_GLUTH
Definition naxxramas.h:101
@ GO_KELTHUZAD_PORTAL03
Definition naxxramas.h:88
@ GO_HORSEMEN_CHEST_HERO
Definition naxxramas.h:83
@ GO_HORSEMEN_CHEST
Definition naxxramas.h:84
@ GO_CONS_EYE_RAMP_BOSS
Definition naxxramas.h:119
@ GO_PLAG_EYE_RAMP_BOSS
Definition naxxramas.h:117
@ GO_BIRTH
Definition naxxramas.h:122
@ GO_PASSAGE_NOTH
Definition naxxramas.h:96
@ GO_ROOM_GROBBULUS
Definition naxxramas.h:100
@ GO_PASSAGE_HEIGAN
Definition naxxramas.h:98
@ GO_MILI_EYE_RAMP_BOSS
Definition naxxramas.h:118
@ GO_ROOM_ANUBREKHAN
Definition naxxramas.h:91
@ GO_ROOM_KELTHUZAD
Definition naxxramas.h:107
@ GO_ROOM_GOTHIK
Definition naxxramas.h:103
@ GO_KELTHUZAD_PORTAL01
Definition naxxramas.h:86
@ GO_PASSAGE_FAERLINA
Definition naxxramas.h:93
@ GO_ROOM_THADDIUS
Definition naxxramas.h:102
@ GO_PLAG_EYE_RAMP
Definition naxxramas.h:113
@ GO_ROOM_NOTH
Definition naxxramas.h:95
@ GO_PASSAGE_GOTHIK
Definition naxxramas.h:104
@ GO_ROOM_MAEXXNA
Definition naxxramas.h:94
@ GO_KELTHUZAD_PORTAL04
Definition naxxramas.h:89
@ GO_KELTHUZAD_PORTAL02
Definition naxxramas.h:87
@ GO_ARAC_EYE_RAMP_BOSS
Definition naxxramas.h:116
@ NPC_BARON
Definition stratholme.h:34
@ DATA_BARON
Definition stratholme.h:20
bool SetBossState(uint32 id, EncounterState state) OVERRIDE
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const *, Unit const *, uint32) OVERRIDE