TrinityCore
zone_azuremyst_isle.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: Azuremyst_Isle
20SD%Complete: 75
21SDComment: Quest support: 9283, 9537, 9582, 9554, ? (special flight path, proper model for mount missing). Injured Draenei cosmetic only, 9582.
22SDCategory: Azuremyst Isle
23EndScriptData */
24
25/* ContentData
26npc_draenei_survivor
27npc_engineer_spark_overgrind
28npc_injured_draenei
29npc_magwin
30EndContentData */
31
32#include "ScriptMgr.h"
33#include "CellImpl.h"
34#include "GameObjectAI.h"
35#include "GridNotifiersImpl.h"
36#include "MotionMaster.h"
37#include "ObjectAccessor.h"
38#include "ScriptedEscortAI.h"
39#include "ScriptedGossip.h"
40#include "SpellScript.h"
41#include "TemporarySummon.h"
42
43/*######
44## npc_draenei_survivor
45######*/
46
48{
56};
57
58Position const CrashSite = { -4115.25f, -13754.75f };
59
61{
62public:
63 npc_draenei_survivor() : CreatureScript("npc_draenei_survivor") { }
64
66 {
68 {
69 Initialize();
70 }
71
73 {
75 _canAskForHelp = true;
76 _canUpdateEvents = false;
77 _tappedBySpell = false;
78 }
79
80 void Reset() override
81 {
82 Initialize();
83 _events.Reset();
84
86
91 }
92
93 void JustEngagedWith(Unit* /*who*/) override { }
94
95 void MoveInLineOfSight(Unit* who) override
96 {
97 if (_canAskForHelp && who->GetTypeId() == TYPEID_PLAYER && me->IsFriendlyTo(who) && me->IsWithinDistInMap(who, 25.0f))
98 {
99 //Random switch between 4 texts
101
103 _canAskForHelp = false;
104 _canUpdateEvents = true;
105 }
106 }
107
108 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
109 {
110 if (spellInfo->SpellFamilyFlags[2] & 0x80000000 && !_tappedBySpell)
111 {
112 _events.Reset();
113 _tappedBySpell = true;
114 _canAskForHelp = false;
115 _canUpdateEvents = true;
116
119
120 _playerGUID = caster->GetGUID();
121 if (Player* player = caster->ToPlayer())
122 player->KilledMonsterCredit(me->GetEntry());
123
124 me->SetFacingToObject(caster);
127 }
128 }
129
130 void UpdateAI(uint32 diff) override
131 {
132 if (!_canUpdateEvents)
133 return;
134
135 _events.Update(diff);
136
137 while (uint32 eventId = _events.ExecuteEvent())
138 {
139 switch (eventId)
140 {
142 _canAskForHelp = true;
143 _canUpdateEvents = false;
144 break;
148 Talk(SAY_THANK_FOR_HEAL, player);
150 break;
151 case EVENT_RUN_AWAY:
153 me->GetMotionMaster()->MovePoint(0, me->GetPositionX() + (std::cos(me->GetAbsoluteAngle(CrashSite)) * 28.0f), me->GetPositionY() + (std::sin(me->GetAbsoluteAngle(CrashSite)) * 28.0f), me->GetPositionZ() + 1.0f);
155 break;
156 default:
157 break;
158 }
159 }
160 }
161
162 private:
168 };
169
170 CreatureAI* GetAI(Creature* creature) const override
171 {
172 return new npc_draenei_survivorAI(creature);
173 }
174};
175
176/*######
177## npc_engineer_spark_overgrind
178######*/
179
181{
185
186 AREA_COVE = 3579,
187 AREA_ISLE = 3639,
189 SPELL_DYNAMITE = 7978
191
193{
194public:
195 npc_engineer_spark_overgrind() : CreatureScript("npc_engineer_spark_overgrind") { }
196
198 {
200 {
201 Initialize();
202 NormFaction = creature->GetFaction();
203 NpcFlags = creature->GetNpcFlags();
204 }
205
207 {
208 DynamiteTimer = 8000;
209 EmoteTimer = urand(120000, 150000);
210
211 if (me->GetAreaId() == AREA_COVE || me->GetAreaId() == AREA_ISLE)
212 IsTreeEvent = true;
213 else
214 IsTreeEvent = false;
215 }
216
217 void Reset() override
218 {
219 Initialize();
220
223 }
224
225 void JustEngagedWith(Unit* who) override
226 {
227 Talk(ATTACK_YELL, who);
228 }
229
230 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
231 {
232 CloseGossipMenuFor(player);
234 me->Attack(player, true);
235 return false;
236 }
237
238 void UpdateAI(uint32 diff) override
239 {
240 if (!me->IsInCombat() && !IsTreeEvent)
241 {
242 if (EmoteTimer <= diff)
243 {
244 Talk(SAY_TEXT);
246 EmoteTimer = urand(120000, 150000);
247 } else EmoteTimer -= diff;
248 }
249 else if (IsTreeEvent)
250 return;
251
252 if (!UpdateVictim())
253 return;
254
255 if (DynamiteTimer <= diff)
256 {
258 DynamiteTimer = 8000;
259 } else DynamiteTimer -= diff;
260 }
261
262 private:
268 };
269
270 CreatureAI* GetAI(Creature* creature) const override
271 {
272 return new npc_engineer_spark_overgrindAI(creature);
273 }
274};
275
276/*######
277## npc_injured_draenei
278######*/
279
281{
282public:
283 npc_injured_draenei() : CreatureScript("npc_injured_draenei") { }
284
286 {
287 npc_injured_draeneiAI(Creature* creature) : ScriptedAI(creature) { }
288
289 void Reset() override
290 {
293 switch (urand(0, 1))
294 {
295 case 0:
297 break;
298
299 case 1:
301 break;
302 }
303 }
304
305 void JustEngagedWith(Unit* /*who*/) override { }
306
307 void MoveInLineOfSight(Unit* /*who*/) override { }
308
309 void UpdateAI(uint32 /*diff*/) override { }
310 };
311
312 CreatureAI* GetAI(Creature* creature) const override
313 {
314 return new npc_injured_draeneiAI(creature);
315 }
316};
317
318/*######
319## npc_magwin
320######*/
321
323{
330 NPC_COWLEN = 17311,
339};
340
342{
343public:
344 npc_magwin() : CreatureScript("npc_magwin") { }
345
346 struct npc_magwinAI : public EscortAI
347 {
348 npc_magwinAI(Creature* creature) : EscortAI(creature) { }
349
350 void Reset() override
351 {
352 _events.Reset();
353 }
354
355 void JustEngagedWith(Unit* who) override
356 {
357 Talk(SAY_AGGRO, who);
358 }
359
360 void OnQuestAccept(Player* player, Quest const* quest) override
361 {
362 if (quest->GetQuestId() == QUEST_A_CRY_FOR_HELP)
363 {
364 _player = player->GetGUID();
366 }
367 }
368
369 void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
370 {
371 if (Player* player = GetPlayerForEscort())
372 {
373 switch (waypointId)
374 {
375 case 17:
376 Talk(SAY_PROGRESS, player);
377 break;
378 case 28:
379 player->GroupEventHappens(QUEST_A_CRY_FOR_HELP, me);
381 break;
382 case 29:
383 if (Creature* cowlen = me->FindNearestCreature(NPC_COWLEN, 50.0f, true))
384 Talk(EMOTE_HUG, cowlen);
385 Talk(SAY_END2, player);
386 break;
387 }
388 }
389 }
390
391 void UpdateEscortAI(uint32 diff) override
392 {
393 _events.Update(diff);
394
395 if (uint32 eventId = _events.ExecuteEvent())
396 {
397 switch (eventId)
398 {
401 Talk(SAY_START, player);
404 break;
407 {
409 EscortAI::Start(true, player->GetGUID());
410 }
412 break;
413 case EVENT_STAND: // Remove kneel standstate. Using a separate delayed event because it causes unwanted delay before starting waypoint movement.
415 break;
416 case EVENT_TALK_END:
418 Talk(SAY_END1, player);
420 break;
422 if (Creature* cowlen = me->FindNearestCreature(NPC_COWLEN, 50.0f, true))
423 cowlen->AI()->Talk(SAY_COWLEN);
424 break;
425 }
426 }
427
429 }
430
431 private:
434 };
435
436 CreatureAI* GetAI(Creature* creature) const override
437 {
438 return new npc_magwinAI(creature);
439 }
440};
441
442/*######
443## npc_geezle
444######*/
445
447{
449
451
459
461
462 NPC_SPARK = 17243,
463 GO_NAGA_FLAG = 181694
465
466Position const SparkPos = {-5029.91f, -11291.79f, 8.096f, 0.0f};
467
469{
470public:
471 npc_geezle() : CreatureScript("npc_geezle") { }
472
473 struct npc_geezleAI : public ScriptedAI
474 {
475 npc_geezleAI(Creature* creature) : ScriptedAI(creature)
476 {
477 Initialize();
478 }
479
481 {
483 Step = 0;
484 EventStarted = false;
485 SayTimer = 0;
486 }
487
489
492
494
495 void Reset() override
496 {
497 Initialize();
498 StartEvent();
499 }
500
501 void JustEngagedWith(Unit* /*who*/) override { }
502
504 {
505 Step = 0;
506 EventStarted = true;
508 {
509 SparkGUID = Spark->GetGUID();
510 Spark->setActive(true);
511 Spark->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
512 }
513 SayTimer = 8000;
514 }
515
517 {
519 if (!Spark)
520 return 99999999;
521
522 switch (step)
523 {
524 case 0:
525 Spark->GetMotionMaster()->MovePoint(0, -5080.70f, -11253.61f, 0.56f);
526 me->GetMotionMaster()->MovePoint(0, -5092.26f, -11252, 0.71f);
527 return 9000;
528 case 1:
529 DespawnNagaFlag(true);
530 Spark->AI()->Talk(EMOTE_SPARK);
531 return 1000;
532 case 2:
533 Talk(GEEZLE_SAY_1, Spark);
534 Spark->SetFacingToObject(me);
535 me->SetFacingToObject(Spark);
536 return 5000;
537 case 3:
538 Spark->AI()->Talk(SPARK_SAY_2);
539 return 7000;
540 case 4:
541 Spark->AI()->Talk(SPARK_SAY_3);
542 return 8000;
543 case 5:
544 Talk(GEEZLE_SAY_4, Spark);
545 return 8000;
546 case 6:
547 Spark->AI()->Talk(SPARK_SAY_5);
548 return 9000;
549 case 7:
550 Spark->AI()->Talk(SPARK_SAY_6);
551 return 8000;
552 case 8:
553 Talk(GEEZLE_SAY_7, Spark);
554 return 2000;
555 case 9:
557 Spark->GetMotionMaster()->MovePoint(0, SparkPos);
559 return 9000;
560 case 10:
561 Spark->DisappearAndDie();
562 DespawnNagaFlag(false);
564 [[fallthrough]];
565 default:
566 return 99999999;
567 }
568 }
569
570 // will complete Tree's company quest for all nearby players that are disguised as trees
572 {
573 float radius = 50.0f;
574 std::list<Player*> players;
577 Cell::VisitWorldObjects(me, searcher, radius);
578
579 for (std::list<Player*>::const_iterator itr = players.begin(); itr != players.end(); ++itr)
580 if ((*itr)->GetQuestStatus(QUEST_TREES_COMPANY) == QUEST_STATUS_INCOMPLETE && (*itr)->HasAura(SPELL_TREE_DISGUISE))
581 (*itr)->KilledMonsterCredit(NPC_SPARK);
582 }
583
584 void DespawnNagaFlag(bool despawn)
585 {
586 std::list<GameObject*> FlagList;
588
589 if (!FlagList.empty())
590 {
591 for (std::list<GameObject*>::const_iterator itr = FlagList.begin(); itr != FlagList.end(); ++itr)
592 {
593 if (despawn)
594 (*itr)->SetLootState(GO_JUST_DEACTIVATED);
595 else
596 (*itr)->Respawn();
597 }
598 }
599 }
600
601 void UpdateAI(uint32 diff) override
602 {
603 if (SayTimer <= diff)
604 {
605 if (EventStarted)
607 }
608 else
609 SayTimer -= diff;
610 }
611 };
612
613 CreatureAI* GetAI(Creature* creature) const override
614 {
615 return new npc_geezleAI(creature);
616 }
617};
618
619// 29528 - Inoculate Nestlewood Owlkin
621{
622 void PeriodicTick(AuraEffect const* /*aurEff*/)
623 {
624 if (GetTarget()->GetTypeId() != TYPEID_UNIT) // prevent error reports in case ignored player target
626 }
627
628 void Register() override
629 {
631 }
632};
633
634/*######
635## Quest 9452: Red Snapper - Very Tasty!
636######*/
637
639{
643
644// 29866 - Cast Fishing Net
646{
647 bool Validate(SpellInfo const* /*spellInfo*/) override
648 {
650 }
651
652 void HandleDummy(SpellEffIndex /*effIndex*/)
653 {
655 }
656
657 void Register() override
658 {
660 }
661};
662
664{
668 new npc_magwin();
671}
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:159
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
Definition: ObjectDefines.h:68
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:145
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
bool roll_chance_i(int chance)
Definition: Random.h:59
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
void CloseGossipMenuFor(Player *player)
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ SPELL_EFFECT_DUMMY
@ FACTION_ESCORTEE_N_NEUTRAL_PASSIVE
@ FACTION_MONSTER
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2046
@ UNIT_STAND_STATE_SLEEP
Definition: UnitDefines.h:45
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:42
@ UNIT_STAND_STATE_SIT
Definition: UnitDefines.h:43
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:295
@ UNIT_NPC_FLAG_GOSSIP
Definition: UnitDefines.h:297
@ UNIT_FLAG_IN_COMBAT
Definition: UnitDefines.h:163
@ UNIT_FLAG_PLAYER_CONTROLLED
Definition: UnitDefines.h:147
void PreventDefaultAction()
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2045
Unit * GetTarget() const
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
CreatureAI * AI() const
Definition: Creature.h:214
void DisappearAndDie()
Definition: Creature.h:83
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
void Reset()
Definition: EventMap.cpp:21
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
void MoveTargetedHome()
void Clear()
Definition: ObjectGuid.h:286
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
uint32 GetQuestId() const
Definition: QuestDef.h:587
flag128 SpellFamilyFlags
Definition: SpellInfo.h:409
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHit
Definition: SpellScript.h:839
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
Definition: Unit.h:627
void SetHealth(uint64 val)
Definition: Unit.cpp:9346
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition: Unit.cpp:10100
NPCFlags GetNpcFlags() const
Definition: Unit.h:980
void SetFaction(uint32 faction) override
Definition: Unit.h:859
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:12671
bool Attack(Unit *victim, bool meleeAttack)
Definition: Unit.cpp:5670
uint32 GetFaction() const override
Definition: Unit.h:858
uint64 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:785
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:984
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
bool IsInCombat() const
Definition: Unit.h:1043
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:834
void GetGameObjectListWithEntryInGrid(Container &gameObjectContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition: Object.cpp:3292
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
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:2025
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1147
uint32 GetAreaId() const
Definition: Object.h:546
bool IsFriendlyTo(WorldObject const *target) const
Definition: Object.cpp:2865
CreatureAI * GetAI(Creature *creature) const 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 Validate(SpellInfo const *) override
void PeriodicTick(AuraEffect const *)
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:191
void Start(bool isActiveAttacker=true, ObjectGuid playerGUID=ObjectGuid::Empty, Quest const *quest=nullptr, bool instantRespawn=false, bool canLoopPath=false)
virtual void UpdateEscortAI(uint32 diff)
void LoadPath(uint32 pathId)
Player * GetPlayerForEscort()
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
float GetAbsoluteAngle(float x, float y) const
Definition: Position.h:125
constexpr float GetPositionZ() const
Definition: Position.h:78
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
bool OnGossipSelect(Player *player, uint32, uint32) override
void DespawnNagaFlag(bool despawn)
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *) override
npc_geezleAI(Creature *creature)
void UpdateEscortAI(uint32 diff) override
npc_magwinAI(Creature *creature)
void OnQuestAccept(Player *player, Quest const *quest) override
void WaypointReached(uint32 waypointId, uint32) override
void JustEngagedWith(Unit *who) override
@ EVENT_CAN_ASK_FOR_HELP
@ SPELL_IRRIDATION
@ EVENT_THANK_PLAYER
@ SAY_ASK_FOR_HELP
@ SPELL_STUNNED
@ SAY_THANK_FOR_HEAL
@ EVENT_RUN_AWAY
Position const SparkPos
Position const CrashSite
RedSnapperVeryTasty
@ SPELL_FISHED_UP_RED_SNAPPER
@ SPELL_FISHED_UP_MURLOC
@ SAY_PROGRESS
@ QUEST_A_CRY_FOR_HELP
@ EVENT_COWLEN_TALK
@ EVENT_START_ESCORT
@ PATH_ESCORT_MAGWIN
@ EVENT_ACCEPT_QUEST
@ EVENT_TALK_END
void AddSC_azuremyst_isle()
@ GEEZLE_SAY_1
@ GEEZLE_SAY_4
@ QUEST_TREES_COMPANY
@ GEEZLE_SAY_7
@ GO_NAGA_FLAG
@ SPELL_TREE_DISGUISE
@ QUEST_GNOMERCY
@ SPELL_DYNAMITE