TrinityCore
Loading...
Searching...
No Matches
karazhan.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/* ScriptData
19SDName: Karazhan
20SD%Complete: 100
21SDComment: Support for Barnes (Opera controller) and Berthold (Doorman), Support for Quest 9645.
22SDCategory: Karazhan
23EndScriptData */
24
25/* ContentData
26npc_barnes
27npc_image_of_medivh
28EndContentData */
29
30#include "ScriptMgr.h"
31#include "InstanceScript.h"
32#include "karazhan.h"
33#include "Log.h"
34#include "Map.h"
35#include "MotionMaster.h"
36#include "ObjectAccessor.h"
37#include "Player.h"
38#include "ScriptedEscortAI.h"
39#include "ScriptedGossip.h"
40#include "SpellScript.h"
41#include "TemporarySummon.h"
42
44{
45 // Barnes
47 SPELL_TUXEDO = 32616,
48
49 // Berthold
51
52 // Image of Medivh
56 SPELL_MANA_SHIELD = 31635
57};
58
60{
62 NPC_SPOTLIGHT = 19525
63};
64
65/*######
66# npc_barnesAI
67######*/
68
69enum Misc
70{
71 OZ_GOSSIP1_MID = 7421, // I'm not an actor.
73 OZ_GOSSIP2_MID = 7422, // Ok, I'll give it a try, then.
75};
76
77#define OZ_GM_GOSSIP1 "[GM] Change event to EVENT_OZ"
78#define OZ_GM_GOSSIP2 "[GM] Change event to EVENT_HOOD"
79#define OZ_GM_GOSSIP3 "[GM] Change event to EVENT_RAJ"
80
86
88{
89 {0, 6000},
90 {1, 18000},
91 {2, 9000},
92 {3, 15000}
93};
94
96{
97 {4, 6000},
98 {5, 10000},
99 {6, 14000},
100 {7, 15000}
101};
102
104{
105 {8, 5000},
106 {9, 7000},
107 {10, 14000},
108 {11, 14000}
109};
110
111// Entries and spawn locations for creatures in Oz event
112float Spawns[6][2]=
113{
114 {17535, -10896}, // Dorothee
115 {17546, -10891}, // Roar
116 {17547, -10884}, // Tinhead
117 {17543, -10902}, // Strawman
118 {17603, -10892}, // Grandmother
119 {17534, -10900}, // Julianne
120};
121
122#define SPAWN_Z 90.5f
123#define SPAWN_Y -1758
124#define SPAWN_O 4.738f
125
126static constexpr uint32 PATH_ESCORT_BARNES = 134498;
127
129{
130public:
131 npc_barnes() : CreatureScript("npc_barnes") { }
132
133 struct npc_barnesAI : public EscortAI
134 {
135 npc_barnesAI(Creature* creature) : EscortAI(creature)
136 {
137 Initialize();
138 RaidWiped = false;
139 m_uiEventId = 0;
140 instance = creature->GetInstanceScript();
141 }
142
144 {
146
147 TalkCount = 0;
148 TalkTimer = 2000;
149 WipeTimer = 5000;
150
151 PerformanceReady = false;
152 }
153
155
157
162
165
166 void Reset() override
167 {
168 Initialize();
169
171 }
172
174 {
176
177 //resets count for this event, in case earlier failed
178 if (m_uiEventId == EVENT_OZ)
180
182 Start(false);
183 }
184
185 void JustEngagedWith(Unit* /*who*/) override { }
186
187 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
188 {
189 switch (waypointId)
190 {
191 case 0:
192 DoCast(me, SPELL_TUXEDO, false);
194 break;
195 case 4:
196 TalkCount = 0;
197 SetEscortPaused(true);
198
199 if (Creature* spotlight = me->SummonCreature(NPC_SPOTLIGHT,
200 me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f,
202 {
203 spotlight->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
204 spotlight->CastSpell(spotlight, SPELL_SPOTLIGHT, false);
205 m_uiSpotlightGUID = spotlight->GetGUID();
206 }
207 break;
208 case 8:
210 PerformanceReady = true;
211 break;
212 case 9:
215 break;
216 }
217 }
218
219 void Talk(uint32 count)
220 {
221 int32 text = 0;
222
223 switch (m_uiEventId)
224 {
225 case EVENT_OZ:
226 if (OzDialogue[count].textid)
227 text = OzDialogue[count].textid;
228 if (OzDialogue[count].timer)
229 TalkTimer = OzDialogue[count].timer;
230 break;
231
232 case EVENT_HOOD:
233 if (HoodDialogue[count].textid)
234 text = HoodDialogue[count].textid;
235 if (HoodDialogue[count].timer)
237 break;
238
239 case EVENT_RAJ:
240 if (RAJDialogue[count].textid)
241 text = RAJDialogue[count].textid;
242 if (RAJDialogue[count].timer)
243 TalkTimer = RAJDialogue[count].timer;
244 break;
245 }
246
247 if (text)
248 CreatureAI::Talk(text);
249 }
250
252 {
253 TC_LOG_DEBUG("scripts", "Barnes Opera Event - Introduction complete - preparing encounter {}", m_uiEventId);
254 uint8 index = 0;
255 uint8 count = 0;
256
257 switch (m_uiEventId)
258 {
259 case EVENT_OZ:
260 index = 0;
261 count = 4;
262 break;
263 case EVENT_HOOD:
264 index = 4;
265 count = index+1;
266 break;
267 case EVENT_RAJ:
268 index = 5;
269 count = index+1;
270 break;
271 }
272
273 for (; index < count; ++index)
274 {
275 uint32 entry = ((uint32)Spawns[index][0]);
276 float PosX = Spawns[index][1];
277
279 creature->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
280 }
281
282 RaidWiped = false;
283 }
284
285 void UpdateAI(uint32 diff) override
286 {
287 EscortAI::UpdateAI(diff);
288
290 {
291 if (TalkTimer <= diff)
292 {
293 if (TalkCount > 3)
294 {
296 pSpotlight->DespawnOrUnsummon();
297
298 SetEscortPaused(false);
299 return;
300 }
301
303 ++TalkCount;
304 } else TalkTimer -= diff;
305 }
306
308 {
309 if (!RaidWiped)
310 {
311 if (WipeTimer <= diff)
312 {
313 Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
314 if (PlayerList.isEmpty())
315 return;
316
317 RaidWiped = true;
318 for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
319 {
320 if (i->GetSource()->IsAlive() && !i->GetSource()->IsGameMaster())
321 {
322 RaidWiped = false;
323 break;
324 }
325 }
326
327 if (RaidWiped)
328 {
330 return;
331 }
332
333 WipeTimer = 15000;
334 } else WipeTimer -= diff;
335 }
336 }
337 }
338
339 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
340 {
341 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
342 ClearGossipMenuFor(player);
343
344 switch (action)
345 {
346 case GOSSIP_ACTION_INFO_DEF + 1:
349 SendGossipMenuFor(player, 8971, me->GetGUID());
350 break;
351 case GOSSIP_ACTION_INFO_DEF + 2:
352 CloseGossipMenuFor(player);
354 StartEvent();
355 break;
356 case GOSSIP_ACTION_INFO_DEF + 3:
357 CloseGossipMenuFor(player);
359 TC_LOG_DEBUG("scripts", "player ({}) manually set Opera event to EVENT_OZ", player->GetGUID().ToString());
360 break;
361 case GOSSIP_ACTION_INFO_DEF + 4:
362 CloseGossipMenuFor(player);
364 TC_LOG_DEBUG("scripts", "player ({}) manually set Opera event to EVENT_HOOD", player->GetGUID().ToString());
365 break;
366 case GOSSIP_ACTION_INFO_DEF + 5:
367 CloseGossipMenuFor(player);
369 TC_LOG_DEBUG("scripts", "player ({}) manually set Opera event to EVENT_RAJ", player->GetGUID().ToString());
370 break;
371 }
372
373 return true;
374 }
375
376 bool OnGossipHello(Player* player) override
377 {
379 // Check for death of Moroes and if opera event is not done already
381 {
383
384 if (player->IsGameMaster())
385 {
389 }
390
391 if (!RaidWiped)
392 SendGossipMenuFor(player, 8970, me->GetGUID());
393 else
394 SendGossipMenuFor(player, 8975, me->GetGUID());
395
396 return true;
397 }
398
399 SendGossipMenuFor(player, 8978, me->GetGUID());
400 return true;
401 }
402 };
403
404 CreatureAI* GetAI(Creature* creature) const override
405 {
406 return GetKarazhanAI<npc_barnesAI>(creature);
407 }
408};
409
410/*###
411# npc_image_of_medivh
412####*/
413
414enum
415{
426
427static float MedivPos[4] = {-11161.49f, -1902.24f, 91.48f, 1.94f};
428static float ArcanagosPos[4] = {-11169.75f, -1881.48f, 95.39f, 4.83f};
429
431{
432public:
433 npc_image_of_medivh() : CreatureScript("npc_image_of_medivh") { }
434
435 CreatureAI* GetAI(Creature* creature) const override
436 {
437 return GetKarazhanAI<npc_image_of_medivhAI>(creature);
438 }
439
441 {
443 {
444 Initialize();
445 Step = 0;
447 FireMedivhTimer = 0;
448 instance = creature->GetInstanceScript();
449 }
450
452 {
454 EventStarted = false;
455 YellTimer = 0;
456 }
457
459
461
466
468
469 void Reset() override
470 {
471 Initialize();
473
475 {
477 (*me).GetMotionMaster()->MovePoint(1, MedivPos[0], MedivPos[1], MedivPos[2]);
478 Step = 0;
479 }
480 else
481 {
483 }
484 }
485 void JustEngagedWith(Unit* /*who*/) override { }
486
487 void MovementInform(uint32 type, uint32 id) override
488 {
489 if (type != POINT_MOTION_TYPE)
490 return;
491 if (id == 1)
492 {
493 StartEvent();
496 }
497 }
498
500 {
501 Step = 1;
502 EventStarted = true;
504 if (!Arcanagos)
505 return;
506 ArcanagosGUID = Arcanagos->GetGUID();
507 Arcanagos->SetDisableGravity(true);
509 Arcanagos->SetOrientation(ArcanagosPos[3]);
511 YellTimer = 10000;
512 }
513
515 {
516 switch (step)
517 {
518 case 0: return 9999999;
519 case 1:
521 return 10000;
522 case 2:
524 arca->AI()->Talk(SAY_DIALOG_ARCANAGOS_2);
525 return 20000;
526 case 3:
528 return 10000;
529 case 4:
531 arca->AI()->Talk(SAY_DIALOG_ARCANAGOS_4);
532 return 20000;
533 case 5:
535 return 20000;
536 case 6:
538 arca->AI()->Talk(SAY_DIALOG_ARCANAGOS_6);
539 return 10000;
540 case 7:
541 FireArcanagosTimer = 500;
542 return 5000;
543 case 8:
544 FireMedivhTimer = 500;
546 return 10000;
547 case 9:
549 return 10000;
550 case 10:
552 DoCast(arca, SPELL_CONFLAGRATION_BLAST, false);
553 return 1000;
554 case 11:
556 arca->AI()->Talk(SAY_DIALOG_ARCANAGOS_8);
557 return 5000;
558 case 12:
560 {
561 arca->GetMotionMaster()->MovePoint(0, -11010.82f, -1761.18f, 156.47f);
562 arca->setActive(true);
563 arca->SetFarVisible(true);
564 arca->InterruptNonMeleeSpells(true);
565 arca->SetSpeedRate(MOVE_FLIGHT, 2.0f);
566 }
567 return 10000;
568 case 13:
570 return 10000;
571 case 14:
572 {
573 me->SetVisible(false);
574 me->ClearInCombat();
575
576 InstanceMap::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
577 for (InstanceMap::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
578 {
579 if (i->GetSource()->IsAlive())
580 {
581 if (i->GetSource()->GetQuestStatus(9645) == QUEST_STATUS_INCOMPLETE)
582 i->GetSource()->CompleteQuest(9645);
583 }
584 }
585 return 50000;
586 }
587 case 15:
589 arca->KillSelf();
590 return 5000;
591 default:
592 return 9999999;
593 }
594 }
595
596 void UpdateAI(uint32 diff) override
597 {
598 if (YellTimer <= diff)
599 {
600 if (EventStarted)
602 } else YellTimer -= diff;
603
604 if (Step >= 7 && Step <= 12)
605 {
607
608 if (FireArcanagosTimer <= diff)
609 {
610 if (arca)
611 arca->CastSpell(me, SPELL_FIRE_BALL, false);
612 FireArcanagosTimer = 6000;
613 } else FireArcanagosTimer -= diff;
614
615 if (FireMedivhTimer <= diff)
616 {
617 if (arca)
618 DoCast(arca, SPELL_FIRE_BALL);
619 FireMedivhTimer = 5000;
620 } else FireMedivhTimer -= diff;
621 }
622 }
623 };
624};
625
627{
628 SPELL_FEAR = 29321
630
631// 29320 - Charge
633{
635
636 bool Validate(SpellInfo const* /*spellInfo*/) override
637 {
638 return ValidateSpellInfo({ SPELL_FEAR });
639 }
640
642 {
644 }
645
650};
651
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ GOSSIP_ICON_DOT
Definition GossipDef.h:70
@ IN_PROGRESS
@ DONE
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
@ POINT_MOTION_TYPE
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
Spells
Definition PlayerAI.cpp:32
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:107
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
@ STATE_ESCORT_PAUSED
void SendGossipMenuFor(Player *player, uint32 npcTextID, ObjectGuid const &guid)
void AddGossipItemFor(Player *player, GossipOptionIcon icon, std::string const &text, uint32 sender, uint32 action)
void ClearGossipMenuFor(Player *player)
void InitGossipMenuFor(Player *player, uint32 menuId)
void CloseGossipMenuFor(Player *player)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
#define SpellHitFn(F)
@ MOVE_FLIGHT
@ UNIT_FLAG_NON_ATTACKABLE
@ UNIT_FLAG_UNINTERACTIBLE
Creatures
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Creature *const me
Definition CreatureAI.h:82
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
virtual bool SetBossState(uint32 id, EncounterState state)
virtual ObjectGuid GetGuidData(uint32 type) const override
void DoUseDoorOrButton(ObjectGuid guid, uint32 withRestoreTime=0, bool useAlternativeState=false)
EncounterState GetBossState(uint32 id) const
bool isEmpty() const
Definition LinkedList.h:108
iterator end()
iterator begin()
PlayerList const & GetPlayers() const
Definition Map.h:448
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
bool IsEmpty() const
Definition ObjectGuid.h:172
std::string ToString() const
void Clear()
Definition ObjectGuid.h:150
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 GetGossipOptionAction(uint32 selection) const
Definition GossipDef.h:269
bool IsGameMaster() const
Definition Player.h:998
PlayerMenu * PlayerTalkClass
Definition Player.h:1969
Unit * GetCaster() const
HookList< HitHandler > AfterHit
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
void SetVisible(bool x)
Definition Unit.cpp:8513
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition Unit.cpp:13286
void ClearInCombat()
Definition Unit.h:1147
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
Map * GetMap() const
Definition Object.h:449
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1992
virtual uint32 GetData(uint32) const
Definition ZoneScript.h:55
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:56
virtual void SetGuidData(uint32, ObjectGuid)
Definition ZoneScript.h:49
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
CreatureAI * GetAI(Creature *creature) const override
Definition karazhan.cpp:404
CreatureAI * GetAI(Creature *creature) const override
Definition karazhan.cpp:435
bool Validate(SpellInfo const *) override
Definition karazhan.cpp:636
void Register() override
Definition karazhan.cpp:646
PrepareSpellScript(spell_karazhan_charge)
Spawns
Definition hyjalAI.cpp:37
static float ArcanagosPos[4]
Definition karazhan.cpp:428
#define OZ_GM_GOSSIP2
Definition karazhan.cpp:78
static float MedivPos[4]
Definition karazhan.cpp:427
KarazhanCharge
Definition karazhan.cpp:627
@ SPELL_FEAR
Definition karazhan.cpp:628
#define SPAWN_Y
Definition karazhan.cpp:123
@ NPC_ARCANAGOS
Definition karazhan.cpp:61
@ NPC_SPOTLIGHT
Definition karazhan.cpp:62
static Dialogue HoodDialogue[]
Definition karazhan.cpp:95
#define SPAWN_O
Definition karazhan.cpp:124
@ OZ_GOSSIP2_MID
Definition karazhan.cpp:73
@ OZ_GOSSIP1_OID
Definition karazhan.cpp:72
@ OZ_GOSSIP2_OID
Definition karazhan.cpp:74
@ OZ_GOSSIP1_MID
Definition karazhan.cpp:71
@ SAY_DIALOG_MEDIVH_1
Definition karazhan.cpp:416
@ SAY_DIALOG_ARCANAGOS_8
Definition karazhan.cpp:423
@ SAY_DIALOG_MEDIVH_9
Definition karazhan.cpp:424
@ SAY_DIALOG_ARCANAGOS_4
Definition karazhan.cpp:419
@ SAY_DIALOG_ARCANAGOS_2
Definition karazhan.cpp:417
@ SAY_DIALOG_MEDIVH_5
Definition karazhan.cpp:420
@ SAY_DIALOG_ARCANAGOS_6
Definition karazhan.cpp:421
@ SAY_DIALOG_MEDIVH_3
Definition karazhan.cpp:418
@ EMOTE_DIALOG_MEDIVH_7
Definition karazhan.cpp:422
@ SPELL_TUXEDO
Definition karazhan.cpp:47
@ SPELL_FIRE_BALL
Definition karazhan.cpp:53
@ SPELL_CONFLAGRATION_BLAST
Definition karazhan.cpp:55
@ SPELL_MANA_SHIELD
Definition karazhan.cpp:56
@ SPELL_TELEPORT
Definition karazhan.cpp:50
@ SPELL_SPOTLIGHT
Definition karazhan.cpp:46
@ SPELL_UBER_FIREBALL
Definition karazhan.cpp:54
static Dialogue OzDialogue[]
Definition karazhan.cpp:87
#define SPAWN_Z
Definition karazhan.cpp:122
#define OZ_GM_GOSSIP3
Definition karazhan.cpp:79
static constexpr uint32 PATH_ESCORT_BARNES
Definition karazhan.cpp:126
static Dialogue RAJDialogue[]
Definition karazhan.cpp:103
#define OZ_GM_GOSSIP1
Definition karazhan.cpp:77
void AddSC_karazhan()
Definition karazhan.cpp:652
@ EVENT_HOOD
Definition karazhan.h:65
@ EVENT_OZ
Definition karazhan.h:64
@ EVENT_RAJ
Definition karazhan.h:66
@ DATA_GO_CURTAINS
Definition karazhan.h:46
@ DATA_GO_STAGEDOORLEFT
Definition karazhan.h:47
@ DATA_IMAGE_OF_MEDIVH
Definition karazhan.h:55
@ DATA_MOROES
Definition karazhan.h:31
@ DATA_OPERA_OZ_DEATHCOUNT
Definition karazhan.h:43
@ DATA_OPERA_PERFORMANCE
Definition karazhan.h:34
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
int32 textid
Definition karazhan.cpp:83
uint32 timer
Definition karazhan.cpp:84
void Start(bool isActiveAttacker=true, ObjectGuid playerGUID=ObjectGuid::Empty, Quest const *quest=nullptr, bool instantRespawn=false, bool canLoopPath=false)
bool HasEscortState(uint32 escortState)
void EnterEvadeMode(EvadeReason=EVADE_REASON_OTHER) override
void LoadPath(uint32 pathId)
void SetEscortPaused(bool on)
void UpdateAI(uint32 diff) override
float GetPositionZ() const
Definition Position.h:81
void SetOrientation(float orientation)
Definition Position.h:74
float GetPositionX() const
Definition Position.h:79
float GetPositionY() const
Definition Position.h:80
void UpdateAI(uint32 diff) override
Definition karazhan.cpp:285
void JustEngagedWith(Unit *) override
Definition karazhan.cpp:185
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
Definition karazhan.cpp:339
void Reset() override
Definition karazhan.cpp:166
void WaypointReached(uint32 waypointId, uint32) override
Definition karazhan.cpp:187
bool OnGossipHello(Player *player) override
Definition karazhan.cpp:376
void Talk(uint32 count)
Definition karazhan.cpp:219
InstanceScript * instance
Definition karazhan.cpp:154
npc_barnesAI(Creature *creature)
Definition karazhan.cpp:135
void MovementInform(uint32 type, uint32 id) override
Definition karazhan.cpp:487
void UpdateAI(uint32 diff) override
Definition karazhan.cpp:596