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
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
285 }
286
287 void JustDied(Unit* /*killer*/) override
288 {
289 _JustDied();
291 }
292
293 void KilledUnit(Unit* victim) override
294 {
295 if (victim->GetTypeId() == TYPEID_PLAYER)
296 Talk(SAY_SLAY);
297 }
298
299 void SetGUID(ObjectGuid const& guid, int32 id) override
300 {
301 switch (id)
302 {
303 case GUID_TYPE_PET:
304 {
305 if (Creature* creature = ObjectAccessor::GetCreature(*me, guid))
306 JustSummoned(creature);
307 else // something has gone horribly wrong
309 break;
310 }
311 case GUID_TYPE_IMPALE:
312 _impaleTarget = guid;
314 break;
315 }
316 }
317
318 void DoAction(int32 action) override
319 {
320 switch (action)
321 {
322 case ACTION_PET_DIED:
323 if (!_petCount) // underflow check - something has gone horribly wrong
324 {
326 return;
327 }
328 if (!--_petCount) // last pet died, emerge
329 {
338 }
339 break;
340 case ACTION_PET_EVADE:
342 break;
343 }
344 }
345
346 void DamageTaken(Unit* /*source*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
347 {
349 damage = 0;
350 else
352 {
355 }
356 }
357
358 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
359 {
360 if (spellInfo->Id == SPELL_SUBMERGE)
361 {
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
459 {
460 static float DISTANCE_MIN = 10.0f;
461 static float DISTANCE_MAX = 30.0f;
462 double angle = rand_norm() * 2.0 * M_PI;
463 return { anubarak->GetPositionX() + (float)(frand(DISTANCE_MIN, DISTANCE_MAX)*std::sin(angle)), anubarak->GetPositionY() + (float)(frand(DISTANCE_MIN, DISTANCE_MAX)*std::cos(angle)), anubarak->GetPositionZ() };
464 }
465
466 void InitializeAI() override
467 {
471 {
472 Position jumpTo;
473 do
474 jumpTo = GetRandomPositionAround(anubarak);
475 while (!CreatureAI::IsInBounds(*boundary, &jumpTo));
476 me->GetMotionMaster()->MoveJump(jumpTo, 40.0f, 40.0f);
478 }
479 }
480
481 void Reset() override
482 {
484 }
485
486 void JustEngagedWith(Unit* /*who*/) override
487 {
488 _scheduler.Schedule(6s, [this](TaskContext task)
489 {
490 if (me->GetVictim() && me->GetVictim()->isInBack(me))
492
493 task.Repeat();
494 });
495 }
496
497 void UpdateAI(uint32 diff) override
498 {
499 if (!UpdateVictim())
500 return;
501
502 _scheduler.Update(diff, [this]
503 {
505 });
506 }
507
508 void MovementInform(uint32 /*type*/, uint32 id) override
509 {
510 if (id == EVENT_JUMP)
511 {
514 }
515 }
516
517private:
519};
520
522{
524
525 void Reset() override
526 {
528 }
529
530 void JustEngagedWith(Unit* /*who*/) override
531 {
532 _scheduler.Schedule(6s, [this](TaskContext task)
533 {
535 task.Repeat(12s);
536 });
537 }
538
539 void UpdateAI(uint32 diff) override
540 {
541 if (!UpdateVictim())
542 return;
543
544 _scheduler.Update(diff, [this]
545 {
547 });
548 }
549
550private:
552};
553
555{
557
558 void Reset() override
559 {
561 }
562
563 void JustEngagedWith(Unit* /*who*/) override
564 {
565 _scheduler.Schedule(5s, [this](TaskContext task)
566 {
568 task.Repeat(2s, 3s);
569 });
570 }
571
572 void UpdateAI(uint32 diff) override
573 {
574 if (!UpdateVictim())
575 return;
576
577 _scheduler.Update(diff, [this]
578 {
580 });
581 }
582
583private:
585};
586
588{
590
591 void InitializeAI() override
592 {
594 {
597 anubarak->AI()->SetGUID(me->GetGUID(), GUID_TYPE_IMPALE);
598 }
599 else
601 }
602};
603
604// 53472, 59433 - Pound
606{
608
609 bool Validate(SpellInfo const* /*spell*/) override
610 {
612 }
613
614 void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
615 {
616 if (Unit* target = GetTarget())
617 GetCaster()->CastSpell(target, SPELL_POUND_DAMAGE, true);
618 }
619
624};
625
626// 53520 - Carrion Beetles
647
Actions
#define M_PI
Definition Common.h:72
std::vector< AreaBoundary const * > CreatureBoundary
Definition CreatureAI.h:36
@ ACHIEVEMENT_TIMED_TYPE_EVENT
Definition DBCEnums.h:122
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ TEMPSUMMON_MANUAL_DESPAWN
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
Spells
Definition PlayerAI.cpp:32
float frand(float min, float max)
Definition Random.cpp:55
double rand_norm()
Definition Random.cpp:75
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
@ 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)
@ UNIT_FLAG_NON_ATTACKABLE
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
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
SummonGroups
@ 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
Yells
HookList< EffectPeriodicHandler > OnEffectPeriodic
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetCaster() const
Unit * GetTarget() const
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
static bool IsInBounds(CreatureBoundary const &boundary, Position const *who)
@ EVADE_REASON_OTHER
Definition CreatureAI.h:98
virtual void JustDied(Unit *)
Definition CreatureAI.h:130
void DoZoneInCombat(Creature *creature=nullptr)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
Creature * DoSummon(uint32 entry, Position const &pos, Milliseconds despawnTime=30s, TempSummonType summonType=TEMPSUMMON_CORPSE_TIMED_DESPAWN)
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void Update(uint32 time)
Definition EventMap.h:67
void Repeat(Milliseconds time)
Definition EventMap.cpp:63
EventId ExecuteEvent()
Definition EventMap.cpp:73
void RescheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:52
void SetPhase(PhaseIndex phase)
Definition EventMap.cpp:28
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
Creature * GetCreature(uint32 type)
CreatureBoundary const * GetBossBoundary(uint32 id) const
void DoStartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
GameObject * GetGameObject(uint32 type)
void DoStopTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=EVENT_JUMP, bool hasOrientation=false)
TypeID GetTypeId() const
Definition Object.h:93
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 Id
Definition SpellInfo.h:289
TaskContext & Repeat(std::chrono::duration< _Rep, _Period > const &duration)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
TaskScheduler & Update(success_t const &callback=EmptyCallback)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
virtual void InitializeAI()
Definition UnitAI.cpp:36
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
virtual ObjectGuid GetGUID(int32=0) const
Definition UnitAI.h:158
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition Unit.h:918
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:3153
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
bool isInBack(WorldObject const *target, float arc=float(M_PI)) const
Definition Object.cpp:1371
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=nullptr)
Definition Object.cpp:2082
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
void JustDied(Unit *killer) override
npc_anubarak_pet_template(Creature *creature, bool isLarge)
void EnterEvadeMode(EvadeReason) override
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_anubarak_carrion_beetles)
void HandlePeriodic(AuraEffect const *)
PrepareAuraScript(spell_anubarak_pound)
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) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition Containers.h:108
float GetPositionZ() const
Definition Position.h:81
float GetPositionX() const
Definition Position.h:79
void GetPosition(float &x, float &y) const
Definition Position.h:84
float GetPositionY() const
Definition Position.h:80
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
Position GetRandomPositionAround(Creature *anubarak)
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)