Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
zone_terokkar_forest.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: Terokkar_Forest
8SD%Complete: 85
9SDComment: Quest support: 9889, 10009, 10873, 10896, 10898, 11096, 10052, 10051. Skettis->Ogri'la Flight
10SDCategory: Terokkar Forest
11EndScriptData */
12
13/* ContentData
14npc_unkor_the_ruthless
15npc_infested_root_walker
16npc_rotting_forest_rager
17npc_netherweb_victim
18npc_floon
19npc_isla_starmane
20npc_slim
21EndContentData */
22
23#include "ScriptMgr.h"
24#include "ScriptedCreature.h"
25#include "ScriptedGossip.h"
26#include "ScriptedEscortAI.h"
27#include "Group.h"
28#include "Player.h"
29#include "WorldSession.h"
30
31/*######
32## npc_unkor_the_ruthless
33######*/
34
45
47{
48public:
49 npc_unkor_the_ruthless() : CreatureScript("npc_unkor_the_ruthless") { }
50
52 {
53 return new npc_unkor_the_ruthlessAI(creature);
54 }
55
57 {
58 npc_unkor_the_ruthlessAI(Creature* creature) : ScriptedAI(creature) { }
59
63
65 {
66 CanDoQuest = false;
68 Pulverize_Timer = 3000;
69 me->SetStandState(UNIT_STAND_STATE_STAND);
70 me->setFaction(FACTION_HOSTILE);
71 }
72
73 void EnterCombat(Unit* /*who*/) OVERRIDE { }
74
75 void DoNice()
76 {
78 me->setFaction(FACTION_FRIENDLY);
79 me->SetStandState(UNIT_STAND_STATE_SIT);
80 me->RemoveAllAuras();
81 me->DeleteThreatList();
82 me->CombatStop(true);
84 }
85
86 void DamageTaken(Unit* done_by, uint32 &damage) OVERRIDE
87 {
88 Player* player = done_by->ToPlayer();
89
90 if (player && me->HealthBelowPctDamaged(30, damage))
91 {
92 if (Group* group = player->GetGroup())
93 {
94 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
95 {
96 Player* groupie = itr->GetSource();
97 if (groupie &&
100 {
102 if (!CanDoQuest)
103 CanDoQuest = true;
104 }
105 }
106 }
109 {
111 CanDoQuest = true;
112 }
113 }
114 }
115
117 {
118 if (CanDoQuest)
119 {
121 {
122 //DoCast(me, SPELL_QUID9889); //not using spell for now
123 DoNice();
124 }
125 else
126 {
127 if (UnkorUnfriendly_Timer <= diff)
128 {
130 return;
131 } else UnkorUnfriendly_Timer -= diff;
132 }
133 }
134
135 if (!UpdateVictim())
136 return;
137
138 if (Pulverize_Timer <= diff)
139 {
141 Pulverize_Timer = 9000;
142 } else Pulverize_Timer -= diff;
143
145 }
146 };
147};
148
149/*######
150## npc_infested_root_walker
151######*/
152
154{
155public:
156 npc_infested_root_walker() : CreatureScript("npc_infested_root_walker") { }
157
159 {
160 return new npc_infested_root_walkerAI(creature);
161 }
162
164 {
166
167 void Reset() OVERRIDE { }
168 void EnterCombat(Unit* /*who*/) OVERRIDE { }
169
170 void DamageTaken(Unit* done_by, uint32 &damage) OVERRIDE
171 {
172 if (done_by && done_by->GetTypeId() == TypeID::TYPEID_PLAYER)
173 if (me->GetHealth() <= damage)
174 if (rand()%100 < 75)
175 //Summon Wood Mites
176 DoCast(me, 39130, true);
177 }
178 };
179};
180
181/*######
182## npc_skywing
183######*/
185{
186public:
187 npc_skywing() : CreatureScript("npc_skywing") { }
188
190 {
191 return new npc_skywingAI(creature);
192 }
193
195 {
196 public:
197 npc_skywingAI(Creature* creature) : npc_escortAI(creature) { }
198
200 {
201 Player* player = GetPlayerForEscort();
202 if (!player)
203 return;
204
205 switch (waypointId)
206 {
207 case 8:
208 player->AreaExploredOrEventHappens(10898);
209 break;
210 }
211 }
212
213 void EnterCombat(Unit* /*who*/) OVERRIDE { }
214
216
217 {
219 return;
220
221 Player* player = who->ToPlayer();
222 if (player && player->GetQuestStatus(10898) == QUEST_STATUS_INCOMPLETE)
223 if (me->IsWithinDistInMap(who, 10.0f))
224 Start(false, false, who->GetGUID());
225 }
226
227 void Reset() OVERRIDE { }
228
230 {
232 }
233 };
234};
235
236/*######
237## npc_rotting_forest_rager
238######*/
239
241{
242public:
243 npc_rotting_forest_rager() : CreatureScript("npc_rotting_forest_rager") { }
244
246 {
247 return new npc_rotting_forest_ragerAI(creature);
248 }
249
251 {
253
254 void Reset() OVERRIDE { }
255 void EnterCombat(Unit* /*who*/) OVERRIDE { }
256
257 void DamageTaken(Unit* done_by, uint32 &damage) OVERRIDE
258 {
259 if (done_by->GetTypeId() == TypeID::TYPEID_PLAYER)
260 if (me->GetHealth() <= damage)
261 if (rand()%100 < 75)
262 //Summon Lots of Wood Mights
263 DoCast(me, 39134, true);
264 }
265 };
266};
267
268/*######
269## npc_netherweb_victim
270######*/
271
273{
275 //SPELL_FREE_WEBBED = 38950
276};
277
279{
280 18470, 16805, 21242, 18452, 22482, 21285
281};
282
284{
285public:
286 npc_netherweb_victim() : CreatureScript("npc_netherweb_victim") { }
287
289 {
290 return new npc_netherweb_victimAI(creature);
291 }
292
294 {
295 npc_netherweb_victimAI(Creature* creature) : ScriptedAI(creature) { }
296
297 void Reset() OVERRIDE { }
298 void EnterCombat(Unit* /*who*/) OVERRIDE { }
299 void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
300
301
302 void JustDied(Unit* killer) OVERRIDE
303 {
304 Player* player = killer->ToPlayer();
305 if (!player)
306 return;
307
308 if (player->GetQuestStatus(10873) == QUEST_STATUS_INCOMPLETE)
309 {
310 if (rand()%100 < 25)
311 {
312 me->SummonCreature(QUEST_TARGET, 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
314 }
315 else
316 me->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
317
318 if (rand()%100 < 75)
319 me->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
320
321 me->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
322 }
323 }
324 };
325};
326
327/*######
328## npc_floon
329######*/
330
331#define GOSSIP_FLOON1 "You owe Sim'salabim money. Hand them over or die!"
332#define GOSSIP_FLOON2 "Hand over the money or die...again!"
333
345
347{
348public:
349 npc_floon() : CreatureScript("npc_floon") { }
350
351 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
352 {
353 player->PlayerTalkClass->ClearMenus();
354 if (action == GOSSIP_ACTION_INFO_DEF)
355 {
357 player->SEND_GOSSIP_MENU(9443, creature->GetGUID());
358 }
359 if (action == GOSSIP_ACTION_INFO_DEF+1)
360 {
361 player->CLOSE_GOSSIP_MENU();
362 creature->setFaction(FACTION_HOSTILE_FL);
363 creature->AI()->Talk(SAY_FLOON_ATTACK, player);
364 creature->AI()->AttackStart(player);
365 }
366 return true;
367 }
368
369 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
370 {
371 if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE)
373
374 player->SEND_GOSSIP_MENU(9442, creature->GetGUID());
375 return true;
376 }
377
379 {
380 return new npc_floonAI(creature);
381 }
382
383 struct npc_floonAI : public ScriptedAI
384 {
385 npc_floonAI(Creature* creature) : ScriptedAI(creature)
386 {
387 m_uiNormFaction = creature->getFaction();
388 }
389
394
396 {
397 Silence_Timer = 2000;
398 Frostbolt_Timer = 4000;
399 FrostNova_Timer = 9000;
400 if (me->getFaction() != m_uiNormFaction)
401 me->setFaction(m_uiNormFaction);
402 }
403
404 void EnterCombat(Unit* /*who*/) OVERRIDE { }
405
407 {
408 if (!UpdateVictim())
409 return;
410
411 if (Silence_Timer <= diff)
412 {
414 Silence_Timer = 30000;
415 } else Silence_Timer -= diff;
416
417 if (FrostNova_Timer <= diff)
418 {
420 FrostNova_Timer = 20000;
421 } else FrostNova_Timer -= diff;
422
423 if (Frostbolt_Timer <= diff)
424 {
426 Frostbolt_Timer = 5000;
427 } else Frostbolt_Timer -= diff;
428
430 }
431 };
432};
433
434/*######
435## npc_isla_starmane
436######*/
449
451{
452public:
453 npc_isla_starmane() : CreatureScript("npc_isla_starmane") { }
454
456 {
457 npc_isla_starmaneAI(Creature* creature) : npc_escortAI(creature) { }
458
460 {
461 Player* player = GetPlayerForEscort();
462 if (!player)
463 return;
464
465 switch (waypointId)
466 {
467 case 0:
468 if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 10))
469 Cage->SetGoState(GOState::GO_STATE_ACTIVE);
470 break;
471 case 2:
472 Talk(SAY_PROGRESS_1, player);
473 break;
474 case 5:
475 Talk(SAY_PROGRESS_2, player);
476 break;
477 case 6:
478 Talk(SAY_PROGRESS_3, player);
479 break;
480 case 29:
481 Talk(SAY_PROGRESS_4, player);
482 if (player->GetTeam() == ALLIANCE)
484 else if (player->GetTeam() == HORDE)
486 me->SetInFront(player);
487 break;
488 case 30:
489 me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
490 break;
491 case 31:
493 me->SetWalk(false);
494 break;
495 }
496 }
497
499 {
500 me->RestoreFaction();
501 }
502
503 void JustDied(Unit* /*killer*/) OVERRIDE
504 {
505 if (Player* player = GetPlayerForEscort())
506 {
507 if (player->GetTeam() == ALLIANCE)
508 player->FailQuest(QUEST_EFTW_A);
509 else if (player->GetTeam() == HORDE)
510 player->FailQuest(QUEST_EFTW_H);
511 }
512 }
513 };
514
515 bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
516 {
517 if (quest->GetQuestId() == QUEST_EFTW_H || quest->GetQuestId() == QUEST_EFTW_A)
518 {
519 CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID());
520 creature->setFaction(113);
521 }
522 return true;
523 }
524
526 {
527 return new npc_isla_starmaneAI(creature);
528 }
529};
530
531/*######
532## go_skull_pile
533######*/
534#define GOSSIP_S_DARKSCREECHER_AKKARAI "Summon Darkscreecher Akkarai"
535#define GOSSIP_S_KARROG "Summon Karrog"
536#define GOSSIP_S_GEZZARAK_THE_HUNTRESS "Summon Gezzarak the Huntress"
537#define GOSSIP_S_VAKKIZ_THE_WINDRAGER "Summon Vakkiz the Windrager"
538
540{
541public:
542 go_skull_pile() : GameObjectScript("go_skull_pile") { }
543
544 bool OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action) OVERRIDE
545 {
546 player->PlayerTalkClass->ClearMenus();
547 switch (sender)
548 {
549 case GOSSIP_SENDER_MAIN: SendActionMenu(player, go, action); break;
550 }
551 return true;
552 }
553
555 {
556 if ((player->GetQuestStatus(11885) == QUEST_STATUS_INCOMPLETE) || player->GetQuestRewardStatus(11885))
557 {
562 }
563
564 player->SEND_GOSSIP_MENU(go->GetGOInfo()->questgiver.gossipID, go->GetGUID());
565 return true;
566 }
567
568 void SendActionMenu(Player* player, GameObject* /*go*/, uint32 action)
569 {
570 switch (action)
571 {
572 case GOSSIP_ACTION_INFO_DEF + 1:
573 player->CastSpell(player, 40642, false);
574 break;
575 case GOSSIP_ACTION_INFO_DEF + 2:
576 player->CastSpell(player, 40640, false);
577 break;
578 case GOSSIP_ACTION_INFO_DEF + 3:
579 player->CastSpell(player, 40632, false);
580 break;
581 case GOSSIP_ACTION_INFO_DEF + 4:
582 player->CastSpell(player, 40644, false);
583 break;
584 }
585 }
586};
587
588/*######
589## npc_slim
590######*/
591
593{
595};
596
598{
599public:
600 npc_slim() : CreatureScript("npc_slim") { }
601
602 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
603 {
604 player->PlayerTalkClass->ClearMenus();
605 if (action == GOSSIP_ACTION_TRADE)
606 player->GetSession()->SendListInventory(creature->GetGUID());
607
608 return true;
609 }
610
611 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
612 {
613 if (creature->IsVendor() && player->GetReputationRank(FACTION_CONSORTIUM) >= REP_FRIENDLY)
614 {
616 player->SEND_GOSSIP_MENU(9896, creature->GetGUID());
617 }
618 else
619 player->SEND_GOSSIP_MENU(9895, creature->GetGUID());
620
621 return true;
622 }
623};
624
625/*########
626####npc_akuno
627#####*/
628
634
636{
637public:
638 npc_akuno() : CreatureScript("npc_akuno") { }
639
640 bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
641 {
642 if (quest->GetQuestId() == QUEST_ESCAPING_THE_TOMB)
643 {
644 if (npc_akunoAI* pEscortAI = CAST_AI(npc_akuno::npc_akunoAI, creature->AI()))
645 pEscortAI->Start(false, false, player->GetGUID());
646
647 if (player->GetTeamId() == TEAM_ALLIANCE)
648 creature->setFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE);
649 else
650 creature->setFaction(FACTION_ESCORT_H_NEUTRAL_PASSIVE);
651 }
652 return true;
653 }
654
656 {
657 return new npc_akunoAI(creature);
658 }
659
660 struct npc_akunoAI : public npc_escortAI
661 {
662 npc_akunoAI(Creature* creature) : npc_escortAI(creature) { }
663
665 {
666 Player* player = GetPlayerForEscort();
667 if (!player)
668 return;
669
670 switch (waypointId)
671 {
672 case 3:
673 me->SummonCreature(NPC_CABAL_SKRIMISHER, -2795.99f, 5420.33f, -34.53f, 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
674 me->SummonCreature(NPC_CABAL_SKRIMISHER, -2793.55f, 5412.79f, -34.53f, 0.0f, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
675 break;
676 case 11:
677 if (player->GetTypeId() == TypeID::TYPEID_PLAYER)
679 break;
680 }
681 }
682
684 {
685 summon->AI()->AttackStart(me);
686 }
687 };
688};
689
691{
696 new npc_floon();
697 new npc_isla_starmane();
698 new go_skull_pile();
699 new npc_skywing();
700 new npc_slim();
701 new npc_akuno();
702}
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ GO_STATE_ACTIVE
Definition GameObject.h:576
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ GOSSIP_ICON_VENDOR
Definition GossipDef.h:47
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
@ FACTION_ESCORT_H_NEUTRAL_PASSIVE
@ FACTION_ESCORT_A_NEUTRAL_PASSIVE
#define CAST_AI(a, b)
@ STATE_ESCORT_ESCORTING
#define GOSSIP_TEXT_BROWSE_GOODS
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_TRADE
@ GOSSIP_ACTION_INFO_DEF
@ EMOTE_ONESHOT_WAVE
@ TEAM_ALLIANCE
@ ALLIANCE
@ HORDE
@ REP_FRIENDLY
@ UNIT_STAND_STATE_STAND
Definition Unit.h:162
@ UNIT_STAND_STATE_SIT
Definition Unit.h:163
@ SPELL_FROST_NOVA
@ FACTION_HOSTILE
@ SPELL_FROSTBOLT
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureScript(const char *name)
GameObjectScript(const char *name)
Definition Group.h:147
GroupReference * next()
Player * ToPlayer()
Definition Object.h:204
TypeID GetTypeId() const
Definition Object.h:131
uint32 GetTeam() const
Definition Player.h:2527
void KilledMonsterCredit(uint32 entry, uint64 guid=0)
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
uint16 GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry)
Group * GetGroup()
Definition Player.h:2972
void AreaExploredOrEventHappens(uint32 questId)
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
uint32 getFaction() const
Definition Unit.h:1695
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)
bool OnGossipHello(Player *player, GameObject *go) OVERRIDE
void SendActionMenu(Player *player, GameObject *, uint32 action)
bool OnGossipSelect(Player *player, GameObject *go, uint32 sender, uint32 action) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnQuestAccept(Player *player, Creature *creature, Quest const *quest) OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnQuestAccept(Player *player, Creature *creature, Quest const *quest) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
Creature * me
ScriptedAI(Creature *creature)
void JustSummoned(Creature *summon) OVERRIDE
void WaypointReached(uint32 waypointId) OVERRIDE
npc_akunoAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
Player * GetPlayerForEscort()
bool HasEscortState(uint32 escortState) const
npc_escortAI(Creature *creature)
void Start(bool isActiveAttacker=true, bool run=false, uint64 playerGUID=0, Quest const *quest=NULL, bool instantRespawn=false, bool canLoopPath=false, bool resetWaypoints=true)
npc_floonAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void EnterCombat(Unit *) OVERRIDE
void DamageTaken(Unit *done_by, uint32 &damage) OVERRIDE
void WaypointReached(uint32 waypointId) OVERRIDE
void DamageTaken(Unit *done_by, uint32 &damage) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void WaypointReached(uint32 waypointId) OVERRIDE
void MoveInLineOfSight(Unit *who) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void DamageTaken(Unit *done_by, uint32 &damage) OVERRIDE
@ GO_CAGE
@ QUEST_CRACK_SKULLS
@ FACTION_FRIENDLY
@ FACTION_CONSORTIUM
#define GOSSIP_S_VAKKIZ_THE_WINDRAGER
void AddSC_terokkar_forest()
#define GOSSIP_FLOON1
#define GOSSIP_S_GEZZARAK_THE_HUNTRESS
#define GOSSIP_S_KARROG
const uint32 netherwebVictims[6]
#define GOSSIP_S_DARKSCREECHER_AKKARAI
@ FACTION_FRIENDLY
@ SPELL_PULVERIZE
@ FACTION_HOSTILE
@ QUEST_DONTKILLTHEFATONE
#define GOSSIP_FLOON2
@ QUEST_CRACK_SKULLS
@ FACTION_HOSTILE_FL
@ NPC_CABAL_SKRIMISHER
@ QUEST_ESCAPING_THE_TOMB