Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
instance_icecrown_citadel.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 "ObjectMgr.h"
7#include "ScriptMgr.h"
8#include "InstanceScript.h"
9#include "ScriptedCreature.h"
10#include "Map.h"
11#include "PoolMgr.h"
12#include "AccountMgr.h"
13#include "icecrown_citadel.h"
14#include "Player.h"
15#include "WorldPacket.h"
16#include "WorldSession.h"
17
24
31
33{
59 {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE}, // END
60};
61
62// this doesnt have to only store questgivers, also can be used for related quest spawns
64{
66 uint32 questId[2]; // 10 and 25 man versions
67};
68
69// when changing the content, remember to update SetData, DATA_BLOOD_QUICKENING_STATE case for NPC_ALRIN_THE_AGILE index
82
84{
85 public:
87
89 {
91 {
102 PlagueSigilGUID = 0;
105 memset(PutricidePipeGUIDs, 0, 2 * sizeof(uint64));
106 memset(PutricideGateGUIDs, 0, 2 * sizeof(uint64));
108 FestergutGUID = 0;
109 RotfaceGUID = 0;
112 memset(BloodCouncilGUIDs, 0, 3 * sizeof(uint64));
116 memset(CrokCaptainGUIDs, 0, 4 * sizeof(uint64));
121 SindragosaGUID = 0;
123 RimefangGUID = 0;
125 TheLichKingGUID = 0;
133 IsBonedEligible = true;
134 IsOozeDanceEligible = true;
135 IsNauseaEligible = true;
140 }
141
143 {
146 builder.AppendState(WORLDSTATE_SHOW_ATTEMPTS, instance->IsHeroic());
147 builder.AppendState(WORLDSTATE_ATTEMPTS_REMAINING, HeroicAttempts);
148 builder.AppendState(WORLDSTATE_ATTEMPTS_MAX, MaxHeroicAttempts);
149 }
150
152 {
153 if (!TeamInInstance)
154 TeamInInstance = player->GetTeam();
155 }
156
158 {
159 if (!TeamInInstance)
160 {
161 Map::PlayerList const &players = instance->GetPlayers();
162 if (!players.isEmpty())
163 if (Player* player = players.begin()->GetSource())
164 TeamInInstance = player->GetTeam();
165 }
166
167 switch (creature->GetEntry())
168 {
171 creature->UpdateEntry(NPC_ALLIANCE_COMMANDER, ALLIANCE);
172 break;
175 creature->UpdateEntry(NPC_SKYBREAKER_LIEUTENANT, ALLIANCE);
176 break;
177 case NPC_TORTUNOK:
179 creature->UpdateEntry(NPC_ALANA_MOONSTRIKE, ALLIANCE);
180 break;
183 creature->UpdateEntry(NPC_TALAN_MOONSTRIKE, ALLIANCE);
184 break;
187 creature->UpdateEntry(NPC_MALFUS_GRIMFROST, ALLIANCE);
188 break;
191 creature->UpdateEntry(NPC_YILI, ALLIANCE);
192 break;
193 case NPC_VOL_GUK:
195 creature->UpdateEntry(NPC_JEDEBIA, ALLIANCE);
196 break;
199 creature->UpdateEntry(NPC_NIBY_THE_ALMIGHTY, ALLIANCE);
200 break;
203 creature->UpdateEntry(NPC_KING_VARIAN_WRYNN, ALLIANCE);
204 break;
206 DeathbringerSaurfangGUID = creature->GetGUID();
207 break;
210 creature->UpdateEntry(NPC_SE_MURADIN_BRONZEBEARD, ALLIANCE, creature->GetCreatureData());
211 // no break;
213 DeathbringerSaurfangEventGUID = creature->GetGUID();
214 creature->LastUsedScriptID = creature->GetScriptId();
215 break;
218 creature->UpdateEntry(NPC_SE_SKYBREAKER_MARINE, ALLIANCE);
219 break;
220 case NPC_FESTERGUT:
221 FestergutGUID = creature->GetGUID();
222 break;
223 case NPC_ROTFACE:
224 RotfaceGUID = creature->GetGUID();
225 break;
227 ProfessorPutricideGUID = creature->GetGUID();
228 break;
230 BloodCouncilGUIDs[0] = creature->GetGUID();
231 break;
233 BloodCouncilGUIDs[1] = creature->GetGUID();
234 break;
236 BloodCouncilGUIDs[2] = creature->GetGUID();
237 break;
239 BloodCouncilControllerGUID = creature->GetGUID();
240 break;
242 BloodQueenLanaThelGUID = creature->GetGUID();
243 break;
245 CrokScourgebaneGUID = creature->GetGUID();
246 break;
247 // we can only do this because there are no gaps in their entries
252 CrokCaptainGUIDs[creature->GetEntry()-NPC_CAPTAIN_ARNATH] = creature->GetGUID();
253 break;
255 SisterSvalnaGUID = creature->GetGUID();
256 break;
258 ValithriaDreamwalkerGUID = creature->GetGUID();
259 break;
261 ValithriaLichKingGUID = creature->GetGUID();
262 break;
264 ValithriaTriggerGUID = creature->GetGUID();
265 break;
266 case NPC_SINDRAGOSA:
267 SindragosaGUID = creature->GetGUID();
268 break;
269 case NPC_SPINESTALKER:
270 SpinestalkerGUID = creature->GetGUID();
271 break;
272 case NPC_RIMEFANG:
273 RimefangGUID = creature->GetGUID();
274 break;
276 // Teleporter visual at center
277 if (creature->GetExactDist2d(4357.052f, 2769.421f) < 10.0f)
278 creature->CastSpell(creature, SPELL_ARTHAS_TELEPORTER_CEREMONY, false);
279 break;
281 TheLichKingGUID = creature->GetGUID();
282 break;
284 HighlordTirionFordringGUID = creature->GetGUID();
285 break;
288 TerenasMenethilGUID = creature->GetGUID();
289 break;
291 // Remove corpse as soon as it dies (and respawn 10 seconds later)
292 creature->SetCorpseDelay(0);
293 creature->SetReactState(REACT_PASSIVE);
294 break;
295 default:
296 break;
297 }
298 }
299
301 {
302 if (creature->GetEntry() == NPC_SINDRAGOSA)
303 SindragosaGUID = 0;
304 }
305
306 // Weekly quest spawn prevention
308 {
309 uint32 entry = data->id;
310 switch (entry)
311 {
319 {
320 for (uint8 questIndex = 0; questIndex < WeeklyNPCs; ++questIndex)
321 {
322 if (WeeklyQuestData[questIndex].creatureEntry == entry)
323 {
324 uint8 diffIndex = uint8(instance->GetSpawnMode() & 1);
325 if (!sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[questIndex].questId[diffIndex]))
326 entry = 0;
327 break;
328 }
329 }
330 break;
331 }
332 default:
333 break;
334 }
335
336 return entry;
337 }
338
340 {
341 Creature* creature = unit->ToCreature();
342 if (!creature)
343 return;
344
345 switch (creature->GetEntry())
346 {
352 if (Creature* crok = instance->GetCreature(CrokScourgebaneGUID))
353 crok->AI()->SetGUID(creature->GetGUID(), ACTION_VRYKUL_DEATH);
354 break;
356 if (FrostwyrmGUIDs.empty())
357 return;
358
359 if (creature->AI()->GetData(1/*DATA_FROSTWYRM_OWNER*/) == DATA_SPINESTALKER)
360 {
361 SpinestalkerTrash.erase(creature->GetDBTableGUIDLow());
362 if (SpinestalkerTrash.empty())
363 if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID))
364 spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
365 }
366 else
367 {
368 RimefangTrash.erase(creature->GetDBTableGUIDLow());
369 if (RimefangTrash.empty())
370 if (Creature* spinestalk = instance->GetCreature(RimefangGUID))
371 spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
372 }
373 break;
374 case NPC_RIMEFANG:
375 case NPC_SPINESTALKER:
376 {
377 if (instance->IsHeroic() && !HeroicAttempts)
378 return;
379
381 return;
382
383 FrostwyrmGUIDs.erase(creature->GetDBTableGUIDLow());
384 if (FrostwyrmGUIDs.empty())
385 {
386 instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
387 if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
388 boss->AI()->DoAction(ACTION_START_FROSTWYRM);
389 }
390 break;
391 }
392 default:
393 break;
394 }
395 }
396
398 {
399 switch (go->GetEntry())
400 {
402 case GO_ICEWALL:
420 case GO_ICE_WALL:
421 AddDoor(go, true);
422 break;
423 // these 2 gates are functional only on 25man modes
426 if (instance->Is25ManRaid())
427 AddDoor(go, true);
428 break;
430 LadyDeathwisperElevatorGUID = go->GetGUID();
432 {
433 go->SetUInt32Value(GAMEOBJECT_FIELD_LEVEL, 0);
434 go->SetGoState(GOState::GO_STATE_READY);
435 }
436 break;
438 DeathbringerSaurfangDoorGUID = go->GetGUID();
439 AddDoor(go, true);
440 break;
445 DeathbringersCacheGUID = go->GetGUID();
446 break;
448 SaurfangTeleportGUID = go->GetGUID();
449 break;
450 case GO_PLAGUE_SIGIL:
451 PlagueSigilGUID = go->GetGUID();
454 break;
456 BloodwingSigilGUID = go->GetGUID();
459 break;
461 FrostwingSigilGUID = go->GetGUID();
464 break;
466 PutricideCollisionGUID = go->GetGUID();
469 break;
471 PutricideGateGUIDs[0] = go->GetGUID();
474 else if (GetBossState(DATA_FESTERGUT) == DONE)
476 break;
478 PutricideGateGUIDs[1] = go->GetGUID();
481 else if (GetBossState(DATA_ROTFACE) == DONE)
483 break;
485 PutricidePipeGUIDs[0] = go->GetGUID();
488 break;
490 PutricidePipeGUIDs[1] = go->GetGUID();
493 break;
494 case GO_DRINK_ME:
495 PutricideTableGUID = go->GetGUID();
496 break;
501 if (Creature* valithria = instance->GetCreature(ValithriaDreamwalkerGUID))
502 go->SetLootRecipient(valithria->GetLootRecipient());
504 break;
506 TheLichKingTeleportGUID = go->GetGUID();
508 go->SetGoState(GOState::GO_STATE_ACTIVE);
509 break;
511 ArthasPlatformGUID = go->GetGUID();
512 break;
514 ArthasPrecipiceGUID = go->GetGUID();
515 break;
517 FrozenThroneEdgeGUID = go->GetGUID();
518 break;
520 FrozenThroneWindGUID = go->GetGUID();
521 break;
523 FrozenThroneWarningGUID = go->GetGUID();
524 break;
526 FrozenBolvarGUID = go->GetGUID();
528 go->SetRespawnTime(7 * DAY);
529 break;
531 PillarsChainedGUID = go->GetGUID();
533 go->SetRespawnTime(7 * DAY);
534 break;
536 PillarsUnchainedGUID = go->GetGUID();
538 go->SetRespawnTime(7 * DAY);
539 break;
540 default:
541 break;
542 }
543 }
544
578
580 {
581 switch (type)
582 {
584 return FrostwyrmGUIDs.size();
586 return SpinestalkerTrash.size();
587 case DATA_RIMEFANG:
588 return RimefangTrash.size();
590 return ColdflameJetsState;
592 return TeamInInstance;
596 return HeroicAttempts;
597 default:
598 break;
599 }
600
601 return 0;
602 }
603
605 {
606 switch (type)
607 {
616 case DATA_FESTERGUT:
617 return FestergutGUID;
618 case DATA_ROTFACE:
619 return RotfaceGUID;
623 return PutricideTableGUID;
625 return BloodCouncilGUIDs[0];
627 return BloodCouncilGUIDs[1];
629 return BloodCouncilGUIDs[2];
635 return CrokScourgebaneGUID;
642 return SisterSvalnaGUID;
649 case DATA_SINDRAGOSA:
650 return SindragosaGUID;
652 return SpinestalkerGUID;
653 case DATA_RIMEFANG:
654 return RimefangGUID;
656 return TheLichKingGUID;
660 return ArthasPlatformGUID;
662 return TerenasMenethilGUID;
663 default:
664 break;
665 }
666
667 return 0;
668 }
669
671 {
672 if (!InstanceScript::SetBossState(type, state))
673 return false;
674
675 switch (type)
676 {
678 SetBossState(DATA_GUNSHIP_EVENT, state); // TEMP HACK UNTIL GUNSHIP SCRIPTED
679 if (state == DONE)
680 {
681 if (GameObject* elevator = instance->GetGameObject(LadyDeathwisperElevatorGUID))
682 {
683 elevator->SetUInt32Value(GAMEOBJECT_FIELD_LEVEL, 0);
684 elevator->SetGoState(GOState::GO_STATE_READY);
685 }
686 }
687 break;
689 switch (state)
690 {
691 case DONE:
692 if (GameObject* loot = instance->GetGameObject(DeathbringersCacheGUID))
693 {
694 if (Creature* deathbringer = instance->GetCreature(DeathbringerSaurfangGUID))
695 loot->SetLootRecipient(deathbringer->GetLootRecipient());
697 }
698 // no break
699 case NOT_STARTED:
700 if (GameObject* teleporter = instance->GetGameObject(SaurfangTeleportGUID))
701 {
702 HandleGameObject(SaurfangTeleportGUID, true, teleporter);
703 teleporter->RemoveFlag(GAMEOBJECT_FIELD_FLAGS, GO_FLAG_IN_USE);
704 }
705 break;
706 default:
707 break;
708 }
709 break;
710 case DATA_FESTERGUT:
711 if (state == DONE)
712 {
714 {
716 if (GameObject* go = instance->GetGameObject(PutricideGateGUIDs[0]))
718 if (GameObject* go = instance->GetGameObject(PutricideGateGUIDs[1]))
720 }
721 else
724 }
725 break;
726 case DATA_ROTFACE:
727 if (state == DONE)
728 {
730 {
732 if (GameObject* go = instance->GetGameObject(PutricideGateGUIDs[0]))
734 if (GameObject* go = instance->GetGameObject(PutricideGateGUIDs[1]))
736 }
737 else
740 }
741 break;
744 if (state == DONE)
746 if (instance->IsHeroic())
747 {
748 if (state == FAIL && HeroicAttempts)
749 {
752 if (!HeroicAttempts)
753 if (Creature* putricide = instance->GetCreature(ProfessorPutricideGUID))
754 putricide->DespawnOrUnsummon();
755 }
756 }
757 break;
760 if (state == DONE)
762 if (instance->IsHeroic())
763 {
764 if (state == FAIL && HeroicAttempts)
765 {
768 if (!HeroicAttempts)
769 if (Creature* bq = instance->GetCreature(BloodQueenLanaThelGUID))
770 bq->DespawnOrUnsummon();
771 }
772 }
773 break;
775 if (state == DONE && sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[8].questId[instance->GetSpawnMode() & 1]))
777 break;
778 case DATA_SINDRAGOSA:
780 if (state == DONE)
782 if (instance->IsHeroic())
783 {
784 if (state == FAIL && HeroicAttempts)
785 {
788 if (!HeroicAttempts)
789 if (Creature* sindra = instance->GetCreature(SindragosaGUID))
790 sindra->DespawnOrUnsummon();
791 }
792 }
793 break;
795 {
796 // set the platform as active object to dramatically increase visibility range
797 // note: "active" gameobjects do not block grid unloading
798 if (GameObject* precipice = instance->GetGameObject(ArthasPrecipiceGUID))
799 precipice->setActive(state == IN_PROGRESS);
800 if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID))
801 platform->setActive(state == IN_PROGRESS);
802
803 if (instance->IsHeroic())
804 {
805 if (state == FAIL && HeroicAttempts)
806 {
809 if (!HeroicAttempts)
810 if (Creature* theLichKing = instance->GetCreature(TheLichKingGUID))
811 theLichKing->DespawnOrUnsummon();
812 }
813 }
814
815 if (state == DONE)
816 {
817 if (GameObject* bolvar = instance->GetGameObject(FrozenBolvarGUID))
818 bolvar->SetRespawnTime(7 * DAY);
819 if (GameObject* pillars = instance->GetGameObject(PillarsChainedGUID))
820 pillars->SetRespawnTime(7 * DAY);
821 if (GameObject* pillars = instance->GetGameObject(PillarsUnchainedGUID))
822 pillars->SetRespawnTime(7 * DAY);
823 }
824 break;
825 }
826 default:
827 break;
828 }
829
830 return true;
831 }
832
833 void SetData(uint32 type, uint32 data) OVERRIDE
834 {
835 switch (type)
836 {
838 IsBonedEligible = data ? true : false;
839 break;
841 IsOozeDanceEligible = data ? true : false;
842 break;
844 IsNauseaEligible = data ? true : false;
845 break;
847 IsOrbWhispererEligible = data ? true : false;
848 break;
850 FrostwyrmGUIDs.insert(data);
851 break;
853 SpinestalkerTrash.insert(data);
854 break;
855 case DATA_RIMEFANG:
856 RimefangTrash.insert(data);
857 break;
859 ColdflameJetsState = data;
861 SaveToDB();
862 break;
864 {
865 // skip if nothing changes
866 if (BloodQuickeningState == data)
867 break;
868
869 // 5 is the index of Blood Quickening
870 if (!sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[5].questId[instance->GetSpawnMode() & 1]))
871 break;
872
873 switch (data)
874 {
875 case IN_PROGRESS:
876 Events.ScheduleEvent(EVENT_UPDATE_EXECUTION_TIME, 60000);
880 break;
881 case DONE:
885 break;
886 default:
887 break;
888 }
889
891 SaveToDB();
892 break;
893 }
894 default:
895 break;
896 }
897 }
898
899 bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) OVERRIDE
900 {
901 switch (criteria_id)
902 {
907 return IsBonedEligible;
912 return IsOozeDanceEligible;
917 return IsNauseaEligible;
923 // Only one criteria for both modes, need to do it like this
927 return instance->ToInstanceMap()->GetMaxPlayers() == 10;
931 return instance->ToInstanceMap()->GetMaxPlayers() == 25;
932 default:
933 break;
934 }
935
936 return false;
937 }
938
939 bool CheckRequiredBosses(uint32 bossId, Player const* player = NULL) const OVERRIDE
940 {
941 if (player && player->GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES))
942 return true;
943
944 switch (bossId)
945 {
947 if (!CheckPlagueworks(bossId))
948 return false;
949 if (!CheckCrimsonHalls(bossId))
950 return false;
951 if (!CheckFrostwingHalls(bossId))
952 return false;
953 break;
954 case DATA_SINDRAGOSA:
956 if (!CheckFrostwingHalls(bossId))
957 return false;
958 break;
961 if (!CheckCrimsonHalls(bossId))
962 return false;
963 break;
964 case DATA_FESTERGUT:
965 case DATA_ROTFACE:
967 if (!CheckPlagueworks(bossId))
968 return false;
969 break;
970 default:
971 break;
972 }
973
974 if (!CheckLowerSpire(bossId))
975 return false;
976
977 return true;
978 }
979
980 bool CheckPlagueworks(uint32 bossId) const
981 {
982 switch (bossId)
983 {
986 return false;
987 // no break
990 return false;
991 break;
992 default:
993 break;
994 }
995
996 return true;
997 }
998
999 bool CheckCrimsonHalls(uint32 bossId) const
1000 {
1001 switch (bossId)
1002 {
1003 case DATA_THE_LICH_KING:
1005 return false;
1006 // no break
1009 return false;
1010 break;
1011 default:
1012 break;
1013 }
1014
1015 return true;
1016 }
1017
1018 bool CheckFrostwingHalls(uint32 bossId) const
1019 {
1020 switch (bossId)
1021 {
1022 case DATA_THE_LICH_KING:
1024 return false;
1025 // no break
1026 case DATA_SINDRAGOSA:
1028 return false;
1029 break;
1030 default:
1031 break;
1032 }
1033
1034 return true;
1035 }
1036
1037 bool CheckLowerSpire(uint32 bossId) const
1038 {
1039 switch (bossId)
1040 {
1041 case DATA_THE_LICH_KING:
1042 case DATA_SINDRAGOSA:
1047 case DATA_ROTFACE:
1048 case DATA_FESTERGUT:
1050 return false;
1051 // no break
1054 return false;
1055 // no break
1056 case DATA_GUNSHIP_EVENT:
1058 return false;
1059 // no break
1062 return false;
1063 // no break
1065 default:
1066 break;
1067 }
1068
1069 return true;
1070 }
1071
1073 {
1075 {
1076 if (GameObject* teleporter = instance->GetGameObject(TheLichKingTeleportGUID))
1077 {
1078 teleporter->SetGoState(GOState::GO_STATE_ACTIVE);
1079
1080 std::list<Creature*> stalkers;
1081 GetCreatureListWithEntryInGrid(stalkers, teleporter, NPC_INVISIBLE_STALKER, 100.0f);
1082 if (stalkers.empty())
1083 return;
1084
1085 stalkers.sort(Skyfire::ObjectDistanceOrderPred(teleporter));
1086 stalkers.front()->CastSpell((Unit*)NULL, SPELL_ARTHAS_TELEPORTER_CEREMONY, false);
1087 stalkers.pop_front();
1088 for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
1089 (*itr)->AI()->Reset();
1090 }
1091 }
1092 }
1093
1094 std::string GetSaveData() OVERRIDE
1095 {
1097
1098 std::ostringstream saveStream;
1099 saveStream << "I C " << GetBossSaveData() << HeroicAttempts << ' '
1101
1103 return saveStream.str();
1104 }
1105
1106 void Load(const char* str) OVERRIDE
1107 {
1108 if (!str)
1109 {
1111 return;
1112 }
1113
1114 OUT_LOAD_INST_DATA(str);
1115
1116 char dataHead1, dataHead2;
1117
1118 std::istringstream loadStream(str);
1119 loadStream >> dataHead1 >> dataHead2;
1120
1121 if (dataHead1 == 'I' && dataHead2 == 'C')
1122 {
1123 for (uint32 i = 0; i < EncounterCount; ++i)
1124 {
1125 uint32 tmpState;
1126 loadStream >> tmpState;
1127 if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
1128 tmpState = NOT_STARTED;
1129 SetBossState(i, EncounterState(tmpState));
1130 }
1131
1132 loadStream >> HeroicAttempts;
1133
1134 uint32 temp = 0;
1135 loadStream >> temp;
1137
1138 loadStream >> temp;
1139 BloodQuickeningState = temp ? DONE : NOT_STARTED; // DONE means finished (not success/fail)
1140 loadStream >> BloodQuickeningMinutes;
1141 }
1142 else
1144
1146 }
1147
1149 {
1151 return;
1152
1153 Events.Update(diff);
1154
1155 while (uint32 eventId = Events.ExecuteEvent())
1156 {
1157 switch (eventId)
1158 {
1160 {
1163 {
1164 Events.ScheduleEvent(EVENT_UPDATE_EXECUTION_TIME, 60000);
1167 }
1168 else
1169 {
1172 if (Creature* bq = instance->GetCreature(BloodQueenLanaThelGUID))
1173 bq->AI()->DoAction(ACTION_KILL_MINCHAR);
1174 }
1175 SaveToDB();
1176 break;
1177 }
1179 {
1180 if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID))
1181 platform->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
1182 if (GameObject* edge = instance->GetGameObject(FrozenThroneEdgeGUID))
1183 edge->SetGoState(GOState::GO_STATE_ACTIVE);
1184 if (GameObject* wind = instance->GetGameObject(FrozenThroneWindGUID))
1185 wind->SetGoState(GOState::GO_STATE_READY);
1186 if (GameObject* warning = instance->GetGameObject(FrozenThroneWarningGUID))
1187 warning->SetGoState(GOState::GO_STATE_READY);
1188 if (Creature* theLichKing = instance->GetCreature(TheLichKingGUID))
1189 theLichKing->AI()->DoAction(ACTION_RESTORE_LIGHT);
1190 break;
1191 }
1193 if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID))
1194 platform->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING);
1195 if (GameObject* edge = instance->GetGameObject(FrozenThroneEdgeGUID))
1196 edge->SetGoState(GOState::GO_STATE_READY);
1197 if (GameObject* wind = instance->GetGameObject(FrozenThroneWindGUID))
1198 wind->SetGoState(GOState::GO_STATE_ACTIVE);
1199 break;
1200 default:
1201 break;
1202 }
1203 }
1204 }
1205
1206 void ProcessEvent(WorldObject* /*source*/, uint32 eventId) OVERRIDE
1207 {
1208 switch (eventId)
1209 {
1210 case EVENT_QUAKE:
1211 if (GameObject* warning = instance->GetGameObject(FrozenThroneWarningGUID))
1212 warning->SetGoState(GOState::GO_STATE_ACTIVE);
1213 Events.ScheduleEvent(EVENT_QUAKE_SHATTER, 5000);
1214 break;
1216 if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID))
1217 {
1218 platform->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED);
1219 Events.ScheduleEvent(EVENT_REBUILD_PLATFORM, 1500);
1220 }
1221 break;
1222 case EVENT_TELEPORT_TO_FROSMOURNE: // Harvest Soul (normal mode)
1223 if (Creature* terenas = instance->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE, TerenasSpawn, NULL, 63000))
1224 {
1225 terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO);
1226 std::list<Creature*> triggers;
1228 if (!triggers.empty())
1229 {
1230 triggers.sort(Skyfire::ObjectDistanceOrderPred(terenas, false));
1231 Unit* visual = triggers.front();
1232 visual->CastSpell(visual, SPELL_FROSTMOURNE_TELEPORT_VISUAL, true);
1233 }
1234
1235 if (Creature* warden = instance->SummonCreature(NPC_SPIRIT_WARDEN, SpiritWardenSpawn, NULL, 63000))
1236 {
1237 terenas->AI()->AttackStart(warden);
1238 warden->AddThreat(terenas, 300000.0f);
1239 }
1240 }
1241 break;
1242 }
1243 }
1244
1245 protected:
1250 uint64 DeathbringerSaurfangEventGUID; // Muradin Bronzebeard or High Overlord Saurfang
1289 std::set<uint32> FrostwyrmGUIDs;
1290 std::set<uint32> SpinestalkerTrash;
1291 std::set<uint32> RimefangTrash;
1299 };
1300
1305};
1306
@ DAY
Definition Common.h:121
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
std::uint16_t uint16
Definition Define.h:78
@ GO_STATE_ACTIVE
Definition GameObject.h:576
@ GO_STATE_READY
Definition GameObject.h:577
@ GO_STATE_ACTIVE_ALTERNATIVE
Definition GameObject.h:578
#define OUT_LOAD_INST_DATA_FAIL
EncounterState
@ IN_PROGRESS
@ FAIL
@ 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_SPAWN_HOLE
@ DOOR_TYPE_ROOM
@ DOOR_TYPE_PASSAGE
@ BOUNDARY_NONE
@ BOUNDARY_SE
@ BOUNDARY_SW
@ BOUNDARY_W
@ BOUNDARY_S
@ BOUNDARY_N
@ BOUNDARY_E
#define sPoolMgr
Definition PoolMgr.h:154
void GetCreatureListWithEntryInGrid(std::list< Creature * > &list, WorldObject *source, uint32 entry, float maxSearchRange)
@ GO_DESTRUCTIBLE_DESTROYED
@ GO_DESTRUCTIBLE_REBUILDING
@ GO_DESTRUCTIBLE_DAMAGED
@ ALLIANCE
@ GO_FLAG_NODESPAWN
@ GO_FLAG_NOT_SELECTABLE
@ GO_FLAG_IN_USE
@ GO_FLAG_LOCKED
@ REACT_PASSIVE
Definition Unit.h:1156
@ GAMEOBJECT_FIELD_LEVEL
@ GAMEOBJECT_FIELD_FLAGS
@ NPC_PRINCE_TALDARAM
Definition ahnkahet.h:37
uint32 const EncounterCount
Position const SindragosaSpawnPos
Position const TerenasSpawn
Position const SpiritWardenSpawn
Position const ValithriaSpawnPos
@ NPC_THE_LICH_KING
Definition chapter5.cpp:143
uint32 GetDBTableGUIDLow() const
Definition Creature.h:445
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 AddDoor(GameObject *door, bool add)
void LoadDoorData(DoorData const *data)
void HandleGameObject(uint64 guid, bool open, GameObject *go=NULL)
void DoUpdateWorldState(uint32 worldstateId, uint32 worldstateValue)
bool isEmpty() const
Definition LinkedList.h:86
MapRefManager PlayerList
Definition Map.h:406
iterator begin()
uint64 GetGUID() const
Definition Object.h:119
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
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
InstanceScript * GetInstanceScript(InstanceMap *map) const OVERRIDE
@ DATA_TEAM_IN_INSTANCE
@ GO_ICE_WALL
uint32 const MaxHeroicAttempts
@ NPC_THE_LICH_KING_VALITHRIA
@ NPC_UVLUS_BANEFIRE
@ NPC_GREEN_DRAGON_COMBAT_TRIGGER
@ NPC_CAPTAIN_BRANDON
@ NPC_INFILTRATOR_MINCHAR_BQ
@ NPC_TERENAS_MENETHIL_FROSTMOURNE
@ NPC_SKYBREAKER_LIEUTENANT
@ NPC_PRINCE_VALANAR
@ NPC_YILI
@ NPC_VALITHRIA_DREAMWALKER
@ NPC_ALRIN_THE_AGILE
@ NPC_YMIRJAR_BATTLE_MAIDEN
@ NPC_ALLIANCE_COMMANDER
@ NPC_TALAN_MOONSTRIKE
@ NPC_ROTTING_FROST_GIANT_25
@ NPC_ALANA_MOONSTRIKE
@ NPC_ALCHEMIST_ADRIANNA
@ NPC_IKFIRUS_THE_VILE
@ NPC_DEATHBRINGER_SAURFANG
@ NPC_KING_VARIAN_WRYNN
@ NPC_KOR_KRON_GENERAL
@ NPC_SPIRIT_WARDEN
@ NPC_SINDRAGOSA
@ NPC_BLOOD_ORB_CONTROLLER
@ NPC_YMIRJAR_WARLORD
@ NPC_KOR_KRON_LIEUTENANT
@ NPC_SE_SKYBREAKER_MARINE
@ NPC_CAPTAIN_RUPERT
@ NPC_ROTTING_FROST_GIANT_10
@ NPC_FESTERGUT
@ NPC_HARAGG_THE_UNSEEN
@ NPC_INFILTRATOR_MINCHAR
@ NPC_WICKED_SPIRIT
@ NPC_BLOOD_QUEEN_LANA_THEL
@ NPC_HIGHLORD_TIRION_FORDRING_LK
@ NPC_YMIRJAR_HUNTRESS
@ NPC_MALFUS_GRIMFROST
@ NPC_JEDEBIA
@ NPC_ROTFACE
@ NPC_SE_HIGH_OVERLORD_SAURFANG
@ NPC_MINCHAR_BEAM_STALKER
@ NPC_PROFESSOR_PUTRICIDE
@ NPC_NIBY_THE_ALMIGHTY
@ NPC_VOL_GUK
@ NPC_CROK_SCOURGEBANE
@ NPC_SE_KOR_KRON_REAVER
@ NPC_TORTUNOK
@ NPC_WORLD_TRIGGER_INFINITE_AOI
@ NPC_GARROSH_HELLSCREAM
@ NPC_FROSTWING_WHELP
@ NPC_SISTER_SVALNA
@ NPC_SPINESTALKER
@ NPC_YMIRJAR_FROSTBINDER
@ NPC_GERARDO_THE_SUAVE
@ NPC_PRINCE_KELESETH
@ NPC_CAPTAIN_GRONDEL
@ NPC_SE_MURADIN_BRONZEBEARD
@ NPC_VALITHRIA_DREAMWALKER_QUEST
@ NPC_TERENAS_MENETHIL_FROSTMOURNE_H
@ NPC_CAPTAIN_ARNATH
@ NPC_INVISIBLE_STALKER
@ CRITERIA_BONED_25H
@ CRITERIA_BONED_10N
@ CRITERIA_NAUSEA_10H
@ CRITERIA_BONED_25N
@ CRITERIA_BONED_10H
@ CRITERIA_ONCE_BITTEN_TWICE_SHY_25V
@ CRITERIA_DANCES_WITH_OOZES_10H
@ CRITERIA_NAUSEA_10N
@ CRITERIA_NAUSEA_25N
@ CRITERIA_ONCE_BITTEN_TWICE_SHY_10V
@ CRITERIA_NAUSEA_25H
@ CRITERIA_ORB_WHISPERER_25H
@ CRITERIA_DANCES_WITH_OOZES_10N
@ CRITERIA_DANCES_WITH_OOZES_25H
@ CRITERIA_KILL_LANA_THEL_25M
@ CRITERIA_ONCE_BITTEN_TWICE_SHY_10N
@ CRITERIA_DANCES_WITH_OOZES_25N
@ CRITERIA_ORB_WHISPERER_25N
@ CRITERIA_KILL_LANA_THEL_10M
@ CRITERIA_ORB_WHISPERER_10N
@ CRITERIA_ORB_WHISPERER_10H
@ CRITERIA_ONCE_BITTEN_TWICE_SHY_25N
@ ACTION_FROSTMOURNE_INTRO
@ ACTION_VRYKUL_DEATH
@ ACTION_START_FROSTWYRM
@ ACTION_RESTORE_LIGHT
@ ACTION_KILL_MINCHAR
#define ICCScriptName
uint32 const WeeklyNPCs
@ SPELL_ARTHAS_TELEPORTER_CEREMONY
@ SPELL_FROSTMOURNE_TELEPORT_VISUAL
@ WORLDSTATE_SHOW_ATTEMPTS
@ WORLDSTATE_ATTEMPTS_REMAINING
@ WORLDSTATE_ATTEMPTS_MAX
@ WORLDSTATE_EXECUTION_TIME
@ WORLDSTATE_SHOW_TIMER
@ GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR
@ GO_SCIENTIST_AIRLOCK_DOOR_GREEN
@ GO_SCOURGE_TRANSPORTER_LK
@ GO_GREEN_PLAGUE_MONSTER_ENTRANCE
@ GO_SAURFANG_S_DOOR
@ GO_SCIENTIST_AIRLOCK_DOOR_COLLISION
@ GO_DOODAD_ICECROWN_GREENTUBES02
@ GO_DEATHBRINGER_S_CACHE_10N
@ GO_CACHE_OF_THE_DREAMWALKER_25H
@ GO_FROZEN_LAVAMAN
@ GO_BLOODWING_SIGIL
@ GO_DEATHBRINGER_S_CACHE_25N
@ GO_LADY_DEATHWHISPER_ELEVATOR
@ GO_CACHE_OF_THE_DREAMWALKER_25N
@ GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT
@ GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR
@ GO_DOODAD_ICECROWN_SNOWEDGEWARNING01
@ GO_SCOURGE_TRANSPORTER_SAURFANG
@ GO_DOODAD_ICECROWN_ICEWALL02
@ GO_ICEWALL
@ GO_LAVAMAN_PILLARS_UNCHAINED
@ GO_ORATORY_OF_THE_DAMNED_ENTRANCE
@ GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04
@ GO_SCIENTIST_AIRLOCK_DOOR_ORANGE
@ GO_ARTHAS_PLATFORM
@ GO_CACHE_OF_THE_DREAMWALKER_10N
@ GO_GREEN_DRAGON_BOSS_EXIT
@ GO_ORANGE_PLAGUE_MONSTER_ENTRANCE
@ GO_PLAGUE_SIGIL
@ GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01
@ GO_DEATHBRINGER_S_CACHE_10H
@ GO_DOODAD_ICECROWN_THRONEFROSTYWIND01
@ GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02
@ GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03
@ GO_SIGIL_OF_THE_FROSTWING
@ GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01
@ GO_BLOOD_ELF_COUNCIL_DOOR
@ GO_DOODAD_ICECROWN_ORANGETUBES02
@ GO_DEATHBRINGER_S_CACHE_25H
@ GO_DOODAD_ICECROWN_GRATE_01
@ GO_LORD_MARROWGAR_S_ENTRANCE
@ GO_SCIENTIST_ENTRANCE
@ GO_LAVAMAN_PILLARS_CHAINED
@ GO_DRINK_ME
@ GO_CRIMSON_HALL_DOOR
@ GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01
@ GO_CACHE_OF_THE_DREAMWALKER_10H
@ GO_GREEN_DRAGON_BOSS_ENTRANCE
@ GO_SINDRAGOSA_ENTRANCE_DOOR
@ GO_ARTHAS_PRECIPICE
@ DATA_ORB_WHISPERER_ACHIEVEMENT
@ DATA_THE_LICH_KING
@ DATA_HEROIC_ATTEMPTS
@ DATA_GUNSHIP_EVENT
@ DATA_SINDRAGOSA_FROSTWYRMS
@ DATA_BLOOD_PRINCE_COUNCIL
@ DATA_DEATHBRINGER_SAURFANG
@ DATA_VALITHRIA_LICH_KING
@ DATA_OOZE_DANCE_ACHIEVEMENT
@ DATA_NAUSEA_ACHIEVEMENT
@ DATA_BLOOD_PRINCES_CONTROL
@ DATA_PRINCE_TALDARAM_GUID
@ DATA_PRINCE_VALANAR_GUID
@ DATA_VALITHRIA_TRIGGER
@ DATA_TERENAS_MENETHIL
@ DATA_SISTER_SVALNA
@ DATA_ROTFACE
@ DATA_CROK_SCOURGEBANE
@ DATA_SAURFANG_EVENT_NPC
@ DATA_VALITHRIA_DREAMWALKER
@ DATA_HIGHLORD_TIRION_FORDRING
@ DATA_SINDRAGOSA
@ DATA_LORD_MARROWGAR
@ DATA_BLOOD_QUICKENING_STATE
@ DATA_COLDFLAME_JETS
@ DATA_BLOOD_QUEEN_LANA_THEL
@ DATA_PROFESSOR_PUTRICIDE
@ DATA_CAPTAIN_RUPERT
@ DATA_PUTRICIDE_TABLE
@ DATA_CAPTAIN_ARNATH
@ DATA_FESTERGUT
@ DATA_SPINESTALKER
@ DATA_PRINCE_KELESETH_GUID
@ DATA_LADY_DEATHWHISPER
@ DATA_BONED_ACHIEVEMENT
@ DATA_CAPTAIN_GRONDEL
@ DATA_CAPTAIN_BRANDON
@ DATA_ARTHAS_PLATFORM
@ QUEST_DEPROGRAMMING_25
@ QUEST_SECURING_THE_RAMPARTS_25
@ QUEST_RESIDUE_RENDEZVOUS_10
@ QUEST_SECURING_THE_RAMPARTS_10
@ QUEST_BLOOD_QUICKENING_10
@ QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_10
@ QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_25
@ QUEST_DEPROGRAMMING_10
@ QUEST_BLOOD_QUICKENING_25
@ QUEST_RESIDUE_RENDEZVOUS_25
DoorData const doorData[]
void AddSC_instance_icecrown_citadel()
DoorData const doorData[]
@ EVENT_UPDATE_EXECUTION_TIME
WeeklyQuest const WeeklyQuestData[WeeklyNPCs]
@ EVENT_SECOND_REMORSELESS_WINTER
@ EVENT_TELEPORT_TO_FROSMOURNE
@ RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES
Definition RBAC.h:53
@ NPC_RIMEFANG
@ NPC_YMIRJAR_DEATHBRINGER
@ DATA_RIMEFANG
bool CheckRequiredBosses(uint32 bossId, Player const *player=NULL) const OVERRIDE
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const *, Unit const *, uint32) OVERRIDE