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/*
19 * Spells 36240 and 39188 are used with ignore category cooldown flag because otherwise Ground Slam
20 will be skipped in too many cases. Investigate this
21 * The way knock back is handled should be re-checked
22 */
23
24#include "ScriptMgr.h"
25#include "gruuls_lair.h"
26#include "ScriptedCreature.h"
27#include "SpellInfo.h"
28#include "SpellScript.h"
29
39
56
65
67{
68 SOUND_ID_DEATH = 11363
69};
70
71// 19044 - Gruul the Dragonkiller
72struct boss_gruul : public BossAI
73{
74 boss_gruul(Creature* creature) : BossAI(creature, DATA_GRUUL) { }
75
88
89 void OnSpellCast(SpellInfo const* spellInfo) override
90 {
91 switch (spellInfo->Id)
92 {
93 case SPELL_GROWTH:
95 break;
98 break;
99 default:
100 break;
101 }
102 }
103
104 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
105 {
106 if (spellInfo->Id == SPELL_GROUND_SLAM_DUMMY)
107 {
111 }
112 }
113
114 void KilledUnit(Unit* who) override
115 {
116 if (who->GetTypeId() == TYPEID_PLAYER)
117 Talk(SAY_SLAY);
118 }
119
120 void JustDied(Unit* /*killer*/) override
121 {
122 _JustDied();
124 }
125
126 void ExecuteEvent(uint32 eventId) override
127 {
128 switch (eventId)
129 {
132 events.Repeat(8s);
133 break;
134 case EVENT_CAVE_IN:
137 events.Repeat(8s);
138 break;
141 events.Repeat(30s, 45s);
142 break;
143 case EVENT_GROWTH:
145 events.Repeat(30s);
146 break;
149 events.Repeat(70s, 90s);
150 break;
151 default:
152 break;
153 }
154 }
155};
156
157// 33812 - Hurtful Strike Primer
159{
161
162 bool Validate(SpellInfo const* /*spellInfo*/) override
163 {
165 }
166
167 void FilterTargets(std::list<WorldObject*>& targets)
168 {
169 Unit* caster = GetCaster();
170
171 // First we get rid of all targets that are not within melee range
172 targets.remove_if([&](WorldObject* target)
173 {
174 if (Unit* unit = target->ToUnit())
175 return !unit->IsWithinMeleeRange(caster);
176
177 return true;
178 });
179
180 if (targets.size() >= 2)
181 {
182 // Now we sort all targets by threat
183 targets.sort([&](WorldObject const* left, WorldObject const* right)
184 {
185 Unit const* leftTarget = ASSERT_NOTNULL(left->ToUnit());
186 Unit const* rightTarget = ASSERT_NOTNULL(right->ToUnit());
187
188 return caster->GetThreatManager().GetThreat(leftTarget) > caster->GetThreatManager().GetThreat(rightTarget);
189 });
190
191 // Now we nuke the top threat target so we are only left with the 2nd top victim
192 targets.pop_front();
193
194 if (targets.size() >= 2)
195 targets.resize(1);
196 }
197 }
198
199 void HandleDummy(SpellEffIndex /*effIndex*/)
200 {
202 }
203
209};
210
211// 33525 - Ground Slam
213{
215
216 bool Validate(SpellInfo const* /*spell*/) override
217 {
219 }
220
221 void HandleScript(SpellEffIndex /*effIndex*/)
222 {
223 /* I guess he forces all enemies including pets to summon creature 19198 by spell 39186(9 summoned units and
224 9 units in his threat list). Summoned by that spell creature 19198 casts 33496 on self after being summoned.
225 Then after small delay they casts 33497(Pull Towards: (150)) (guess) on their creators and that's how that
226 knockback without fall damage is handled. If you look closely, players are knocked to random destinations
227 with random angles, means there is no only one spell which handles knockback. However the spell to summon
228 that trigger is TARGET_DEST_CASTER_RADIUS, so creature may be spawned just few yards away from player. In
229 that case player will be knocked back for a really small distance. It may look weird and wrong.
230 Script for 19198 is handled in SAI. 19198 probably is used in Cata dungeons or raids too, also at least in
231 one TBC raid or dungeon since there are more spells to summon that creature. */
233 }
234
236 {
238 }
239
245};
246
247// 33572 - Gronn Lord's Grasp
268
269// 33965 - Look Around
271{
273
274 bool Validate(SpellInfo const* /*spell*/) override
275 {
277 }
278
279 void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
280 {
281 if (Creature* creature = GetTarget()->ToCreature())
282 {
283 creature->AI()->Talk(EMOTE_ROAR);
284 creature->AI()->Talk(SAY_SHATTER);
285 creature->CastSpell(creature, SPELL_SHATTER);
286 }
287 }
288
293};
294
295// 33654 - Shatter
297{
299
300 bool Validate(SpellInfo const* /*spell*/) override
301 {
303 }
304
305 void HandleScript(SpellEffIndex /*effIndex*/)
306 {
307 Unit* target = GetHitUnit();
309 target->CastSpell(nullptr, SPELL_SHATTER_EFFECT, true);
310 }
311
316};
317
318// 33671 - Shatter
320{
322
324 {
325 if (!GetHitUnit())
326 return;
327
328 float radius = GetEffectInfo(EFFECT_0).CalcRadius(GetCaster());
329 if (!radius)
330 return;
331
332 float distance = GetCaster()->GetDistance2d(GetHitUnit());
333 if (distance > 1.0f)
334 SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius)));
335 }
336
341};
342
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:84
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TARGET_UNIT_SRC_AREA_ENEMY
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAPPLY
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_MOD_DECREASE_SPEED
@ SPELL_AURA_MOD_STUN
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define SpellCastFn(F)
#define AuraEffectApplyFn(F, I, N, M)
#define SpellHitFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
GruulSpells
@ SPELL_REVERBERATION
@ SPELL_SHATTER_EFFECT
@ SPELL_GROUND_SLAM_DUMMY
@ SPELL_SUMMON_RANDOM_TRACTOR
@ SPELL_CAVE_IN
@ SPELL_GROUND_SLAM
@ SPELL_GROWTH
@ SPELL_SHATTER
@ SPELL_HURTFUL_STRIKE
@ SPELL_LOOK_AROUND
@ SPELL_STONED
@ SPELL_HURTFUL_STRIKE_PRIMER
GruulTexts
@ EMOTE_GROW
@ SAY_AGGRO
@ SAY_SLAM
@ SAY_SLAY
@ SAY_SHATTER
@ EMOTE_ROAR
void AddSC_boss_gruul()
GruulEvents
@ EVENT_REVERBERATION
@ EVENT_GROWTH
@ EVENT_GROUND_SLAM
@ EVENT_HURTFUL_STRIKE
@ EVENT_CAVE_IN
GruulMisc
@ SOUND_ID_DEATH
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetTarget() const
uint8 GetStackAmount() const
void JustEngagedWith(Unit *who) override
EventMap events
Creature *const me
Definition CreatureAI.h:82
void Repeat(Milliseconds time)
Definition EventMap.cpp:63
void RescheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:52
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
static Unit * ToUnit(Object *o)
Definition Object.h:192
TypeID GetTypeId() const
Definition Object.h:93
float CalcRadius(WorldObject *caster=nullptr, Spell *=nullptr) const
uint32 Id
Definition SpellInfo.h:289
HookList< CastHandler > AfterCast
int32 GetHitDamage() const
Unit * GetCaster() const
HookList< HitHandler > OnHit
Unit * GetHitUnit() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
void SetHitDamage(int32 damage)
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
float GetThreat(Unit const *who, bool includeOffline=false) const
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
ThreatManager & GetThreatManager()
Definition Unit.h:1155
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1141
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_gruul_gronn_lords_grasp)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleScript(SpellEffIndex)
void Register() override
PrepareSpellScript(spell_gruul_ground_slam)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_gruul_hurtful_strike_primer)
void FilterTargets(std::list< WorldObject * > &targets)
void AfterRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_gruul_look_around)
bool Validate(SpellInfo const *) override
void Register() override
PrepareSpellScript(spell_gruul_shatter_effect)
void Register() override
PrepareSpellScript(spell_gruul_shatter)
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *) override
@ DATA_GRUUL
Definition gruuls_lair.h:31
#define RegisterGruulsLairCreatureAI(ai_name)
Definition gruuls_lair.h:63
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void OnSpellCast(SpellInfo const *spellInfo) override
void JustEngagedWith(Unit *who) override
void JustDied(Unit *) override
boss_gruul(Creature *creature)
void ExecuteEvent(uint32 eventId) override
void KilledUnit(Unit *who) override