Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
zone_nagrand.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/* ScriptData
7SDName: Nagrand
8SD%Complete: 90
9SDComment: Quest support: 9868, 9874, 10044, 10172, 10085. TextId's unknown for altruis_the_sufferer and greatmother_geyah (npc_text)
10SDCategory: Nagrand
11EndScriptData */
12
13/* ContentData
14npc_greatmother_geyah
15npc_maghar_captive
16npc_creditmarker_visit_with_ancestors
17EndContentData */
18#include "ScriptMgr.h"
19#include "ScriptedCreature.h"
20#include "ScriptedGossip.h"
21#include "ScriptedEscortAI.h"
22#include "Player.h"
23#include "SpellInfo.h"
24
25/*######
26## npc_greatmother_geyah
27######*/
28
29#define GOSSIP_HGG1 "Hello, Greatmother. Garrosh told me that you wanted to speak with me."
30#define GOSSIP_HGG2 "Garrosh is beyond redemption, Greatmother. I fear that in helping the Mag'har, I have convinced Garrosh that he is unfit to lead."
31
32#define GOSSIP_SGG1 "You raised all of the orcs here, Greatmother?"
33#define GOSSIP_SGG2 "Do you believe that?"
34#define GOSSIP_SGG3 "What can be done? I have tried many different things. I have done my best to help the people of Nagrand. Each time I have approached Garrosh, he has dismissed me."
35#define GOSSIP_SGG4 "Left? How can you choose to leave?"
36#define GOSSIP_SGG5 "What is this duty?"
37#define GOSSIP_SGG6 "Is there anything I can do for you, Greatmother?"
38#define GOSSIP_SGG7 "I have done all that I could, Greatmother. I thank you for your kind words."
39#define GOSSIP_SGG8 "Greatmother, you are the mother of Durotan?"
40#define GOSSIP_SGG9 "Greatmother, I never had the honor. Durotan died long before my time, but his heroics are known to all on my world. The orcs of Azeroth reside in a place known as Durotar, named after your son. And ... (You take a moment to breathe and think through what you are about to tell the Greatmother.)"
41#define GOSSIP_SGG10 "It is my Warchief, Greatmother. The leader of my people. From my world. He ... He is the son of Durotan. He is your grandchild."
42#define GOSSIP_SGG11 "I will return to Azeroth at once, Greatmother."
43
44//all the textId's for the below is unknown, but i do believe the gossip item texts are proper.
46{
47public:
48 npc_greatmother_geyah() : CreatureScript("npc_greatmother_geyah") { }
49
50 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
51 {
52 player->PlayerTalkClass->ClearMenus();
53 switch (action)
54 {
57 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
58 break;
61 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
62 break;
65 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
66 break;
69 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
70 break;
73 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
74 break;
77 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
78 break;
80 player->AreaExploredOrEventHappens(10044);
81 player->CLOSE_GOSSIP_MENU();
82 break;
83 case GOSSIP_ACTION_INFO_DEF + 10:
85 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
86 break;
87 case GOSSIP_ACTION_INFO_DEF + 11:
89 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
90 break;
91 case GOSSIP_ACTION_INFO_DEF + 12:
93 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
94 break;
95 case GOSSIP_ACTION_INFO_DEF + 13:
97 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
98 break;
99 case GOSSIP_ACTION_INFO_DEF + 14:
101 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
102 break;
103 case GOSSIP_ACTION_INFO_DEF + 15:
104 player->AreaExploredOrEventHappens(10172);
105 player->CLOSE_GOSSIP_MENU();
106 break;
107 }
108 return true;
109 }
110
111 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
112 {
113 if (creature->IsQuestGiver())
114 player->PrepareQuestMenu(creature->GetGUID());
115
116 if (player->GetQuestStatus(10044) == QUEST_STATUS_INCOMPLETE)
117 {
119 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
120 }
121 else if (player->GetQuestStatus(10172) == QUEST_STATUS_INCOMPLETE)
122 {
124 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
125 }
126 else
127 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
128
129 return true;
130 }
131};
132
133/*#####
134## npc_maghar_captive
135#####*/
136
159
160static float m_afAmbushA[]= {-1568.805786f, 8533.873047f, 1.958f};
161static float m_afAmbushB[]= {-1491.554321f, 8506.483398f, 1.248f};
162
164{
165public:
166 npc_maghar_captive() : CreatureScript("npc_maghar_captive") { }
167
168 bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
169 {
170 if (quest->GetQuestId() == QUEST_TOTEM_KARDASH_H)
171 {
172 if (npc_maghar_captiveAI* pEscortAI = dynamic_cast<npc_maghar_captiveAI*>(creature->AI()))
173 {
174 creature->SetStandState(UNIT_STAND_STATE_STAND);
175 creature->setFaction(232);
176
177 pEscortAI->Start(true, false, player->GetGUID(), quest);
178
179 creature->AI()->Talk(SAY_MAG_START);
180
181 creature->SummonCreature(NPC_MURK_RAIDER, m_afAmbushA[0]+2.5f, m_afAmbushA[1]-2.5f, m_afAmbushA[2], 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
182 creature->SummonCreature(NPC_MURK_PUTRIFIER, m_afAmbushA[0]-2.5f, m_afAmbushA[1]+2.5f, m_afAmbushA[2], 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
184 }
185 }
186 return true;
187 }
188
190 {
191 return new npc_maghar_captiveAI(creature);
192 }
193
195 {
196 npc_maghar_captiveAI(Creature* creature) : npc_escortAI(creature) { Reset(); }
197
201
203 {
205 m_uiHealTimer = 0;
206 m_uiFrostShockTimer = 6000;
207 }
208
209 void EnterCombat(Unit* /*who*/) OVERRIDE
210 {
212 }
213
215 {
216 switch (waypointId)
217 {
218 case 7:
220
222 temp->AI()->Talk(SAY_MAG_MORE_REPLY);
223
227 break;
228 case 16:
230
231 if (Player* player = GetPlayerForEscort())
232 player->GroupEventHappens(QUEST_TOTEM_KARDASH_H, me);
233
234 SetRun();
235 break;
236 }
237 }
238
240 {
241 if (summoned->GetEntry() == NPC_MURK_BRUTE)
242 summoned->AI()->Talk(SAY_MAG_NO_ESCAPE);
243
244 if (summoned->IsTotem())
245 return;
246
247 summoned->SetWalk(false);
248 summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
249 summoned->AI()->AttackStart(me);
250 }
251
252 void SpellHitTarget(Unit* /*target*/, const SpellInfo* pSpell) OVERRIDE
253 {
254 if (pSpell->Id == SPELL_CHAIN_LIGHTNING)
255 {
256 if (rand()%10)
257 return;
258
260 }
261 }
262
264 {
266 if (!me->GetVictim())
267 return;
268
269 if (m_uiChainLightningTimer <= uiDiff)
270 {
272 m_uiChainLightningTimer = std::rand() % 14000 + 7000;
273 }
274 else
275 m_uiChainLightningTimer -= uiDiff;
276
277 if (HealthBelowPct(30))
278 {
279 if (m_uiHealTimer <= uiDiff)
280 {
282 m_uiHealTimer = 5000;
283 }
284 else
285 m_uiHealTimer -= uiDiff;
286 }
287
288 if (m_uiFrostShockTimer <= uiDiff)
289 {
291 m_uiFrostShockTimer = std::rand() % 15000 + 7500;
292 }
293 else
294 m_uiFrostShockTimer -= uiDiff;
295
297 }
298 };
299};
300
301/*######
302## npc_creditmarker_visist_with_ancestors
303######*/
304
306{
307public:
308 npc_creditmarker_visit_with_ancestors() : CreatureScript("npc_creditmarker_visit_with_ancestors") { }
309
311 {
312 return new npc_creditmarker_visit_with_ancestorsAI(creature);
313 }
314
316 {
318
319 void Reset() OVERRIDE { }
320
321 void EnterCombat(Unit* /*who*/) OVERRIDE { }
322
324
325 {
326 if (!who)
327 return;
328
329 Player* player = who->ToPlayer();
330 if (player && player->GetQuestStatus(10085) == QUEST_STATUS_INCOMPLETE)
331 {
332 uint32 creditMarkerId = me->GetEntry();
333 if (creditMarkerId >= 18840 && creditMarkerId <= 18843)
334 {
335 // 18840: Sunspring, 18841: Laughing, 18842: Garadar, 18843: Bleeding
336 if (!player->GetReqKillOrCastCurrentCount(10085, creditMarkerId))
337 player->KilledMonsterCredit(creditMarkerId, me->GetGUID());
338 }
339 }
340 }
341 };
342};
343
344/*######
345## go_corkis_prison and npc_corki
346######*/
347
368
370{
371public:
372 go_corkis_prison() : GameObjectScript("go_corkis_prison") { }
373
375 {
376 go->SetGoState(GOState::GO_STATE_READY);
377 if (go->GetEntry() == GO_CORKIS_PRISON)
378 {
379 if (Creature* corki = go->FindNearestCreature(NPC_CORKI, 25, true))
380 {
381 corki->GetMotionMaster()->MovePoint(1, go->GetPositionX()+5, go->GetPositionY(), go->GetPositionZ());
382 if (player)
383 player->KilledMonsterCredit(NPC_CORKI_CREDIT_1, 0);
384 }
385 }
386
387 if (go->GetEntry() == GO_CORKIS_PRISON_2)
388 {
389 if (Creature* corki = go->FindNearestCreature(NPC_CORKI_2, 25, true))
390 {
391 corki->GetMotionMaster()->MovePoint(1, go->GetPositionX()-5, go->GetPositionY(), go->GetPositionZ());
392 if (player)
393 player->KilledMonsterCredit(NPC_CORKI_2, 0);
394 }
395 }
396
397 if (go->GetEntry() == GO_CORKIS_PRISON_3)
398 {
399 if (Creature* corki = go->FindNearestCreature(NPC_CORKI_3, 25, true))
400 {
401 corki->GetMotionMaster()->MovePoint(1, go->GetPositionX()+4, go->GetPositionY(), go->GetPositionZ());
402 if (player)
403 player->KilledMonsterCredit(NPC_CORKI_CREDIT_3, 0);
404 }
405 }
406 return true;
407 }
408};
409
411{
412public:
413 npc_corki() : CreatureScript("npc_corki") { }
414
416 {
417 return new npc_corkiAI(creature);
418 }
419
420 struct npc_corkiAI : public ScriptedAI
421 {
422 npc_corkiAI(Creature* creature) : ScriptedAI(creature) { }
423
426
428 {
429 Say_Timer = 5000;
430 ReleasedFromCage = false;
431 }
432
434 {
436 {
437 if (Say_Timer <= diff)
438 {
439 me->DespawnOrUnsummon();
440 ReleasedFromCage = false;
441 }
442 else
443 Say_Timer -= diff;
444 }
445 }
446
448 {
449 if (type == POINT_MOTION_TYPE && id == 1)
450 {
451 Say_Timer = 5000;
452 ReleasedFromCage = true;
453 if (me->GetEntry() == NPC_CORKI)
455 if (me->GetEntry() == NPC_CORKI_2)
457 if (me->GetEntry() == NPC_CORKI_3)
459 }
460 };
461 };
462};
463
464/*#####
465## npc_kurenai_captive
466#####*/
467
490
491static float kurenaiAmbushA[]= {-1568.805786f, 8533.873047f, 1.958f};
492static float kurenaiAmbushB[]= {-1491.554321f, 8506.483398f, 1.248f};
493
495{
496public:
497 npc_kurenai_captive() : CreatureScript("npc_kurenai_captive") { }
498
499 bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
500 {
501 if (quest->GetQuestId() == QUEST_TOTEM_KARDASH_A)
502 {
503 if (npc_kurenai_captiveAI* EscortAI = dynamic_cast<npc_kurenai_captiveAI*>(creature->AI()))
504 {
505 creature->SetStandState(UNIT_STAND_STATE_STAND);
506 EscortAI->Start(true, false, player->GetGUID(), quest);
507 creature->AI()->Talk(SAY_KUR_START);
508
512 }
513 }
514 return true;
515 }
516
518 {
519 return new npc_kurenai_captiveAI(creature);
520 }
521
523 {
524 npc_kurenai_captiveAI(Creature* creature) : npc_escortAI(creature) { }
525
529
531 {
532 ChainLightningTimer = 1000;
533 HealTimer = 0;
534 FrostShockTimer = 6000;
535 }
536
537 void EnterCombat(Unit* /*who*/) OVERRIDE
538 {
540 }
541
542 void JustDied(Unit* /*killer*/) OVERRIDE
543 {
545 return;
546
547 if (Player* player = GetPlayerForEscort())
548 {
549 if (player->GetQuestStatus(QUEST_TOTEM_KARDASH_A) != QUEST_STATUS_COMPLETE)
550 player->FailQuest(QUEST_TOTEM_KARDASH_A);
551 }
552 }
553
555 {
556 switch (waypointId)
557 {
558 case 3:
559 {
561
564
568 break;
569 }
570 case 7:
571 {
573
574 if (Player* player = GetPlayerForEscort())
575 player->GroupEventHappens(QUEST_TOTEM_KARDASH_A, me);
576
577 SetRun();
578 break;
579 }
580 }
581 }
582
584 {
585 if (summoned->GetEntry() == NPC_KUR_MURK_BRUTE)
587
588 // This function is for when we summoned enemies to fight - so that does NOT mean we should make our totem count in this!
589 if (summoned->IsTotem())
590 return;
591
592 summoned->SetWalk(false);
593 summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
594 summoned->AI()->AttackStart(me);
595 }
596
597 void SpellHitTarget(Unit* /*target*/, const SpellInfo* spell) OVERRIDE
598 {
599 if (spell->Id == SPELL_KUR_CHAIN_LIGHTNING)
600 {
601 if (rand()%30)
602 return;
603
605 }
606
607 if (spell->Id == SPELL_KUR_FROST_SHOCK)
608 {
609 if (rand()%30)
610 return;
611
613 }
614 }
615
617 {
618 if (!UpdateVictim())
619 return;
620
621 if (me->HasUnitState(UNIT_STATE_CASTING))
622 return;
623
624 if (ChainLightningTimer <= diff)
625 {
627 ChainLightningTimer = std::rand() % 14000 + 7000;
628 } else ChainLightningTimer -= diff;
629
630 if (HealthBelowPct(30))
631 {
632 if (HealTimer <= diff)
633 {
635 HealTimer = 5000;
636 } else HealTimer -= diff;
637 }
638
639 if (FrostShockTimer <= diff)
640 {
642 FrostShockTimer = std::rand() % 15000 + 7500;
643 } else FrostShockTimer -= diff;
644
646 }
647 };
648};
649
650/*######
651## go_warmaul_prison
652######*/
653
661
663{
664 public:
665 go_warmaul_prison() : GameObjectScript("go_warmaul_prison") { }
666
668 {
669 go->UseDoorOrButton();
670 if (player->GetQuestStatus(QUEST_FINDING_THE_SURVIVORS) != QUEST_STATUS_INCOMPLETE)
671 return false;
672
673 if (Creature* prisoner = go->FindNearestCreature(NPC_MAGHAR_PRISONER, 5.0f))
674 {
675 player->KilledMonsterCredit(NPC_MAGHAR_PRISONER, 0);
676
677 prisoner->AI()->Talk(SAY_FREE, player);
678 prisoner->DespawnOrUnsummon(6000);
679 }
680 return true;
681 }
682};
683
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ GO_STATE_READY
Definition GameObject.h:577
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ POINT_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:87
@ STATE_ESCORT_ESCORTING
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
@ UNIT_STAND_STATE_STAND
Definition Unit.h:162
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ SPELL_EARTHBIND_TOTEM
@ SPELL_HEALING_WAVE
@ SPELL_CHAIN_LIGHTNING
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureScript(const char *name)
GameObjectScript(const char *name)
Player * ToPlayer()
Definition Object.h:204
void KilledMonsterCredit(uint32 entry, uint64 guid=0)
uint16 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry)
QuestStatus GetQuestStatus(uint32 quest_id) const
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2801
bool OnGossipHello(Player *player, GameObject *go) OVERRIDE
bool OnGossipHello(Player *player, GameObject *go) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnQuestAccept(Player *player, Creature *creature, const Quest *quest) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnQuestAccept(Player *player, Creature *creature, const Quest *quest) OVERRIDE
Creature * me
bool HealthBelowPct(uint32 pct) const
ScriptedAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
npc_corkiAI(Creature *creature)
void MovementInform(uint32 type, uint32 id) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
Player * GetPlayerForEscort()
void SetRun(bool on=true)
bool HasEscortState(uint32 escortState) const
npc_escortAI(Creature *creature)
void SpellHitTarget(Unit *, const SpellInfo *spell) OVERRIDE
void JustSummoned(Creature *summoned) OVERRIDE
void WaypointReached(uint32 waypointId) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 uiDiff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHitTarget(Unit *, const SpellInfo *pSpell) OVERRIDE
void JustSummoned(Creature *summoned) OVERRIDE
void WaypointReached(uint32 waypointId) OVERRIDE
FindingTheSurvivorsData
@ SAY_FREE
@ QUEST_FINDING_THE_SURVIVORS
@ NPC_MAGHAR_PRISONER
KurenaiCaptive
@ QUEST_TOTEM_KARDASH_A
@ NPC_KUR_MURK_BRUTE
@ SAY_KUR_NO_ESCAPE
@ SPELL_KUR_HEALING_WAVE
@ SAY_KUR_MORE_TWO
@ SAY_KUR_LIGHTNING
@ SPELL_KUR_FROST_SHOCK
@ SPELL_KUR_EARTHBIND_TOTEM
@ SPELL_KUR_CHAIN_LIGHTNING
@ SAY_KUR_MORE
@ NPC_KUR_MURK_PUTRIFIER
@ SAY_KUR_COMPLETE
@ SAY_KUR_START
@ SAY_KUR_SHOCK
@ NPC_KUR_MURK_SCAVENGER
@ NPC_KUR_MURK_RAIDER
#define GOSSIP_SGG7
#define GOSSIP_SGG8
#define GOSSIP_HGG1
void AddSC_nagrand()
#define GOSSIP_SGG11
#define GOSSIP_SGG9
#define GOSSIP_SGG6
#define GOSSIP_SGG4
#define GOSSIP_HGG2
#define GOSSIP_SGG5
#define GOSSIP_SGG10
static float kurenaiAmbushA[]
#define GOSSIP_SGG1
MagharCaptive
@ QUEST_TOTEM_KARDASH_H
@ SPELL_EARTHBIND_TOTEM
@ NPC_MURK_SCAVENGER
@ NPC_MURK_RAIDER
@ SAY_MAG_START
@ SAY_MAG_SHOCK
@ SAY_MAG_MORE_REPLY
@ SAY_MAG_LIGHTNING
@ SAY_MAG_MORE
@ SPELL_FROST_SHOCK
@ SAY_MAG_COMPLETE
@ SPELL_HEALING_WAVE
@ NPC_MURK_PUTRIFIER
@ SPELL_CHAIN_LIGHTNING
@ NPC_MURK_BRUTE
@ SAY_MAG_NO_ESCAPE
static float m_afAmbushB[]
CorkiData
@ NPC_CORKI_CREDIT_3
@ GO_CORKIS_PRISON
@ NPC_CORKI_CREDIT_1
@ QUEST_HELP
@ CORKI_SAY_THANKS
@ NPC_CORKI_2
@ QUEST_CORKIS_GONE_MISSING_AGAIN
@ NPC_CORKI_3
@ GO_CORKIS_PRISON_2
@ NPC_CORKI
@ CORKI_SAY_LAST
@ GO_CORKIS_PRISON_3
@ QUEST_CHOWAR_THE_PILLAGER
@ CORKI_SAY_PROMISE
#define GOSSIP_SGG3
static float m_afAmbushA[]
static float kurenaiAmbushB[]
#define GOSSIP_SGG2