Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_erekem.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
22
32
34{
35public:
36 boss_erekem() : CreatureScript("boss_erekem") { }
37
39 {
40 return new boss_erekemAI(creature);
41 }
42
43 struct boss_erekemAI : public ScriptedAI
44 {
45 boss_erekemAI(Creature* creature) : ScriptedAI(creature)
46 {
47 instance = creature->GetInstanceScript();
48 }
49
55
57
59 {
60 uiBloodlustTimer = 15000;
62 uiEarthShockTimer = std::rand() % 8000 + 2000;
63 uiLightningBoltTimer = std::rand() % 10000 + 5000;
64 uiEarthShieldTimer = 20000;
65 if (instance)
66 {
67 if (instance->GetData(DATA_WAVE_COUNT) == 6)
69 else if (instance->GetData(DATA_WAVE_COUNT) == 12)
71 }
72
73 if (Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0))
74 {
75 if (!pGuard1->IsAlive())
76 pGuard1->Respawn();
77 }
78 if (Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0))
79 {
80 if (!pGuard2->IsAlive())
81 pGuard2->Respawn();
82 }
83 }
84
86 {
88 return;
89
90 if (me->Attack(who, true))
91 {
92 me->AddThreat(who, 0.0f);
93 me->SetInCombatWith(who);
94 who->SetInCombatWith(me);
95 DoStartMovement(who);
96
97 if (Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0))
98 {
100 if (!pGuard1->GetVictim() && pGuard1->AI())
101 pGuard1->AI()->AttackStart(who);
102 }
103 if (Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0))
104 {
106 if (!pGuard2->GetVictim() && pGuard2->AI())
107 pGuard2->AI()->AttackStart(who);
108 }
109 }
110 }
111
112 void EnterCombat(Unit* /*who*/) OVERRIDE
113 {
116
117 if (instance)
118 {
119 if (GameObject* pDoor = instance->instance->GetGameObject(instance->GetData64(DATA_EREKEM_CELL)))
120 if (pDoor->GetGoState() == GOState::GO_STATE_READY)
121 {
123 return;
124 }
125
126 if (instance->GetData(DATA_WAVE_COUNT) == 6)
128 else if (instance->GetData(DATA_WAVE_COUNT) == 12)
130 }
131 }
132
133 void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
134
135
137 {
138 //Return since we have no target
139 if (!UpdateVictim())
140 return;
141
142 //spam stormstrike in hc mode if spawns are dead
143 if (IsHeroic())
144 {
145 if (Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0))
146 {
147 if (Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0))
148 {
149 if (!pGuard1->IsAlive() && !pGuard2->IsAlive())
151 }
152 }
153 }
154
155 if (uiEarthShieldTimer <= diff)
156 {
158 uiEarthShieldTimer = 20000;
159 } else uiEarthShieldTimer -= diff;
160
161 if (uiChainHealTimer <= diff)
162 {
163 if (uint64 TargetGUID = GetChainHealTargetGUID())
164 {
165 if (Creature* target = Unit::GetCreature(*me, TargetGUID))
166 DoCast(target, SPELL_CHAIN_HEAL);
167
168 //If one of the adds is dead spawn heals faster
169 Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0);
170 Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0);
171 uiChainHealTimer = ((pGuard1 && !pGuard1->IsAlive()) || (pGuard2 && !pGuard2->IsAlive()) ? 3000 : 8000) + rand()%3000;
172 }
173 } else uiChainHealTimer -= diff;
174
175 if (uiBloodlustTimer <= diff)
176 {
178 uiBloodlustTimer = std::rand() % 45000 + 35000;
179 } else uiBloodlustTimer -= diff;
180
181 if (uiEarthShockTimer <= diff)
182 {
184 uiEarthShockTimer = std::rand() % 13000 + 8000;
185 } else uiEarthShockTimer -= diff;
186
187 if (uiLightningBoltTimer <= diff)
188 {
189 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
191 uiLightningBoltTimer = std::rand() % 24000 + 18000;
192 } else uiLightningBoltTimer -= diff;
193
195 }
196
197 void JustDied(Unit* /*killer*/) OVERRIDE
198 {
200
201 if (instance)
202 {
203 if (instance->GetData(DATA_WAVE_COUNT) == 6)
204 {
206 instance->SetData(DATA_WAVE_COUNT, 7);
207 }
208 else if (instance->GetData(DATA_WAVE_COUNT) == 12)
209 {
211 instance->SetData(DATA_WAVE_COUNT, 13);
212 }
213 }
214 }
215
217 {
218 if (victim->GetTypeId() != TypeID::TYPEID_PLAYER)
219 return;
220
221 Talk(SAY_SLAY);
222 }
223
225 {
226 if (HealthBelowPct(85))
227 return me->GetGUID();
228
229 Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0);
230 if (pGuard1 && pGuard1->IsAlive() && !pGuard1->HealthAbovePct(75))
231 return pGuard1->GetGUID();
232
233 Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0);
234 if (pGuard2 && pGuard2->IsAlive() && !pGuard2->HealthAbovePct(75))
235 return pGuard2->GetGUID();
236
237 return 0;
238 }
239 };
240};
241
248
250{
251public:
252 npc_erekem_guard() : CreatureScript("npc_erekem_guard") { }
253
255 {
256 return new npc_erekem_guardAI(creature);
257 }
258
260 {
262 {
263 instance = creature->GetInstanceScript();
264 }
265
269
271
273 {
274 uiStrikeTimer = std::rand() % 8000 + 4000;
275 uiHowlingScreechTimer = std::rand() % 130000 + 8000;
276 uiGushingWoundTimer = std::rand() % 3000 + 1000;
277 }
278
280 {
282 return;
283
284 if (me->Attack(who, true))
285 {
286 me->AddThreat(who, 0.0f);
287 me->SetInCombatWith(who);
288 who->SetInCombatWith(me);
289 DoStartMovement(who);
290 }
291 }
292
293 void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
294
295
297 {
298 if (!UpdateVictim())
299 return;
300
302
303 if (uiStrikeTimer <= diff)
304 {
306 uiStrikeTimer = std::rand() % 8000 + 4000;
307 } else uiStrikeTimer -= diff;
308
309 if (uiHowlingScreechTimer <= diff)
310 {
312 uiHowlingScreechTimer = std::rand() % 13000 + 8000;
313 } else uiHowlingScreechTimer -= diff;
314
315 if (uiGushingWoundTimer <= diff)
316 {
318 uiGushingWoundTimer = std::rand() % 12000 + 7000;
319 } else uiGushingWoundTimer -= diff;
320 }
321 };
322};
323
325{
326 new boss_erekem();
327 new npc_erekem_guard();
328}
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ GO_STATE_READY
Definition GameObject.h:577
@ IN_PROGRESS
@ DONE
@ NOT_STARTED
@ TYPEID_PLAYER
Definition Object.h:55
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_IMMUNE_TO_PC
Definition Unit.h:633
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
@ SAY_SLAY
#define SAY_DEATH
#define SAY_AGGRO
@ SAY_DEATH
@ SAY_AGGRO
@ SAY_ADD_KILLED
@ SAY_BOTH_ADDS_KILLED
@ SAY_SLAY
@ SPELL_BLOODLUST
@ SPELL_STORMSTRIKE
@ SPELL_BREAK_BONDS
@ SPELL_CHAIN_HEAL
@ SPELL_EARTH_SHIELD
@ SPELL_LIGHTNING_BOLT
@ H_SPELL_CHAIN_HEAL
@ H_SPELL_EARTH_SHIELD
@ SPELL_EARTH_SHOCK
void AddSC_boss_erekem()
GuardSpells
@ SPELL_STRIKE
@ SPELL_HOWLING_SCREECH
@ SPELL_GUSHING_WOUND
@ SPELL_EARTH_SHIELD
@ SPELL_LIGHTNING_BOLT
@ SPELL_EARTH_SHOCK
@ SPELL_CHAIN_HEAL
Definition chapter5.cpp:204
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureScript(const char *name)
uint64 GetGUID() const
Definition Object.h:119
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
bool HealthAbovePct(int32 pct) const
Definition Unit.h:1621
bool IsAlive() const
Definition Unit.h:2032
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
@ DATA_WAVE_COUNT
bool IsHeroic() const
Creature * me
bool HealthBelowPct(uint32 pct) const
ScriptedAI(Creature *creature)
void DoStartMovement(Unit *target, float distance=0.0f, float angle=0.0f)
void EnterCombat(Unit *) OVERRIDE
boss_erekemAI(Creature *creature)
void MoveInLineOfSight(Unit *) OVERRIDE
void KilledUnit(Unit *victim) OVERRIDE
void JustDied(Unit *) OVERRIDE
void AttackStart(Unit *who) OVERRIDE
InstanceScript * instance
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void AttackStart(Unit *who) OVERRIDE
void MoveInLineOfSight(Unit *) OVERRIDE
@ DATA_EREKEM_GUARD_2
Definition violet_hold.h:34
@ DATA_EREKEM_CELL
Definition violet_hold.h:41
@ DATA_EREKEM_GUARD_1
Definition violet_hold.h:33
@ DATA_1ST_BOSS_EVENT
Definition violet_hold.h:11
@ DATA_2ND_BOSS_EVENT
Definition violet_hold.h:12