Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
zone_dustwallow_marsh.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: Dustwallow_Marsh
8SD%Complete: 95
9SDComment: Quest support: 1270, 1222, 27245
10SDCategory: Dustwallow Marsh
11EndScriptData */
12
13/* ContentData
14npc_stinky
15go_blackhoof_cage
16EndContentData */
17
18#include "ScriptMgr.h"
19#include "ScriptedCreature.h"
20#include "ScriptedEscortAI.h"
21#include "ScriptedGossip.h"
22#include "SpellScript.h"
23#include "Player.h"
24#include "WorldSession.h"
25
26/*######
27## npc_risen_husk_spirit
28######*/
29
31{
32 // Quest
34
35 // General spells
38
39 // Risen Husk specific
42
43 // Risen Spirit specific
46
47 // Events
50};
51
53{
54 public:
55 npc_risen_husk_spirit() : CreatureScript("npc_risen_husk_spirit") { }
56
58 {
59 npc_risen_husk_spiritAI(Creature* creature) : ScriptedAI(creature) { }
60
62 {
63 events.Reset();
64 if (me->GetEntry() == NPC_RISEN_HUSK)
65 events.ScheduleEvent(EVENT_CONSUME_FLESH, 5000);
66 else if (me->GetEntry() == NPC_RISEN_SPIRIT)
67 events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 5000);
68 }
69
70 void JustDied(Unit* killer) OVERRIDE
71 {
72 if (killer->GetTypeId() == TypeID::TYPEID_PLAYER)
73 {
74 if (killer->ToPlayer()->GetQuestStatus(QUEST_WHATS_HAUNTING_WITCH_HILL) == QUEST_STATUS_INCOMPLETE)
75 {
78 }
79 }
80 }
81
83 {
84 if (!UpdateVictim())
85 return;
86
87 events.Update(diff);
88
89 while (uint32 eventId = events.ExecuteEvent())
90 {
91 switch (eventId)
92 {
95 events.ScheduleEvent(EVENT_CONSUME_FLESH, 15000);
96 break;
99 events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 15000);
100 break;
101 default:
102 break;
103 }
104 }
105
107 }
108
109 private:
111 };
112
114 {
115 return new npc_risen_husk_spiritAI(creature);
116 }
117};
118
119/*######
120## npc_theramor_guard
121######*/
122
136
137#define GOSSIP_ITEM_THERAMORE_GUARD "You look like an intelligent person. Why don't you read one of these leaflets and give it some thought?"
138
140{
141public:
142 npc_theramore_guard() : CreatureScript("npc_theramore_guard") { }
143
144 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
145 {
146 if (player->GetQuestStatus(QUEST_DISCREDITING_THE_DESERTERS) == QUEST_STATUS_INCOMPLETE)
148
149 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
150
151 return true;
152 }
153
154 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
155 {
156 player->PlayerTalkClass->ClearMenus();
157
158 if (action == GOSSIP_SENDER_INFO)
159 {
160 player->CLOSE_GOSSIP_MENU();
161 player->KilledMonsterCredit(NPC_THERAMORE_GUARD, 0);
162 creature->AI()->Talk(SAY_QUEST1);
163 creature->CastSpell(creature, SPELL_DOCTORED_LEAFLET, false);
164 creature->RemoveFlag(UNIT_FIELD_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
165 CAST_AI(npc_theramore_guard::npc_theramore_guardAI, creature->AI())->YellTimer = 4000;
166 CAST_AI(npc_theramore_guard::npc_theramore_guardAI, creature->AI())->bYellTimer = true;
167 }
168
169 return true;
170 }
171
173 {
174 return new npc_theramore_guardAI(creature);
175 }
176
178 {
179 npc_theramore_guardAI(Creature* creature) : ScriptedAI(creature) { }
180
184
186 {
187 bYellTimer = false;
188 Step = 0;
189 }
190
192 {
193 if (!me->HasAura(SPELL_PROPAGANDIZED))
195
196 if (bYellTimer && YellTimer <= Diff)
197 {
198 switch (Step)
199 {
200 case 0:
202 YellTimer = 3000;
203 ++Step;
204 break;
205 case 1:
207 me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH);
208 Step = 0;
209 bYellTimer = false;
210 break;
211 }
212 }
213 else
214 YellTimer -= Diff;
215 }
216 };
217};
218
219/*######
220## npc_lady_jaina_proudmoore
221######*/
222
228
229#define GOSSIP_ITEM_JAINA "I know this is rather silly but i have a young ward who is a bit shy and would like your autograph."
230
232{
233public:
234 npc_lady_jaina_proudmoore() : CreatureScript("npc_lady_jaina_proudmoore") { }
235
236 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
237 {
238 player->PlayerTalkClass->ClearMenus();
239 if (action == GOSSIP_SENDER_INFO)
240 {
241 player->SEND_GOSSIP_MENU(7012, creature->GetGUID());
242 player->CastSpell(player, SPELL_JAINAS_AUTOGRAPH, false);
243 }
244 return true;
245 }
246
247 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
248 {
249 if (creature->IsQuestGiver())
250 player->PrepareQuestMenu(creature->GetGUID());
251
252 if (player->GetQuestStatus(QUEST_JAINAS_AUTOGRAPH) == QUEST_STATUS_INCOMPLETE)
254
255 player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
256
257 return true;
258 }
259};
260
261/*######
262## npc_nat_pagle
263######*/
264
269
271{
272public:
273 npc_nat_pagle() : CreatureScript("npc_nat_pagle") { }
274
275 bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
276 {
277 player->PlayerTalkClass->ClearMenus();
278 if (action == GOSSIP_ACTION_TRADE)
279 player->GetSession()->SendListInventory(creature->GetGUID());
280
281 return true;
282 }
283
284 bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
285 {
286 if (creature->IsQuestGiver())
287 player->PrepareQuestMenu(creature->GetGUID());
288
289 if (creature->IsVendor() && player->GetQuestRewardStatus(QUEST_NATS_MEASURING_TAPE))
290 {
292 player->SEND_GOSSIP_MENU(7640, creature->GetGUID());
293 }
294 else
295 player->SEND_GOSSIP_MENU(7638, creature->GetGUID());
296
297 return true;
298 }
299};
300
301/*######
302## npc_private_hendel
303######*/
304
306{
312
314 FACTION_HOSTILE = 168, //guessed, may be different
315
316 NPC_SENTRY = 5184, //helps hendel
317 NPC_JAINA = 4968, //appears once hendel gives up
319};
320
323{
324public:
325 npc_private_hendel() : CreatureScript("npc_private_hendel") { }
326
327 bool OnQuestAccept(Player* /*player*/, Creature* creature, const Quest* quest) OVERRIDE
328 {
329 if (quest->GetQuestId() == QUEST_MISSING_DIPLO_PT16)
330 creature->setFaction(FACTION_HOSTILE);
331
332 return true;
333 }
334
336 {
337 return new npc_private_hendelAI(creature);
338 }
339
341 {
342 npc_private_hendelAI(Creature* creature) : ScriptedAI(creature) { }
343
345 {
346 me->RestoreFaction();
347 }
348
349 void AttackedBy(Unit* pAttacker) OVERRIDE
350 {
351 if (me->GetVictim())
352 return;
353
354 if (me->IsFriendlyTo(pAttacker))
355 return;
356
357 AttackStart(pAttacker);
358 }
359
360 void DamageTaken(Unit* pDoneBy, uint32 &Damage) OVERRIDE
361 {
362 if (Damage > me->GetHealth() || me->HealthBelowPctDamaged(20, Damage))
363 {
364 Damage = 0;
365
366 if (Player* player = pDoneBy->GetCharmerOrOwnerPlayerOrPlayerItself())
367 player->GroupEventHappens(QUEST_MISSING_DIPLO_PT16, me);
368
371 }
372 }
373 };
374};
375
376/*######
377## npc_zelfrax
378######*/
379
380Position const MovePosition = {-2967.030f, -3872.1799f, 35.620f, 0.0f};
381
387
389{
390public:
391 npc_zelfrax() : CreatureScript("npc_zelfrax") { }
392
394 {
395 return new npc_zelfraxAI(creature);
396 }
397
398 struct npc_zelfraxAI : public ScriptedAI
399 {
400 npc_zelfraxAI(Creature* creature) : ScriptedAI(creature)
401 {
402 MoveToDock();
403 }
404
406 {
407 if (!who)
408 return;
409
410 if (me->Attack(who, true))
411 {
412 me->SetInCombatWith(who);
413 who->SetInCombatWith(me);
414
416 me->GetMotionMaster()->MoveChase(who);
417 }
418 }
419
421 {
422 if (Type != POINT_MOTION_TYPE)
423 return;
424
425 me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
427 SetCombatMovement(true);
428
429 if (me->IsInCombat())
430 if (Unit* unit = me->GetVictim())
431 me->GetMotionMaster()->MoveChase(unit);
432 }
433
435 {
436 SetCombatMovement(false);
437 me->GetMotionMaster()->MovePoint(0, MovePosition);
440 }
441
442 void UpdateAI(uint32 /*Diff*/) OVERRIDE
443 {
444 if (!UpdateVictim())
445 return;
446
448 }
449 };
450};
451
452/*######
453## npc_stinky
454######*/
455
471
473{
474public:
475 npc_stinky() : CreatureScript("npc_stinky") { }
476
478 {
479 return new npc_stinkyAI(creature);
480 }
481
482 bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
483 {
484 if (quest->GetQuestId() == QUEST_STINKYS_ESCAPE_H || quest->GetQuestId() == QUEST_STINKYS_ESCAPE_A)
485 {
486 if (npc_stinkyAI* pEscortAI = CAST_AI(npc_stinky::npc_stinkyAI, creature->AI()))
487 {
488 creature->setFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE);
489 creature->SetStandState(UNIT_STAND_STATE_STAND);
490 creature->AI()->Talk(SAY_QUEST_ACCEPTED);
491 pEscortAI->Start(false, false, player->GetGUID());
492 }
493 }
494 return true;
495 }
496
498 {
499 npc_stinkyAI(Creature* creature) : npc_escortAI(creature) { }
500
502 {
503 Player* player = GetPlayerForEscort();
504 if (!player)
505 return;
506
507 switch (waypointId)
508 {
509 case 7:
510 Talk(SAY_STAY_1, player);
511 break;
512 case 11:
513 Talk(SAY_STAY_2, player);
514 break;
515 case 25:
516 Talk(SAY_STAY_3, player);
517 break;
518 case 26:
519 Talk(SAY_STAY_4, player);
520 break;
521 case 27:
522 Talk(SAY_STAY_5, player);
523 break;
524 case 28:
525 Talk(SAY_STAY_6, player);
526 me->SetStandState(UNIT_STAND_STATE_KNEEL);
527 break;
528 case 29:
529 me->SetStandState(UNIT_STAND_STATE_STAND);
530 break;
531 case 37:
532 Talk(SAY_QUEST_COMPLETE, player);
533 me->SetSpeed(MOVE_RUN, 1.2f, true);
534 me->SetWalk(false);
539 break;
540 case 39:
542 break;
543 }
544 }
545
547 {
548 Talk(SAY_ATTACKED_1, who);
549 }
550
551 void Reset() OVERRIDE { }
552
553 void JustDied(Unit* /*killer*/) OVERRIDE
554 {
555 Player* player = GetPlayerForEscort();
557 {
560
563 }
564 }
565
567 {
569
570 if (!UpdateVictim())
571 return;
572
574 }
575 };
576};
577
585
587{
588 public:
589 spell_ooze_zap() : SpellScriptLoader("spell_ooze_zap") { }
590
592 {
594
595 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
596 {
597 if (!sSpellMgr->GetSpellInfo(SPELL_OOZE_ZAP))
598 return false;
599 return true;
600 }
601
603 {
604 if (!GetCaster()->HasAura(GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
605 return SpellCastResult::SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; // This is actually correct
606
607 if (!GetExplTargetUnit())
609
611 }
612
614 {
615 PreventHitDefaultEffect(effIndex);
616 if (GetHitUnit())
618 }
619
625 };
626
628 {
629 return new spell_ooze_zap_SpellScript();
630 }
631};
632
634{
635 public:
636 spell_ooze_zap_channel_end() : SpellScriptLoader("spell_ooze_zap_channel_end") { }
637
639 {
641
642 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
643 {
644 if (!sSpellMgr->GetSpellInfo(SPELL_OOZE_ZAP_CHANNEL_END))
645 return false;
646 return true;
647 }
648
650 {
651 PreventHitDefaultEffect(effIndex);
652 if (Player* player = GetCaster()->ToPlayer())
653 player->CastSpell(player, SPELL_OOZE_CHANNEL_CREDIT, true);
655 }
656
661 };
662
667};
668
670{
671 public:
672 spell_energize_aoe() : SpellScriptLoader("spell_energize_aoe") { }
673
675 {
677
678 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
679 {
680 if (!sSpellMgr->GetSpellInfo(SPELL_ENERGIZED))
681 return false;
682 return true;
683 }
684
685 void FilterTargets(std::list<WorldObject*>& targets)
686 {
687 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
688 {
689 if ((*itr)->GetTypeId() == TypeID::TYPEID_PLAYER && (*itr)->ToPlayer()->GetQuestStatus(GetSpellInfo()->Effects[EFFECT_1].CalcValue()) == QUEST_STATUS_INCOMPLETE)
690 ++itr;
691 else
692 targets.erase(itr++);
693 }
694 targets.push_back(GetCaster());
695 }
696
698 {
699 PreventHitDefaultEffect(effIndex);
701 }
702
709 };
710
715};
716
717/*######
718## go_blackhoof_cage
719######*/
720
726
728{
729public:
730 go_blackhoof_cage() : GameObjectScript("go_blackhoof_cage") { }
731
733 {
734 go->UseDoorOrButton();
735 if (Creature* prisoner = go->FindNearestCreature(NPC_THERAMORE_PRISONER, 1.0f))
736 {
737 if (player)
738 player->KilledMonsterCredit(NPC_THERAMORE_PRISONER, 0);
739
740 prisoner->AI()->Talk(SAY_FREE); // We also emote cry here (handled in creature_text.emote)
741 prisoner->DespawnOrUnsummon(6000);
742 }
743 return true;
744 }
745};
746
748{
749 new npc_stinky();
750 new spell_ooze_zap();
752 new spell_energize_aoe();
753 new go_blackhoof_cage();
754}
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ GOSSIP_ICON_CHAT
Definition GossipDef.h:46
@ GOSSIP_ICON_VENDOR
Definition GossipDef.h:47
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
@ FACTION_ESCORT_N_NEUTRAL_ACTIVE
#define CAST_AI(a, b)
@ STATE_ESCORT_ESCORTING
#define GOSSIP_TEXT_BROWSE_GOODS
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_TRADE
@ GOSSIP_SENDER_INFO
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ EMOTE_ONESHOT_LAUGH
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TARGET_UNIT_SRC_AREA_ENTRY
SpellCastResult
@ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW
#define sSpellMgr
Definition SpellMgr.h:744
#define SpellCheckCastFn(F)
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
@ UNIT_NPC_FLAG_GOSSIP
Definition Unit.h:687
@ UNIT_STAND_STATE_KNEEL
Definition Unit.h:170
@ UNIT_STAND_STATE_STAND
Definition Unit.h:162
@ MOVE_RUN
Definition Unit.h:556
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ UNIT_FIELD_NPC_FLAGS
@ UNIT_FIELD_FLAGS
@ FACTION_HOSTILE
@ SPELL_INTANGIBLE_PRESENCE
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureScript(const char *name)
GameObjectScript(const char *name)
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
QuestStatus GetQuestStatus(uint32 quest_id) const
void FailQuest(uint32 quest_id)
Unit * GetExplTargetUnit()
HookList< CheckCastHandler > OnCheckCast
SpellInfo const * GetSpellInfo()
void PreventHitDefaultEffect(SpellEffIndex effIndex)
HookList< EffectHandler > OnEffectHitTarget
Unit * GetHitUnit()
int32 GetEffectValue()
Unit * GetCaster()
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
SpellScriptLoader(const char *name)
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
void Kill(Unit *victim, bool durabilityLoss=true)
Definition Unit.cpp:6342
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)
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:2355
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2801
bool OnGossipHello(Player *player, GameObject *go) OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
bool OnGossipSelect(Player *player, Creature *creature, uint32, uint32 action) OVERRIDE
bool OnGossipHello(Player *player, Creature *creature) OVERRIDE
bool OnQuestAccept(Player *, Creature *creature, const Quest *quest) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const 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
PrepareSpellScript(spell_energize_aoe_SpellScript)
void FilterTargets(std::list< WorldObject * > &targets)
SpellScript * GetSpellScript() const OVERRIDE
PrepareSpellScript(spell_ooze_zap_SpellScript)
PrepareSpellScript(spell_ooze_zap_channel_end_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
@ NPC_SENTRY
void SetCombatMovement(bool allowMovement)
Creature * me
bool IsCombatMovementAllowed() const
ScriptedAI(Creature *creature)
void AttackStart(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
Player * GetPlayerForEscort()
bool HasEscortState(uint32 escortState) const
npc_escortAI(Creature *creature)
void DamageTaken(Unit *pDoneBy, uint32 &Damage) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 uiDiff) OVERRIDE
== Triggered Actions Requested ==================
void EnterCombat(Unit *who) OVERRIDE
void WaypointReached(uint32 waypointId) OVERRIDE
void UpdateAI(uint32 Diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void AttackStart(Unit *who) OVERRIDE
void MovementInform(uint32 Type, uint32) OVERRIDE
#define GOSSIP_ITEM_THERAMORE_GUARD
@ QUEST_STINKYS_ESCAPE_H
@ QUEST_STINKYS_ESCAPE_A
Position const MovePosition
@ QUEST_MISSING_DIPLO_PT16
@ SPELL_WITCH_HILL_INFORMATION_CREDIT
@ QUEST_WHATS_HAUNTING_WITCH_HILL
@ SPELL_SUMMON_RESTLESS_APPARITION
@ SPELL_CONSUME_FLESH
@ SPELL_INTANGIBLE_PRESENCE
@ EVENT_INTANGIBLE_PRESENCE
@ EVENT_CONSUME_FLESH
@ NPC_THERAMORE_PRISONER
@ SPELL_OOZE_ZAP_CHANNEL_END
@ SPELL_OOZE_CHANNEL_CREDIT
void AddSC_dustwallow_marsh()
@ QUEST_JAINAS_AUTOGRAPH
@ SPELL_JAINAS_AUTOGRAPH
#define GOSSIP_ITEM_JAINA
@ NPC_THERAMORE_GUARD
@ SPELL_DOCTORED_LEAFLET
@ SPELL_PROPAGANDIZED
@ QUEST_DISCREDITING_THE_DESERTERS
@ QUEST_NATS_MEASURING_TAPE