TrinityCore
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
boss_kelidan_the_breaker.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/* Find a more elegant way to handle channelers */
19
20#include "ScriptMgr.h"
21#include "blood_furnace.h"
22#include "ObjectAccessor.h"
23#include "ScriptedCreature.h"
24#include "SpellAuras.h"
25#include "TemporarySummon.h"
26
28{
33
34 SAY_AGGRO = 0
35};
36
38{
41
44
47
49 SPELL_VORTEX = 37370,
50
51 // Shadowmoon Channeler
54
56 SPELL_CHANNELING = 39123
57};
58
60{
61 NPC_KELIDAN = 17377,
62 NPC_CHANNELER = 17653
63};
64
66{
67 { 301.988f, -86.7465f, -24.4517f, 0.15708f },
68 { 320.750f, -63.6121f, -24.6361f, 4.88692f },
69 { 345.848f, -74.4559f, -24.6402f, 3.59538f },
70 { 343.584f, -103.631f, -24.5688f, 2.35619f },
71 { 316.274f, -108.877f, -24.6027f, 1.25664f }
72};
73
74// 17377 - Keli'dan the Breaker
76{
78 {
79 Initialize();
81 }
82
84 {
85 ShadowVolley_Timer = 1000;
86 BurningNova_Timer = 15000;
87 Corruption_Timer = 5000;
88 check_Timer = 0;
89 Firenova = false;
90 }
91
99
100 void Reset() override
101 {
102 _Reset();
103 Initialize();
105 me->SetImmuneToNPC(true);
108 }
109
110 void JustEngagedWith(Unit* who) override
111 {
113 Talk(SAY_WAKE);
114 if (me->IsNonMeleeSpellCast(false))
116 DoStartMovement(who);
117 }
118
119 void KilledUnit(Unit* /*victim*/) override
120 {
121 if (rand32() % 2)
122 return;
123
124 Talk(SAY_SLAY);
125 }
126
128 {
129 for (uint8 i = 0; i<5; ++i)
130 {
132 if (who && channeler && !channeler->IsInCombat())
133 channeler->AI()->AttackStart(who);
134 }
135 }
136
137 void ChannelerDied(Unit* killer)
138 {
139 for (uint8 i = 0; i < 5; ++i)
140 {
142 if (channeler && channeler->IsAlive())
143 return;
144 }
146 me->SetImmuneToNPC(false);
148 if (killer)
149 AttackStart(killer);
150 }
151
153 {
155 if (!channeler1)
156 return ObjectGuid::Empty;
157
158 uint8 i;
159 for (i = 0; i < 5; ++i)
160 {
162 if (channeler && channeler->GetGUID() == channeler1->GetGUID())
163 break;
164 }
165 return Channelers[(i + 2) % 5];
166 }
167
169 {
170 for (uint8 i = 0; i < 5; ++i)
171 {
173 if (!channeler || channeler->isDead())
175 if (channeler)
176 Channelers[i] = channeler->GetGUID();
177 else
178 Channelers[i].Clear();
179 }
180 }
181
182 void JustDied(Unit* /*killer*/) override
183 {
184 _JustDied();
186 }
187
188 void UpdateAI(uint32 diff) override
189 {
190 if (!UpdateVictim())
191 {
192 if (check_Timer <= diff)
193 {
194 if (!me->IsNonMeleeSpellCast(false))
196 check_Timer = 5000;
197 }
198 else
199 check_Timer -= diff;
200 return;
201 }
202
203 if (Firenova)
204 {
205 if (Firenova_Timer <= diff)
206 {
207 DoCast(me, SPELL_FIRE_NOVA, true);
208 Firenova = false;
209 ShadowVolley_Timer = 2000;
210 }
211 else
212 Firenova_Timer -=diff;
213
214 return;
215 }
216
217 if (ShadowVolley_Timer <= diff)
218 {
220 ShadowVolley_Timer = 5000 + rand32() % 8000;
221 }
222 else
223 ShadowVolley_Timer -=diff;
224
225 if (Corruption_Timer <= diff)
226 {
228 Corruption_Timer = 30000 + rand32() % 20000;
229 }
230 else
231 Corruption_Timer -=diff;
232
233 if (BurningNova_Timer <= diff)
234 {
235 if (me->IsNonMeleeSpellCast(false))
237
238 Talk(SAY_NOVA);
239
241
242 if (IsHeroic())
244
245 BurningNova_Timer = 20000 + rand32() % 8000;
246 Firenova_Timer= 5000;
247 Firenova = true;
248 }
249 else
250 BurningNova_Timer -=diff;
251
253 }
254};
255
256// 17653 - Shadowmoon Channeler
258{
260 {
261 Initialize();
262 }
263
265 {
266 ShadowBolt_Timer = 1000 + rand32() % 1000;
267 MarkOfShadow_Timer = 5000 + rand32() % 2000;
268 check_Timer = 0;
269 }
270
274
275 void Reset() override
276 {
277 Initialize();
278 if (me->IsNonMeleeSpellCast(false))
280 }
281
282 void JustEngagedWith(Unit* who) override
283 {
285
286 if (Creature* Kelidan = me->FindNearestCreature(NPC_KELIDAN, 100))
287 ENSURE_AI(boss_kelidan_the_breaker, Kelidan->AI())->ChannelerEngaged(who);
288 if (me->IsNonMeleeSpellCast(false))
290 DoStartMovement(who);
291 }
292
293 void JustDied(Unit* killer) override
294 {
295 if (!killer)
296 return;
297
298 if (Creature* Kelidan = me->FindNearestCreature(NPC_KELIDAN, 100))
299 ENSURE_AI(boss_kelidan_the_breaker, Kelidan->AI())->ChannelerDied(killer);
300 }
301
302 void UpdateAI(uint32 diff) override
303 {
304 if (!UpdateVictim())
305 {
306 if (check_Timer <= diff)
307 {
308 if (!me->IsNonMeleeSpellCast(false))
309 {
310 if (Creature* Kelidan = me->FindNearestCreature(NPC_KELIDAN, 100))
311 {
312 ObjectGuid channeler = ENSURE_AI(boss_kelidan_the_breaker, Kelidan->AI())->GetChanneled(me);
313 if (Unit* channeled = ObjectAccessor::GetUnit(*me, channeler))
314 DoCast(channeled, SPELL_CHANNELING);
315 }
316 }
317 check_Timer = 5000;
318 }
319 else
320 check_Timer -= diff;
321
322 return;
323 }
324
325 if (MarkOfShadow_Timer <= diff)
326 {
329 MarkOfShadow_Timer = 15000 + rand32() % 5000;
330 }
331 else
332 MarkOfShadow_Timer -=diff;
333
334 if (ShadowBolt_Timer <= diff)
335 {
337 ShadowBolt_Timer = 5000 + rand32() % 1000;
338 }
339 else
340 ShadowBolt_Timer -=diff;
341
343 }
344};
345
347{
350}
uint8_t uint8
Definition: Define.h:135
uint32_t uint32
Definition: Define.h:133
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
Definition: ObjectDefines.h:66
uint32 rand32()
Definition: Random.cpp:70
#define ENSURE_AI(a, b)
Definition: UnitAI.h:28
@ REACT_PASSIVE
Definition: UnitDefines.h:408
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:410
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:136
#define RegisterBloodFurnaceCreatureAI(ai_name)
Definition: blood_furnace.h:93
@ DATA_KELIDAN_THE_BREAKER
Definition: blood_furnace.h:33
Position const ShadowmoonChannelers[5]
@ SPELL_SHADOW_BOLT_VOLLEY
@ SPELL_MARK_OF_SHADOW
@ SPELL_SHADOW_BOLT_VOLLEY_H
void AddSC_boss_kelidan_the_breaker()
void JustEngagedWith(Unit *who) override
void _JustDied()
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:48
bool UpdateVictim()
Definition: CreatureAI.cpp:240
Creature *const me
Definition: CreatureAI.h:81
void SetReactState(ReactStates st)
Definition: Creature.h:119
void SetImmuneToNPC(bool apply) override
Definition: Creature.h:132
CreatureAI * AI() const
Definition: Creature.h:154
static ObjectGuid const Empty
Definition: ObjectGuid.h:132
void Clear()
Definition: ObjectGuid.h:151
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:77
void DoMeleeAttackIfReady()
Definition: UnitAI.cpp:62
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:174
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:104
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:30
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:114
Definition: Unit.h:769
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3093
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:3063
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:11997
bool IsAlive() const
Definition: Unit.h:1234
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:952
bool IsInCombat() const
Definition: Unit.h:1142
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:953
bool isDead() const
Definition: Unit.h:1236
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition: Object.cpp:1992
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2099
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
float GetPositionZ() const
Definition: Position.h:81
float GetOrientation() const
Definition: Position.h:82
float GetPositionX() const
Definition: Position.h:79
float GetPositionY() const
Definition: Position.h:80
bool IsHeroic() const
void AttackStart(Unit *) override
void DoTeleportAll(float x, float y, float z, float o)
void DoStartMovement(Unit *target, float distance=0.0f, float angle=0.0f)
boss_kelidan_the_breaker(Creature *creature)
ObjectGuid GetChanneled(Creature *channeler1)
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *who) override
npc_shadowmoon_channeler(Creature *creature)
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *killer) override