Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_ichoron.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#include "ScriptMgr.h"
7#include "ScriptedCreature.h"
8#include "violet_hold.h"
9
23
28
39
45
47#define MAX_SPAWN_LOC 5
49{
50 {1840.64f, 795.407f, 44.079f, 1.676f},
51 {1886.24f, 757.733f, 47.750f, 5.201f},
52 {1877.91f, 845.915f, 43.417f, 3.560f},
53 {1918.97f, 850.645f, 47.225f, 4.136f},
54 {1935.50f, 796.224f, 52.492f, 4.224f},
55};
56
57enum Misc
58{
60};
61
63{
64public:
65 boss_ichoron() : CreatureScript("boss_ichoron") { }
66
68 {
69 return new boss_ichoronAI(creature);
70 }
71
72 struct boss_ichoronAI : public ScriptedAI
73 {
74 boss_ichoronAI(Creature* creature) : ScriptedAI(creature), m_waterElements(creature)
75 {
76 instance = creature->GetInstanceScript();
77 }
78
82
85
87
89
91 {
92 bIsExploded = false;
93 bIsFrenzy = false;
94 dehydration = true;
96 uiWaterBoltVolleyTimer = std::rand() % 15000 + 10000;
97
98 me->SetVisible(true);
100
101 if (instance)
102 {
103 if (instance->GetData(DATA_WAVE_COUNT) == 6)
105 else if (instance->GetData(DATA_WAVE_COUNT) == 12)
107 }
108 }
109
110 void EnterCombat(Unit* /*who*/) OVERRIDE
111 {
113
115
116 if (instance)
117 {
118 if (GameObject* pDoor = instance->instance->GetGameObject(instance->GetData64(DATA_ICHORON_CELL)))
119 if (pDoor->GetGoState() == GOState::GO_STATE_READY)
120 {
122 return;
123 }
124 if (instance->GetData(DATA_WAVE_COUNT) == 6)
126 else if (instance->GetData(DATA_WAVE_COUNT) == 12)
128 }
129 }
130
132 {
134 return;
135
136 if (me->Attack(who, true))
137 {
138 me->AddThreat(who, 0.0f);
139 me->SetInCombatWith(who);
140 who->SetInCombatWith(me);
141 DoStartMovement(who);
142 }
143 }
144
146 {
147 if (!me->IsAlive())
148 return;
149
150 switch (param)
151 {
153 me->ModifyHealth(int32(me->CountPctFromMaxHealth(1)));
154
155 if (bIsExploded)
157
158 dehydration = false;
159 break;
161 uint32 damage = me->CountPctFromMaxHealth(3);
162 me->ModifyHealth(-int32(damage));
163 me->LowerPlayerDamageReq(damage);
164 break;
165 }
166 }
167
169 {
170 m_waterElements.DespawnAll();
171 }
172
173 // call when explode shall stop.
174 // either when "hit" by a bubble, or when there is no bubble left.
176 {
177 bIsExploded = false;
178
179 if (!HealthBelowPct(25))
180 {
183 }
184
185 me->SetVisible(true);
186 me->GetMotionMaster()->MoveChase(me->GetVictim());
187 }
188
190 {
191 if (type == DATA_DEHYDRATION)
192 return dehydration ? 1 : 0;
193
194 return 0;
195 }
196
197 void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
198
199
201 {
202 if (!UpdateVictim())
203 return;
204
205 if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded)
206 {
208 DoCast(me, SPELL_FRENZY, true);
209 bIsFrenzy = true;
210 }
211
212 if (!bIsFrenzy)
213 {
214 if (uiBubbleCheckerTimer <= uiDiff)
215 {
216 if (!bIsExploded)
217 {
218 if (!me->HasAura(SPELL_PROTECTIVE_BUBBLE, 0))
219 {
223 bIsExploded = true;
224 me->AttackStop();
225 me->SetVisible(false);
226 for (uint8 i = 0; i < 10; i++)
227 {
228 int tmp = std::rand() % (MAX_SPAWN_LOC-1);
230 }
231 }
232 }
233 else
234 {
235 bool bIsWaterElementsAlive = false;
236 if (!m_waterElements.empty())
237 {
238 for (std::list<uint64>::const_iterator itr = m_waterElements.begin(); itr != m_waterElements.end(); ++itr)
239 if (Creature* temp = Unit::GetCreature(*me, *itr))
240 if (temp->IsAlive())
241 {
242 bIsWaterElementsAlive = true;
243 break;
244 }
245 }
246
247 if (!bIsWaterElementsAlive)
249 }
251 }
252 else uiBubbleCheckerTimer -= uiDiff;
253 }
254
255 if (!bIsExploded)
256 {
257 if (uiWaterBoltVolleyTimer <= uiDiff)
258 {
260 uiWaterBoltVolleyTimer = std::rand() % 15000 + 10000;
261 }
262 else uiWaterBoltVolleyTimer -= uiDiff;
263
265 }
266 }
267
268 void JustDied(Unit* /*killer*/) OVERRIDE
269 {
271
272 if (bIsExploded)
273 {
274 bIsExploded = false;
275 me->SetVisible(true);
276 }
277
279
280 if (instance)
281 {
282 if (instance->GetData(DATA_WAVE_COUNT) == 6)
283 {
285 instance->SetData(DATA_WAVE_COUNT, 7);
286 }
287 else if (instance->GetData(DATA_WAVE_COUNT) == 12)
288 {
290 instance->SetData(DATA_WAVE_COUNT, 13);
291 }
292 }
293 }
294
296 {
297 if (summoned)
298 {
299 summoned->SetSpeed(MOVE_RUN, 0.3f);
300 summoned->GetMotionMaster()->MoveFollow(me, 0, 0);
301 m_waterElements.Summon(summoned);
302 instance->SetData64(DATA_ADD_TRASH_MOB, summoned->GetGUID());
303 }
304 }
305
307 {
308 if (summoned)
309 {
310 m_waterElements.Despawn(summoned);
311 instance->SetData64(DATA_DEL_TRASH_MOB, summoned->GetGUID());
312 }
313 }
314
316 {
317 if (victim->GetTypeId() != TypeID::TYPEID_PLAYER)
318 return;
319
320 Talk(SAY_SLAY);
321 }
322 };
323};
324
326{
327public:
328 npc_ichor_globule() : CreatureScript("npc_ichor_globule") { }
329
331 {
332 return new npc_ichor_globuleAI(creature);
333 }
334
336 {
338 {
339 instance = creature->GetInstanceScript();
340 }
341
343
345
347 {
348 uiRangeCheck_Timer = 1000;
350 }
351
352 void AttackStart(Unit* /*who*/) OVERRIDE
353 {
354 return;
355 }
356
358 {
359 if (uiRangeCheck_Timer < uiDiff)
360 {
361 if (instance)
362 {
363 if (Creature* pIchoron = Unit::GetCreature(*me, instance->GetData64(DATA_ICHORON)))
364 {
365 if (me->IsWithinDist(pIchoron, 2.0f, false))
366 {
367 if (pIchoron->AI())
368 pIchoron->AI()->DoAction(ACTION_WATER_ELEMENT_HIT);
369 me->DespawnOrUnsummon();
370 }
371 }
372 }
373 uiRangeCheck_Timer = 1000;
374 }
375 else uiRangeCheck_Timer -= uiDiff;
376 }
377
378 void JustDied(Unit* /*killer*/) OVERRIDE
379 {
381 if (Creature* pIchoron = Unit::GetCreature(*me, instance->GetData64(DATA_ICHORON)))
382 if (pIchoron->AI())
383 pIchoron->AI()->DoAction(ACTION_WATER_ELEMENT_KILLED);
384 }
385 };
386};
387
389{
390 public:
392 {
393 }
394
395 bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
396 {
397 if (!target)
398 return false;
399
400 if (Creature* Ichoron = target->ToCreature())
401 if (Ichoron->AI()->GetData(DATA_DEHYDRATION))
402 return true;
403
404 return false;
405 }
406};
407
409{
410 new boss_ichoron();
411 new npc_ichor_globule();
413}
Actions
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
@ GO_STATE_READY
Definition GameObject.h:577
@ IN_PROGRESS
@ DONE
@ NOT_STARTED
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_CORPSE_DESPAWN
Definition Object.h:72
@ MOVE_RUN
Definition Unit.h:556
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ UNIT_FIELD_FLAGS
@ SAY_SLAY
#define SAY_DEATH
#define SAY_AGGRO
@ SAY_ENRAGE
@ SPELL_FRENZY
@ ACTION_WATER_ELEMENT_KILLED
@ ACTION_WATER_ELEMENT_HIT
@ DATA_DEHYDRATION
@ SAY_DEATH
@ SAY_AGGRO
@ SAY_BUBBLE
@ SAY_SLAY
@ SAY_SHATTER
@ SAY_ENRAGE
void AddSC_boss_ichoron()
@ SPELL_WATER_BOLT_VOLLEY_H
@ SPELL_WATER_BOLT_VOLLEY
@ SPELL_WATER_BLAST_H
@ SPELL_FRENZY
@ SPELL_FRENZY_H
@ SPELL_WATER_BLAST
@ SPELL_SPLASH
@ SPELL_PROTECTIVE_BUBBLE
@ SPELL_DRAINED
@ SPELL_WATER_GLOBULE
static Position SpawnLoc[MAX_SPAWN_LOC]
IchoronCreatures
@ NPC_ICHOR_GLOBULE
#define MAX_SPAWN_LOC
@ SAY_SHATTER
static Position SpawnLoc[]
AchievementCriteriaScript(const char *name)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureScript(const char *name)
Creature * ToCreature()
Definition Object.h:207
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
Definition Unit.h:1367
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
bool OnCheck(Player *, Unit *target) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
@ DATA_WAVE_COUNT
Creature * me
bool HealthBelowPct(uint32 pct) const
ScriptedAI(Creature *creature)
void DoStartMovement(Unit *target, float distance=0.0f, float angle=0.0f)
void UpdateAI(uint32 uiDiff) OVERRIDE
== Triggered Actions Requested ==================
uint32 GetData(uint32 type) const OVERRIDE
void JustSummoned(Creature *summoned) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
void SummonedCreatureDespawn(Creature *summoned) OVERRIDE
void JustDied(Unit *) OVERRIDE
void KilledUnit(Unit *victim) OVERRIDE
boss_ichoronAI(Creature *creature)
void AttackStart(Unit *who) OVERRIDE
void MoveInLineOfSight(Unit *) OVERRIDE
void DoAction(int32 param) OVERRIDE
void UpdateAI(uint32 uiDiff) OVERRIDE
== Triggered Actions Requested ==================
@ DATA_ICHORON
Definition violet_hold.h:35
@ DATA_ADD_TRASH_MOB
Definition violet_hold.h:52
@ DATA_DEL_TRASH_MOB
Definition violet_hold.h:53
@ DATA_ICHORON_CELL
Definition violet_hold.h:44
@ DATA_1ST_BOSS_EVENT
Definition violet_hold.h:11
@ DATA_2ND_BOSS_EVENT
Definition violet_hold.h:12