TrinityCore
Loading...
Searching...
No Matches
zone_sholazar_basin.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#include "ScriptMgr.h"
19#include "CombatAI.h"
20#include "Map.h"
21#include "MotionMaster.h"
22#include "ObjectAccessor.h"
23#include "ObjectMgr.h"
24#include "Player.h"
25#include "ScriptedEscortAI.h"
26#include "SpellAuras.h"
27#include "SpellInfo.h"
28#include "SpellScript.h"
29#include "Vehicle.h"
30#include "GameObject.h"
31
32/*#####
33## npc_jungle_punch_target
34#####*/
35
48
64
66{
68 {
69 Initialize();
70 }
71
73 {
74 sayTimer = 3500;
75 sayStep = 0;
76 timer = 0;
77 phase = 0;
80 }
81
82 void Reset() override
83 {
84 Initialize();
85 }
86
87 void MoveInLineOfSight(Unit* who) override
88 {
89 if (!phase && who && who->GetDistance2d(me) < 10.0f)
90 if (Player* player = who->ToPlayer())
92 {
93 playerGUID = player->GetGUID();
94 if (Aura* orphanOut = player->GetAura(SPELL_ORPHAN_OUT))
95 if (orphanOut->GetCaster() && orphanOut->GetCaster()->GetEntry() == ORPHAN_WOLVAR)
96 {
97 orphanGUID = orphanOut->GetCaster()->GetGUID();
98 phase = 1;
99 }
100 }
101 }
102
103 void proceedCwEvent(const uint32 diff)
104 {
105 if (timer <= diff)
106 {
109
110 if (!orphan || !player)
111 {
112 Reset();
113 return;
114 }
115
116 switch (phase)
117 {
118 case 1:
119 orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ());
120 orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_6);
121 timer = 5000;
122 break;
123 case 2:
124 orphan->SetFacingToObject(me);
125 orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_7);
126 timer = 5000;
127 break;
128 case 3:
130 timer = 5000;
131 break;
132 case 4:
133 orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_8);
134 timer = 5000;
135 break;
136 case 5:
137 orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_9);
138 timer = 5000;
139 break;
140 case 6:
143 Reset();
144 return;
145 }
146 ++phase;
147 }
148 else
149 timer -= diff;
150 }
151
152 void UpdateAI(uint32 diff) override
153 {
154 if (phase)
155 proceedCwEvent(diff);
156
157 if (!sayStep)
158 return;
159
160 if (sayTimer < diff)
161 {
163 sayTimer = 3000;
164 sayStep++;
165
166 if (sayStep > 3) // end
167 sayStep = 0;
168 }
169 else
170 sayTimer -= diff;
171 }
172
173 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
174 {
175 if (spellInfo->Id != SPELL_OFFER)
176 return;
177
178 Player* player = caster->ToPlayer();
179 if (!player)
180 return;
181
182 Quest const* quest = sObjectMgr->GetQuestTemplate(QUEST_TASTE_TEST);
183 if (!quest)
184 return;
185
186 QuestStatusMap::const_iterator itr = player->getQuestStatusMap().find(QUEST_TASTE_TEST);
187 if (itr->second.Status != QUEST_STATUS_INCOMPLETE)
188 return;
189
190 for (uint8 i = 0; i < 3; ++i)
191 {
192 if (uint32(quest->RequiredNpcOrGo[i]) != me->GetEntry())
193 continue;
194
195 if (itr->second.CreatureOrGOCount[i] != 0)
196 continue;
197
198 player->KilledMonsterCredit(me->GetEntry());
199 sayStep = 1;
200 break;
201 }
202 }
203
204private:
211};
212
213/*######
214## Quest: Song of Wind and Water ID: 12726
215######*/
216/*This quest precisly needs core script since battle vehicles are not well integrated with SAI,
217may be easily converted to SAI when they get.*/
219{
220 // Spells
223 // NPCs
225 NPC_HAIPHOON_AIR = 28985
227
228struct npc_haiphoon : public VehicleAI
229{
230 npc_haiphoon(Creature* creature) : VehicleAI(creature) { }
231
232 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
233 {
234 if (target == me)
235 return;
236
238 {
240 }
242 {
244 }
245 }
246};
247
248/*######
249## Quest 12589: Kick, What Kick?
250######*/
251
274
275// 51330 - Shoot RJR
277{
279
289
290 void HandleDummy(SpellEffIndex /*effIndex*/)
291 {
292 uint32 roll = urand(1, 100);
293
294 uint8 ev;
295 if (roll <= 50)
296 ev = EVENT_MISS;
297 else if (roll <= 83)
298 ev = EVENT_HIT;
299 else
300 ev = EVENT_MISS_BIRD;
301
302 Unit* shooter = GetCaster();
303 Creature* wilhelm = GetHitUnit()->ToCreature();
304 Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30);
305 Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30);
306
307 if (!wilhelm || !apple || !drostan)
308 return;
309
310 switch (ev)
311 {
312 case EVENT_MISS_BIRD:
313 {
314 Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30);
315 Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30);
316
317 if (bird && crunchy)
318 {
319 shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE);
320 bird->CastSpell(bird, SPELL_BIRD_FALL);
321 wilhelm->AI()->Talk(SAY_WILHELM_MISS);
322 drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
323
324 bird->KillSelf();
325 crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(),
326 bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhaseMask(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
328 break;
329 }
330 [[fallthrough]];
331 }
332 case EVENT_MISS:
333 {
334 shooter->CastSpell(wilhelm, SPELL_MISS_APPLE);
335 wilhelm->AI()->Talk(SAY_WILHELM_MISS);
336 drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
337 break;
338 }
339 case EVENT_HIT:
340 {
341 shooter->CastSpell(apple, SPELL_HIT_APPLE);
342 apple->CastSpell(apple, SPELL_APPLE_FALL);
343 wilhelm->AI()->Talk(SAY_WILHELM_HIT);
344 if (Player* player = shooter->ToPlayer())
345 player->KilledMonsterCredit(NPC_APPLE);
346 break;
347 }
348 }
349 }
350
356};
357
358/*######
359## Quest 12620: The Lifewarden's Wrath
360######*/
361
372
373// 51957 - Call of the Lifewarden
375{
377
379 {
380 PreventHitDefaultEffect(effIndex);
381
382 if (Creature* presence = GetCaster()->FindNearestCreature(NPC_FREYAS_PRESENCE, 50.0f))
383 {
384 presence->AI()->Talk(WHISPER_ACTIVATE, GetCaster());
385 presence->AI()->SetData(1, 1);
386 }
387 }
388
393};
394
395// 51318 - Freya Dummy
397{
399
400 bool Validate(SpellInfo const* /*spellInfo*/) override
401 {
402 return ValidateSpellInfo(
403 {
407 });
408 }
409
410 void HandleScript(SpellEffIndex /*effIndex*/)
411 {
412 Unit* target = GetHitUnit();
413
414 target->CastSpell(target, SPELL_FREYA_DUMMY_TRIGGER, true);
415 target->CastSpell(target, SPELL_LASHER_EMERGE, false);
416 target->CastSpell(target, SPELL_WILD_GROWTH, false);
417 // This probably is scripted by the Emerge spell from above
420 target->SetImmuneToNPC(false);
421 }
422
427};
428
429/*######
430## Quest 12611: Returned Sevenfold
431######*/
432
439
440// 51854 - Deathbolt
442{
444
445 bool Validate(SpellInfo const* /*spellInfo*/) override
446 {
447 return ValidateSpellInfo(
448 {
452 });
453 }
454
455 void HandleScript(SpellEffIndex /* effIndex */)
456 {
457 Unit* caster = GetCaster();
458 Unit* target = GetHitUnit();
459
460 if (target->HasAura(SPELL_FREYAS_WARD))
461 target->CastSpell(caster, SPELL_SEVENFOLD_RETRIBUTION, true);
462 else
463 caster->CastSpell(target, SPELL_DEATHBOLT, true);
464 }
465
470};
471
472/*######
473## Quest 12683: Burning to Help
474######*/
475
477{
478 SPELL_HYDRA_SPUTUM = 52307
480
481// 52308 - Take Sputum Sample
514
515// 52306 - Sputum Collected
535
536/*######
537## Quest 12735: A Cleansing Song
538######*/
539
550
551// 52941 - Song of Cleansing
553{
555
556 bool Validate(SpellInfo const* /*spellInfo*/) override
557 {
558 return ValidateSpellInfo(
559 {
563 });
564 }
565
566 void HandleScript(SpellEffIndex /*effIndex*/)
567 {
568 Unit* caster = GetCaster();
569 switch (caster->GetAreaId())
570 {
572 caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_ATHA);
573 break;
576 break;
578 caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_KOOSU);
579 break;
580 default:
581 break;
582 }
583 }
584
589};
590
591/*######
592## Quest 12741: Strength of the Tempest
593######*/
594
599
600// 53062 - Lightning Strike
620
621/*######
622## Quest 12521: Where in the World is Hemet Nesingwary?
623######*/
624
625// 51071 - Flight to Sholazar (Missile Warning)
627{
629
630 bool Validate(SpellInfo const* spellInfo) override
631 {
632 return sObjectMgr->GetBroadcastText(uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()));
633 }
634
635 void HandleScript(SpellEffIndex /*effIndex*/)
636 {
637 // 51076 (triggers 51071) is Area Aura - Party and applies on player too (no aura in sniffs on player)
638 // That makes both player and creature say
639 if (Creature* caster = GetCaster()->ToCreature())
640 caster->Unit::Say(uint32(GetEffectValue()), caster);
641 }
642
647};
648
649/*######
650## Quest 12634: Some Make Lemonade, Some Make Liquor
651######*/
652
660
661// This should be scripted in DB but our action lists aren't good enough to properly support chance
662// 51840 - Despawn Fruit Tosser
664{
666
667 bool Validate(SpellInfo const* /*spellEntry*/) override
668 {
669 return ValidateSpellInfo(
670 {
675 });
676 }
677
678 void HandleDummy(SpellEffIndex /*effIndex*/)
679 {
681 switch (urand(0, 3))
682 {
683 case 1: spellId = SPELL_ORANGE_FALLS_TO_GROUND; break;
684 case 2: spellId = SPELL_PAPAYA_FALLS_TO_GROUND; break;
685 }
686 // sometimes, if you're lucky, you get a dwarf
687 if (roll_chance_i(5))
689
690 GetHitUnit()->CastSpell(GetCaster(), spellId);
691 }
692
697};
698
699/*######
700## Quest 12805: Salvaging Life's Strength
701######*/
702
707
708// 54190 - Lifeblood Dummy
710{
712
713 bool Validate(SpellInfo const* spellInfo) override
714 {
715 return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) }) &&
716 sObjectMgr->GetCreatureTemplate(NPC_SHARD_KILL_CREDIT);
717 }
718
719 void HandleScript(SpellEffIndex /*effIndex*/)
720 {
721 if (GetHitUnit()->HasAura(uint32(GetEffectValue())))
722 {
723 if (Player* caster = GetCaster()->ToPlayer())
724 caster->KilledMonsterCredit(NPC_SHARD_KILL_CREDIT);
725
727 }
728 }
729
734};
735
736/*######
737## Quest 12607: A Mammoth Undertaking
738######*/
739
744
745// 51656 - Mount Mammoth Cue
765
uint8_t uint8
Definition Define.h:135
int8_t int8
Definition Define.h:131
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
#define sObjectMgr
Definition ObjectMgr.h:1721
#define PET_FOLLOW_ANGLE
Definition PetDefines.h:86
#define PET_FOLLOW_DIST
Definition PetDefines.h:85
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:107
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
bool roll_chance_i(int chance)
Definition Random.h:59
#define RegisterCreatureAI(ai_name)
Definition ScriptMgr.h:1139
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SEND_EVENT
@ EMOTE_ONESHOT_NONE
@ SPELL_CUSTOM_ERROR_MUST_TARGET_WILHELM
SpellCastResult
@ SPELL_FAILED_CASTER_AURASTATE
@ SPELL_FAILED_CUSTOM_ERROR
@ SPELL_CAST_OK
#define SpellCheckCastFn(F)
#define SpellEffectFn(F, I, N)
@ UNIT_FLAG_UNINTERACTIBLE
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Creature *const me
Definition CreatureAI.h:82
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition Creature.cpp:540
CreatureAI * AI() const
Definition Creature.h:154
float GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float *ground=nullptr, bool swim=false, float collisionHeight=2.03128f) const
Definition Map.cpp:2458
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
void MoveFollow(Unit *target, float dist, ChaseAngle angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
void Clear()
Definition ObjectGuid.h:150
static Creature * ToCreature(Object *o)
Definition Object.h:186
uint32 GetEntry() const
Definition Object.h:81
static Player * ToPlayer(Object *o)
Definition Object.h:180
void KilledMonsterCredit(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition Player.cpp:16140
QuestStatusMap & getQuestStatusMap()
Definition Player.h:1415
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
Definition Player.cpp:16032
int32 RequiredNpcOrGo[QUEST_OBJECTIVES_COUNT]
Definition QuestDef.h:308
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr) const
uint32 Id
Definition SpellInfo.h:289
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:483
HookList< CheckCastHandler > OnCheckCast
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
int32 GetEffectValue() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
void SetCustomCastResultMessage(SpellCustomErrors result)
Unit * GetExplTargetUnit() const
Definition Unit.h:769
void KillSelf(bool durabilityLoss=true)
Definition Unit.h:1023
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
void SetImmuneToNPC(bool apply, bool keepCombat)
Definition Unit.cpp:8339
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
void SetFacingToObject(WorldObject const *object, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13259
void SetEmoteState(Emote emote)
Definition Unit.h:967
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
uint32 GetPhaseMask() const
Definition Object.h:368
Map * GetMap() const
Definition Object.h:449
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1141
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2099
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Object.cpp:2203
uint32 GetAreaId() const
Definition Object.h:374
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
void HandleSendEvent(SpellEffIndex effIndex)
PrepareSpellScript(spell_sholazar_call_of_the_lifewarden)
PrepareSpellScript(spell_sholazar_deathbolt)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_sholazar_despawn_fruit_tosser)
PrepareSpellScript(spell_sholazar_flight_to_sholazar)
bool Validate(SpellInfo const *spellInfo) override
PrepareSpellScript(spell_sholazar_freya_dummy)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_sholazar_lifeblood_dummy)
bool Validate(SpellInfo const *spellInfo) override
PrepareSpellScript(spell_sholazar_lightning_strike)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_sholazar_mount_mammoth_cue)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_sholazar_shoot_rjr)
PrepareSpellScript(spell_sholazar_song_of_cleansing)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_sholazar_sputum_collected)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_sholazar_take_sputum_sample)
bool Validate(SpellInfo const *spellInfo) override
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
float GetPositionZ() const
Definition Position.h:81
float GetOrientation() const
Definition Position.h:82
float GetPositionX() const
Definition Position.h:79
float GetPositionY() const
Definition Position.h:80
npc_haiphoon(Creature *creature)
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
void proceedCwEvent(const uint32 diff)
void UpdateAI(uint32 diff) override
npc_jungle_punch_target(Creature *creature)
void MoveInLineOfSight(Unit *who) override
SomeMakeLemonadeSomeMakeLiquor
@ SPELL_ORANGE_FALLS_TO_GROUND
@ SPELL_PAPAYA_FALLS_TO_GROUND
@ SPELL_BANANAS_FALL_TO_GROUND
@ SPELL_TRIGGER_SPAWN_DWARF
SalvagingLifesStength
@ NPC_SHARD_KILL_CREDIT
@ SAY_HEMET_HADRIUS_TAMARA_1
@ SAY_HEMET_HADRIUS_TAMARA_3
@ QUEST_TASTE_TEST
@ SAY_HEMET_HADRIUS_TAMARA_2
NesingwaryChildrensWeek
@ QUEST_THE_MIGHTY_HEMET_NESINGWARY
@ TEXT_WOLVAR_ORPHAN_6
@ TEXT_WOLVAR_ORPHAN_7
@ ORPHAN_WOLVAR
@ TEXT_NESINGWARY_1
@ TEXT_WOLVAR_ORPHAN_8
@ SPELL_ORPHAN_OUT
@ TEXT_WOLVAR_ORPHAN_9
void AddSC_sholazar_basin()
@ SPELL_HYDRA_SPUTUM
@ WHISPER_ACTIVATE
@ SPELL_LASHER_EMERGE
@ SPELL_WILD_GROWTH
@ SPELL_FREYA_DUMMY_TRIGGER
@ NPC_FREYAS_PRESENCE
@ SPELL_FREYAS_WARD
@ SPELL_SEVENFOLD_RETRIBUTION
@ SPELL_DEATHBOLT
@ SPELL_RIDE_SHATTERTUSK_MAMMOTH
@ SPELL_CREATE_POWER_OF_THE_TEMPEST
@ SPELL_DEVOUR_WIND
@ NPC_HAIPHOON_AIR
@ NPC_HAIPHOON_WATER
@ SPELL_DEVOUR_WATER
@ SPELL_BIRD_FALL
@ SPELL_MISS_APPLE
@ SAY_DROSTAN_REPLY_MISS
@ SPELL_MISS_BIRD_APPLE
@ SAY_WILHELM_HIT
@ NPC_LUCKY_WILHELM
@ SPELL_APPLE_FALL
@ SAY_WILHELM_MISS
@ EVENT_MISS_BIRD
@ SPELL_HIT_APPLE
@ AREA_BITTERTIDE_LAKE
@ SPELL_SUMMON_SPIRIT_HAKHALAN
@ SPELL_SUMMON_SPIRIT_ATHA
@ AREA_RIVERS_HEART
@ SPELL_SUMMON_SPIRIT_KOOSU
@ AREA_WINTERGRASP_RIVER