Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
zone_azuremyst_isle.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: Azuremyst_Isle
8SD%Complete: 75
9SDComment: Quest support: 9283, 9537, 9582, 9554, ? (special flight path, proper model for mount missing). Injured Draenei cosmetic only, 9582.
10SDCategory: Azuremyst Isle
11EndScriptData */
12
13/* ContentData
14npc_draenei_survivor
15npc_engineer_spark_overgrind
16npc_injured_draenei
17npc_magwin
18go_ravager_cage
19npc_death_ravager
20EndContentData */
21
22#include "ScriptMgr.h"
23#include "ScriptedCreature.h"
24#include "ScriptedEscortAI.h"
25#include "ScriptedGossip.h"
26#include "Cell.h"
27#include "CellImpl.h"
28#include "GridNotifiersImpl.h"
29#include "GridNotifiers.h"
30
31/*######
32## npc_draenei_survivor
33######*/
34
36{
38
40
43};
44
46{
47public:
48 npc_draenei_survivor() : CreatureScript("npc_draenei_survivor") { }
49
51 {
52 return new npc_draenei_survivorAI(creature);
53 }
54
56 {
58 {
59 pCaster = 0;
60
62 RunAwayTimer = 0;
63 SayHelpTimer = 0;
64
65 CanSayHelp = false;
66 }
67
69 {
70 pCaster = 0;
71
73 RunAwayTimer = 0;
74 SayHelpTimer = 10000;
75
76 CanSayHelp = true;
77
79
82 me->SetHealth(me->CountPctFromMaxHealth(10));
83 me->SetStandState(UNIT_STAND_STATE_SLEEP);
84 }
85
86 void EnterCombat(Unit* /*who*/) OVERRIDE { }
87
89
90 {
91 if (CanSayHelp && who->GetTypeId() == TypeID::TYPEID_PLAYER && me->IsFriendlyTo(who) && me->IsWithinDistInMap(who, 25.0f))
92 {
93 //Random switch between 4 texts
94 Talk(SAY_HELP, who);
95
96 SayHelpTimer = 20000;
97 CanSayHelp = false;
98 }
99 }
100
101 void SpellHit(Unit* Caster, const SpellInfo* Spell) OVERRIDE
102 {
103 if (Spell->SpellFamilyFlags[2] & 0x080000000)
104 {
106 me->SetStandState(UNIT_STAND_STATE_STAND);
107
108 DoCast(me, SPELL_STUNNED, true);
109
110 pCaster = Caster->GetGUID();
111
112 SayThanksTimer = 5000;
113 }
114 }
115
117 {
118 if (SayThanksTimer)
119 {
120 if (SayThanksTimer <= diff)
121 {
122 me->RemoveAurasDueToSpell(SPELL_IRRIDATION);
123
125 {
126 Talk(SAY_HEAL, player);
127
128 player->TalkedToCreature(me->GetEntry(), me->GetGUID());
129 }
130
131 me->GetMotionMaster()->Clear();
132 me->GetMotionMaster()->MovePoint(0, -4115.053711f, -13754.831055f, 73.508949f);
133
134 RunAwayTimer = 10000;
135 SayThanksTimer = 0;
136 } else SayThanksTimer -= diff;
137
138 return;
139 }
140
141 if (RunAwayTimer)
142 {
143 if (RunAwayTimer <= diff)
144 me->DespawnOrUnsummon();
145 else
146 RunAwayTimer -= diff;
147
148 return;
149 }
150
151 if (SayHelpTimer <= diff)
152 {
153 CanSayHelp = true;
154 SayHelpTimer = 20000;
155 } else SayHelpTimer -= diff;
156 }
157
158 private:
160
164
166 };
167};
168
169/*######
170## npc_engineer_spark_overgrind
171######*/
172
185
186#define GOSSIP_FIGHT "Traitor! You will be brought to justice!"
187
189{
190public:
191 npc_engineer_spark_overgrind() : CreatureScript("npc_engineer_spark_overgrind") { }
192
193 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
194 {
195 player->PlayerTalkClass->ClearMenus();
196 if (action == GOSSIP_ACTION_INFO_DEF)
197 {
198 player->CLOSE_GOSSIP_MENU();
199 creature->setFaction(FACTION_HOSTILE);
200 CAST_AI(npc_engineer_spark_overgrind::npc_engineer_spark_overgrindAI, creature->AI())->AttackStart(player);
201 }
202 return true;
203 }
204
205 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
206 {
207 if (player->GetQuestStatus(QUEST_GNOMERCY) == QUEST_STATUS_INCOMPLETE)
209
210 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
211 return true;
212 }
213
215 {
216 return new npc_engineer_spark_overgrindAI(creature);
217 }
218
220 {
222 {
223 NormFaction = creature->getFaction();
225 DynamiteTimer = 0;
226 EmoteTimer = 0;
227
228 IsTreeEvent = false;
229
230 if (creature->GetAreaId() == AREA_COVE || creature->GetAreaId() == AREA_ISLE)
231 IsTreeEvent = true;
232 }
233
235 {
236 DynamiteTimer = 8000;
237 EmoteTimer = std::rand() % 150000 + 120000;
238
239 me->setFaction(NormFaction);
240 me->SetUInt32Value(UNIT_FIELD_NPC_FLAGS, NpcFlags);
241
242 IsTreeEvent = false;
243 }
244
246 {
247 Talk(ATTACK_YELL, who);
248 }
249
251 {
252 if (!me->IsInCombat() && !IsTreeEvent)
253 {
254 if (EmoteTimer <= diff)
255 {
256 Talk(SAY_TEXT);
258 EmoteTimer = std::rand() % 150000 + 120000;
259 } else EmoteTimer -= diff;
260 }
261 else if (IsTreeEvent)
262 return;
263
264 if (!UpdateVictim())
265 return;
266
267 if (DynamiteTimer <= diff)
268 {
270 DynamiteTimer = 8000;
271 } else DynamiteTimer -= diff;
272
274 }
275
276 private:
279
282
284 };
285};
286
287/*######
288## npc_injured_draenei
289######*/
290
292{
293public:
294 npc_injured_draenei() : CreatureScript("npc_injured_draenei") { }
295
297 {
298 return new npc_injured_draeneiAI(creature);
299 }
300
302 {
303 npc_injured_draeneiAI(Creature* creature) : ScriptedAI(creature) { }
304
306 {
308 me->SetHealth(me->CountPctFromMaxHealth(15));
309 switch (std::rand() % 1)
310 {
311 case 0:
312 me->SetStandState(UNIT_STAND_STATE_SIT);
313 break;
314
315 case 1:
316 me->SetStandState(UNIT_STAND_STATE_SLEEP);
317 break;
318 }
319 }
320
321 void EnterCombat(Unit* /*who*/) OVERRIDE { }
322
323 void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
324
325
326 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
327 };
328};
329
330/*######
331## npc_magwin
332######*/
333
345
347{
348public:
349 npc_magwin() : CreatureScript("npc_magwin") { }
350
351 bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
352 {
353 if (quest->GetQuestId() == QUEST_A_CRY_FOR_SAY_HELP)
354 {
355 creature->setFaction(113);
356 if (npc_escortAI* pEscortAI = CAST_AI(npc_escortAI, creature->AI()))
357 pEscortAI->Start(true, false, player->GetGUID());
358 }
359 return true;
360 }
361
363 {
364 return new npc_magwinAI(creature);
365 }
366
368 {
369 npc_magwinAI(Creature* creature) : npc_escortAI(creature) { }
370
372 {
373 if (Player* player = GetPlayerForEscort())
374 {
375 switch (waypointId)
376 {
377 case 0:
378 Talk(SAY_START, player);
379 break;
380 case 17:
381 Talk(SAY_PROGRESS, player);
382 break;
383 case 28:
384 Talk(SAY_END1, player);
385 break;
386 case 29:
387 Talk(EMOTE_HUG, player);
388 Talk(SAY_END2, player);
389 player->GroupEventHappens(QUEST_A_CRY_FOR_SAY_HELP, me);
390 break;
391 }
392 }
393 }
394
396 {
397 Talk(SAY_AGGRO, who);
398 }
399
400 void Reset() OVERRIDE { }
401 };
402};
403
404/*######
405## npc_geezle
406######*/
407
427
428Position const SparkPos = {-5029.91f, -11291.79f, 8.096f, 0.0f};
429
431{
432public:
433 npc_geezle() : CreatureScript("npc_geezle") { }
434
436 {
437 return new npc_geezleAI(creature);
438 }
439
440 struct npc_geezleAI : public ScriptedAI
441 {
442 npc_geezleAI(Creature* creature) : ScriptedAI(creature)
443 {
444 SparkGUID = 0;
445 Step = 0;
446 SayTimer = 0;
447 EventStarted = false;
448 }
449
451 {
452 SparkGUID = 0;
453 Step = 0;
454 StartEvent();
455 }
456
457 void EnterCombat(Unit* /*who*/)OVERRIDE { }
458
460 {
461 Step = 0;
462 EventStarted = true;
464 {
465 SparkGUID = Spark->GetGUID();
466 Spark->setActive(true);
467 Spark->RemoveFlag(UNIT_FIELD_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
468 }
469 SayTimer = 8000;
470 }
471
473 {
475 if (!Spark)
476 return 99999999;
477
478 switch (Step)
479 {
480 case 0:
481 Spark->GetMotionMaster()->MovePoint(0, -5080.70f, -11253.61f, 0.56f);
482 me->GetMotionMaster()->MovePoint(0, -5092.26f, -11252, 0.71f);
483 return 9000;
484 case 1:
485 DespawnNagaFlag(true);
486 Spark->AI()->Talk(EMOTE_SPARK);
487 return 1000;
488 case 2:
489 Talk(GEEZLE_SAY_1, Spark);
490 Spark->SetInFront(me);
491 me->SetInFront(Spark);
492 return 5000;
493 case 3:
494 Spark->AI()->Talk(SPARK_SAY_2);
495 return 7000;
496 case 4:
497 Spark->AI()->Talk(SPARK_SAY_3);
498 return 8000;
499 case 5:
500 Talk(GEEZLE_SAY_4, Spark);
501 return 8000;
502 case 6:
503 Spark->AI()->Talk(SPARK_SAY_5);
504 return 9000;
505 case 7:
506 Spark->AI()->Talk(SPARK_SAY_6);
507 return 8000;
508 case 8:
509 Talk(GEEZLE_SAY_7, Spark);
510 return 2000;
511 case 9:
512 me->GetMotionMaster()->MoveTargetedHome();
513 Spark->GetMotionMaster()->MovePoint(0, SparkPos);
515 return 9000;
516 case 10:
517 Spark->DisappearAndDie();
518 DespawnNagaFlag(false);
519 me->DisappearAndDie();
520 default: return 99999999;
521 }
522 }
523
524 // will complete Tree's company quest for all nearby players that are disguised as trees
526 {
527 float radius = 50.0f;
528 std::list<Player*> players;
531 me->VisitNearbyWorldObject(radius, searcher);
532
533 for (std::list<Player*>::const_iterator itr = players.begin(); itr != players.end(); ++itr)
534 if ((*itr)->GetQuestStatus(QUEST_TREES_COMPANY) == QUEST_STATUS_INCOMPLETE && (*itr)->HasAura(SPELL_TREE_DISGUISE))
535 (*itr)->KilledMonsterCredit(NPC_SPARK, 0);
536 }
537
538 void DespawnNagaFlag(bool despawn)
539 {
540 std::list<GameObject*> FlagList;
541 me->GetGameObjectListWithEntryInGrid(FlagList, GO_NAGA_FLAG, 100.0f);
542
543 if (!FlagList.empty())
544 {
545 for (std::list<GameObject*>::const_iterator itr = FlagList.begin(); itr != FlagList.end(); ++itr)
546 {
547 if (despawn)
548 (*itr)->SetLootState(LootState::GO_JUST_DEACTIVATED);
549 else
550 (*itr)->Respawn();
551 }
552 }
553 else
554 SF_LOG_ERROR("scripts", "SD2 ERROR: FlagList is empty!");
555 }
556
558 {
559 if (SayTimer <= diff)
560 {
561 if (EventStarted)
563 }
564 else
565 SayTimer -= diff;
566 }
567
568 private:
570
573
575 };
576};
577
587
589{
590public:
591 go_ravager_cage() : GameObjectScript("go_ravager_cage") { }
592
594 {
595 go->UseDoorOrButton();
596 if (player->GetQuestStatus(QUEST_STRENGTH_ONE) == QUEST_STATUS_INCOMPLETE)
597 {
598 if (Creature* ravager = go->FindNearestCreature(NPC_DEATH_RAVAGER, 5.0f, true))
599 {
600 ravager->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
601 ravager->SetReactState(REACT_AGGRESSIVE);
602 ravager->AI()->AttackStart(player);
603 }
604 }
605 return true;
606 }
607};
608
610{
611public:
612 npc_death_ravager() : CreatureScript("npc_death_ravager") { }
613
615 {
616 return new npc_death_ravagerAI(creature);
617 }
618
620 {
622 {
623 RendTimer = 0;
625 }
626
628 {
629 RendTimer = 30000;
630 EnragingBiteTimer = 20000;
631
633 me->SetReactState(REACT_PASSIVE);
634 }
635
637 {
638 if (!UpdateVictim())
639 return;
640
641 if (RendTimer <= diff)
642 {
644 RendTimer = 30000;
645 }
646 else RendTimer -= diff;
647
648 if (EnragingBiteTimer <= diff)
649 {
651 EnragingBiteTimer = 15000;
652 }
653 else EnragingBiteTimer -= diff;
654
656 }
657
658 private:
661 };
662};
663
664/*########
665## Quest: The Prophecy of Akida
666########*/
667
679
681{
682public:
683 npc_stillpine_capitive() : CreatureScript("npc_stillpine_capitive") { }
684
686 {
688 {
689 _player = NULL;
690 _movementComplete = false;
691 }
692
694 {
695 if (GameObject* cage = me->FindNearestGameObject(GO_BRISTELIMB_CAGE, 5.0f))
696 {
697 cage->SetLootState(LootState::GO_JUST_DEACTIVATED);
698 cage->SetGoState(GOState::GO_STATE_READY);
699 }
700 _events.Reset();
701 _player = NULL;
702 _movementComplete = false;
703 }
704
705 void StartMoving(Player* owner)
706 {
707 if (owner)
708 {
709 Talk(CAPITIVE_SAY, owner);
710 _player = owner;
711 }
712 Position pos;
713 me->GetNearPosition(pos, 3.0f, 0.0f);
714 me->GetMotionMaster()->MovePoint(POINT_INIT, pos);
715 }
716
718 {
719 if (type != POINT_MOTION_TYPE || id != POINT_INIT)
720 return;
721
722 if (_player)
723 _player->KilledMonsterCredit(me->GetEntry(), me->GetGUID());
724
725 _movementComplete = true;
726 _events.ScheduleEvent(EVENT_DESPAWN, 3500);
727 }
728
730 {
732 return;
733
734 _events.Update(diff);
735
736 if (_events.ExecuteEvent() == EVENT_DESPAWN)
737 me->DespawnOrUnsummon();
738 }
739
740 private:
744 };
745
747 {
748 return new npc_stillpine_capitiveAI(creature);
749 }
750};
751
753{
754public:
755 go_bristlelimb_cage() : GameObjectScript("go_bristlelimb_cage") { }
756
758 {
759 go->SetGoState(GOState::GO_STATE_READY);
760 if (player->GetQuestStatus(QUEST_THE_PROPHECY_OF_AKIDA) == QUEST_STATUS_INCOMPLETE)
761 {
762 if (Creature* capitive = go->FindNearestCreature(NPC_STILLPINE_CAPITIVE, 5.0f, true))
763 {
764 go->ResetDoorOrButton();
765 CAST_AI(npc_stillpine_capitive::npc_stillpine_capitiveAI, capitive->AI())->StartMoving(player);
766 return false;
767 }
768 }
769 return true;
770 }
771};
772
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
@ GO_JUST_DEACTIVATED
Definition GameObject.h:619
@ GO_STATE_READY
Definition GameObject.h:577
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
Definition Object.h:73
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
#define CAST_AI(a, b)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_INFO_DEF
@ UNIT_NPC_FLAG_GOSSIP
Definition Unit.h:687
@ UNIT_STAND_STATE_SLEEP
Definition Unit.h:165
@ UNIT_STAND_STATE_STAND
Definition Unit.h:162
@ UNIT_STAND_STATE_SIT
Definition Unit.h:163
@ REACT_PASSIVE
Definition Unit.h:1156
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_IN_COMBAT
Definition Unit.h:644
@ UNIT_FLAG_PVP_ATTACKABLE
Definition Unit.h:628
@ UNIT_FIELD_NPC_FLAGS
@ UNIT_FIELD_FLAGS
@ FACTION_HOSTILE
#define SAY_AGGRO
@ SPELL_REND
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureAI * AI() const
Definition Creature.h:483
void DisappearAndDie()
Definition Creature.cpp:206
CreatureScript(const char *name)
GameObjectScript(const char *name)
void MovePoint(uint32 id, Position const &pos, bool generatePath=true)
static Player * GetPlayer(WorldObject const &, uint64 guid)
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
Definition Spell.h:289
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
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
void SetInFront(WorldObject const *target)
Definition Unit.cpp:9108
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2801
uint32 GetAreaId() const
Definition Object.cpp:1602
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 OnGossipHello(Player *player, Creature *creature) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) 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
Creature * me
ScriptedAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHit(Unit *Caster, const SpellInfo *Spell) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
Player * GetPlayerForEscort()
npc_escortAI(Creature *creature)
void EnterCombat(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void WaypointReached(uint32 waypointId) OVERRIDE
void EnterCombat(Unit *who) OVERRIDE
void MovementInform(uint32 type, uint32 id) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
#define GOSSIP_FIGHT
@ SPELL_IRRIDATION
@ SPELL_STUNNED
Position const SparkPos
@ QUEST_A_CRY_FOR_SAY_HELP
void AddSC_azuremyst_isle()
@ QUEST_TREES_COMPANY
@ SPELL_TREE_DISGUISE
@ QUEST_THE_PROPHECY_OF_AKIDA
@ GO_BRISTELIMB_CAGE
@ NPC_STILLPINE_CAPITIVE
@ FACTION_HOSTILE
@ QUEST_STRENGTH_ONE
@ NPC_DEATH_RAVAGER
@ SPELL_ENRAGING_BITE
@ SAY_START
@ SAY_END1
@ SAY_END2