TrinityCore
zone_howling_fjord.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 "Containers.h"
20#include "MotionMaster.h"
21#include "ObjectAccessor.h"
22#include "ObjectMgr.h"
23#include "Player.h"
24#include "QuestDef.h"
25#include "ScriptedCreature.h"
26#include "ScriptedEscortAI.h"
27#include "Spell.h"
28#include "SpellInfo.h"
29#include "SpellScript.h"
30#include "TemporarySummon.h"
31#include "Vehicle.h"
32
33/*######
34## npc_daegarn
35######*/
36
38{
40 NPC_FIRJUS = 24213,
41 NPC_JLARBORN = 24215,
42 NPC_YOROS = 24214,
43 NPC_OLUF = 23931,
44 NPC_PRISONER_1 = 24253, // looks the same but has different abilities
47 SAY_TEXT = 0
48};
49
50static Position const daegarnSummonPosition = { 838.81f, -4678.06f, -94.182f, 0.0f };
51static Position const daegarnCenterPosition = { 801.88f, -4721.87f, -96.143f, 0.0f };
52
54struct npc_daegarn : public ScriptedAI
55{
56 npc_daegarn(Creature* creature) : ScriptedAI(creature), _eventInProgress(false), _summons(creature)
57 {
58 }
59
60 void Reset() override
61 {
62 _eventInProgress = false;
66
67 _scheduler.Schedule(40s, [this](TaskContext context)
68 {
70 context.Repeat(40s);
71 });
72 }
73
74 void EnterEvadeMode(EvadeReason why) override
75 {
76 if (!_EnterEvadeMode(why))
77 return;
78
79 if (!me->GetVehicle())
80 {
81 if (Unit* owner = me->GetCharmerOrOwner())
82 {
85 }
86 else
87 {
90 }
91 }
92
93 if (me->IsVehicle())
94 me->GetVehicleKit()->Reset(true);
95 }
96
97 void UpdateAI(uint32 diff) override
98 {
99 _scheduler.Update(diff);
100
101 if (!UpdateVictim())
102 return;
103 }
104
105 void JustSummoned(Creature* summon) override
106 {
107 _summons.Summon(summon);
108
110 {
111 if (player->IsAlive())
112 {
113 summon->SetWalk(false);
116 return;
117 }
118 }
119
120 Reset();
121 }
122
123 void SummonedCreatureDespawn(Creature* summon) override
124 {
125 _summons.Despawn(summon);
126 }
127
128 void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
129 {
130 uint32 entry = 0;
131
132 _summons.Despawn(summon);
133
134 // will eventually reset the event if something goes wrong
135 switch (summon->GetEntry())
136 {
137 case NPC_FIRJUS:
138 entry = NPC_JLARBORN;
139 break;
140 case NPC_JLARBORN:
141 entry = NPC_YOROS;
142 break;
143 case NPC_YOROS:
144 entry = NPC_OLUF;
145 break;
146 case NPC_OLUF:
147 Reset();
148 return;
149 }
150
151 SummonGladiator(entry);
152 }
153
154 void OnQuestAccept(Player* player, Quest const* quest) override
155 {
156 if (quest->GetQuestId() == QUEST_DEFEAT_AT_RING)
157 {
159 return;
160
161 _eventInProgress = true;
162 _playerGUID = player->GetGUID();
165
166 _scheduler.Schedule(20s, [this](TaskContext context)
167 {
168 bool reset = true;
170 {
171 if (player->IsAlive() && player->IsEngaged())
172 {
173 for (auto itr = _summons.begin(); reset && itr != _summons.end(); ++itr)
174 {
175 Creature* summon = ObjectAccessor::GetCreature(*me, *_summons.begin());
176 if (summon && player->IsEngagedBy(summon))
177 {
178 context.Repeat(5s);
179 reset = false;
180 }
181 }
182 }
183 }
184
185 if (reset)
186 Reset();
187 });
188
190 }
191 }
192
193private:
195 {
196 me->SummonCreature(entry, daegarnSummonPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30s);
197 }
198
203};
204
205/*######
206## Quest 11310: Warning: Some Assembly Required
207######*/
208
210{
216
217// 43393 - Ping Master
219{
220 bool Validate(SpellInfo const* /*spellInfo*/) override
221 {
223 }
224
225 void HandleScript(SpellEffIndex /*effIndex*/)
226 {
228 }
229
230 void Register() override
231 {
233 }
234};
235
236// 42268 - Quest - Mindless Abomination Explosion FX Master
238{
239 bool Validate(SpellInfo const* /*spellInfo*/) override
240 {
241 return ValidateSpellInfo(
242 {
246 });
247 }
248
250 {
251 Unit* caster = GetCaster();
252
253 for (uint8 i = 0; i < 11; ++i)
255
256 for (uint8 i = 0; i < 6; ++i)
258
259 for (uint8 i = 0; i < 4; ++i)
261 }
262
263 void Register() override
264 {
266 }
267};
268
269/*######
270## Quest 11296: Rivenwood Captives
271######*/
272
274{
288
289std::array<uint32, 11> const CocoonSummonSpells =
290{
302};
303
304// 43288 - Rivenwood Captives: Player Not On Quest
306{
307 bool Validate(SpellInfo const* /*spellInfo*/) override
308 {
310 }
311
312 void HandleDummy(SpellEffIndex /*effIndex*/)
313 {
315 }
316
317 void Register() override
318 {
320 }
321};
322
323// 43287 - Rivenwood Captives: Player On Quest
325{
326 bool Validate(SpellInfo const* /*spellInfo*/) override
327 {
329 }
330
331 void HandleDummy(SpellEffIndex /*effIndex*/)
332 {
333 Unit* caster = GetCaster();
334 Unit* target = GetHitUnit();
335
336 if (roll_chance_i(80))
338 else
340 }
341
342 void Register() override
343 {
345 }
346};
347
348/*######
349## Quest 11317, 11322: The Cleansing
350######*/
351
353{
358
362
363// 43365 - The Cleansing: Shrine Cast
365{
366 bool Validate(SpellInfo const* /*spellInfo*/) override
367 {
369 sObjectMgr->GetQuestTemplate(QUEST_THE_CLEANSING_H) &&
370 sObjectMgr->GetQuestTemplate(QUEST_THE_CLEANSING_A);
371 }
372
374 {
375 // Error is correct for quest check but may be not correct for aura and this may be a wrong place to send error
376 if (Player* target = GetExplTargetUnit()->ToPlayer())
377 {
378 if (target->HasAura(SPELL_RECENT_MEDITATION) || (!(target->GetQuestStatus(QUEST_THE_CLEANSING_H) == QUEST_STATUS_INCOMPLETE ||
379 target->GetQuestStatus(QUEST_THE_CLEANSING_A) == QUEST_STATUS_INCOMPLETE)))
380 {
381 Spell::SendCastResult(target, GetSpellInfo(), GetSpell()->m_SpellVisual, GetSpell()->m_castId, SPELL_FAILED_FIZZLE);
382 return SPELL_FAILED_FIZZLE;
383 }
384 }
385 return SPELL_CAST_OK;
386 }
387
388 void HandleScript(SpellEffIndex /*effIndex*/)
389 {
391 }
392
393 void Register() override
394 {
397 }
398};
399
400// 43351 - Cleansing Soul
402{
403 bool Validate(SpellInfo const* /*spellInfo*/) override
404 {
406 }
407
408 void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
409 {
411 }
412
413 void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
414 {
415 Unit* target = GetTarget();
417 target->CastSpell(target, SPELL_SUMMON_INNER_TURMOIL, true);
418 target->CastSpell(target, SPELL_RECENT_MEDITATION, true);
419 }
420
421 void Register() override
422 {
425 }
426};
427
428// 50217 - The Cleansing: Script Effect Player Cast Mirror Image
430{
431 bool Validate(SpellInfo const* /*spellInfo*/) override
432 {
434 }
435
436 void HandleScript(SpellEffIndex /*effIndex*/)
437 {
439 }
440
441 void Register() override
442 {
444 }
445};
446
447// 50238 - The Cleansing: Your Inner Turmoil's On Death Cast on Master
449{
450 bool Validate(SpellInfo const* spellInfo) override
451 {
452 return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
453 }
454
455 void HandleScript(SpellEffIndex /*effIndex*/)
456 {
457 if (TempSummon* casterSummon = GetCaster()->ToTempSummon())
458 if (Unit* summoner = casterSummon->GetSummonerUnit())
459 summoner->CastSpell(summoner, uint32(GetEffectValue()));
460 }
461
462 void Register() override
463 {
465 }
466};
467
468/*######
469## Quest 11472: The Way to His Heart...
470######*/
471
473{
477
478// 21014 - Anuniaq's Net
480{
481 bool Validate(SpellInfo const* /*spell*/) override
482 {
484 }
485
486 void HandleDummy(SpellEffIndex /*effIndex*/)
487 {
488 Unit* caster = GetCaster();
490 }
491
492 void Register() override
493 {
495 }
496};
497
498// 44455 - The Way to His Heart...: Character Script Effect Reverse Cast
500{
501 bool Validate(SpellInfo const* spellInfo) override
502 {
503 return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
504 }
505
506 void HandleScript(SpellEffIndex /*effIndex*/)
507 {
509 }
510
511 void Register() override
512 {
514 }
515};
516
517// 44462 - The Way to His Heart...: Cast Quest Complete on Master
519{
520 bool Validate(SpellInfo const* spellInfo) override
521 {
522 return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
523 }
524
525 void HandleScript(SpellEffIndex /*effIndex*/)
526 {
527 if (TempSummon* casterSummon = GetCaster()->ToTempSummon())
528 if (Unit* summoner = casterSummon->GetSummonerUnit())
529 summoner->CastSpell(summoner, uint32(GetEffectValue()), true);
530 }
531
532 void Register() override
533 {
535 }
536};
537
539{
552}
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition: ObjectDefines.h:66
#define sObjectMgr
Definition: ObjectMgr.h:1946
#define PET_FOLLOW_DIST
Definition: PetDefines.h:97
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:145
bool roll_chance_i(int chance)
Definition: Random.h:59
#define RegisterCreatureAI(ai_name)
Definition: ScriptMgr.h:1380
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
SpellCastResult
@ SPELL_FAILED_FIZZLE
@ SPELL_CAST_OK
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_DUMMY
#define SpellCheckCastFn(F)
Definition: SpellScript.h:830
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define AuraEffectApplyFn(F, I, N, M)
Definition: SpellScript.h:2029
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2040
EvadeReason
Definition: UnitAICommon.h:30
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:42
@ UNIT_STAND_STATE_SIT
Definition: UnitDefines.h:43
@ UNIT_STATE_EVADE
Definition: Unit.h:277
HookList< EffectApplyHandler > AfterEffectRemove
Definition: SpellScript.h:2039
HookList< EffectApplyHandler > AfterEffectApply
Definition: SpellScript.h:2028
Unit * GetTarget() const
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool _EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:299
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:371
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
void MoveFollow(Unit *target, float dist, ChaseAngle angle, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_ACTIVE)
void MoveTargetedHome()
void Clear()
Definition: ObjectGuid.h:286
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
uint32 GetQuestId() const
Definition: QuestDef.h:587
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
Definition: SpellInfo.cpp:495
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:577
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
HookList< CheckCastHandler > OnCheckCast
Definition: SpellScript.h:829
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHit
Definition: SpellScript.h:839
Unit * GetHitUnit() const
int32 GetEffectValue() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
Spell * GetSpell() const
Definition: SpellScript.h:987
Unit * GetExplTargetUnit() const
SpellInfo const * GetSpellInfo() const
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, SpellCastVisual spellVisual, ObjectGuid cast_count, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE, int32 *param1=nullptr, int32 *param2=nullptr)
Definition: Spell.cpp:4643
void Despawn(Creature const *summon)
void Summon(Creature const *summon)
TaskContext & Repeat(std::chrono::duration< Rep, Period > duration)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(std::chrono::duration< Rep, Period > time, task_handler_t task)
TaskScheduler & Update(success_t const &callback=nullptr)
Definition: Unit.h:627
bool IsVehicle() const
Definition: Unit.h:743
Vehicle * GetVehicle() const
Definition: Unit.h:1713
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition: Unit.cpp:10100
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsAlive() const
Definition: Unit.h:1164
void AddUnitState(uint32 f)
Definition: Unit.h:731
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1200
bool SetWalk(bool enable)
Definition: Unit.cpp:12707
virtual float GetFollowAngle() const
Definition: Unit.h:1744
Vehicle * GetVehicleKit() const
Definition: Unit.h:1711
virtual bool IsEngaged() const
Definition: Unit.h:1019
void Reset(bool evading=false)
Reapplies immunities and reinstalls accessories. Only has effect for creatures.
Definition: Vehicle.cpp:138
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
void AfterRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *spellInfo) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *spellInfo) override
bool Validate(SpellInfo const *spellInfo) override
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
void UpdateAI(uint32 diff) override
void OnQuestAccept(Player *player, Quest const *quest) override
void SummonGladiator(uint32 entry)
void EnterEvadeMode(EvadeReason why) override
void Reset() override
void JustSummoned(Creature *summon) override
TaskScheduler _scheduler
void SummonedCreatureDies(Creature *summon, Unit *) override
void SummonedCreatureDespawn(Creature *summon) override
ObjectGuid _playerGUID
npc_daegarn(Creature *creature)
RivenwoodCaptives
@ SPELL_SUMMON_WINTERSKORN_BERSERKER
@ SPELL_SUMMON_PUTRID_HORROR
@ SPELL_SUMMON_WINTERSKORN_TRIBESMAN
@ SPELL_SUMMON_BABY_RIVEN_WIDOWS
@ SPELL_SUMMON_FANGGORE_WORG
@ SPELL_SUMMON_WINTERSKORN_WOODSMAN
@ SPELL_SUMMON_GJALERBRON_WARRIOR
@ SPELL_SUMMON_GJALERBRON_SLEEPWATCHER
@ SPELL_SUMMON_WINTERSKORN_ORACLE
@ SPELL_SUMMON_FREED_MIST_WHISPER_SCOUT
@ SPELL_SUMMON_GJALERBRON_RUNECASTER
@ SPELL_SUMMON_DARKCLAW_BAT
SomeAssemblyRequired
@ SPELL_RANDOM_CIRCUMFERENCE_POINT_POISON
@ SPELL_RANDOM_CIRCUMFERENCE_POINT_BONE
@ SPELL_RANDOM_CIRCUMFERENCE_POINT_BONE_2
@ SPELL_MINDLESS_ABOMINATION_CONTROL
void AddSC_howling_fjord()
@ QUEST_THE_CLEANSING_A
@ SPELL_CLEANSING_SOUL
@ QUEST_THE_CLEANSING_H
@ SPELL_MIRROR_IMAGE_AURA
@ SPELL_SUMMON_INNER_TURMOIL
@ SPELL_RECENT_MEDITATION
TheWayToHisHeart
@ SPELL_FISHED_UP_REEF_SHARK
@ SPELL_CREATE_TASTY_REEF_FISH
static Position const daegarnSummonPosition
std::array< uint32, 11 > const CocoonSummonSpells
static Position const daegarnCenterPosition
@ NPC_OLUF
@ NPC_FIRJUS
@ QUEST_DEFEAT_AT_RING
@ SAY_TEXT
@ NPC_PRISONER_3
@ NPC_JLARBORN
@ NPC_PRISONER_2
@ NPC_PRISONER_1
@ NPC_YOROS