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 "DB2Stores.h"
21#include "Map.h"
22#include "MotionMaster.h"
23#include "ObjectAccessor.h"
24#include "ObjectMgr.h"
25#include "Player.h"
26#include "ScriptedEscortAI.h"
27#include "SpellAuras.h"
28#include "SpellInfo.h"
29#include "SpellScript.h"
30#include "Vehicle.h"
31#include "GameObject.h"
32
33/*#####
34## npc_jungle_punch_target
35#####*/
36
49
65
67{
69 {
70 Initialize();
71 }
72
74 {
75 sayTimer = 3500;
76 sayStep = 0;
77 timer = 0;
78 phase = 0;
81 }
82
83 void Reset() override
84 {
85 Initialize();
86 }
87
88 void MoveInLineOfSight(Unit* who) override
89 {
90 if (!phase && who && who->GetDistance2d(me) < 10.0f)
91 if (Player* player = who->ToPlayer())
93 {
94 playerGUID = player->GetGUID();
95 if (Aura* orphanOut = player->GetAura(SPELL_ORPHAN_OUT))
96 if (orphanOut->GetCaster() && orphanOut->GetCaster()->GetEntry() == ORPHAN_WOLVAR)
97 {
98 orphanGUID = orphanOut->GetCaster()->GetGUID();
99 phase = 1;
100 }
101 }
102 }
103
104 void proceedCwEvent(const uint32 diff)
105 {
106 if (timer <= diff)
107 {
110
111 if (!orphan || !player)
112 {
113 Reset();
114 return;
115 }
116
117 switch (phase)
118 {
119 case 1:
120 orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ());
121 orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_6);
122 timer = 5000;
123 break;
124 case 2:
125 orphan->SetFacingToObject(me);
126 orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_7);
127 timer = 5000;
128 break;
129 case 3:
131 timer = 5000;
132 break;
133 case 4:
134 orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_8);
135 timer = 5000;
136 break;
137 case 5:
138 orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_9);
139 timer = 5000;
140 break;
141 case 6:
144 Reset();
145 return;
146 }
147 ++phase;
148 }
149 else
150 timer -= diff;
151 }
152
153 void UpdateAI(uint32 diff) override
154 {
155 if (phase)
156 proceedCwEvent(diff);
157
158 if (!sayStep)
159 return;
160
161 if (sayTimer < diff)
162 {
164 sayTimer = 3000;
165 sayStep++;
166
167 if (sayStep > 3) // end
168 sayStep = 0;
169 }
170 else
171 sayTimer -= diff;
172 }
173
174 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
175 {
176 if (spellInfo->Id != SPELL_OFFER)
177 return;
178
179 Player* player = caster->ToPlayer();
180 if (!player)
181 return;
182
183 Quest const* quest = sObjectMgr->GetQuestTemplate(QUEST_TASTE_TEST);
184 if (!quest)
185 return;
186
188 return;
189
190 for (uint32 i = 0; i < quest->Objectives.size(); ++i)
191 {
192 if (uint32(quest->Objectives[i].ObjectID) != me->GetEntry())
193 continue;
194
195 if (player->GetQuestObjectiveData(quest->Objectives[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{
287
288 void HandleDummy(SpellEffIndex /*effIndex*/)
289 {
290 uint32 roll = urand(1, 100);
291
292 uint8 ev;
293 if (roll <= 50)
294 ev = EVENT_MISS;
295 else if (roll <= 83)
296 ev = EVENT_HIT;
297 else
298 ev = EVENT_MISS_BIRD;
299
300 Unit* shooter = GetCaster();
301 Creature* wilhelm = GetHitUnit()->ToCreature();
302 Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30);
303 Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30);
304
305 if (!wilhelm || !apple || !drostan)
306 return;
307
308 switch (ev)
309 {
310 case EVENT_MISS_BIRD:
311 {
312 Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30);
313 Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30);
314
315 if (bird && crunchy)
316 {
317 shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE);
318 bird->CastSpell(bird, SPELL_BIRD_FALL);
319 wilhelm->AI()->Talk(SAY_WILHELM_MISS);
320 drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
321
322 bird->KillSelf();
323 crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(),
324 bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhaseShift(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
326 break;
327 }
328 [[fallthrough]];
329 }
330 case EVENT_MISS:
331 {
332 shooter->CastSpell(wilhelm, SPELL_MISS_APPLE);
333 wilhelm->AI()->Talk(SAY_WILHELM_MISS);
334 drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
335 break;
336 }
337 case EVENT_HIT:
338 {
339 shooter->CastSpell(apple, SPELL_HIT_APPLE);
340 apple->CastSpell(apple, SPELL_APPLE_FALL);
341 wilhelm->AI()->Talk(SAY_WILHELM_HIT);
342 if (Player* player = shooter->ToPlayer())
343 player->KilledMonsterCredit(NPC_APPLE);
344 break;
345 }
346 }
347 }
348
354};
355
356/*######
357## Quest 12620: The Lifewarden's Wrath
358######*/
359
370
371// 51957 - Call of the Lifewarden
373{
375 {
376 PreventHitDefaultEffect(effIndex);
377
378 if (Creature* presence = GetCaster()->FindNearestCreature(NPC_FREYAS_PRESENCE, 50.0f))
379 {
380 presence->AI()->Talk(WHISPER_ACTIVATE, GetCaster());
381 presence->AI()->SetData(1, 1);
382 }
383 }
384
389};
390
391// 51318 - Freya Dummy
393{
394 bool Validate(SpellInfo const* /*spellInfo*/) override
395 {
396 return ValidateSpellInfo(
397 {
401 });
402 }
403
404 void HandleScript(SpellEffIndex /*effIndex*/)
405 {
406 Unit* target = GetHitUnit();
407
408 target->CastSpell(target, SPELL_FREYA_DUMMY_TRIGGER, true);
409 target->CastSpell(target, SPELL_LASHER_EMERGE, false);
410 target->CastSpell(target, SPELL_WILD_GROWTH, false);
411 // This probably is scripted by the Emerge spell from above
413 target->SetUninteractible(false);
414 target->SetImmuneToNPC(false);
415 }
416
421};
422
423/*######
424## Quest 12611: Returned Sevenfold
425######*/
426
433
434// 51854 - Deathbolt
436{
437 bool Validate(SpellInfo const* /*spellInfo*/) override
438 {
439 return ValidateSpellInfo(
440 {
444 });
445 }
446
447 void HandleScript(SpellEffIndex /* effIndex */)
448 {
449 Unit* caster = GetCaster();
450 Unit* target = GetHitUnit();
451
452 if (target->HasAura(SPELL_FREYAS_WARD))
453 target->CastSpell(caster, SPELL_SEVENFOLD_RETRIBUTION, true);
454 else
455 caster->CastSpell(target, SPELL_DEATHBOLT, true);
456 }
457
462};
463
464/*######
465## Quest 12683: Burning to Help
466######*/
467
469{
470 SPELL_HYDRA_SPUTUM = 52307
472
473// 52308 - Take Sputum Sample
475{
476 bool Validate(SpellInfo const* spellInfo) override
477 {
478 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } }) && ValidateSpellInfo(
479 {
482 });
483 }
484
486 {
487 if (!GetCaster()->HasAura(uint32(GetEffectInfo(EFFECT_1).CalcValueAsInt())))
489
490 return SPELL_CAST_OK;
491 }
492
493 void HandleDummy(SpellEffIndex /*effIndex*/)
494 {
496 }
497
503};
504
505// 52306 - Sputum Collected
523
524/*######
525## Quest 12735: A Cleansing Song
526######*/
527
538
539// 52941 - Song of Cleansing
541{
542 bool Validate(SpellInfo const* /*spellInfo*/) override
543 {
544 return ValidateSpellInfo(
545 {
549 });
550 }
551
552 void HandleScript(SpellEffIndex /*effIndex*/)
553 {
554 Unit* caster = GetCaster();
555 switch (caster->GetAreaId())
556 {
558 caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_ATHA);
559 break;
562 break;
564 caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_KOOSU);
565 break;
566 default:
567 break;
568 }
569 }
570
575};
576
577/*######
578## Quest 12741: Strength of the Tempest
579######*/
580
585
586// 53062 - Lightning Strike
604
605/*######
606## Quest 12521: Where in the World is Hemet Nesingwary?
607######*/
608
609// 51071 - Flight to Sholazar (Missile Warning)
611{
612 bool Validate(SpellInfo const* spellInfo) override
613 {
614 return sBroadcastTextStore.LookupEntry(uint32(spellInfo->GetEffect(EFFECT_0).CalcValueAsInt()));
615 }
616
617 void HandleScript(SpellEffIndex /*effIndex*/)
618 {
619 // 51076 (triggers 51071) is Area Aura - Party and applies on player too (no aura in sniffs on player)
620 // That makes both player and creature say
621 if (Creature* caster = GetCaster()->ToCreature())
622 caster->Unit::Say(uint32(GetEffectValueAsInt()), caster);
623 }
624
629};
630
631/*######
632## Quest 12634: Some Make Lemonade, Some Make Liquor
633######*/
634
642
643// This should be scripted in DB but our action lists aren't good enough to properly support chance
644// 51840 - Despawn Fruit Tosser
646{
647 bool Validate(SpellInfo const* /*spellEntry*/) override
648 {
649 return ValidateSpellInfo(
650 {
655 });
656 }
657
658 void HandleDummy(SpellEffIndex /*effIndex*/)
659 {
661 switch (urand(0, 3))
662 {
663 case 1: spellId = SPELL_ORANGE_FALLS_TO_GROUND; break;
664 case 2: spellId = SPELL_PAPAYA_FALLS_TO_GROUND; break;
665 }
666 // sometimes, if you're lucky, you get a dwarf
667 if (roll_chance(5))
669
670 GetHitUnit()->CastSpell(GetCaster(), spellId);
671 }
672
677};
678
679/*######
680## Quest 12805: Salvaging Life's Strength
681######*/
682
687
688// 54190 - Lifeblood Dummy
690{
691 bool Validate(SpellInfo const* spellInfo) override
692 {
693 return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) }) &&
694 sObjectMgr->GetCreatureTemplate(NPC_SHARD_KILL_CREDIT);
695 }
696
697 void HandleScript(SpellEffIndex /*effIndex*/)
698 {
700 {
701 if (Player* caster = GetCaster()->ToPlayer())
702 caster->KilledMonsterCredit(NPC_SHARD_KILL_CREDIT);
703
705 }
706 }
707
712};
713
714/*######
715## Quest 12607: A Mammoth Undertaking
716######*/
717
722
723// 51656 - Mount Mammoth Cue
741
DB2Storage< BroadcastTextEntry > sBroadcastTextStore("BroadcastText.db2", &BroadcastTextLoadInfo::Instance)
uint8_t uint8
Definition Define.h:156
int8_t int8
Definition Define.h:152
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
#define sObjectMgr
Definition ObjectMgr.h:1873
#define PET_FOLLOW_ANGLE
Definition PetDefines.h:99
#define PET_FOLLOW_DIST
Definition PetDefines.h:98
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:146
bool roll_chance(float chance, PseudoRandomDistributionState &state)
Definition Random.cpp:131
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:43
#define RegisterCreatureAI(ai_name)
Definition ScriptMgr.h:1392
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
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)
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Creature *const me
Definition CreatureAI.h:63
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition Creature.cpp:591
CreatureAI * AI() const
Definition Creature.h:235
float GetWaterOrGroundLevel(PhaseShift const &phaseShift, float x, float y, float z, float *ground=nullptr, bool swim=false, float collisionHeight=2.03128f)
Definition Map.cpp:1755
void MoveFollow(Unit *target, float dist, Optional< ChaseAngle > angle={}, Optional< Milliseconds > duration={}, bool ignoreTargetWalk=false, MovementSlot slot=MOTION_SLOT_ACTIVE, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={}, Optional< MovementFadeObject > fadeObject={}, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void Clear()
Definition ObjectGuid.h:329
Player * ToPlayer()
Definition Object.h:126
uint32 GetEntry() const
Definition Object.h:89
Creature * ToCreature()
Definition Object.h:121
void KilledMonsterCredit(uint32 entry, ObjectGuid guid=ObjectGuid::Empty)
Definition Player.cpp:16646
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
Definition Player.cpp:16540
int32 GetQuestObjectiveData(uint32 questId, uint32 objectiveId) const
Definition Player.cpp:16407
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15929
QuestObjectives Objectives
Definition QuestDef.h:753
SpellEffectValue CalcValue(WorldObject const *caster=nullptr, SpellEffectValue const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
int32 CalcValueAsInt(WorldObject const *caster=nullptr, SpellEffectValue const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
uint32 const Id
Definition SpellInfo.h:328
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:590
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
HookList< CheckCastHandler > OnCheckCast
Unit * GetCaster() const
SpellEffectValue GetEffectValue() const
int32 GetEffectValueAsInt() const
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
void SetCustomCastResultMessage(SpellCustomErrors result)
Unit * GetExplTargetUnit() const
Definition Unit.h:647
MotionMaster * GetMotionMaster()
Definition Unit.h:1750
void SetImmuneToNPC(bool apply, bool keepCombat)
Definition Unit.cpp:8560
void SetUninteractible(bool apply)
Definition Unit.cpp:8583
void SetFacingToObject(WorldObject const *object, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13394
void SetEmoteState(Emote emote)
Definition Unit.h:880
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4822
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition Unit.h:951
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3992
Map * GetMap() const
Definition Object.h:411
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
PhaseShift & GetPhaseShift()
Definition Object.h:310
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:448
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:1522
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Object.cpp:1626
uint32 GetAreaId() const
Definition Object.h:333
void HandleSendEvent(SpellEffIndex effIndex)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *spellInfo) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *spellInfo) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
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)
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
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