Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_drakkari_colossus.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6/*
7 * 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!
8 */
9
10#include "ScriptMgr.h"
11#include "ScriptedCreature.h"
12#include "gundrak.h"
13#include "SpellInfo.h"
14
28
33
40
47
53
58
63
65{
66 public:
67 boss_drakkari_colossus() : CreatureScript("boss_drakkari_colossus") { }
68
70 {
72 {
73 me->SetReactState(REACT_PASSIVE);
74 introDone = false;
75 }
76
78 {
79 if (!me->isDead())
80 Reset();
81 }
82
84 {
85 _Reset();
86
88 {
89 me->SetReactState(REACT_AGGRESSIVE);
91 me->RemoveAura(SPELL_FREEZE_ANIM);
92 }
93
94 //events.Reset(); -> done in _Reset();
95 events.ScheduleEvent(EVENT_MIGHTY_BLOW, std::rand() % 30000 + 10000);
96
98
99 // Note: This should not be called, but before use SetBossState function we should use BossAI
100 // in all the bosses of the instance
102 }
103
104 void EnterCombat(Unit* /*who*/) OVERRIDE
105 {
106 _EnterCombat();
107
108 me->RemoveAura(SPELL_FREEZE_ANIM);
109
110 // Note: This should not be called, but before use SetBossState function we should use BossAI
111 // in all the bosses of the instance
113 }
114
115 void JustDied(Unit* /*killer*/) OVERRIDE
116 {
117 _JustDied();
118
119 // Note: This should not be called, but before use SetBossState function we should use BossAI
120 // in all the bosses of the instance
122 }
123
125 {
126 // Note: This should not be called, but before use SetBossState function we should use BossAI
127 // in all the bosses of the instance
129 }
130
132 {
133 switch (action)
134 {
137 break;
139 me->GetMotionMaster()->Clear();
140 me->GetMotionMaster()->MoveIdle();
141
142 me->SetReactState(REACT_PASSIVE);
145 break;
147
148 if (me->GetReactState() == REACT_AGGRESSIVE)
149 return;
150
151 me->SetReactState(REACT_AGGRESSIVE);
153 me->RemoveAura(SPELL_FREEZE_ANIM);
154
155 me->SetInCombatWithZone();
156
157 if (me->GetVictim())
158 me->GetMotionMaster()->MoveChase(me->GetVictim(), 0, 0);
159
160 break;
161 }
162 }
163
181
183 {
184 if (data == DATA_COLOSSUS_PHASE)
185 return phase;
186 else if (data == DATA_INTRO_DONE)
187 return introDone;
188
189 return 0;
190 }
191
192 void SetData(uint32 type, uint32 data) OVERRIDE
193 {
194 if (type == DATA_INTRO_DONE)
195 introDone = data;
196 }
197
199 {
200 if (!UpdateVictim())
201 return;
202
203 events.Update(diff);
204
205 if (me->HasUnitState(UNIT_STATE_CASTING))
206 return;
207
208 while (uint32 eventId = events.ExecuteEvent())
209 {
210 switch (eventId)
211 {
214 events.ScheduleEvent(EVENT_MIGHTY_BLOW, std::rand() % 15000 + 5000);
215 break;
216 }
217 }
218
219 if (me->GetReactState() == REACT_AGGRESSIVE)
221 }
222
224 {
225 summon->SetInCombatWithZone();
226
228 summon->SetHealth(summon->GetMaxHealth() / 2);
229 }
230
231 private:
234 };
235
237 {
238 return new boss_drakkari_colossusAI(creature);
239 }
240};
241
243{
244 public:
245 boss_drakkari_elemental() : CreatureScript("boss_drakkari_elemental") { }
246
248 {
254
256 {
257 events.Reset();
258 events.ScheduleEvent(EVENT_SURGE, std::rand() % 15000 + 5000);
259
260 me->AddAura(SPELL_MOJO_VOLLEY, me);
261 }
262
263 void JustDied(Unit* killer) OVERRIDE
264 {
265 if (killer == me)
266 return;
267
268 if (instance)
269 {
270 if (Creature* colossus = Unit::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS)))
271 killer->Kill(colossus);
272 }
273 }
274
276 {
277 if (!UpdateVictim())
278 return;
279
280 events.Update(diff);
281
282 if (me->HasUnitState(UNIT_STATE_CASTING))
283 return;
284
285 while (uint32 eventId = events.ExecuteEvent())
286 {
287 switch (eventId)
288 {
289 case EVENT_SURGE:
291 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
292 DoCast(target, SPELL_SURGE);
293 events.ScheduleEvent(EVENT_SURGE, std::rand() % 15000 + 5000);
294 break;
295 }
296 }
297
299 }
300
302 {
303 switch (action)
304 {
307 if (instance)
308 {
309 if (Creature* colossus = Unit::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS)))
310 // what if the elemental is more than 80 yards from drakkari colossus ?
311 DoCast(colossus, SPELL_MERGE, true);
312 }
313 break;
314 }
315 }
316
317 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
318 {
319 if (HealthBelowPct(50) && instance)
320 {
321 if (Creature* colossus = Unit::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS)))
322 {
323 if (colossus->AI()->GetData(DATA_COLOSSUS_PHASE) == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON)
324 {
325 damage = 0;
326
327 // to prevent spell spaming
328 if (me->HasUnitState(UNIT_STATE_CHARGING))
329 return;
330
331 // not sure about this, the idea of this code is to prevent bug the elemental
332 // if it is not in a acceptable distance to cast the charge spell.
333 /*if (me->GetDistance(colossus) > 80.0f)
334 {
335 if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
336 return;
337
338 me->GetMotionMaster()->MovePoint(0, colossus->GetPositionX(), colossus->GetPositionY(), colossus->GetPositionZ());
339 return;
340 }*/
342 }
343 }
344 }
345 }
346
348 {
349 me->DespawnOrUnsummon();
350 }
351
352 void SpellHitTarget(Unit* target, SpellInfo const* spell) OVERRIDE
353 {
354 if (spell->Id == SPELL_MERGE)
355 {
356 if (Creature* colossus = target->ToCreature())
357 {
358 colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
359 me->DespawnOrUnsummon();
360 }
361 }
362 }
363
364 private:
367 };
368
370 {
371 return new boss_drakkari_elementalAI(creature);
372 }
373};
374
376{
377public:
378 npc_living_mojo() : CreatureScript("npc_living_mojo") { }
379
381 {
382 return new npc_living_mojoAI(creature);
383 }
384
386 {
387 npc_living_mojoAI(Creature* creature) : ScriptedAI(creature)
388 {
389 instance = creature->GetInstanceScript();
390 }
391
397
398 void MoveMojos(Creature* boss)
399 {
400 std::list<Creature*> mojosList;
401 boss->GetCreatureListWithEntryInGrid(mojosList, me->GetEntry(), 12.0f);
402 if (!mojosList.empty())
403 {
404 for (std::list<Creature*>::const_iterator itr = mojosList.begin(); itr != mojosList.end(); ++itr)
405 {
406 if (Creature* mojo = *itr)
407 mojo->GetMotionMaster()->MovePoint(1, boss->GetHomePosition().GetPositionX(), boss->GetHomePosition().GetPositionY(), boss->GetHomePosition().GetPositionZ());
408 }
409 }
410 }
411
413 {
414 if (type != POINT_MOTION_TYPE)
415 return;
416
417 if (id == 1)
418 {
419 if (Creature* colossus = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
420 {
421 colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
422 if (!colossus->AI()->GetData(DATA_INTRO_DONE))
423 colossus->AI()->SetData(DATA_INTRO_DONE, true);
424 colossus->SetInCombatWithZone();
425 me->DespawnOrUnsummon();
426 }
427 }
428 }
429
430 void AttackStart(Unit* attacker) OVERRIDE
431 {
432 if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
433 return;
434
435 // we do this checks to see if the creature is one of the creatures that sorround the boss
436 if (Creature* colossus = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
437 {
438 Position homePosition;
439 me->GetHomePosition().GetPosition(&homePosition);
440
441 Position colossusHomePosition;
442 colossus->GetHomePosition().GetPosition(&colossusHomePosition);
443
444 float distance = homePosition.GetExactDist(colossusHomePosition.GetPositionX(), colossusHomePosition.GetPositionY(), colossusHomePosition.GetPositionZ());
445
446 if (distance < 12.0f)
447 {
448 MoveMojos(colossus);
449 me->SetReactState(REACT_PASSIVE);
450 }
451 else
452 ScriptedAI::AttackStart(attacker);
453 }
454 }
455
457 {
458 //Return since we have no target
459 if (!UpdateVictim())
460 return;
461
462 if (mojoWaveTimer <= diff)
463 {
466 } else mojoWaveTimer -= diff;
467
468 if (mojoPuddleTimer <= diff)
469 {
472 } else mojoPuddleTimer -= diff;
473
475 }
476 private:
480 };
481};
482
@ IN_MILLISECONDS
Definition Common.h:125
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ IN_PROGRESS
@ FAIL
@ DONE
@ NOT_STARTED
@ POINT_MOTION_TYPE
@ UNIT_STATE_CHARGING
Definition Unit.h:529
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ REACT_PASSIVE
Definition Unit.h:1156
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
@ DATA_COLOSSUS_PHASE
void AddSC_boss_drakkari_colossus()
@ SPELL_ELEMENTAL_SPAWN_EFFECT
@ ACTION_SUMMON_ELEMENTAL
@ ACTION_UNFREEZE_COLOSSUS
@ ACTION_FREEZE_COLOSSUS
@ COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON
@ COLOSSUS_PHASE_SECOND_ELEMENTAL_SUMMON
@ COLOSSUS_PHASE_NORMAL
@ ACTION_RETURN_TO_COLOSSUS
InstanceScript *const instance
EventMap events
BossAI(Creature *creature, uint32 bossId)
void _EnterCombat()
bool UpdateVictim()
void GetHomePosition(float &x, float &y, float &z, float &ori) const
Definition Creature.h:628
CreatureScript(const char *name)
Creature * ToCreature()
Definition Object.h:207
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
Definition UnitAI.cpp:66
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
void GetCreatureListWithEntryInGrid(std::list< Creature * > &lList, uint32 uiEntry, float fMaxSearchRange) const
Definition Object.cpp:2841
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
@ DATA_DRAKKARI_COLOSSUS
Definition gundrak.h:27
@ DATA_DRAKKARI_COLOSSUS_EVENT
Definition gundrak.h:13
float GetExactDist(float x, float y, float z) const
Definition Object.h:382
float GetPositionZ() const
Definition Object.h:330
float GetPositionX() const
Definition Object.h:328
void GetPosition(float &x, float &y) const
Definition Object.h:333
float GetPositionY() const
Definition Object.h:329
Creature * me
bool HealthBelowPct(uint32 pct) const
ScriptedAI(Creature *creature)
void AttackStart(Unit *) OVERRIDE
void SetData(uint32 type, uint32 data) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHitTarget(Unit *target, SpellInfo const *spell) OVERRIDE
void MovementInform(uint32 type, uint32 id) OVERRIDE
void AttackStart(Unit *attacker) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================