TrinityCore
Loading...
Searching...
No Matches
boss_anubarak.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 "AreaBoundary.h"
20#include "azjol_nerub.h"
21#include "Containers.h"
22#include "GameObject.h"
23#include "InstanceScript.h"
24#include "MotionMaster.h"
25#include "ObjectAccessor.h"
26#include "PassiveAI.h"
27#include "ScriptedCreature.h"
28#include "SpellInfo.h"
29#include "SpellScript.h"
30#include "TemporarySummon.h"
31
56
58{
60};
61
71
85
91
92enum Misc
93{
95};
96
102
108
113
114struct boss_anub_arak : public BossAI
115{
117
118 void Reset() override
119 {
122 me->SetUninteractible(false);
123 _nextSubmerge = 75;
124 _petCount = 0;
125 }
126
127 bool CanAIAttack(Unit const* /*who*/) const override { return true; } // do not check boundary here
128
129 void JustEngagedWith(Unit* who) override
130 {
132
134 door->SetGoState(GO_STATE_ACTIVE); // open door for now
136 door2->SetGoState(GO_STATE_ACTIVE);
137
140
146
147 // set up world triggers
148 std::list<TempSummon*> summoned;
150 if (summoned.empty()) // something went wrong
151 {
153 return;
154 }
155 _guardianTrigger = (*summoned.begin())->GetGUID();
156
158 _assassinTrigger = trigger->GetGUID();
159 else
160 {
162 return;
163 }
164 }
165
166 void EnterEvadeMode(EvadeReason /*why*/) override
167 {
170 }
171
172 void UpdateAI(uint32 diff) override
173 {
174 if (!UpdateVictim())
175 return;
176
177 events.Update(diff);
178
180 return;
181
182 while (uint32 eventId = events.ExecuteEvent())
183 {
184 switch (eventId)
185 {
186 case EVENT_CLOSE_DOOR:
188 door->SetGoState(GO_STATE_READY);
190 door2->SetGoState(GO_STATE_READY);
191 break;
192 case EVENT_POUND:
194 events.Repeat(26s, 32s);
195 break;
199 events.Repeat(25s, 28s);
200 break;
203 events.Repeat(24s, 27s);
204 break;
205 case EVENT_IMPALE:
207 DoCast(impaleTarget, SPELL_IMPALE_DAMAGE, true);
208 break;
209 case EVENT_SUBMERGE:
212 break;
213 case EVENT_DARTER:
214 {
215 std::list<Creature*> triggers;
217 if (!triggers.empty())
218 {
220 trigger->CastSpell(trigger, SPELL_SUMMON_DARTER, true);
221
222 events.Repeat(11s);
223 }
224 else
226 break;
227 }
228 case EVENT_ASSASSIN:
230 {
231 trigger->CastSpell(trigger, SPELL_SUMMON_ASSASSIN, true);
232 trigger->CastSpell(trigger, SPELL_SUMMON_ASSASSIN, true);
233 if (_assassinCount > 2)
234 {
235 _assassinCount -= 2;
236 events.Repeat(20s);
237 }
238 else
239 _assassinCount = 0;
240 }
241 else // something went wrong
243 break;
244 case EVENT_GUARDIAN:
246 {
247 trigger->CastSpell(trigger, SPELL_SUMMON_GUARDIAN, true);
248 trigger->CastSpell(trigger, SPELL_SUMMON_GUARDIAN, true);
249 if (_guardianCount > 2)
250 {
251 _guardianCount -= 2;
252 events.Repeat(20s);
253 }
254 else
255 _guardianCount = 0;
256 }
257 else
259 break;
260 case EVENT_VENOMANCER:
262 {
263 trigger->CastSpell(trigger, SPELL_SUMMON_VENOMANCER, true);
264 trigger->CastSpell(trigger, SPELL_SUMMON_VENOMANCER, true);
265 if (_venomancerCount > 2)
266 {
267 _venomancerCount -= 2;
268 events.Repeat(20s);
269 }
270 else
272 }
273 else
275 break;
276 default:
277 break;
278 }
279
281 return;
282 }
283 }
284
285 void JustDied(Unit* /*killer*/) override
286 {
287 _JustDied();
289 }
290
291 void KilledUnit(Unit* victim) override
292 {
293 if (victim->GetTypeId() == TYPEID_PLAYER)
294 Talk(SAY_SLAY);
295 }
296
297 void SetGUID(ObjectGuid const& guid, int32 id) override
298 {
299 switch (id)
300 {
301 case GUID_TYPE_PET:
302 {
303 if (Creature* creature = ObjectAccessor::GetCreature(*me, guid))
304 JustSummoned(creature);
305 else // something has gone horribly wrong
307 break;
308 }
309 case GUID_TYPE_IMPALE:
310 _impaleTarget = guid;
312 break;
313 }
314 }
315
316 void DoAction(int32 action) override
317 {
318 switch (action)
319 {
320 case ACTION_PET_DIED:
321 if (!_petCount) // underflow check - something has gone horribly wrong
322 {
324 return;
325 }
326 if (!--_petCount) // last pet died, emerge
327 {
331 me->SetUninteractible(false);
337 }
338 break;
339 case ACTION_PET_EVADE:
341 break;
342 }
343 }
344
345 void DamageTaken(Unit* /*source*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
346 {
348 damage = 0;
349 else
351 {
354 }
355 }
356
357 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
358 {
359 if (spellInfo->Id == SPELL_SUBMERGE)
360 {
362 me->SetUninteractible(true);
365
367 switch (_nextSubmerge)
368 {
369 case 50: // first submerge phase
370 _assassinCount = 4;
371 _guardianCount = 2;
373 break;
374 case 25: // second submerge phase
375 _assassinCount = 6;
376 _guardianCount = 2;
378 break;
379 case 0: // third submerge phase
380 _assassinCount = 6;
381 _guardianCount = 2;
384 break;
385 }
387 if (_assassinCount)
389 if (_guardianCount)
393 }
394 }
395
396 private:
405};
406
408{
409 public:
410 npc_anubarak_pet_template(Creature* creature, bool isLarge) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _isLarge(isLarge) { }
411
412 void InitializeAI() override
413 {
416 anubarak->AI()->SetGUID(me->GetGUID(), GUID_TYPE_PET);
417 else
419 }
420
421 void JustDied(Unit* killer) override
422 {
423 ScriptedAI::JustDied(killer);
424 if (_isLarge)
426 anubarak->AI()->DoAction(ACTION_PET_DIED);
427 }
428
429 void EnterEvadeMode(EvadeReason /*why*/) override
430 {
432 anubarak->AI()->DoAction(ACTION_PET_EVADE);
433 else
435 }
436
437 protected:
439 private:
440 bool const _isLarge;
441};
442
453
455{
457
458 void InitializeAI() override
459 {
463 {
464 Position jumpTo;
465 uint32 attempts = 0;
466 do
467 jumpTo = anubarak->GetRandomPoint(anubarak->GetPosition(), 30.0f, 10.f);
468 while (!CreatureAI::IsInBounds(*boundary, &jumpTo) && attempts < 10);
469 me->GetMotionMaster()->MoveJump(EVENT_JUMP, jumpTo, 24.0f, 20.0f, 30.0f);
471 }
472 }
473
474 void Reset() override
475 {
477 }
478
479 void JustEngagedWith(Unit* /*who*/) override
480 {
481 _scheduler.Schedule(6s, [this](TaskContext& task)
482 {
483 if (me->GetVictim() && me->GetVictim()->isInBack(me))
485
486 task.Repeat();
487 });
488 }
489
490 void UpdateAI(uint32 diff) override
491 {
492 if (!UpdateVictim())
493 return;
494
495 _scheduler.Update(diff);
496 }
497
498 void MovementInform(uint32 /*type*/, uint32 id) override
499 {
500 if (id == EVENT_JUMP)
501 {
504 }
505 }
506
507private:
509};
510
512{
514
515 void Reset() override
516 {
518 }
519
520 void JustEngagedWith(Unit* /*who*/) override
521 {
522 _scheduler.Schedule(6s, [this](TaskContext& task)
523 {
525 task.Repeat(12s);
526 });
527 }
528
529 void UpdateAI(uint32 diff) override
530 {
531 if (!UpdateVictim())
532 return;
533
534 _scheduler.Update(diff);
535 }
536
537private:
539};
540
542{
544
545 void Reset() override
546 {
548 }
549
550 void JustEngagedWith(Unit* /*who*/) override
551 {
552 _scheduler.Schedule(5s, [this](TaskContext& task)
553 {
555 task.Repeat(2s, 3s);
556 });
557 }
558
559 void UpdateAI(uint32 diff) override
560 {
561 if (!UpdateVictim())
562 return;
563
564 _scheduler.Update(diff);
565 }
566
567private:
569};
570
572{
574
575 void InitializeAI() override
576 {
578 {
581 anubarak->AI()->SetGUID(me->GetGUID(), GUID_TYPE_IMPALE);
582 }
583 else
585 }
586};
587
588// 53472, 59433 - Pound
590{
591 bool Validate(SpellInfo const* /*spell*/) override
592 {
594 }
595
596 void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
597 {
598 if (Unit* target = GetTarget())
599 GetCaster()->CastSpell(target, SPELL_POUND_DAMAGE, true);
600 }
601
606};
607
608// 53520 - Carrion Beetles
627
std::vector< AreaBoundary const * > CreatureBoundary
Definition CreatureAI.h:39
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
@ TEMPSUMMON_MANUAL_DESPAWN
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
Spells
Definition PlayerAI.cpp:32
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
@ EFFECT_0
@ EFFECT_2
@ EVENT_JUMP
@ GO_STATE_READY
@ GO_STATE_ACTIVE
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_FLY
@ SPELL_AURA_PERIODIC_DUMMY
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
EvadeReason
DamageEffectType
@ UNIT_FLAG_NON_ATTACKABLE
@ UNIT_STATE_CASTING
Definition Unit.h:276
Creatures
@ DATA_ANUBARAK
Definition azjol_nerub.h:33
@ DATA_ANUBARAK_WALL_2
Definition azjol_nerub.h:40
@ DATA_ANUBARAK_WALL
Definition azjol_nerub.h:39
#define RegisterAzjolNerubCreatureAI(ai_name)
Definition azjol_nerub.h:75
@ SUMMON_GROUP_WORLD_TRIGGER_GUARDIAN
@ ACTION_PET_DIED
@ ACTION_PET_EVADE
@ NPC_WORLD_TRIGGER
@ ACHIEV_GOTTA_GO_START_EVENT
@ SAY_DEATH
@ SAY_AGGRO
@ SAY_SLAY
@ SAY_SUBMERGE
@ SAY_LOCUST
@ SAY_INTRO
@ SPELL_DART
@ SPELL_LEECHING_SWARM
@ SPELL_SUMMON_GUARDIAN
@ SPELL_EMERGE
@ SPELL_IMPALE_AURA
@ SPELL_SUMMON_ASSASSIN
@ SPELL_BACKSTAB
@ SPELL_POISON_BOLT
@ SPELL_SUMMON_VENOMANCER
@ SPELL_CARRION_BEETLE
@ SPELL_POUND_DAMAGE
@ SPELL_CARRION_BEETLES
@ SPELL_SUNDER_ARMOR
@ SPELL_IMPALE_VISUAL
@ SPELL_ASSASSIN_VISUAL
@ SPELL_SUBMERGE
@ SPELL_POUND
@ SPELL_IMPALE_DAMAGE
@ SPELL_SUMMON_DARTER
@ PHASE_EMERGE
@ PHASE_SUBMERGE
void AddSC_boss_anub_arak()
GUIDTypes
@ GUID_TYPE_PET
@ GUID_TYPE_IMPALE
@ EVENT_CARRION_BEETLES
@ EVENT_ASSASSIN
@ EVENT_DARTER
@ EVENT_GUARDIAN
@ EVENT_CLOSE_DOOR
@ EVENT_VENOMANCER
@ EVENT_SUBMERGE
@ EVENT_IMPALE
@ EVENT_LEECHING_SWARM
@ EVENT_POUND
SummonGroups
Yells
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetCaster() const
Unit * GetTarget() const
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
void JustSummoned(Creature *summon) override
void _DespawnAtEvade(Seconds delayToRespawn=30s, Creature *who=nullptr)
SummonList summons
EventMap events
void Reset() override
void DoZoneInCombat()
Definition CreatureAI.h:169
static bool IsInBounds(CreatureBoundary const &boundary, Position const *who)
virtual void JustDied(Unit *)
Definition CreatureAI.h:107
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
Creature * DoSummon(uint32 entry, Position const &pos, Milliseconds despawnTime=30s, TempSummonType summonType=TEMPSUMMON_CORPSE_TIMED_DESPAWN)
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void Update(uint32 time)
Definition EventMap.h:61
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:40
void SetPhase(uint8 phase)
Definition EventMap.cpp:32
void RescheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:56
Creature * GetCreature(uint32 type)
CreatureBoundary const * GetBossBoundary(uint32 id) const
void TriggerGameEvent(uint32 gameEventId, WorldObject *source=nullptr, WorldObject *target=nullptr) override
GameObject * GetGameObject(uint32 type)
void MoveJump(uint32 id, Position const &pos, std::variant< std::monostate, float, Milliseconds > speedOrTime={}, Optional< float > minHeight={}, Optional< float > maxHeight={}, MovementFacingTarget const &facing={}, bool orientationFixed=false, bool unlimitedSpeed=false, Optional< float > speedMultiplier={}, JumpArrivalCastArgs const *arrivalCast=nullptr, Movement::SpellEffectExtraData const *spellEffectExtraData=nullptr, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
uint32 const Id
Definition SpellInfo.h:328
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & Update()
Update the scheduler to the current time.
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
virtual void InitializeAI()
Definition UnitAI.cpp:43
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:180
virtual ObjectGuid GetGUID(int32 id) const
Definition UnitAI.h:77
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:162
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:89
Definition Unit.h:635
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
void SetUninteractible(bool apply)
Definition Unit.cpp:8564
bool HealthBelowPctDamaged(float pct, uint32 damage) const
Definition Unit.h:793
Unit * GetVictim() const
Definition Unit.h:726
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4804
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:846
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3974
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:847
InstanceScript * GetInstanceScript() const
Definition Object.cpp:396
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:2658
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
bool isInBack(WorldObject const *target, float arc=float(M_PI)) const
Definition Object.cpp:675
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=nullptr)
Definition Object.cpp:1507
void JustDied(Unit *killer) override
npc_anubarak_pet_template(Creature *creature, bool isLarge)
void EnterEvadeMode(EvadeReason) override
bool Validate(SpellInfo const *) override
void HandlePeriodic(AuraEffect const *)
bool Validate(SpellInfo const *) override
void Register() override
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
Definition Containers.h:110
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
void UpdateAI(uint32 diff) override
void SetGUID(ObjectGuid const &guid, int32 id) override
boss_anub_arak(Creature *creature)
void Reset() override
ObjectGuid _assassinTrigger
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void KilledUnit(Unit *victim) override
bool CanAIAttack(Unit const *) const override
void DoAction(int32 action) override
ObjectGuid _impaleTarget
void EnterEvadeMode(EvadeReason) override
ObjectGuid _guardianTrigger
void JustDied(Unit *) override
void JustEngagedWith(Unit *who) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
npc_anubarak_anub_ar_assassin(Creature *creature)
void MovementInform(uint32, uint32 id) override
void JustEngagedWith(Unit *) override
void UpdateAI(uint32 diff) override
npc_anubarak_anub_ar_darter(Creature *creature)
void JustEngagedWith(Unit *) override
void UpdateAI(uint32 diff) override
npc_anubarak_anub_ar_guardian(Creature *creature)
npc_anubarak_anub_ar_venomancer(Creature *creature)
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *) override
npc_anubarak_impale_target(Creature *creature)