TrinityCore
boss_drakkari_colossus.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/*
19 * Comment: The event with the Living Mojos is not implemented, just is done that when one of the mojos around the boss take damage will make the boss enter in combat!
20 */
21
22#include "ScriptMgr.h"
23#include "gundrak.h"
24#include "InstanceScript.h"
25#include "MotionMaster.h"
26#include "ScriptedCreature.h"
27#include "SpellInfo.h"
28
30{
31 // Drakkari Elemental
34};
35
37{
38 SPELL_EMERGE = 54850,
42 SPELL_MERGE = 54878,
44 SPELL_SURGE = 54801,
50};
51
52#define SPELL_MORTAL_STRIKES DUNGEON_MODE<uint32>(SPELL_MORTAL_STRIKES_NORMAL, SPELL_MORTAL_STRIKES_HEROIC)
53
55{
57};
58
60{
64};
65
67{
71};
72
74{
77};
78
80{
82};
83
85{
86 EVENT_SURGE = 1
87};
88
90{
92 {
93 Initialize();
95 introDone = false;
96 }
97
99 {
101 }
102
103 void Reset() override
104 {
105 _Reset();
106
108 {
110 me->SetImmuneToPC(false);
112 }
113
115
116 Initialize();
117
119 }
120
121 void JustEngagedWith(Unit* who) override
122 {
125 }
126
127 void JustDied(Unit* /*killer*/) override
128 {
129 _JustDied();
130 }
131
132 void DoAction(int32 action) override
133 {
134 switch (action)
135 {
138 break;
142
144 me->SetImmuneToPC(true);
146 break;
148
150 return;
151
152 me->SetImmuneToPC(false);
155
157
158 break;
159 }
160 }
161
162 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
163 {
164 if (me->IsImmuneToPC())
165 damage = 0;
166
169 {
171 {
172 damage = 0;
176 }
177 }
178 }
179
180 uint32 GetData(uint32 data) const override
181 {
182 if (data == DATA_COLOSSUS_PHASE)
183 return phase;
184 else if (data == DATA_INTRO_DONE)
185 return introDone;
186
187 return 0;
188 }
189
190 void SetData(uint32 type, uint32 data) override
191 {
192 if (type == DATA_INTRO_DONE)
193 introDone = data != 0;
194 }
195
196 void UpdateAI(uint32 diff) override
197 {
198 if (!UpdateVictim())
199 return;
200
201 events.Update(diff);
202
204 return;
205
206 while (uint32 eventId = events.ExecuteEvent())
207 {
208 switch (eventId)
209 {
213 break;
214 }
215
217 return;
218 }
219 }
220
221 void JustSummoned(Creature* summon) override
222 {
223 DoZoneInCombat(summon);
224
226 summon->SetHealth(summon->GetMaxHealth() / 2);
227 }
228
229private:
232};
233
235{
237 {
239 instance = creature->GetInstanceScript();
240 }
241
242 void Reset() override
243 {
244 events.Reset();
246
248 }
249
250 void JustDied(Unit* killer) override
251 {
253
255 Unit::Kill(killer, colossus);
256 }
257
258 void UpdateAI(uint32 diff) override
259 {
260 if (!UpdateVictim())
261 return;
262
263 events.Update(diff);
264
266 return;
267
268 while (uint32 eventId = events.ExecuteEvent())
269 {
270 switch (eventId)
271 {
272 case EVENT_SURGE:
274 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
275 DoCast(target, SPELL_SURGE);
277 break;
278 }
279
281 return;
282 }
283 }
284
285 void DoAction(int32 action) override
286 {
287 switch (action)
288 {
293 // what if the elemental is more than 80 yards from drakkari colossus ?
294 DoCast(colossus, SPELL_MERGE, true);
295 break;
296 }
297 }
298
299 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
300 {
301 if (HealthBelowPct(50))
302 {
304 {
305 if (colossus->AI()->GetData(DATA_COLOSSUS_PHASE) == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON)
306 {
307 damage = 0;
308
309 // to prevent spell spaming
311 return;
312
313 // not sure about this, the idea of this code is to prevent bug the elemental
314 // if it is not in a acceptable distance to cast the charge spell.
315 /*if (me->GetDistance(colossus) > 80.0f)
316 {
317 if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
318 return;
319
320 me->GetMotionMaster()->MovePoint(0, colossus->GetPositionX(), colossus->GetPositionY(), colossus->GetPositionZ());
321 return;
322 }*/
324 }
325 }
326 }
327 }
328
329 void EnterEvadeMode(EvadeReason /*why*/) override
330 {
332 }
333
334 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
335 {
336 if (spellInfo->Id == SPELL_MERGE)
337 {
338 if (Creature* colossus = target->ToCreature())
339 {
340 colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
342 }
343 }
344 }
345
346private:
349};
350
352{
353 npc_living_mojo(Creature* creature) : ScriptedAI(creature)
354 {
355 instance = creature->GetInstanceScript();
356 }
357
358 void Reset() override
359 {
361 }
362
363 void JustEngagedWith(Unit* /*who*/) override
364 {
365 _scheduler.Schedule(2s, [this](TaskContext task)
366 {
368 task.Repeat(15s);
369 })
370 .Schedule(7s, [this](TaskContext task)
371 {
373 task.Repeat(18s);
374 });
375 }
376
377 void MoveMojos(Creature* boss)
378 {
379 std::list<Creature*> mojosList;
380 boss->GetCreatureListWithEntryInGrid(mojosList, me->GetEntry(), 12.0f);
381 if (!mojosList.empty())
382 {
383 for (std::list<Creature*>::const_iterator itr = mojosList.begin(); itr != mojosList.end(); ++itr)
384 {
385 if (Creature* mojo = *itr)
386 mojo->GetMotionMaster()->MovePoint(1, boss->GetHomePosition().GetPositionX(), boss->GetHomePosition().GetPositionY(), boss->GetHomePosition().GetPositionZ());
387 }
388 }
389 }
390
391 void MovementInform(uint32 type, uint32 id) override
392 {
393 if (type != POINT_MOTION_TYPE)
394 return;
395
396 if (id == 1)
397 {
399 {
400 colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
401 if (!colossus->AI()->GetData(DATA_INTRO_DONE))
402 colossus->AI()->SetData(DATA_INTRO_DONE, true);
403 DoZoneInCombat(colossus);
405 }
406 }
407 }
408
409 void AttackStart(Unit* attacker) override
410 {
412 return;
413
414 // we do this checks to see if the creature is one of the creatures that sorround the boss
416 {
417 Position homePosition = me->GetHomePosition();
418
419 float distance = homePosition.GetExactDist(&colossus->GetHomePosition());
420
421 if (distance < 12.0f)
422 {
423 MoveMojos(colossus);
425 }
426 else
427 ScriptedAI::AttackStart(attacker);
428 }
429 }
430
431 void UpdateAI(uint32 diff) override
432 {
433 //Return since we have no target
434 if (!UpdateVictim())
435 return;
436
437 _scheduler.Update(diff);
438 }
439
440private:
443};
444
446{
450}
Texts
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
@ POINT_MOTION_TYPE
Spells
Definition: PlayerAI.cpp:32
EvadeReason
Definition: UnitAICommon.h:30
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_STATE_CHARGING
Definition: Unit.h:272
@ UNIT_STATE_CASTING
Definition: Unit.h:270
@ EVENT_MIGHTY_BLOW
@ DATA_COLOSSUS_PHASE
void AddSC_boss_drakkari_colossus()
@ SPELL_FREEZE_ANIM
@ SPELL_ELEMENTAL_SPAWN_EFFECT
@ SPELL_MORTAL_STRIKES_NORMAL
@ SPELL_MOJO_VOLLEY
@ SPELL_SURGE_VISUAL
@ SPELL_MORTAL_STRIKES_HEROIC
@ SPELL_MIGHTY_BLOW
@ SPELL_MOJO_PUDDLE
@ ACTION_SUMMON_ELEMENTAL
@ ACTION_UNFREEZE_COLOSSUS
@ ACTION_FREEZE_COLOSSUS
#define SPELL_MORTAL_STRIKES
@ EMOTE_ACTIVATE_ALTAR
@ COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON
@ COLOSSUS_PHASE_SECOND_ELEMENTAL_SUMMON
@ COLOSSUS_PHASE_NORMAL
@ ACTION_RETURN_TO_COLOSSUS
void JustEngagedWith(Unit *who) override
EventMap events
void _JustDied()
void DoZoneInCombat()
Definition: CreatureAI.h:161
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 SetImmuneToPC(bool apply) override
Definition: Creature.h:170
void GetHomePosition(float &x, float &y, float &z, float &ori) const
Definition: Creature.h:373
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
ReactStates GetReactState() const
Definition: Creature.h:161
bool IsImmuneToPC() const
Definition: Unit.h:1030
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
void Reset()
Definition: EventMap.cpp:21
Creature * GetCreature(uint32 type)
MovementGeneratorType GetCurrentMovementGeneratorType() const
static Creature * ToCreature(Object *o)
Definition: Object.h:219
uint32 GetEntry() const
Definition: Object.h:161
uint32 const Id
Definition: SpellInfo.h:325
TaskContext & Repeat(std::chrono::duration< Rep, Period > duration)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(std::chrono::duration< Rep, Period > time, task_handler_t task)
TaskScheduler & Update(success_t const &callback=nullptr)
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
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:627
void SetHealth(uint64 val)
Definition: Unit.cpp:9346
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3685
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:11618
uint64 GetMaxHealth() const
Definition: Unit.h:777
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
static void Kill(Unit *attacker, Unit *victim, bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition: Unit.cpp:10591
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition: Object.cpp:3312
#define RegisterGundrakCreatureAI(ai_name)
Definition: gundrak.h:99
@ DATA_DRAKKARI_COLOSSUS
Definition: gundrak.h:32
float GetExactDist(float x, float y, float z) const
Definition: Position.h:118
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
bool HealthBelowPct(uint32 pct) const
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void JustDied(Unit *) override
boss_drakkari_colossus(Creature *creature)
uint32 GetData(uint32 data) const override
void SetData(uint32 type, uint32 data) override
void JustSummoned(Creature *summon) override
void DoAction(int32 action) override
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
void DoAction(int32 action) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
boss_drakkari_elemental(Creature *creature)
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *killer) override
void EnterEvadeMode(EvadeReason) override
void JustEngagedWith(Unit *) override
npc_living_mojo(Creature *creature)
void AttackStart(Unit *attacker) override
== Triggered Actions Requested ==================
void MovementInform(uint32 type, uint32 id) override
void MoveMojos(Creature *boss)
InstanceScript * instance
void UpdateAI(uint32 diff) override