TrinityCore
boss_auriaya.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#include "ScriptMgr.h"
19#include "InstanceScript.h"
20#include "ScriptedCreature.h"
21#include "SpellAuras.h"
22#include "SpellScript.h"
23#include "ulduar.h"
24
26{
27 // Auriaya
36
37 // Feral Defender
51
52 // Seeping Essence Stalker
54
55 // Sanctum Sentry
59
60 // Swarming Guardian
62 SPELL_POUNCE = 64399
63};
64
66{
67 // Auriaya
75
76 // Sanctum Sentry
79
80 // Feral Defender
87};
88
90{
96};
97
99{
103
105{
106 DATA_NINE_LIVES = 30763077,
113 NPC_SANCTUM_SENTRY = 34014
115
117{
118public:
119 CatsTargetSelector(Unit const* unit, float minDist, float maxDist) : _me(unit), _minDist(minDist), _maxDist(maxDist) { }
120
121 bool operator()(Unit* unit) const
122 {
123 float dist = _me->GetDistance(unit);
124 return unit->GetTypeId() == TYPEID_PLAYER && dist >= _minDist && dist < _maxDist && _me->IsWithinLOSInMap(unit);
125 }
126
127private:
128 Unit const* _me;
129 float _minDist;
130 float _maxDist;
131};
132
133struct boss_auriaya : public BossAI
134{
135 boss_auriaya(Creature* creature) : BossAI(creature, DATA_AURIAYA), _crazyCatLady(true), _nineLives(false) { }
136
137 void Reset() override
138 {
139 _Reset();
140 _crazyCatLady = true;
141 _nineLives = false;
142 HandleCats(true);
143 }
144
145 void HandleCats(bool isResetting)
146 {
147 std::list<Creature*> catList;
149 for (std::list<Creature*>::const_iterator itr = catList.begin(); itr != catList.end(); ++itr)
150 {
151 if (!isResetting)
152 (*itr)->DespawnOrUnsummon();
153 else if (!(*itr)->IsAlive())
154 (*itr)->Respawn(true);
155 }
156 }
157
158 void JustEngagedWith(Unit* who) override
159 {
168 }
169
170 void KilledUnit(Unit* who) override
171 {
172 if (who->GetTypeId() == TYPEID_PLAYER && roll_chance_i(50))
173 Talk(SAY_SLAY);
174 }
175
176 void DoAction(int32 action) override
177 {
178 switch (action)
179 {
181 _crazyCatLady = false;
182 break;
184 _nineLives = true;
185 break;
186 default:
187 break;
188 }
189 }
190
191 uint32 GetData(uint32 type) const override
192 {
193 switch (type)
194 {
195 case DATA_NINE_LIVES:
196 return _nineLives ? 1 : 0;
198 return _crazyCatLady ? 1 : 0;
199 default:
200 return 0;
201 }
202 }
203
204 void JustDied(Unit* /*killer*/) override
205 {
206 _JustDied();
209 HandleCats(false);
210 }
211
212 void EnterEvadeMode(EvadeReason why) override
213 {
216 }
217
218 void UpdateAI(uint32 diff) override
219 {
220 if (!UpdateVictim())
221 return;
222
223 events.Update(diff);
224
226 return;
227
228 while (uint32 eventId = events.ExecuteEvent())
229 {
230 switch (eventId)
231 {
234 events.Repeat(22s, 30s);
235 break;
240 events.Repeat(36s, 45s);
241 break;
242 case EVENT_BLAST:
244 break;
249 break;
252 break;
254 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
256 events.Repeat(25s, 45s);
257 break;
258 case EVENT_BERSERK:
261 break;
262 default:
263 break;
264 }
265
267 return;
268 }
269 }
270
271private:
274};
275
277{
278 npc_sanctum_sentry(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
279
280 void Reset() override
281 {
282 _events.Reset();
284 me->SetWalk(true);
285 }
286
287 void JustEngagedWith(Unit* /*who*/) override
288 {
291 me->SetWalk(false);
292 }
293
294 void JustDied(Unit* /*killer*/) override
295 {
297 auriaya->AI()->DoAction(ACTION_CRAZY_CAT_LADY);
298 }
299
300 void UpdateAI(uint32 diff) override
301 {
302 if (!UpdateVictim())
303 return;
304
305 _events.Update(diff);
306
308 return;
309
310 while (uint32 eventId = _events.ExecuteEvent())
311 {
312 switch (eventId)
313 {
314 case EVENT_RIP:
316 _events.Repeat(10s, 12s);
317 break;
319 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, CatsTargetSelector(me, 10.0f, 15.0f)))
320 {
322 _events.Repeat(10s);
323 break;
324 }
325 _events.Repeat(1s);
326 break;
327 default:
328 break;
329 }
330
332 return;
333 }
334 }
335
336private:
339};
340
342{
343 npc_feral_defender(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
344
345 void Reset() override
346 {
354
356 auriaya->AI()->JustSummoned(me);
357 }
358
359 void UpdateAI(uint32 diff) override
360 {
362 return;
363
364 _events.Update(diff);
365
367 return;
368
369 while (uint32 eventId = _events.ExecuteEvent())
370 {
371 switch (eventId)
372 {
376 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
377 AttackStart(target);
380 break;
383 {
384 if (Unit* target = me->GetVictim())
385 {
386 float distance = me->GetDistance2d(target);
387 if (distance > 5.0f && distance <= 45.0f)
388 {
390 _events.Repeat(5s);
391 break;
392 }
393 }
394 }
395 _events.Repeat(1s);
396 break;
397 case EVENT_RUSH:
398 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, CatsTargetSelector(me, 10.0f, 11.0f)))
399 {
400 DoCast(target, SPELL_FERAL_RUSH, true);
401 _events.Repeat(5s);
402 break;
403 }
404 _events.Repeat(1s);
405 break;
407 me->SetDisableGravity(true);
408 me->SetHover(true);
412 break;
415 break;
419 me->SetUninteractible(false);
421 me->SetDisableGravity(false);
422 me->SetHover(false);
424 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
425 AttackStart(target);
427 break;
428 default:
429 break;
430 }
431
433 return;
434 }
435 }
436
437 void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
438 {
439 if (damage >= me->GetHealth() && me->HasAura(SPELL_FERAL_ESSENCE))
440 {
441 damage = 0;
443 {
445 me->AttackStop();
446 me->SetUninteractible(true);
455 }
456 }
457 }
458
459 void JustDied(Unit* /*killer*/) override
460 {
463 auriaya->AI()->DoAction(ACTION_DEFENDER_DIED);
464 }
465
466private:
469};
470
472{
473 npc_swarming_guardian(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
474
475 void Reset() override
476 {
478 _scheduler.Schedule(1s, [this](TaskContext /*context*/)
479 {
482 });
484 auriaya->AI()->JustSummoned(me);
485 }
486
487 void UpdateAI(uint32 diff) override
488 {
489 _scheduler.Update(diff);
490 if (!UpdateVictim())
491 return;
492 }
493
494private:
497};
498
500{
501 npc_seeping_essence_stalker(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
502
503 void Reset() override
504 {
507 auriaya->AI()->JustSummoned(me);
508 }
509
510 void UpdateAI(uint32 /*diff*/) override { }
511
512private:
514};
515
516// 64381 - Strength of the Pack
518{
519 void FilterTargets(std::list<WorldObject*>& unitList)
520 {
521 unitList.remove_if([](WorldObject* obj) { return obj->GetEntry() != NPC_SANCTUM_SENTRY; });
522 }
523
524 void Register() override
525 {
527 }
528};
529
530// 64392, 64679 - Sentinel Blast
532{
533 void FilterTargets(std::list<WorldObject*>& targets)
534 {
535 targets.remove_if([](WorldObject* object) -> bool
536 {
537 if (object->GetTypeId() == TYPEID_PLAYER)
538 return false;
539
540 if (Creature* creature = object->ToCreature())
541 return !creature->IsPet();
542
543 return true;
544 });
545 }
546
547 void Register() override
548 {
551 }
552};
553
554// 63709 - Aggro Creator
556{
557 bool Validate(SpellInfo const* /*spellInfo*/) override
558 {
560 }
561
563 {
564 Creature* caster = GetCaster()->ToCreature();
565 if (!caster || !caster->IsAIEnabled() || caster->HasReactState(REACT_PASSIVE))
566 return;
567
568 if (Unit* target = caster->AI()->SelectTarget(SelectTargetMethod::Random, 0, CatsTargetSelector(caster, 5.0f, 10.0f)))
569 {
570 caster->CastSpell(target, SPELL_POUNCE, true);
571 caster->GetThreatManager().AddThreat(target, 50000000.0f, nullptr, true);
572 caster->AI()->AttackStart(target);
573 }
574 }
575
576 void Register() override
577 {
579 }
580};
581
582// 64456 - Feral Essence Application Removal
584{
585 bool Validate(SpellInfo const* /*spellInfo*/) override
586 {
588 }
589
591 {
592 if (Aura* essence = GetCaster()->GetAura(SPELL_FERAL_ESSENCE))
593 essence->ModStackAmount(-1);
594 }
595
596 void Register() override
597 {
599 }
600};
601
602// 64496, 64674 - Feral Rush
604{
605 bool Validate(SpellInfo const* /*spellInfo*/) override
606 {
608 }
609
610 void HandleOnHit(SpellEffIndex /*effIndex*/)
611 {
613 }
614
615 void Register() override
616 {
618 }
619};
620
622{
623 public:
624 achievement_nine_lives() : AchievementCriteriaScript("achievement_nine_lives") { }
625
626 bool OnCheck(Player* /*player*/, Unit* target) override
627 {
628 if (!target)
629 return false;
630
631 if (Creature* auriaya = target->ToCreature())
632 if (auriaya->AI()->GetData(DATA_NINE_LIVES))
633 return true;
634
635 return false;
636 }
637};
638
640{
641 public:
642 achievement_crazy_cat_lady() : AchievementCriteriaScript("achievement_crazy_cat_lady") { }
643
644 bool OnCheck(Player* /*player*/, Unit* target) override
645 {
646 if (!target)
647 return false;
648
649 if (Creature* auriaya = target->ToCreature())
650 if (auriaya->AI()->GetData(DATA_CRAZY_CAT_LADY))
651 return true;
652
653 return false;
654 }
655};
656
658{
671}
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_ENGAGE
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
bool roll_chance_i(int chance)
Definition: Random.h:59
if(posix_memalign(&__mallocedMemory, __align, __size)) return NULL
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_SRC_AREA_ALLY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SCHOOL_DAMAGE
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
EvadeReason
Definition: UnitAICommon.h:30
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_STATE_CASTING
Definition: Unit.h:270
AuriayaSpells
@ SPELL_RIP_FLESH
@ SPELL_CLEAR_ALL_DEBUFFS
@ SPELL_POUNCE
@ SPELL_SHADOW_PAWS
@ SPELL_RANDOM_AGRO_PERIODIC
@ SPELL_FERAL_ESSENCE_APPLICATION_REMOVAL
@ SPELL_SUMMON_ESSENCE
@ SPELL_SUMMON_SWARMING_GUARDIAN
@ SPELL_AGRO_CREATOR
@ SPELL_SAVAGE_POUNCE
@ SPELL_STRENGHT_OF_THE_PACK
@ SPELL_SENTINEL_BLAST
@ SPELL_FERAL_RUSH_2
@ SPELL_FERAL_POUNCE
@ SPELL_INSTAKILL_ARACHNOPOD
@ SPELL_DEFENDER_TRIGGER
@ SPELL_ACTIVATE_DEFENDER
@ SPELL_FERAL_RUSH
@ SPELL_FULL_HEAL
@ SPELL_TERRIFYING_SCREECH
@ SPELL_DROWNED_STATE
@ SPELL_BERSERK
@ SPELL_FERAL_ESSENCE
@ SPELL_SEEPING_ESSENCE
@ SPELL_PERMANENT_FEIGN_DEATH
@ SPELL_SONIC_SCREECH
@ SPELL_REDUCE_CRITCAL
@ SUMMON_GROUP_25_MAN
@ AURIAYA_DEATH_SOUNDID
@ SUMMON_GROUP_10_MAN
@ NPC_SANCTUM_SENTRY
@ PHASE_NONE
@ DATA_NINE_LIVES
@ DATA_CRAZY_CAT_LADY
@ PHASE_COMBAT
AuriayaEvents
@ EVENT_BLAST
@ EVENT_RUSH
@ EVENT_START_COMBAT
@ EVENT_ACTIVATE_DEFENDER
@ EVENT_SONIC_SCREECH
@ EVENT_FERAL_POUNCE
@ EVENT_SUMMON_DEFENDER
@ EVENT_RESPAWN_DEFENDER_3
@ EVENT_RIP
@ EVENT_BERSERK
@ EVENT_RESPAWN_DEFENDER
@ EVENT_TERRIFYING_SCREECH
@ EVENT_SWARNING_GUARDIAN
@ EVENT_SAVAGE_POUNCE
@ EVENT_RESPAWN_DEFENDER_2
AuriayaActions
@ ACTION_CRAZY_CAT_LADY
@ ACTION_DEFENDER_DIED
void AddSC_boss_auriaya()
AuriayaYells
@ EMOTE_FEAR
@ SAY_AGGRO
@ SAY_SLAY
@ EMOTE_DEFENDER
@ SAY_BERSERK
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
EventMap events
void _JustDied()
CatsTargetSelector(Unit const *unit, float minDist, float maxDist)
bool operator()(Unit *unit) const
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:219
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
void AttackStart(Unit *victim) override
== Triggered Actions Requested ==================
Definition: CreatureAI.cpp:328
Creature *const me
Definition: CreatureAI.h:61
bool HasReactState(ReactStates state) const
Definition: Creature.h:162
void SetReactState(ReactStates st)
Definition: Creature.h:160
ReactStates GetReactState() const
Definition: Creature.h:161
CreatureAI * AI() const
Definition: Creature.h:214
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void Repeat(Milliseconds time)
Definition: EventMap.cpp:63
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
bool IsInPhase(uint8 phase) const
Definition: EventMap.h:217
void CancelEvent(uint32 eventId)
Definition: EventMap.cpp:131
void SetPhase(uint8 phase)
Definition: EventMap.cpp:28
void Reset()
Definition: EventMap.cpp:21
Creature * GetCreature(uint32 type)
void SendEncounterUnit(EncounterFrameType type, Unit const *unit, Optional< int32 > param1={}, Optional< int32 > param2={})
static Creature * ToCreature(Object *o)
Definition: Object.h:219
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
TaskScheduler & Schedule(std::chrono::duration< Rep, Period > time, task_handler_t task)
TaskScheduler & Update(success_t const &callback=nullptr)
void AddThreat(Unit *target, float amount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false, bool ignoreRedirects=false)
== AFFECT MY THREAT LIST ==
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
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 DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
void SetAuraStack(uint32 spellId, Unit *target, uint32 stack)
Definition: Unit.cpp:11665
bool SetHover(bool enable, bool updateAnimTier=true)
Definition: Unit.cpp:12938
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition: Unit.cpp:12725
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
bool IsAIEnabled() const
Definition: Unit.h:658
uint64 GetHealth() const
Definition: Unit.h:776
bool SetWalk(bool enable)
Definition: Unit.cpp:12707
Unit * GetVictim() const
Definition: Unit.h:715
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
bool AttackStop()
Definition: Unit.cpp:5781
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition: Object.cpp:3312
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
float GetDistance2d(WorldObject const *obj) const
Definition: Object.cpp:1096
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition: Object.cpp:1181
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1078
bool OnCheck(Player *, Unit *target) override
bool OnCheck(Player *, Unit *target) override
void HandleDummyEffect(SpellEffIndex)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleScriptEffect(SpellEffIndex)
void HandleOnHit(SpellEffIndex)
bool Validate(SpellInfo const *) override
void Register() override
void FilterTargets(std::list< WorldObject * > &targets)
void FilterTargets(std::list< WorldObject * > &unitList)
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
void ResetThreatList(Unit *who=nullptr)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void EnterEvadeMode(EvadeReason why) override
void DoAction(int32 action) override
void HandleCats(bool isResetting)
boss_auriaya(Creature *creature)
void Reset() override
void KilledUnit(Unit *who) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
void JustEngagedWith(Unit *who) override
uint32 GetData(uint32 type) const override
void JustDied(Unit *) override
void Reset() override
npc_feral_defender(Creature *creature)
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void UpdateAI(uint32 diff) override
InstanceScript * _instance
void JustEngagedWith(Unit *) override
InstanceScript * _instance
void JustDied(Unit *) override
void UpdateAI(uint32 diff) override
npc_sanctum_sentry(Creature *creature)
void Reset() override
void UpdateAI(uint32) override
npc_seeping_essence_stalker(Creature *creature)
void UpdateAI(uint32 diff) override
InstanceScript * _instance
npc_swarming_guardian(Creature *creature)
void Reset() override
TaskScheduler _scheduler
@ DATA_AURIAYA
Definition: ulduar.h:43
#define RegisterUlduarCreatureAI(ai_name)
Definition: ulduar.h:524