TrinityCore
boss_devourer_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 "Containers.h"
20#include "forge_of_souls.h"
21#include "InstanceScript.h"
22#include "Map.h"
23#include "MotionMaster.h"
24#include "ScriptedCreature.h"
25#include "SpellAuraEffects.h"
26#include "SpellInfo.h"
27#include "SpellScript.h"
28#include "TemporarySummon.h"
29
30/*
31 * @todo
32 * - Fix model id during unleash soul -> seems DB issue 36503 is missing (likewise 36504 is also missing).
33 * - Fix outro npc movement
34 */
35
37{
48
51};
52
54{
63 SPELL_WAILING_SOULS_STARTING = 68912, // Initial spell cast at begining of wailing souls phase
64 SPELL_WAILING_SOULS_BEAM = 68875, // the beam visual
65 SPELL_WAILING_SOULS = 68873, // the actual spell
67// 68871, 68873, 68875, 68876, 68899, 68912, 70324,
68// 68899 trigger 68871
69};
70
72{
80};
81
83{
87};
88
90{
94{
95 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5590.47f, 2427.79f, 705.935f, 0.802851f } },
96 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5593.59f, 2428.34f, 705.935f, 0.977384f } },
97 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5600.81f, 2429.31f, 705.935f, 0.890118f } },
98 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5600.81f, 2421.12f, 705.935f, 0.890118f } },
99 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5601.43f, 2426.53f, 705.935f, 0.890118f } },
100 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5601.55f, 2418.36f, 705.935f, 1.15192f } },
101 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5598, 2429.14f, 705.935f, 1.0472f } },
102 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5594.04f, 2424.87f, 705.935f, 1.15192f } },
103 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5597.89f, 2421.54f, 705.935f, 0.610865f } },
104 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5598.57f, 2434.62f, 705.935f, 1.13446f } },
105 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5585.46f, 2417.99f, 705.935f, 1.06465f } },
106 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5605.81f, 2428.42f, 705.935f, 0.820305f } },
107 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5591.61f, 2412.66f, 705.935f, 0.925025f } },
108 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5593.9f, 2410.64f, 705.935f, 0.872665f } },
109 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5586.76f, 2416.73f, 705.935f, 0.942478f } },
110 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 5592.23f, 2419.14f, 705.935f, 0.855211f } },
111 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 5594.61f, 2416.87f, 705.935f, 0.907571f } },
112 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 5589.77f, 2421.03f, 705.935f, 0.855211f } },
113
114 { { NPC_KORELN, NPC_LORALEN }, { 5602.58f, 2435.95f, 705.935f, 0.959931f } },
115 { { NPC_ELANDRA, NPC_KALIRA }, { 5606.13f, 2433.16f, 705.935f, 0.785398f } },
116 { { NPC_JAINA_PART2, NPC_SYLVANAS_PART2 }, { 5606.12f, 2436.6f, 705.935f, 0.890118f } },
117
118 { { 0, 0 }, { 0.0f, 0.0f, 0.0f, 0.0f } }
120
121static constexpr Position CrucibleSummonPos = { 5672.294f, 2520.686f, 713.4386f, 0.9599311f };
122
124{
126 {
127 beamAngle = 0.f;
128 beamAngleDiff = float(M_PI) / 20.0f;
129 wailingSoulTick = 0;
130 }
131
132 void Reset() override
133 {
134 _Reset();
139 }
140
141 void JustEngagedWith(Unit* who) override
142 {
145
146 if (!me->FindNearestCreature(NPC_CRUCIBLE_OF_SOULS, 60)) // Prevent double spawn
153 }
154
155 void KilledUnit(Unit* victim) override
156 {
157 if (victim->GetTypeId() != TYPEID_PLAYER)
158 return;
159
160 uint8 textId = 0;
161 switch (me->GetDisplayId())
162 {
163 case DISPLAY_ANGER:
164 textId = SAY_FACE_ANGER_SLAY;
165 break;
166 case DISPLAY_SORROW:
167 textId = SAY_FACE_SORROW_SLAY;
168 break;
169 case DISPLAY_DESIRE:
170 textId = SAY_FACE_DESIRE_SLAY;
171 break;
172 default:
173 break;
174 }
175
176 if (textId)
177 Talk(textId);
178 }
179
180 void JustDied(Unit* /*killer*/) override
181 {
182 _JustDied();
183
184 Position spawnPoint = {5618.139f, 2451.873f, 705.854f, 0};
185
187
188 int32 entryIndex;
190 entryIndex = 0;
191 else
192 entryIndex = 1;
193
194 for (int8 i = 0; outroPositions[i].entry[entryIndex] != 0; ++i)
195 {
196 if (TempSummon* summon = instance->instance->SummonCreature(outroPositions[i].entry[entryIndex], spawnPoint))
197 {
198 summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN);
199 summon->GetMotionMaster()->MovePoint(0, outroPositions[i].movePosition);
200 if (summon->GetEntry() == NPC_JAINA_PART2)
201 summon->AI()->Talk(SAY_JAINA_OUTRO);
202 else if (summon->GetEntry() == NPC_SYLVANAS_PART2)
203 summon->AI()->Talk(SAY_SYLVANAS_OUTRO);
204 }
205 }
206 }
207
208 void SpellHitTarget(WorldObject* /*target*/, SpellInfo const* spellInfo) override
209 {
210 if (spellInfo->Id == H_SPELL_PHANTOM_BLAST)
212 }
213
214 void UpdateAI(uint32 diff) override
215 {
216 // Return since we have no target
217 if (!UpdateVictim())
218 return;
219
220 events.Update(diff);
221
223 return;
224
225 while (uint32 eventId = events.ExecuteEvent())
226 {
227 switch (eventId)
228 {
232 break;
237 break;
242 break;
251 break;
252 case EVENT_FACE_ANGER:
254 break;
255
262 {
263 me->SetFacingToObject(target);
265 }
266
268
269 if (roll_chance_i(50))
271
274
275 //Remove any target
277
280
281 wailingSoulTick = 20;
282 events.DelayEvents(13s); // no other events during wailing souls
283 events.ScheduleEvent(EVENT_WAILING_SOULS_TICK, 3s); // first one after 3 secs.
284 break;
285
287 if (--wailingSoulTick)
288 {
293 }
294 else
295 {
301 }
302 break;
303 }
304
306 return;
307 }
308 }
309
310private:
311 // wailing soul event
315};
316
317// 69051 - Mirrored Soul
319{
320 bool Validate(SpellInfo const* /*spellInfo*/) override
321 {
323 }
324
325 void HandleScript(SpellEffIndex /*effIndex*/)
326 {
327 if (Unit* target = GetHitUnit())
328 target->CastSpell(GetCaster(), SPELL_MIRRORED_SOUL_PROC_AURA, true);
329 }
330
331 void Register() override
332 {
334 }
335};
336
337// 69023 - Mirrored Soul (Proc)
339{
340 bool Validate(SpellInfo const* /*spellInfo*/) override
341 {
343 }
344
345 bool CheckProc(ProcEventInfo& /*eventInfo*/)
346 {
347 return GetCaster() && GetCaster()->IsAlive();
348 }
349
350 void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& eventInfo)
351 {
353 DamageInfo* damageInfo = eventInfo.GetDamageInfo();
354 if (!damageInfo || !damageInfo->GetDamage())
355 return;
356
358 args.AddSpellBP0(CalculatePct(damageInfo->GetDamage(), 45));
360 }
361
362 void Register() override
363 {
366 }
367};
368
369// 69048 - Mirrored Soul (Target Selector)
371{
372 bool Validate(SpellInfo const* /*spellInfo*/) override
373 {
375 }
376
377 void FilterTargets(std::list<WorldObject*>& targets)
378 {
379 if (targets.empty())
380 return;
381
383 targets.clear();
384 targets.push_back(target);
385 }
386
387 void HandleScript(SpellEffIndex /*effIndex*/)
388 {
389 if (Unit* target = GetHitUnit())
391 }
392
393 void Register() override
394 {
397 }
398};
399
401{
406}
#define M_PI
Definition: Common.h:115
uint8_t uint8
Definition: Define.h:144
int8_t int8
Definition: Define.h:140
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
@ TEMPSUMMON_DEAD_DESPAWN
Definition: ObjectDefines.h:69
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
Spells
Definition: PlayerAI.cpp:32
bool roll_chance_i(int chance)
Definition: Random.h:59
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_SRC_AREA_ENTRY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ ALLIANCE
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
#define AuraEffectProcFn(F, I, N)
Definition: SpellScript.h:2160
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
#define AuraCheckProcFn(F)
Definition: SpellScript.h:2130
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
@ UNIT_STATE_ROOT
Definition: Unit.h:265
@ UNIT_STATE_CASTING
Definition: Unit.h:270
T CalculatePct(T base, U pct)
Definition: Util.h:72
struct outroPosition outroPositions[]
@ EMOTE_WAILING_SOUL
@ SAY_FACE_ANGER_SLAY
@ SAY_FACE_DESIRE_SLAY
@ EMOTE_MIRRORED_SOUL
@ SAY_FACE_WAILING_SOUL
@ SAY_FACE_SORROW_SLAY
@ EMOTE_UNLEASH_SOUL
@ SAY_SYLVANAS_OUTRO
@ SAY_FACE_UNLEASH_SOUL
void AddSC_boss_devourer_of_souls()
@ SPELL_MIRRORED_SOUL_DAMAGE
@ SPELL_PHANTOM_BLAST
@ SPELL_MIRRORED_SOUL_PROC_AURA
@ SPELL_WAILING_SOULS_BEAM
@ H_SPELL_WAILING_SOULS
@ SPELL_MIRRORED_SOUL_TARGET_SELECTOR
@ H_SPELL_PHANTOM_BLAST
@ SPELL_WELL_OF_SOULS
@ SPELL_WAILING_SOULS_STARTING
@ SPELL_MIRRORED_SOUL_BUFF
@ SPELL_UNLEASHED_SOULS
@ SPELL_WAILING_SOULS
static constexpr Position CrucibleSummonPos
@ EVENT_WAILING_SOULS
@ EVENT_WELL_OF_SOULS
@ EVENT_FACE_ANGER
@ EVENT_UNLEASHED_SOULS
@ EVENT_WAILING_SOULS_TICK
@ EVENT_PHANTOM_BLAST
@ EVENT_MIRRORED_SOUL
Yells
void PreventDefaultAction()
Unit * GetCaster() const
Unit * GetTarget() const
HookList< CheckProcHandler > DoCheckProc
Definition: SpellScript.h:2129
HookList< EffectProcHandler > OnEffectProc
Definition: SpellScript.h:2155
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
EventMap events
void _JustDied()
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void StartDefaultCombatMovement(Unit *victim, Optional< float > range={}, Optional< float > angle={})
Definition: Creature.cpp:2855
void SetReactState(ReactStates st)
Definition: Creature.h:160
void SetTarget(ObjectGuid const &guid) override
Definition: Creature.cpp:3419
void SetDisplayId(uint32 displayId, bool setNative=false) override
Definition: Creature.cpp:3402
uint32 GetDamage() const
Definition: Unit.h:446
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void DelayEvents(Milliseconds delay)
Definition: EventMap.cpp:96
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
void DoUpdateWorldState(int32 worldStateId, int32 value)
InstanceMap * instance
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, Milliseconds duration=0ms, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty, SmoothPhasingInfo const *smoothPhasingInfo=nullptr)
Definition: Object.cpp:1836
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
TypeID GetTypeId() const
Definition: Object.h:173
DamageInfo * GetDamageInfo() const
Definition: Unit.h:505
uint32 const Id
Definition: SpellInfo.h:325
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetCaster() const
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void SetControlled(bool apply, UnitState state)
Definition: Unit.cpp:10911
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3089
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:12671
bool IsAlive() const
Definition: Unit.h:1164
uint32 GetDisplayId() const
Definition: Unit.h:1567
Unit * GetVictim() const
Definition: Unit.h:715
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
virtual uint32 GetData(uint32) const
Definition: ZoneScript.h:91
void HandleProc(AuraEffect *, ProcEventInfo &eventInfo)
void FilterTargets(std::list< WorldObject * > &targets)
bool Validate(SpellInfo const *) override
@ WORLD_STATE_THREE_FACED_FAILED
@ DATA_TEAM_IN_INSTANCE
@ DATA_DEVOURER_OF_SOULS
@ NPC_CHAMPION_1_ALLIANCE
@ NPC_JAINA_PART2
@ NPC_KALIRA
@ NPC_CRUCIBLE_OF_SOULS
@ NPC_KORELN
@ NPC_CHAMPION_1_HORDE
@ NPC_CHAMPION_2_ALLIANCE
@ NPC_SYLVANAS_PART2
@ NPC_LORALEN
@ NPC_ELANDRA
@ NPC_CHAMPION_3_HORDE
@ NPC_CHAMPION_2_HORDE
#define RegisterForgeOfSoulsCreatureAI(ai_name)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
CastSpellExtraArgs & AddSpellBP0(int32 val)
Definition: SpellDefines.h:475
constexpr float GetOrientation() const
Definition: Position.h:79
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
boss_devourer_of_souls(Creature *creature)
void SpellHitTarget(WorldObject *, SpellInfo const *spellInfo) override
void KilledUnit(Unit *victim) override