TrinityCore
Loading...
Searching...
No Matches
boss_reliquary_of_souls.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 "black_temple.h"
20#include "Containers.h"
21#include "InstanceScript.h"
22#include "MotionMaster.h"
23#include "Player.h"
24#include "ScriptedCreature.h"
25#include "Spell.h"
26#include "SpellAuraEffects.h"
27#include "SpellScript.h"
28
30{
31 // Essence of Suffering
36 //SUFF_SAY_AFTER = 4,
38
39 // Essence of Desire
44 //DESI_SAY_AFTER = 4,
45
46 // Essence of Anger
51 //ANGER_SAY_SPEC = 4,
53 //ANGER_SAY_DEATH = 6
54};
55
57{
58 // Reliquary
63
64 // Essence of Suffering
67 SPELL_FRENZY = 41305,
68
69 // Essence of Desire
73 SPELL_DEADEN = 41410,
75
76 // Essence of Anger
79 SPELL_SPITE = 41376,
81 SPELL_SEETHE = 41364,
82
83 // Enslaved Soul
86
87 // World Trigger
89};
90
100
107
124
125Position const DespawnPoint = { 497.4939f, 183.2081f, 94.53341f };
126
128{
129 public: EnslavedSoulEvent(Creature* owner) : _owner(owner) { }
130
131 bool Execute(uint64 /*time*/, uint32 /*diff*/) override
132 {
134 return true;
135 }
136
137 private:
139};
140
141// 22856 - Reliquary of the Lost
143{
145
146 void Reset() override
147 {
148 _Reset();
150 _inCombat = false;
152 }
153
154 void JustSummoned(Creature* summon) override
155 {
156 summons.Summon(summon);
157 summon->AI()->DoZoneInCombat();
158 }
159
171
172 void DoAction(int32 actionId) override
173 {
174 switch (actionId)
175 {
181 break;
187 break;
188 case ACTION_KILL_SELF:
189 me->KillSelf();
191 combatTrigger->AI()->DoAction(ACTION_KILL_SELF);
192 break;
194 _inCombat = true;
197 break;
198 default:
199 break;
200 }
201 }
202
204 {
205 std::vector<Creature*> _worldTriggerList;
207
208 if (_worldTriggerList.empty())
209 return;
210
211 //Get random creatures
212 Trinity::Containers::RandomShuffle(_worldTriggerList);
213 _worldTriggerList.resize(21);
214
215 for (uint8 i = 0; i < 21; i++)
216 {
217 Creature* wTrigger = _worldTriggerList[i];
218 if (i < 3)
219 wTrigger->m_Events.AddEventAtOffset(new EnslavedSoulEvent(wTrigger), 4s);
220 else if (i < 6)
221 wTrigger->m_Events.AddEventAtOffset(new EnslavedSoulEvent(wTrigger), 8s);
222 else if (i < 9)
223 wTrigger->m_Events.AddEventAtOffset(new EnslavedSoulEvent(wTrigger), 12s);
224 else if (i < 12)
225 wTrigger->m_Events.AddEventAtOffset(new EnslavedSoulEvent(wTrigger), 16s);
226 else if (i < 15)
227 wTrigger->m_Events.AddEventAtOffset(new EnslavedSoulEvent(wTrigger), 20s);
228 else if (i < 18)
229 wTrigger->m_Events.AddEventAtOffset(new EnslavedSoulEvent(wTrigger), 24s);
230 else
231 wTrigger->m_Events.AddEventAtOffset(new EnslavedSoulEvent(wTrigger), 28s);
232 }
233 }
234
236 {
237 std::vector<Creature*> _worldTriggerList;
239
240 if (_worldTriggerList.empty())
241 return;
242
243 for (Creature* trigger : _worldTriggerList)
244 trigger->m_Events.KillAllEvents(true);
245 }
246
247 void EnterEvadeMode(EvadeReason /*why*/) override
248 {
249 events.Reset();
253 }
254
255 void JustDied(Unit* /*killer*/) override
256 {
257 events.Reset();
259 }
260
261 void UpdateAI(uint32 diff) override
262 {
263 if (!_inCombat)
264 return;
265
266 events.Update(diff);
267
269 return;
270
271 while (uint32 eventId = events.ExecuteEvent())
272 {
273 if (eventId == EVENT_SUBMERGE)
274 {
279 }
280 }
281 }
282
283private:
285};
286
287// 23418 - Essence of Suffering
289{
294
295 void Reset() override
296 {
298 events.Reset();
299 _dead = false;
300 }
301
302 void MovementInform(uint32 motionType, uint32 pointId) override
303 {
304 if (motionType != POINT_MOTION_TYPE)
305 return;
306
307 if (pointId == RELIQUARY_DESPAWN_WAYPOINT)
308 {
310 reliquary->AI()->DoAction(ACTION_ESSENCE_OF_SUFFERING_DEAD);
311
314 }
315 }
316
317 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
318 {
319 if (damage >= me->GetHealth())
320 {
321 damage = 0;
322 if (!_dead)
323 {
324 _dead = true;
326 me->AttackStop();
328 events.Reset();
331 }
332 }
333 }
334
335 void JustEngagedWith(Unit* /*who*/) override
336 {
338 me->setActive(true);
339
343 }
344
345 void KilledUnit(Unit* victim) override
346 {
347 if (victim->GetTypeId() == TYPEID_PLAYER)
349 }
350
351 void UpdateAI(uint32 diff) override
352 {
353 if (!UpdateVictim())
354 return;
355
357 return;
358
359 events.Update(diff);
360
361 while (uint32 eventId = events.ExecuteEvent())
362 {
363 switch (eventId)
364 {
365 case EVENT_SOUL_DRAIN:
367 events.Repeat(30s, 35s);
368 break;
369 case EVENT_FRENZY:
372 events.Repeat(45s, 50s);
373 break;
374 default:
375 break;
376 }
377
379 return;
380 }
381
383 }
384private:
385 bool _dead;
386};
387
388// 23419 - Essence of Desire
390{
395
396 void Reset() override
397 {
399 events.Reset();
400 _dead = false;
401 }
402
403 void JustEngagedWith(Unit* /*who*/) override
404 {
408
410 me->setActive(true);
412 }
413
414 void MovementInform(uint32 motionType, uint32 pointId) override
415 {
416 if (motionType != POINT_MOTION_TYPE)
417 return;
418
419 if (pointId == RELIQUARY_DESPAWN_WAYPOINT)
420 {
422 reliquary->AI()->DoAction(ACTION_ESSENCE_OF_DESIRE_DEAD);
423
426 }
427 }
428
429 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
430 {
431 if (damage >= me->GetHealth())
432 {
433 damage = 0;
434 if (!_dead)
435 {
436 _dead = true;
438 me->AttackStop();
440 events.Reset();
443 }
444 }
445 }
446
447 void KilledUnit(Unit* victim) override
448 {
449 if (victim->GetTypeId() == TYPEID_PLAYER)
451 }
452
453 void UpdateAI(uint32 diff) override
454 {
455 if (!UpdateVictim())
456 return;
457
459 return;
460
461 events.Update(diff);
462
463 while (uint32 eventId = events.ExecuteEvent())
464 {
465 switch (eventId)
466 {
469 events.Repeat(10s, 15s);
470 break;
473 events.Repeat(16s);
474 break;
475 case EVENT_DEADEN:
478 events.Repeat(31s);
479 break;
480 default:
481 break;
482 }
483
485 return;
486 }
487
489 }
490private:
491 bool _dead;
492};
493
494// 23420 - Essence of Anger
496{
501
502 void Reset() override
503 {
504 events.Reset();
507 }
508
521
522 void JustDied(Unit* /*killer*/) override
523 {
526 reliquary->AI()->DoAction(ACTION_KILL_SELF);
527 }
528
529 void UpdateAI(uint32 diff) override
530 {
531 if (!UpdateVictim())
532 return;
533
535 return;
536
537 events.Update(diff);
538
539 while (uint32 eventId = events.ExecuteEvent())
540 {
541 switch (eventId)
542 {
544 {
545 Unit* target = me->GetVictim();
546 if (!_targetGUID || !target)
547 return;
548
549 if (target->GetGUID() != _targetGUID)
550 {
553 _targetGUID = target->GetGUID();
555 }
556 break;
557 }
560 events.Repeat(11s);
561 break;
562 case EVENT_SPITE:
565 events.Repeat(20s);
566 break;
568 if (Unit* target = me->GetVictim())
569 {
570 _targetGUID = target->GetGUID();
572 }
573 else
574 events.Repeat(1s);
575 break;
576 case EVENT_FREED_2:
578 break;
579 default:
580 break;
581 }
582
584 return;
585 }
586
588 }
589
590private:
592};
593
594// 23469 - Enslaved Soul
596{
597 npc_enslaved_soul(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _dead(false) { }
598
599 void Reset() override
600 {
603 reliquary->AI()->JustSummoned(me);
604
606
607 _scheduler.Schedule(3s, [this](TaskContext /*context*/)
608 {
611 });
612 _dead = false;
613 }
614
615 void DoAction(int32 actionId) override
616 {
617 if (actionId == ACTION_KILL_SELF)
619 }
620
622 {
624 me->AttackStop();
627 me->m_Events.AddEventAtOffset([this]() { me->KillSelf(); }, 500ms);
628 }
629
630 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
631 {
632 if (damage >= me->GetHealth())
633 {
634 damage = 0;
635 if (!_dead)
636 {
637 _dead = true;
639 }
640 }
641 }
642
643 void UpdateAI(uint32 diff) override
644 {
645 if (!UpdateVictim())
646 return;
647
648 _scheduler.Update(diff);
649
651 }
652
653private:
656 bool _dead;
657};
658
659// 23417 - Reliquary Combat Trigger
661{
662 npc_reliquary_combat_trigger(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
663 {
664 SetCombatMovement(false);
665 creature->m_SightDistance = 70.0f;
667 }
668
669 bool CanAIAttack(Unit const* who) const override
670 {
671 return ScriptedAI::CanAIAttack(who) && IsInBoundary(who);
672 }
673
680
681 void MoveInLineOfSight(Unit* who) override
682 {
683 if (!me->IsEngaged() && who->GetTypeId() == TYPEID_PLAYER && !who->ToPlayer()->IsGameMaster() && CanAIAttack(who))
684 {
686 {
688 reliquary->AI()->DoAction(ACTION_START_COMBAT);
689 }
690 }
691 }
692
693 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
694 {
695 damage = 0;
696 }
697
698 void EnterEvadeMode(EvadeReason why) override
699 {
702 reliquary->AI()->EnterEvadeMode(why);
703 }
704
705 void DoAction(int32 actionId) override
706 {
707 if (actionId == ACTION_KILL_SELF)
708 me->KillSelf();
709 }
710
711 void UpdateAI(uint32 /*diff*/) override
712 {
713 if (!UpdateVictim())
714 return;
715 }
716
717private:
719};
720
721// 41350 - Aura of Desire
723{
725
726 bool Validate(SpellInfo const* /*spellInfo*/) override
727 {
729 }
730
731 void OnProcSpell(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
732 {
734 DamageInfo* damageInfo = eventInfo.GetDamageInfo();
735 if (!damageInfo || !damageInfo->GetDamage())
736 return;
737
738 Unit* caster = eventInfo.GetActor();
739 caster->CastSpell(caster, SPELL_AURA_OF_DESIRE_DAMAGE, CastSpellExtraArgs(aurEff).AddSpellBP0(damageInfo->GetDamage() / 2));
740 }
741
742 void UpdateAmount(AuraEffect* /*aurEff*/)
743 {
744 if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1))
745 effect->ChangeAmount(effect->GetAmount() - 5);
746 }
747
753};
754
755// 41337 - Aura of Anger
772
773// 28819 - Submerge Visual
794
795// 41376 - Spite
797{
799
800 bool Validate(SpellInfo const* /*spellInfo*/) override
801 {
803 }
804
805 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
806 {
807 if (Unit* caster = GetCaster())
808 caster->CastSpell(GetTarget(), SPELL_SPITE_DAMAGE, true);
809 }
810
815};
816
817// 41305 - Frenzy
819{
821
823 {
824 if (Creature* caster = GetCaster()->ToCreature())
825 caster->AI()->Talk(SUFF_EMOTE_ENRAGE, caster);
826 }
827
832};
833
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
uint32_t uint32
Definition Define.h:133
@ DONE
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
@ EFFECT_1
@ EFFECT_0
@ EFFECT_2
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_DUMMY
@ SPELL_AURA_MOD_HEALING_PCT
@ SPELL_AURA_DAMAGE_IMMUNITY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ SPELLVALUE_MAX_TARGETS
#define AuraEffectProcFn(F, I, N)
#define AuraEffectUpdatePeriodicFn(F, I, N)
#define SpellCastFn(F)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraEffectRemoveFn(F, I, N, M)
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_STAND_STATE_SUBMERGED
Definition UnitDefines.h:43
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:34
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
#define RegisterBlackTempleCreatureAI(ai_name)
@ DATA_ESSENCE_OF_SUFFERING
@ DATA_RELIQUARY_COMBAT_TRIGGER
@ DATA_ESSENCE_OF_ANGER
@ DATA_ESSENCE_OF_DESIRE
@ DATA_RELIQUARY_OF_SOULS
@ NPC_ENSLAVED_SOUL
@ NPC_RELIQUARY_WORLD_TRIGGER
void AddSC_boss_reliquary_of_souls()
@ ACTION_ESSENCE_OF_DESIRE_DEAD
@ RELIQUARY_DESPAWN_WAYPOINT
@ ACTION_ESSENCE_OF_SUFFERING_DEAD
@ PHASE_ESSENCE_OF_SUFFERING
@ PHASE_ESSENCE_OF_DESIRE
@ EVENT_START_CHECK_TANKER
@ SPELL_ENSLAVED_SOUL_PASSIVE
@ SPELL_SUMMON_ESSENCE_OF_DESIRE
@ SPELL_SUMMON_ESSENCE_OF_SUFFERING
@ SPELL_AURA_OF_DESIRE_DAMAGE
@ SPELL_SUMMON_ESSENCE_OF_ANGER
@ SPELL_SUBMERGE_VISUAL
@ SPELL_AURA_OF_SUFFERING
Position const DespawnPoint
uint32 GetTickNumber() const
void SetAmount(int32 amount)
Aura * GetBase() const
void PreventDefaultAction()
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetCaster() const
HookList< EffectUpdatePeriodicHandler > OnEffectUpdatePeriodic
AuraEffect * GetEffect(uint8 effIndex) const
Aura * GetAura() const
Unit * GetTarget() const
HookList< EffectProcHandler > OnEffectProc
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:201
InstanceScript *const instance
void _DespawnAtEvade(Seconds delayToRespawn=30s, Creature *who=nullptr)
SummonList summons
EventMap events
void DoZoneInCombat(Creature *creature=nullptr)
bool IsInBoundary(Position const *who=nullptr) const
bool UpdateVictim()
void SetBoundary(CreatureBoundary const *boundary, bool negativeBoundaries=false)
Creature *const me
Definition CreatureAI.h:82
virtual void EnterEvadeMode(EvadeReason why=EVADE_REASON_OTHER)
void SetCombatPulseDelay(uint32 delay)
Definition Creature.h:269
bool IsEngaged() const override
void SetReactState(ReactStates st)
Definition Creature.h:119
float m_SightDistance
Definition Creature.h:335
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
CreatureAI * AI() const
Definition Creature.h:154
uint32 GetDamage() const
Definition Unit.h:464
EnslavedSoulEvent(Creature *owner)
bool Execute(uint64, uint32) override
void Update(uint32 time)
Definition EventMap.h:67
void Repeat(Milliseconds time)
Definition EventMap.cpp:63
EventId ExecuteEvent()
Definition EventMap.cpp:73
bool IsInPhase(PhaseIndex phase) const
Definition EventMap.h:236
void SetPhase(PhaseIndex phase)
Definition EventMap.cpp:28
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void Reset()
Definition EventMap.cpp:21
void AddEventAtOffset(BasicEvent *event, Milliseconds offset)
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
CreatureBoundary const * GetBossBoundary(uint32 id) const
EncounterState GetBossState(uint32 id) const
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
void Clear()
Definition ObjectGuid.h:150
TypeID GetTypeId() const
Definition Object.h:93
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
static Player * ToPlayer(Object *o)
Definition Object.h:180
bool IsGameMaster() const
Definition Player.h:998
Unit * GetActor()
Definition Unit.h:508
DamageInfo * GetDamageInfo() const
Definition Unit.h:519
HookList< CastHandler > AfterCast
Unit * GetCaster() const
void Summon(Creature const *summon)
void DoAction(int32 info, Predicate &&predicate, uint16 max=0)
TaskScheduler & Schedule(std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
TaskScheduler & Update(success_t const &callback=EmptyCallback)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
virtual bool CanAIAttack(Unit const *) const
Definition UnitAI.h:139
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
Definition Unit.h:769
void KillSelf(bool durabilityLoss=true)
Definition Unit.h:1023
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
uint32 GetHealth() const
Definition Unit.h:913
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void SetStandState(UnitStandStateType state)
Definition Unit.cpp:10363
bool AttackStop()
Definition Unit.cpp:5645
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:3153
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
void setActive(bool isActiveObject)
Definition Object.cpp:991
EventProcessor m_Events
Definition Object.h:591
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
PrepareAuraScript(spell_reliquary_of_souls_aura_of_anger)
PrepareAuraScript(spell_reliquary_of_souls_aura_of_desire)
void OnProcSpell(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
PrepareSpellScript(spell_reliquary_of_souls_frenzy)
PrepareAuraScript(spell_reliquary_of_souls_spite)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void OnApply(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_reliquary_of_souls_submerge)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
void RandomShuffle(C &container)
Reorder the elements of the container randomly.
Definition Containers.h:166
void SetCombatMovement(bool allowMovement)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void UpdateAI(uint32 diff) override
boss_essence_of_anger(Creature *creature)
void JustEngagedWith(Unit *) override
boss_essence_of_desire(Creature *creature)
void MovementInform(uint32 motionType, uint32 pointId) override
void KilledUnit(Unit *victim) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void JustEngagedWith(Unit *) override
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
boss_essence_of_suffering(Creature *creature)
void KilledUnit(Unit *victim) override
void MovementInform(uint32 motionType, uint32 pointId) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
boss_reliquary_of_souls(Creature *creature)
void UpdateAI(uint32 diff) override
void JustSummoned(Creature *summon) override
void EnterEvadeMode(EvadeReason) override
void DoAction(int32 actionId) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
npc_enslaved_soul(Creature *creature)
void DoAction(int32 actionId) override
void UpdateAI(uint32 diff) override
void DoAction(int32 actionId) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
bool CanAIAttack(Unit const *who) const override
void MoveInLineOfSight(Unit *who) override
void EnterEvadeMode(EvadeReason why) override