TrinityCore
Loading...
Searching...
No Matches
instance_trial_of_the_crusader.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
18#include "ScriptMgr.h"
19#include "AreaBoundary.h"
20#include "GameObject.h"
21#include "InstanceScript.h"
22#include "Log.h"
23#include "Map.h"
24#include "ObjectAccessor.h"
25#include "Player.h"
26#include "ScriptedCreature.h"
27#include "TemporarySummon.h"
29
30 // ToDo: Remove magic numbers of events
31
33{
34 { DATA_NORTHREND_BEASTS, new CircleBoundary(Position(563.26f, 139.6f), 75.0) },
35 { DATA_JARAXXUS, new CircleBoundary(Position(563.26f, 139.6f), 75.0) },
36 { DATA_FACTION_CRUSADERS, new CircleBoundary(Position(563.26f, 139.6f), 75.0) },
37 { DATA_TWIN_VALKIRIES, new CircleBoundary(Position(563.26f, 139.6f), 75.0) },
38 { DATA_ANUBARAK, new EllipseBoundary(Position(746.0f, 135.0f), 100.0, 75.0) }
39};
40
63
84
95
97{
98 public:
100
102 {
125
126 void OnPlayerEnter(Player* player) override
127 {
128 if (instance->IsHeroic())
129 {
132 }
133 else
135
136 if (Team == TEAM_OTHER)
137 Team = player->GetTeam();
138
141 }
142
143 void OnCreatureCreate(Creature* creature) override
144 {
146 if (creature->GetEntry() == NPC_SNOBOLD_VASSAL)
147 snoboldGUIDS.push_back(creature->GetGUID());
148 }
149
150 // Summon prevention to heroic modes
151 uint32 GetCreatureEntry(ObjectGuid::LowType /*guidLow*/, CreatureData const* data) override
152 {
153 if (!TrialCounter)
154 return 0;
155
156 return data->id;
157 }
158
166
167 void OnUnitDeath(Unit* unit) override
168 {
171
172 }
173
174 bool SetBossState(uint32 type, EncounterState state) override
175 {
176 if (!InstanceScript::SetBossState(type, state))
177 return false;
178
179 switch (type)
180 {
182 break;
183 case DATA_JARAXXUS:
184 if (state == FAIL)
185 {
186 if (Creature* fordring = GetCreature(DATA_FORDRING))
187 fordring->AI()->DoAction(ACTION_JARAXXUS_WIPE);
189 }
190 else if (state == DONE)
191 {
192 if (Creature* fordring = GetCreature(DATA_FORDRING))
193 fordring->AI()->DoAction(ACTION_JARAXXUS_DEFEATED);
194 EventStage = 2000;
195 }
196 break;
198 switch (state)
199 {
200 case IN_PROGRESS:
202 break;
203 case FAIL:
204 CrusadersSpecialState = false;
205 if (Creature* fordring = GetCreature(DATA_FORDRING))
206 fordring->AI()->DoAction(ACTION_FACTION_WIPE);
207 break;
208 case DONE:
214 cache->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
215 if (Creature* fordring = GetCreature(DATA_FORDRING))
216 fordring->AI()->DoAction(ACTION_CHAMPIONS_DEFEATED);
217 EventStage = 3100;
218 break;
219 default:
220 break;
221 }
222 break;
224 // Cleanup chest
226 cache->Delete();
227 switch (state)
228 {
229 case FAIL:
230 if (Creature* fordring = GetCreature(DATA_FORDRING))
231 fordring->AI()->DoAction(ACTION_VALKYR_WIPE);
232 break;
233 case DONE:
234 if (Creature* fordring = GetCreature(DATA_FORDRING))
235 fordring->AI()->DoAction(ACTION_VALKYR_DEFEATED);
236 break;
237 default:
238 break;
239 }
240 break;
241 case DATA_LICH_KING:
242 break;
243 case DATA_ANUBARAK:
244 switch (state)
245 {
246 case DONE:
247 {
248 EventStage = 6000;
249 uint32 tributeChest = 0;
251 {
252 if (TrialCounter >= 50)
253 tributeChest = GO_TRIBUTE_CHEST_10H_99;
254 else
255 {
256 if (TrialCounter >= 45)
257 tributeChest = GO_TRIBUTE_CHEST_10H_50;
258 else
259 {
260 if (TrialCounter >= 25)
261 tributeChest = GO_TRIBUTE_CHEST_10H_45;
262 else
263 tributeChest = GO_TRIBUTE_CHEST_10H_25;
264 }
265 }
266 }
268 {
269 if (TrialCounter >= 50)
270 tributeChest = GO_TRIBUTE_CHEST_25H_99;
271 else
272 {
273 if (TrialCounter >= 45)
274 tributeChest = GO_TRIBUTE_CHEST_25H_50;
275 else
276 {
277 if (TrialCounter >= 25)
278 tributeChest = GO_TRIBUTE_CHEST_25H_45;
279 else
280 tributeChest = GO_TRIBUTE_CHEST_25H_25;
281 }
282 }
283 }
284
285 if (tributeChest)
286 if (Creature* tirion = GetCreature(DATA_FORDRING))
287 if (GameObject* chest = tirion->SummonGameObject(tributeChest, 805.62f, 134.87f, 142.16f, 3.27f, QuaternionData(), 7_days))
288 chest->SetRespawnTime(chest->GetRespawnDelay());
289 break;
290 }
291 default:
292 break;
293 }
294 break;
295 default:
296 break;
297 }
298
299 if (type < EncounterCount)
300 {
301 TC_LOG_DEBUG("scripts", "[ToCr] BossState(type {}) {} = state {};", type, GetBossState(type), state);
302 if (state == FAIL)
303 {
304 if (instance->IsHeroic())
305 {
306 --TrialCounter;
307 // decrease attempt counter at wipe
308 Map::PlayerList const& PlayerList = instance->GetPlayers();
309 for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
310 if (Player* player = itr->GetSource())
311 player->SendUpdateWorldState(UPDATE_STATE_UI_COUNT, TrialCounter);
312
313 // if theres no more attemps allowed
314 if (!TrialCounter)
315 {
316 if (Creature* anubarak = GetCreature(DATA_ANUBARAK))
317 anubarak->DespawnOrUnsummon();
318 }
319 }
320 NeedSave = true;
321 EventStage = (type == DATA_NORTHREND_BEASTS ? 666 : 0);
322 state = NOT_STARTED;
323 }
324
325 if (state == DONE || NeedSave)
326 Save();
327 }
328 return true;
329 }
330
332 {
335 {
339 EventStage = 400;
340 if (Creature* combatStalker = GetCreature(DATA_BEASTS_COMBAT_STALKER))
341 combatStalker->DespawnOrUnsummon();
342 HandlePlayerVehicle(false);
343 if (Creature* fordring = GetCreature(DATA_FORDRING))
344 fordring->AI()->DoAction(ACTION_NORTHREND_BEASTS_DEFEATED);
345 }
346 }
347
348 void HandlePlayerVehicle(bool apply)
349 {
350 Map::PlayerList const &players = instance->GetPlayers();
351 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
352 if (Player* player = itr->GetSource())
353 {
354 if (apply)
355 player->CreateVehicleKit(PLAYER_VEHICLE_ID, 0);
356 else
357 player->RemoveVehicleKit();
358 }
359 }
360
361 void SetData(uint32 type, uint32 data) override
362 {
363 switch (type)
364 {
365 case TYPE_COUNTER:
366 TrialCounter = data;
367 data = DONE;
368 break;
369 case TYPE_EVENT:
370 EventStage = data;
371 data = NOT_STARTED;
372 break;
373 case TYPE_EVENT_TIMER:
374 EventTimer = data;
375 data = NOT_STARTED;
376 break;
378 NorthrendBeasts = data;
379 switch (data)
380 {
385 break;
386 case GORMOK_DONE:
387 if (Creature* tirion = GetCreature(DATA_FORDRING))
388 tirion->AI()->DoAction(ACTION_START_JORMUNGARS);
390 break;
393 break;
394 case SNAKES_SPECIAL:
397 break;
398 case SNAKES_DONE:
401 if (Creature* tirion = GetCreature(DATA_FORDRING))
402 tirion->AI()->DoAction(ACTION_START_ICEHOWL);
404 break;
405 case ICEHOWL_DONE:
407 break;
408 case FAIL:
409 HandlePlayerVehicle(false);
411 if (Creature* tirion = GetCreature(DATA_FORDRING))
412 tirion->AI()->DoAction(ACTION_NORTHREND_BEASTS_WIPE);
413 SnoboldCount = 0;
414 break;
415 default:
416 break;
417 }
418 break;
420 for (ObjectGuid guid : snoboldGUIDS)
421 if (Creature* snobold = instance->GetCreature(guid))
422 snobold->DespawnOrUnsummon();
423 snoboldGUIDS.clear();
424 break;
425 //Achievements
427 if (data == INCREASE)
428 ++SnoboldCount;
429 else if (data == DECREASE)
430 --SnoboldCount;
431 break;
433 if (data == INCREASE)
435 else if (data == DECREASE)
437 break;
438 case DATA_FACTION_CRUSADERS: // Achivement Resilience will Fix
441 break;
442 default:
443 break;
444 }
445 }
446
447 uint32 GetData(uint32 type) const override
448 {
449 switch (type)
450 {
451 case DATA_TEAM:
452 return Team;
453 case TYPE_COUNTER:
454 return TrialCounter;
455 case TYPE_EVENT:
456 return EventStage;
458 return NorthrendBeasts;
459 case TYPE_EVENT_TIMER:
460 return EventTimer;
461 case TYPE_EVENT_NPC:
462 switch (EventStage)
463 {
464 case 110:
465 case 140:
466 case 150:
467 case 155:
468 case 200:
469 case 205:
470 case 210:
471 case 220:
472 case 300:
473 case 305:
474 case 310:
475 case 315:
476 case 400:
477 case 666:
478 case 1010:
479 case 1180:
480 case 2000:
481 case 2030:
482 case 3000:
483 case 3001:
484 case 3060:
485 case 3061:
486 case 3090:
487 case 3091:
488 case 3092:
489 case 3100:
490 case 3110:
491 case 4000:
492 case 4010:
493 case 4015:
494 case 4016:
495 case 4040:
496 case 4050:
497 case 5000:
498 case 5005:
499 case 5020:
500 case 6000:
501 case 6005:
502 case 6010:
503 return NPC_TIRION_FORDRING;
504 break;
505 case 5010:
506 case 5030:
507 case 5040:
508 case 5050:
509 case 5060:
510 case 5070:
511 case 5080:
512 return NPC_LICH_KING;
513 break;
514 case 120:
515 case 122:
516 case 2020:
517 case 3080:
518 case 3051:
519 case 3071:
520 case 4020:
521 return NPC_VARIAN;
522 break;
523 case 130:
524 case 132:
525 case 2010:
526 case 3050:
527 case 3070:
528 case 3081:
529 case 4030:
530 return NPC_GARROSH;
531 break;
532 case 1110:
533 case 1120:
534 case 1130:
535 case 1132:
536 case 1134:
537 case 1135:
538 case 1140:
539 case 1142:
540 case 1144:
541 case 1150:
542 return NPC_FIZZLEBANG;
543 break;
544 default:
545 return NPC_TIRION_FORDRING;
546 break;
547 };
548 default:
549 break;
550 }
551
552 return 0;
553 }
554
555 void Update(uint32 diff) override
556 {
558 {
559 if (NotOneButTwoJormungarsTimer <= diff)
561 else
563 }
564
566 {
567 if (ResilienceWillFixItTimer <= diff)
569 else
571 }
572 }
573
574 void Save()
575 {
576 SaveToDB();
577 NeedSave = false;
578 }
579
580 void WriteSaveDataMore(std::ostringstream& data) override
581 {
582 data << TrialCounter << ' '
583 << uint32(TributeToImmortalityEligible ? 1 : 0) << ' '
585 }
586
587 void ReadSaveDataMore(std::istringstream& data) override
588 {
589 uint32 temp = 0;
590
591 data >> TrialCounter;
592
593 data >> temp;
595
596 data >> temp;
597 TributeToDedicatedInsanity = temp != 0;
598 }
599
600 bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) override
601 {
602 switch (criteria_id)
603 {
606 return SnoboldCount >= 2;
609 return SnoboldCount >= 4;
614 return MistressOfPainCount >= 2;
617 return TrialCounter >= 25;
620 return TrialCounter >= 45;
624 return TrialCounter == 50;
629 return false/*TrialCounter == 50 && TributeToDedicatedInsanity*/;
630 default:
631 break;
632 }
633
634 return false;
635 }
636
637 protected:
646
647 // Achievement stuff
655 };
656
661};
662
@ IN_MILLISECONDS
Definition Common.h:35
@ RAID_DIFFICULTY_25MAN_HEROIC
Definition DBCEnums.h:289
@ RAID_DIFFICULTY_10MAN_HEROIC
Definition DBCEnums.h:288
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition DBCEnums.h:154
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
EncounterState
@ IN_PROGRESS
@ FAIL
@ DONE
@ NOT_STARTED
@ DOOR_TYPE_ROOM
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
std::vector< ObjectGuid > GuidVector
Definition ObjectGuid.h:262
@ GO_DESTRUCTIBLE_DAMAGED
@ TEAM_OTHER
@ GO_FLAG_NOT_SELECTABLE
@ DATA_ANUBARAK
Definition azjol_nerub.h:33
@ NPC_ANUBARAK
Definition azjol_nerub.h:48
#define DataHeader
uint32 const EncounterCount
void SetDestructibleState(GameObjectDestructibleState state, WorldObject *attackerOrHealer=nullptr, bool setHealth=false)
void SetBossNumber(uint32 number)
virtual bool SetBossState(uint32 id, EncounterState state)
virtual void OnCreatureCreate(Creature *creature) override
Creature * GetCreature(uint32 type)
void DoUpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
virtual ObjectGuid GetGuidData(uint32 type) const override
InstanceMap * instance
EncounterState GetBossState(uint32 id) const
void DoRespawnGameObject(ObjectGuid guid, Seconds timeToDespawn=1min)
virtual void OnGameObjectCreate(GameObject *go) override
virtual bool IsEncounterInProgress() const
void LoadDoorData(DoorData const *data)
GameObject * GetGameObject(uint32 type)
void LoadBossBoundaries(BossBoundaryData const &data)
void SetHeaders(std::string const &dataHeaders)
void LoadObjectData(ObjectData const *creatureData, ObjectData const *gameObjectData)
iterator end()
iterator begin()
uint8 GetSpawnMode() const
Definition Map.h:388
bool IsHeroic() const
Definition Map.cpp:4256
PlayerList const & GetPlayers() const
Definition Map.h:448
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:4397
uint32 LowType
Definition ObjectGuid.h:142
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 GetTeam() const
Definition Player.h:1832
void SendUpdateWorldState(uint32 variable, uint32 value) const
Definition Player.cpp:8493
Definition Unit.h:769
bool CreateVehicleKit(uint32 id, uint32 creatureEntry)
Definition Unit.cpp:11796
GameObject * SummonGameObject(uint32 entry, Position const &pos, QuaternionData const &rot, Seconds respawnTime, GOSummonType summonType=GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)
Definition Object.cpp:2015
InstanceScript * GetInstanceScript(InstanceMap *map) const override
ObjectData const gameObjectData[]
ObjectData const creatureData[]
DoorData const doorData[]
BossBoundaryData const boundaries
void AddSC_instance_trial_of_the_crusader()
uint32 id
Definition SpawnData.h:96
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const *, Unit const *, uint32) override
@ DATA_MAIN_GATE
@ NPC_CHAMPIONS_CONTROLLER
@ NPC_SNOBOLD_VASSAL
@ NPC_FJOLA_LIGHTBANE
@ NPC_BEASTS_COMBAT_STALKER
@ NPC_EYDIS_DARKBANE
@ NPC_TIRION_FORDRING_ANUBARAK
@ NPC_FURIOUS_CHARGE_STALKER
@ NPC_TIRION_FORDRING
@ NPC_LICH_KING_VOICE
@ ACTION_START_JORMUNGARS
@ ACTION_FACTION_WIPE
@ ACTION_JARAXXUS_WIPE
@ ACTION_NORTHREND_BEASTS_DEFEATED
@ ACTION_NORTHREND_BEASTS_WIPE
@ ACTION_JARAXXUS_DEFEATED
@ ACTION_CHAMPIONS_DEFEATED
@ ACTION_START_ICEHOWL
@ ACTION_VALKYR_DEFEATED
@ ACTION_VALKYR_WIPE
@ PLAYER_VEHICLE_ID
@ THREE_SIXTY_PAIN_SPIKE_25_PLAYER
@ THREE_SIXTY_PAIN_SPIKE_10_PLAYER
@ A_TRIBUTE_TO_INSANITY_10_PLAYER
@ THREE_SIXTY_PAIN_SPIKE_25_PLAYER_HEROIC
@ A_TRIBUTE_TO_MAD_SKILL_10_PLAYER
@ SPELL_DEFEAT_FACTION_CHAMPIONS
@ A_TRIBUTE_TO_IMMORTALITY_ALLIANCE
@ SPELL_CHAMPIONS_KILLED_IN_MINUTE
@ UPPER_BACK_PAIN_25_PLAYER
@ A_TRIBUTE_TO_MAD_SKILL_25_PLAYER
@ A_TRIBUTE_TO_INSANITY_25_PLAYER
@ REALM_FIRST_GRAND_CRUSADER
@ THREE_SIXTY_PAIN_SPIKE_10_PLAYER_HEROIC
@ UPPER_BACK_PAIN_25_PLAYER_HEROIC
@ UPPER_BACK_PAIN_10_PLAYER
@ A_TRIBUTE_TO_SKILL_10_PLAYER
@ A_TRIBUTE_TO_DEDICATED_INSANITY
@ UPPER_BACK_PAIN_10_PLAYER_HEROIC
@ SPELL_WORMS_KILLED_IN_10_SECONDS
@ A_TRIBUTE_TO_IMMORTALITY_HORDE
@ A_TRIBUTE_TO_SKILL_25_PLAYER
@ DATA_EAST_PORTCULLIS
@ DATA_TWIN_VALKIRIES
@ DATA_WEB_DOOR
@ DATA_TRIBUTE_CHEST
@ DATA_DESPAWN_SNOBOLDS
@ DATA_DREADSCALE
@ DATA_COLISEUM_FLOOR
@ DATA_GORMOK_THE_IMPALER
@ DATA_FORDRING_ANUBARAK
@ TYPE_EVENT_NPC
@ DATA_JARAXXUS
@ DATA_NORTHREND_BEASTS
@ DATA_MISTRESS_OF_PAIN_COUNT
@ DATA_LICH_KING
@ DATA_FACTION_CRUSADERS
@ DATA_FORDRING
@ TYPE_NORTHREND_BEASTS
@ DATA_SNOBOLD_COUNT
@ DATA_LICH_KING_VOICE
@ DATA_CRUSADERS_CHEST
@ DATA_EYDIS_DARKBANE
@ TYPE_EVENT_TIMER
@ DATA_FIZZLEBANG
@ DATA_FJOLA_LIGHTBANE
@ DATA_BEASTS_COMBAT_STALKER
@ DATA_FURIOUS_CHARGE
@ GORMOK_IN_PROGRESS
@ SNAKES_IN_PROGRESS
@ UPDATE_STATE_UI_COUNT
@ UPDATE_STATE_UI_SHOW
@ GO_TRIBUTE_CHEST_10H_99
@ GO_TRIBUTE_CHEST_25H_25
@ GO_TRIBUTE_CHEST_25H_99
@ GO_TRIBUTE_CHEST_25H_45
@ GO_CRUSADERS_CACHE_10_H
@ GO_TRIBUTE_CHEST_10H_45
@ GO_TRIBUTE_CHEST_25H_50
@ GO_CRUSADERS_CACHE_10
@ GO_CRUSADERS_CACHE_25_H
@ GO_TRIBUTE_CHEST_10H_25
@ GO_EAST_PORTCULLIS
@ GO_CRUSADERS_CACHE_25
@ GO_ARGENT_COLISEUM_FLOOR
@ GO_MAIN_GATE_DOOR
@ GO_TRIBUTE_CHEST_10H_50
#define ToCrScriptName