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{
160 bool Validate(SpellInfo const* /*spellInfo*/) override
161 {
163 }
164
165 void FilterTargets(std::list<WorldObject*>& targets)
166 {
167 Unit* caster = GetCaster();
168
169 // First we get rid of all targets that are not within melee range
170 targets.remove_if([&](WorldObject* target)
171 {
172 if (Unit* unit = target->ToUnit())
173 return !unit->IsWithinMeleeRange(caster);
174
175 return true;
176 });
177
178 if (targets.size() >= 2)
179 {
180 // Now we sort all targets by threat
181 targets.sort([&](WorldObject const* left, WorldObject const* right)
182 {
183 Unit const* leftTarget = ASSERT_NOTNULL(left->ToUnit());
184 Unit const* rightTarget = ASSERT_NOTNULL(right->ToUnit());
185
186 return caster->GetThreatManager().GetThreat(leftTarget) > caster->GetThreatManager().GetThreat(rightTarget);
187 });
188
189 // Now we nuke the top threat target so we are only left with the 2nd top victim
190 targets.pop_front();
191
192 if (targets.size() >= 2)
193 targets.resize(1);
194 }
195 }
196
197 void HandleDummy(SpellEffIndex /*effIndex*/)
198 {
200 }
201
207};
208
209// 33525 - Ground Slam
211{
212 bool Validate(SpellInfo const* /*spell*/) override
213 {
215 }
216
217 void HandleScript(SpellEffIndex /*effIndex*/)
218 {
219 /* I guess he forces all enemies including pets to summon creature 19198 by spell 39186(9 summoned units and
220 9 units in his threat list). Summoned by that spell creature 19198 casts 33496 on self after being summoned.
221 Then after small delay they casts 33497(Pull Towards: (150)) (guess) on their creators and that's how that
222 knockback without fall damage is handled. If you look closely, players are knocked to random destinations
223 with random angles, means there is no only one spell which handles knockback. However the spell to summon
224 that trigger is TARGET_DEST_CASTER_RADIUS, so creature may be spawned just few yards away from player. In
225 that case player will be knocked back for a really small distance. It may look weird and wrong.
226 Script for 19198 is handled in SAI. 19198 probably is used in Cata dungeons or raids too, also at least in
227 one TBC raid or dungeon since there are more spells to summon that creature. */
229 }
230
232 {
234 }
235
241};
242
243// 33572 - Gronn Lord's Grasp
245{
246 bool Validate(SpellInfo const* /*spellInfo*/) override
247 {
249 }
250
251 void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
252 {
253 if (GetStackAmount() == 5)
255 }
256
261};
262
263// 33965 - Look Around
265{
266 bool Validate(SpellInfo const* /*spell*/) override
267 {
269 }
270
271 void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
272 {
273 if (Creature* creature = GetTarget()->ToCreature())
274 {
275 creature->AI()->Talk(EMOTE_ROAR);
276 creature->AI()->Talk(SAY_SHATTER);
277 creature->CastSpell(creature, SPELL_SHATTER);
278 }
279 }
280
285};
286
287// 33654 - Shatter
289{
290 bool Validate(SpellInfo const* /*spell*/) override
291 {
293 }
294
295 void HandleScript(SpellEffIndex /*effIndex*/)
296 {
297 Unit* target = GetHitUnit();
299 target->CastSpell(nullptr, SPELL_SHATTER_EFFECT, true);
300 }
301
306};
307
308// 33671 - Shatter
310{
311 bool Validate(SpellInfo const* spellInfo) override
312 {
313 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } });
314 }
315
317 {
318 if (!GetHitUnit())
319 return;
320
322 if (radius <= 0.0f)
323 return;
324
325 float distance = GetCaster()->GetDistance2d(GetHitUnit());
326 if (distance > 1.0f)
327 SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius)));
328 }
329
334};
335
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:74
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
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 Spell and Category cooldowns.
#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
TypeID GetTypeId() const
Definition BaseEntity.h:166
void JustEngagedWith(Unit *who) override
EventMap events
Creature *const me
Definition CreatureAI.h:63
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
void RescheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:56
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:40
Unit * ToUnit()
Definition Object.h:116
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)
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:160
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:71
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:81
Definition Unit.h:647
ThreatManager & GetThreatManager()
Definition Unit.h:1093
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3992
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:448
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleScript(SpellEffIndex)
void Register() override
bool Validate(SpellInfo const *) override
void FilterTargets(std::list< WorldObject * > &targets)
void AfterRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void Register() override
bool Validate(SpellInfo const *spellInfo) override
void Register() override
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