TrinityCore
Loading...
Searching...
No Matches
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 "Player.h"
25#include "ScriptedCreature.h"
26#include "SpellAuraEffects.h"
27#include "SpellInfo.h"
28#include "SpellScript.h"
29#include "TemporarySummon.h"
30
31/*
32 * @todo
33 * - Fix model id during unleash soul -> seems DB issue 36503 is missing (likewise 36504 is also missing).
34 * - Fix outro npc movement
35 */
36
53
55{
64 SPELL_WAILING_SOULS_STARTING = 68912, // Initial spell cast at begining of wailing souls phase
65 SPELL_WAILING_SOULS_BEAM = 68875, // the beam visual
66 SPELL_WAILING_SOULS = 68873, // the actual spell
68// 68871, 68873, 68875, 68876, 68899, 68912, 70324,
69// 68899 trigger 68871
70};
71
82
84{
88};
89
95{
96 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5590.47f, 2427.79f, 705.935f, 0.802851f } },
97 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5593.59f, 2428.34f, 705.935f, 0.977384f } },
98 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5600.81f, 2429.31f, 705.935f, 0.890118f } },
99 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5600.81f, 2421.12f, 705.935f, 0.890118f } },
100 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5601.43f, 2426.53f, 705.935f, 0.890118f } },
101 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5601.55f, 2418.36f, 705.935f, 1.15192f } },
102 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5598, 2429.14f, 705.935f, 1.0472f } },
103 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5594.04f, 2424.87f, 705.935f, 1.15192f } },
104 { { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5597.89f, 2421.54f, 705.935f, 0.610865f } },
105 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5598.57f, 2434.62f, 705.935f, 1.13446f } },
106 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5585.46f, 2417.99f, 705.935f, 1.06465f } },
107 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5605.81f, 2428.42f, 705.935f, 0.820305f } },
108 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5591.61f, 2412.66f, 705.935f, 0.925025f } },
109 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5593.9f, 2410.64f, 705.935f, 0.872665f } },
110 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5586.76f, 2416.73f, 705.935f, 0.942478f } },
111 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 5592.23f, 2419.14f, 705.935f, 0.855211f } },
112 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 5594.61f, 2416.87f, 705.935f, 0.907571f } },
113 { { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 5589.77f, 2421.03f, 705.935f, 0.855211f } },
114
115 { { NPC_KORELN, NPC_LORALEN }, { 5602.58f, 2435.95f, 705.935f, 0.959931f } },
116 { { NPC_ELANDRA, NPC_KALIRA }, { 5606.13f, 2433.16f, 705.935f, 0.785398f } },
117 { { NPC_JAINA_PART2, NPC_SYLVANAS_PART2 }, { 5606.12f, 2436.6f, 705.935f, 0.890118f } },
118
119 { { 0, 0 }, { 0.0f, 0.0f, 0.0f, 0.0f } }
121
122Position const CrucibleSummonPos = {5672.294f, 2520.686f, 713.4386f, 0.9599311f};
123
125{
128
130{
132 {
133 Initialize();
134 beamAngle = 0.f;
135 beamAngleDiff = 0.f;
136 wailingSoulTick = 0;
137 }
138
140 {
141 threeFaced = true;
142 }
143
144 void Reset() override
145 {
146 _Reset();
150
151 Initialize();
152 }
153
167
168 void KilledUnit(Unit* victim) override
169 {
170 if (victim->GetTypeId() != TYPEID_PLAYER)
171 return;
172
173 uint8 textId = 0;
174 switch (me->GetDisplayId())
175 {
176 case DISPLAY_ANGER:
177 textId = SAY_FACE_ANGER_SLAY;
178 break;
179 case DISPLAY_SORROW:
180 textId = SAY_FACE_SORROW_SLAY;
181 break;
182 case DISPLAY_DESIRE:
183 textId = SAY_FACE_DESIRE_SLAY;
184 break;
185 default:
186 break;
187 }
188
189 if (textId)
190 Talk(textId);
191 }
192
193 void JustDied(Unit* /*killer*/) override
194 {
195 _JustDied();
196
197 Position spawnPoint = {5618.139f, 2451.873f, 705.854f, 0};
198
200
201 int32 entryIndex;
203 entryIndex = 0;
204 else
205 entryIndex = 1;
206
207 for (int8 i = 0; outroPositions[i].entry[entryIndex] != 0; ++i)
208 {
209 if (TempSummon* summon = instance->instance->SummonCreature(outroPositions[i].entry[entryIndex], spawnPoint))
210 {
211 summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN);
212 summon->GetMotionMaster()->MovePoint(0, outroPositions[i].movePosition);
213 if (summon->GetEntry() == NPC_JAINA_PART2)
214 summon->AI()->Talk(SAY_JAINA_OUTRO);
215 else if (summon->GetEntry() == NPC_SYLVANAS_PART2)
216 summon->AI()->Talk(SAY_SYLVANAS_OUTRO);
217 }
218 }
219 }
220
221 void SpellHitTarget(WorldObject* /*target*/, SpellInfo const* spellInfo) override
222 {
223 if (spellInfo->Id == H_SPELL_PHANTOM_BLAST)
224 threeFaced = false;
225 }
226
227 uint32 GetData(uint32 type) const override
228 {
229 if (type == DATA_THREE_FACED)
230 return threeFaced;
231
232 return 0;
233 }
234
235 void UpdateAI(uint32 diff) override
236 {
237 // Return since we have no target
238 if (!UpdateVictim())
239 return;
240
241 events.Update(diff);
242
244 return;
245
246 while (uint32 eventId = events.ExecuteEvent())
247 {
248 switch (eventId)
249 {
253 break;
258 break;
263 break;
272 break;
273 case EVENT_FACE_ANGER:
275 break;
276
283 {
284 me->SetFacingToObject(target);
286 }
287
289
290 beamAngleDiff = float(M_PI)/30.0f; // PI/2 in 15 sec = PI/30 per tick
291 if (RAND(true, false))
293
296
297 //Remove any target
299
302
303 wailingSoulTick = 15;
304 events.DelayEvents(18s); // no other events during wailing souls
305 events.ScheduleEvent(EVENT_WAILING_SOULS_TICK, 3s); // first one after 3 secs.
306 break;
307
311
313
314 if (--wailingSoulTick)
316 else
317 {
323 }
324 break;
325 }
326
328 return;
329 }
330
332 }
333
334private:
336
337 // wailing soul event
341};
342
343// 69051 - Mirrored Soul
364
365// 69023 - Mirrored Soul (Proc)
367{
369
370 bool Validate(SpellInfo const* /*spellInfo*/) override
371 {
373 }
374
375 bool CheckProc(ProcEventInfo& /*eventInfo*/)
376 {
377 return GetCaster() && GetCaster()->IsAlive();
378 }
379
380 void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
381 {
383 DamageInfo* damageInfo = eventInfo.GetDamageInfo();
384 if (!damageInfo || !damageInfo->GetDamage())
385 return;
386
388 args.AddSpellBP0(CalculatePct(damageInfo->GetDamage(), 45));
390 }
391
397};
398
399// 69048 - Mirrored Soul (Target Selector)
431
433{
434 public:
435 achievement_three_faced() : AchievementCriteriaScript("achievement_three_faced") { }
436
437 bool OnCheck(Player* /*player*/, Unit* target) override
438 {
439 if (!target)
440 return false;
441
442 if (Creature* Devourer = target->ToCreature())
443 if (Devourer->AI()->GetData(DATA_THREE_FACED))
444 return true;
445
446 return false;
447 }
448};
449
#define M_PI
Definition Common.h:72
First const & RAND(First const &first, Second const &second, Rest const &... rest)
uint8_t uint8
Definition Define.h:135
int8_t int8
Definition Define.h:131
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ TEMPSUMMON_DEAD_DESPAWN
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
Spells
Definition PlayerAI.cpp:32
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
SpellEffIndex
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TARGET_UNIT_SRC_AREA_ENTRY
@ ALLIANCE
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
#define AuraEffectProcFn(F, I, N)
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraCheckProcFn(F)
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_STATE_ROOT
Definition Unit.h:230
@ UNIT_STATE_CASTING
Definition Unit.h:235
T CalculatePct(T base, U pct)
Definition Util.h:71
struct outroPosition outroPositions[]
@ SAY_FACE_ANGER_SLAY
@ SAY_FACE_DESIRE_SLAY
@ EMOTE_MIRRORED_SOUL
@ SAY_FACE_WAILING_SOUL
@ SAY_FACE_SORROW_SLAY
@ 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
Position const CrucibleSummonPos
@ EVENT_WAILING_SOULS
@ EVENT_WELL_OF_SOULS
@ 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
HookList< EffectProcHandler > OnEffectProc
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
EventMap events
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void SetDisplayId(uint32 modelId) override
void SetReactState(ReactStates st)
Definition Creature.h:119
void SetTarget(ObjectGuid guid) override
uint32 GetDamage() const
Definition Unit.h:464
void Update(uint32 time)
Definition EventMap.h:67
void DelayEvents(Milliseconds delay)
Definition EventMap.cpp:95
EventId ExecuteEvent()
Definition EventMap.cpp:73
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
InstanceMap * instance
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1852
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
static ObjectGuid const Empty
Definition ObjectGuid.h:140
static Creature * ToCreature(Object *o)
Definition Object.h:186
TypeID GetTypeId() const
Definition Object.h:93
DamageInfo * GetDamageInfo() const
Definition Unit.h:519
uint32 Id
Definition SpellInfo.h:289
Unit * GetCaster() const
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
void SetControlled(bool apply, UnitState state)
Definition Unit.cpp:11256
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool IsAlive() const
Definition Unit.h:1234
void SetFacingToObject(WorldObject const *object, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13259
uint32 GetDisplayId() const
Definition Unit.h:1582
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13250
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2099
virtual uint32 GetData(uint32) const
Definition ZoneScript.h:55
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
bool OnCheck(Player *, Unit *target) override
PrepareAuraScript(spell_devourer_of_souls_mirrored_soul_proc)
void HandleProc(AuraEffect const *, ProcEventInfo &eventInfo)
void FilterTargets(std::list< WorldObject * > &targets)
PrepareSpellScript(spell_devourer_of_souls_mirrored_soul_target_selector)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_devourer_of_souls_mirrored_soul)
@ 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:108
CastSpellExtraArgs & AddSpellBP0(int32 val)
float GetOrientation() const
Definition Position.h:82
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
boss_devourer_of_souls(Creature *creature)
void SpellHitTarget(WorldObject *, SpellInfo const *spellInfo) override
uint32 GetData(uint32 type) const override
void KilledUnit(Unit *victim) override