TrinityCore
Loading...
Searching...
No Matches
boss_the_black_stalker.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 "ScriptedCreature.h"
19#include "ScriptMgr.h"
20#include "SpellScript.h"
21#include "the_underbog.h"
22
23/*
24How levitation sequence works: boss casts Levitate and it triggers a chain of spells, target(any target, player or pet, any position in
25threat list) eventually gets pulled towards by randomly selected trigger. Then target becomes protected from Pull Towards by Suspension
26aura which is triggered every 1 sec up to 4 times. Since it has stun mechanic, diminishing returns cuts off its duration every cast in
27half (20 > 10 > 5 > 0). Eventually player becomes immune to Suspension and vulnerable to another pull towards.
28Whole levitate sequence is designed to pull player towards up to 3 times. Usually it works like this: player gets pulled towards,
29gets protected by Suspension from Pull Towards next 2 times. If player is unlucky, boss can cast Levitate on same player again, in that case
30player can be pulled towards 2 times in a row without any protection from fall damage by Suspension(case from sniffs).
31
32However currently diminishing returns affects Suspension after first cast, its duration is 10 instead of 20 seconds and player will be
33immune to 4th cast. That allows to pull player towards when levitation sequence ends. Levitation sequence has sensetive design and looks
34like lack of delays between packets makes it work differently too.
35Of course as was said above player can be pulled towards 2 times in a row but that looks like a rare case.
36*/
37
39{
42 SPELL_STATIC_CHARGE = 31715, // Never seen any cast on retail, probably because of shared cooldown with Chain Lightning
43 SPELL_SUMMON_PLAYER = 20279, // NYI, may be 20311 or any other
45
51
53};
54
63
68
70{
72
85
86 void UpdateAI(uint32 diff) override
87 {
88 if (!UpdateVictim())
89 return;
90
91 _events.Update(diff);
92
94 return;
95
96 while (uint32 eventId = _events.ExecuteEvent())
97 {
98 switch (eventId)
99 {
101 {
102 float x, y, z, o;
103 me->GetHomePosition(x, y, z, o);
104 if (!me->IsWithinDist3d(x, y, z, 60))
105 {
107 return;
108 }
109 _events.Repeat(1s);
110 break;
111 }
112 case EVENT_LEVITATE:
114 _events.Repeat(18s, 24s);
115 break;
118 _events.Repeat(6s, 12s);
119 break;
121 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30, true))
123 _events.Repeat(10s);
124 break;
127 _events.Repeat(15s, 25s);
128 break;
129 default:
130 break;
131 }
132
134 return;
135 }
136 }
137
138 void WaypointReached(uint32 waypointId, uint32 pathId) override
139 {
140 if (pathId != PATH_BLACK_STALKER_IDLE)
141 return;
142
143 if (waypointId == 2 || waypointId == 4 || waypointId == 6)
144 {
145 scheduler.Schedule(2s, [this](TaskContext const& /*task*/)
146 {
148 });
149 }
150 }
151
152private:
155};
156
157// 31704 - Levitate
175
176// 31701 - Levitation Pulse
194
195// 31702 - Someone Grab Me
214
215// 31703 - Magnetic Pull
233
234// 38756 - Summon Spore Strider
236{
237 bool Validate(SpellInfo const* /*spellInfo*/) override
238 {
240 }
241
242 void HandleScript(SpellEffIndex /*effIndex*/)
243 {
244 for (uint8 i = 0; i < 3; i++)
246 }
247
252};
253
uint8_t uint8
Definition Define.h:156
uint32_t uint32
Definition Define.h:154
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ EMOTE_ONESHOT_EAT
@ SPELL_EFFECT_SCRIPT_EFFECT
#define SpellEffectFn(F, I, N)
@ UNIT_STATE_CASTING
Definition Unit.h:276
@ EVENT_CHAIN_LIGHTNING
@ EVENT_STATIC_CHARGE
@ EVENT_SUMMON_SPORE_STRIDER
@ SPELL_SUSPENSION_PRIMER
@ SPELL_MAGNETIC_PULL
@ SPELL_SUMMON_PLAYER
@ SPELL_SUMMON_SPORE_STRIDER
@ SPELL_SOMEONE_GRAB_ME
@ SPELL_CHAIN_LIGHTNING
@ SPELL_STATIC_CHARGE
@ SPELL_LEVITATION_PULSE
@ SPELL_SUMMON_SPORE_STRIDER_SCRIPT
@ PATH_BLACK_STALKER_IDLE
void AddSC_boss_the_black_stalker()
void JustEngagedWith(Unit *who) override
TaskScheduler scheduler
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void GetHomePosition(float &x, float &y, float &z, float &ori) const
Definition Creature.h:388
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void Update(uint32 time)
Definition EventMap.h:61
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:40
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHit
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
TaskScheduler & CancelAll()
TaskScheduler & Schedule(duration_t time, task_handler_t task)
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
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 DoCast(uint32 spellId)
Definition UnitAI.cpp:89
Definition Unit.h:635
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition Unit.cpp:1657
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:476
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
bool IsHeroic() const
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *who) override
boss_the_black_stalker(Creature *creature)
void WaypointReached(uint32 waypointId, uint32 pathId) override
#define RegisterTheUnderbogCreatureAI(ai_name)
@ DATA_THE_BLACK_STALKER