Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_gruul.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/* ScriptData
7SDName: Boss_Gruul
8SD%Complete: 60
9SDComment: Ground Slam need further development (knock back effect must be added to the core)
10SDCategory: Gruul's Lair
11EndScriptData */
12
13#include "ScriptMgr.h"
14#include "ScriptedCreature.h"
15#include "SpellScript.h"
16#include "gruuls_lair.h"
17
28
30{
31 SPELL_GROWTH = 36300,
33 SPELL_GROUND_SLAM = 33525, // AoE Ground Slam applying Ground Slam to everyone with a script effect (most likely the knock back, we can code it to a set knockback)
36
39 SPELL_STONED = 33652, // Spell is self cast by target
40
42 SPELL_KNOCK_BACK = 24199, // Knockback spell until correct implementation is made
43};
44
54
56{
57 public:
58 boss_gruul() : CreatureScript("boss_gruul") { }
59
60 struct boss_gruulAI : public BossAI
61 {
62 boss_gruulAI(Creature* creature) : BossAI(creature, DATA_GRUUL) { }
63
70
72
74 {
75 _Reset();
76 m_uiGrowth_Timer= 30000;
77 m_uiCaveIn_Timer= 27000;
82 m_uiReverberation_Timer= 60000+45000;
83 }
84
85 void EnterCombat(Unit* /*who*/) OVERRIDE
86 {
89 }
90
92 {
93 if (who->GetTypeId() == TypeID::TYPEID_PLAYER)
95 }
96
97 void JustDied(Unit* /*killer*/) OVERRIDE
98 {
99 _JustDied();
101 }
102
103 void SpellHitTarget(Unit* target, const SpellInfo* pSpell) OVERRIDE
104 {
105 //This to emulate effect1 (77) of SPELL_GROUND_SLAM, knock back to any direction
106 //It's initially wrong, since this will cause fall damage, which is by comments, not intended.
107 if (pSpell->Id == SPELL_GROUND_SLAM)
108 {
109 if (target->GetTypeId() == TypeID::TYPEID_PLAYER)
110 {
111 switch (std::rand() % 1)
112 {
113 case 0:
114 target->CastSpell(target, SPELL_MAGNETIC_PULL, true, NULL, NULL, me->GetGUID());
115 break;
116
117 case 1:
118 target->CastSpell(target, SPELL_KNOCK_BACK, true, NULL, NULL, me->GetGUID());
119 break;
120 }
121 }
122 }
123
124 //this part should be in the core
125 if (pSpell->Id == SPELL_SHATTER)
126 {
128 //clear this, if we are still performing
130 {
132
133 //and correct movement, if not already
134 if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
135 {
136 if (me->GetVictim())
137 me->GetMotionMaster()->MoveChase(me->GetVictim());
138 }
139 }
140 }
141 }
142
144 {
145 if (!UpdateVictim())
146 return;
147
148 events.Update(diff);
149
150 if (me->HasUnitState(UNIT_STATE_CASTING))
151 return;
152
154
155 // Growth
156 // Gruul can cast this spell up to 30 times
157 if (m_uiGrowth_Timer <= diff)
158 {
161 m_uiGrowth_Timer = 30000;
162 }
163 else
164 m_uiGrowth_Timer -= diff;
165
167 {
168 if (m_uiGroundSlamTimer <= diff)
169 {
170 m_uiGroundSlamTimer =120000;
172
173 if (m_uiReverberation_Timer < 10000) //Give a little time to the players to undo the damage from shatter
175
177 }
178 else
179 m_uiGroundSlamTimer -= diff;
180 }
181 else
182 {
183 // Hurtful Strike
184 if (m_uiHurtfulStrike_Timer <= diff)
185 {
187
188 if (target && me->IsWithinMeleeRange(me->GetVictim()))
190 else
192
194 }
195 else
197
198 // Reverberation
199 if (m_uiReverberation_Timer <= diff)
200 {
202 m_uiReverberation_Timer = std::rand() % 25000 + 15000;
203 }
204 else
206
207 // Cave In
208 if (m_uiCaveIn_Timer <= diff)
209 {
210 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
211 DoCast(target, SPELL_CAVE_IN);
212
213 if (m_uiCaveIn_StaticTimer >= 4000)
216 }
217 else
218 m_uiCaveIn_Timer -= diff;
219
220 // Ground Slam, Gronn Lord's Grasp, Stoned, Shatter
221 if (m_uiGroundSlamTimer <= diff)
222 {
223 me->GetMotionMaster()->Clear();
224 me->GetMotionMaster()->MoveIdle();
225
227 m_uiGroundSlamTimer = 10000;
228
230 }
231 else
232 m_uiGroundSlamTimer -= diff;
233
235 }
236 }
237 };
238
240 {
241 return GetGruulsLairAI<boss_gruulAI>(creature);
242 }
243};
244
246{
247 public:
248 spell_gruul_shatter() : SpellScriptLoader("spell_gruul_shatter") { }
249
251 {
253
254 bool Validate(SpellInfo const* /*spell*/) OVERRIDE
255 {
256 if (!sSpellMgr->GetSpellInfo(SPELL_STONED))
257 return false;
258 if (!sSpellMgr->GetSpellInfo(SPELL_SHATTER_EFFECT))
259 return false;
260 return true;
261 }
262
263 void HandleScript(SpellEffIndex /*effIndex*/)
264 {
265 if (Unit* target = GetHitUnit())
266 {
267 target->RemoveAurasDueToSpell(SPELL_STONED);
268 target->CastSpell((Unit*)NULL, SPELL_SHATTER_EFFECT, true);
269 }
270 }
271
276 };
277
282};
283
285{
286 public:
287 spell_gruul_shatter_effect() : SpellScriptLoader("spell_gruul_shatter_effect") { }
288
290 {
292
294 {
295 if (!GetHitUnit())
296 return;
297
298 float radius = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
299 if (!radius)
300 return;
301
302 float distance = GetCaster()->GetDistance2d(GetHitUnit());
303 if (distance > 1.0f)
304 SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius)));
305 }
306
311 };
312
317};
318
320{
321 new boss_gruul();
324}
std::int32_t int32
Definition Define.h:73
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ CHASE_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
SpellEffIndex
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
#define sSpellMgr
Definition SpellMgr.h:744
#define SpellEffectFn(F, I, N)
#define SpellHitFn(F)
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ SELECT_TARGET_TOPAGGRO
Definition UnitAI.h:24
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ SAY_SLAY
#define SAY_DEATH
#define SAY_AGGRO
@ SAY_DEATH
@ EMOTE_GROW
@ SAY_AGGRO
@ SAY_SLAM
@ SAY_SLAY
void AddSC_boss_gruul()
@ SPELL_REVERBERATION
@ SPELL_SHATTER_EFFECT
@ SPELL_KNOCK_BACK
@ SPELL_MAGNETIC_PULL
@ SPELL_CAVE_IN
@ SPELL_GROUND_SLAM
@ SPELL_GROWTH
@ SPELL_SHATTER
@ SPELL_HURTFUL_STRIKE
@ SPELL_STONED
@ EVENT_REVERBERATION
@ EVENT_GROWTH
@ EVENT_GROUND_SLAM
@ EVENT_CAVE_IN_STATIC
@ EVENT_HURTFUL_STRIKE
@ EVENT_CAVE_IN
@ SAY_SHATTER
@ SPELL_SHATTER_EFFECT
@ SPELL_GROUND_SLAM
@ SPELL_SHATTER
@ SPELL_STONED
@ SPELL_MAGNETIC_PULL
EventMap events
BossAI(Creature *creature, uint32 bossId)
void _EnterCombat()
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureScript(const char *name)
float CalcRadius(Unit *caster=NULL, Spell *=NULL) const
SpellEffectInfo Effects[MAX_SPELL_EFFECTS]
Definition SpellInfo.h:255
SpellInfo const * GetSpellInfo()
HookList< HitHandler > OnHit
HookList< EffectHandler > OnEffectHitTarget
Unit * GetHitUnit()
void SetHitDamage(int32 damage)
Unit * GetCaster()
int32 GetHitDamage()
SpellScriptLoader(const char *name)
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
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1684
CreatureAI * GetAI(Creature *creature) const OVERRIDE
PrepareSpellScript(spell_gruul_shatter_SpellScript)
PrepareSpellScript(spell_gruul_shatter_effect_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
AI * GetGruulsLairAI(Creature *creature)
Definition gruuls_lair.h:36
@ DATA_GRUUL
Definition gruuls_lair.h:17
Creature * me
void EnterCombat(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
boss_gruulAI(Creature *creature)
void JustDied(Unit *) OVERRIDE
void KilledUnit(Unit *who) OVERRIDE
void Reset() OVERRIDE
void SpellHitTarget(Unit *target, const SpellInfo *pSpell) OVERRIDE