TrinityCore
Loading...
Searching...
No Matches
boss_gruul.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/*
19TO-DO:
20Slighly(400ms) after spell cast 33965 creatures 19198 are spawned. I guess he forces all enemies including pets(9 summoned units
21and 9 units in his threatlist) to cast 39186(19198 were created by that spell(sniff)). Summoned by that spell creature 19198 casts 33496
22on self after being summoned. Then probably they casts 33497(Pull Towards: (150)) on their creators and that's how that knockback is handled.
23If you look closely, players are knocked to random destinations with random angles, means there is no only one spell which handles knockback.
2419198 despawns after 800ms after being summoned.
25*/
26
27#include "ScriptMgr.h"
28#include "gruuls_lair.h"
29#include "MotionMaster.h"
30#include "ScriptedCreature.h"
31#include "SpellInfo.h"
32#include "SpellScript.h"
33
44
46{
47 SPELL_GROWTH = 36300,
49 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)
52
55 SPELL_STONED = 33652, // Spell is self cast by target
56
58 SPELL_KNOCK_BACK = 24199, // Knockback spell until correct implementation is made
59};
60
70
72{
73 public:
74 boss_gruul() : CreatureScript("boss_gruul") { }
75
76 struct boss_gruulAI : public BossAI
77 {
78 boss_gruulAI(Creature* creature) : BossAI(creature, DATA_GRUUL)
79 {
80 Initialize();
81 }
82
84 {
85 m_uiGrowth_Timer = 30000;
86 m_uiCaveIn_Timer = 27000;
88 m_uiGroundSlamTimer = 35000;
91 m_uiReverberation_Timer = 60000 + 45000;
92 }
93
100
102
103 void Reset() override
104 {
105 _Reset();
106 Initialize();
107 }
108
109 void JustEngagedWith(Unit* who) override
110 {
113 }
114
115 void KilledUnit(Unit* who) override
116 {
117 if (who->GetTypeId() == TYPEID_PLAYER)
118 Talk(SAY_SLAY);
119 }
120
121 void JustDied(Unit* /*killer*/) override
122 {
123 _JustDied();
125 }
126
127 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
128 {
129 //This to emulate effect1 (77) of SPELL_GROUND_SLAM, knock back to any direction
130 //It's initially wrong, since this will cause fall damage, which is by comments, not intended.
131 if (spellInfo->Id == SPELL_GROUND_SLAM)
132 {
133 if (target->GetTypeId() == TYPEID_PLAYER)
134 {
135 switch (urand(0, 1))
136 {
137 case 0:
139 .SetOriginalCaster(me->GetGUID()));
140 break;
141
142 case 1:
144 .SetOriginalCaster(me->GetGUID()));
145 break;
146 }
147 }
148 }
149
150 //this part should be in the core
151 if (spellInfo->Id == SPELL_SHATTER)
152 {
154 //clear this, if we are still performing
156 {
158
159 //and correct movement, if not already
161 {
162 if (me->GetVictim())
164 }
165 }
166 }
167 }
168
169 void UpdateAI(uint32 diff) override
170 {
171 if (!UpdateVictim())
172 return;
173
174 events.Update(diff);
175
177 return;
178
180
181 // Growth
182 // Gruul can cast this spell up to 30 times
183 if (m_uiGrowth_Timer <= diff)
184 {
187 m_uiGrowth_Timer = 30000;
188 }
189 else
190 m_uiGrowth_Timer -= diff;
191
193 {
194 if (m_uiGroundSlamTimer <= diff)
195 {
196 m_uiGroundSlamTimer =120000;
198
199 if (m_uiReverberation_Timer < 10000) //Give a little time to the players to undo the damage from shatter
201
203 }
204 else
205 m_uiGroundSlamTimer -= diff;
206 }
207 else
208 {
209 // Hurtful Strike
210 if (m_uiHurtfulStrike_Timer <= diff)
211 {
213
214 if (target && me->IsWithinMeleeRange(me->GetVictim()))
216 else
218
220 }
221 else
223
224 // Reverberation
225 if (m_uiReverberation_Timer <= diff)
226 {
228 m_uiReverberation_Timer = urand(15000, 25000);
229 }
230 else
232
233 // Cave In
234 if (m_uiCaveIn_Timer <= diff)
235 {
237 DoCast(target, SPELL_CAVE_IN);
238
239 if (m_uiCaveIn_StaticTimer >= 4000)
241
243 }
244 else
245 m_uiCaveIn_Timer -= diff;
246
247 // Ground Slam, Gronn Lord's Grasp, Stoned, Shatter
248 if (m_uiGroundSlamTimer <= diff)
249 {
252
254 m_uiGroundSlamTimer = 10000;
255
257 }
258 else
259 m_uiGroundSlamTimer -= diff;
260 }
261 }
262 };
263
264 CreatureAI* GetAI(Creature* creature) const override
265 {
266 return GetGruulsLairAI<boss_gruulAI>(creature);
267 }
268};
269
271{
272 public:
273 spell_gruul_shatter() : SpellScriptLoader("spell_gruul_shatter") { }
274
276 {
277 bool Validate(SpellInfo const* /*spell*/) override
278 {
280 }
281
282 void HandleScript(SpellEffIndex /*effIndex*/)
283 {
284 if (Unit* target = GetHitUnit())
285 {
286 target->RemoveAurasDueToSpell(SPELL_STONED);
287 target->CastSpell(nullptr, SPELL_SHATTER_EFFECT, true);
288 }
289 }
290
295 };
296
297 SpellScript* GetSpellScript() const override
298 {
300 }
301};
302
304{
305 public:
306 spell_gruul_shatter_effect() : SpellScriptLoader("spell_gruul_shatter_effect") { }
307
309 {
310 bool Validate(SpellInfo const* spellInfo) override
311 {
312 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } });
313 }
314
316 {
317 if (!GetHitUnit())
318 return;
319
321 if (radius <= 0.0f)
322 return;
323
324 float distance = GetCaster()->GetDistance2d(GetHitUnit());
325 if (distance > 1.0f)
326 SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius)));
327 }
328
333 };
334
335 SpellScript* GetSpellScript() const override
336 {
338 }
339};
340
342{
343 new boss_gruul();
346}
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
@ CHASE_MOTION_TYPE
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
Spells
Definition PlayerAI.cpp:32
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
SpellEffIndex
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
#define SpellEffectFn(F, I, N)
#define SpellHitFn(F)
@ UNIT_STATE_CASTING
Definition Unit.h:276
@ SAY_DEATH
@ EMOTE_GROW
@ SAY_AGGRO
@ SAY_SLAM
@ SAY_SLAY
@ SAY_SHATTER
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
Yells
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
void JustEngagedWith(Unit *who) override
EventMap events
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void Update(uint32 time)
Definition EventMap.h:61
MovementGeneratorType GetCurrentMovementGeneratorType() const
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
SpellRange CalcRadius(WorldObject const *caster=nullptr, SpellTargetIndex targetIndex=SpellTargetIndex::TargetA, Spell *spell=nullptr) const
uint32 const Id
Definition SpellInfo.h:328
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
int32 GetHitDamage() const
Unit * GetCaster() const
HookList< HitHandler > OnHit
Unit * GetHitUnit() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
void SetHitDamage(int32 damage)
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:635
bool IsWithinMeleeRange(Unit const *obj) const
Definition Unit.h:710
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
Unit * GetVictim() const
Definition Unit.h:726
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:450
CreatureAI * GetAI(Creature *creature) const override
SpellScript * GetSpellScript() const override
SpellScript * GetSpellScript() const override
@ DATA_GRUUL
Definition gruuls_lair.h:32
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void KilledUnit(Unit *who) override
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
boss_gruulAI(Creature *creature)