fix(Core/TempleOfAhnQiraj): Bug trio (#13141)

This commit is contained in:
Angelo Venturini
2022-09-29 19:02:59 -03:00
committed by GitHub
parent ed68d1bffa
commit fc9bf2665d
2 changed files with 99 additions and 98 deletions
@@ -50,6 +50,7 @@ enum Spells
enum Misc enum Misc
{ {
ACTION_CONSUME = 0, ACTION_CONSUME = 0,
ACTION_EXPLODE = 1,
EMOTE_DEVOURED = 0, EMOTE_DEVOURED = 0,
@@ -78,20 +79,20 @@ public:
void EnterCombatWithTrio(Unit* who) void EnterCombatWithTrio(Unit* who)
{ {
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM))) if (Creature* vem = instance->GetCreature(DATA_VEM))
if (vem->GetGUID() != me->GetGUID()) if (vem->GetGUID() != me->GetGUID())
vem->GetAI()->AttackStart(who); vem->GetAI()->AttackStart(who);
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI))) if (Creature* kri = instance->GetCreature(DATA_KRI))
if (kri->GetGUID() != me->GetGUID()) if (kri->GetGUID() != me->GetGUID())
kri->GetAI()->AttackStart(who); kri->GetAI()->AttackStart(who);
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ))) if (Creature* yauj = instance->GetCreature(DATA_YAUJ))
if (yauj->GetGUID() != me->GetGUID()) if (yauj->GetGUID() != me->GetGUID())
yauj->GetAI()->AttackStart(who); yauj->GetAI()->AttackStart(who);
} }
void EvadeAllBosses(EvadeReason why) void EvadeAllBosses(EvadeReason why)
{ {
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM))) if (Creature* vem = instance->GetCreature(DATA_VEM))
{ {
if (vem->GetGUID() != me->GetGUID()) if (vem->GetGUID() != me->GetGUID())
{ {
@@ -102,7 +103,7 @@ public:
} }
} }
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI))) if (Creature* kri = instance->GetCreature(DATA_KRI))
{ {
if (kri->GetGUID() != me->GetGUID()) if (kri->GetGUID() != me->GetGUID())
{ {
@@ -113,7 +114,7 @@ public:
} }
} }
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ))) if (Creature* yauj = instance->GetCreature(DATA_YAUJ))
{ {
if (yauj->GetGUID() != me->GetGUID()) if (yauj->GetGUID() != me->GetGUID())
{ {
@@ -127,14 +128,19 @@ public:
void DoAction(int32 action) override void DoAction(int32 action) override
{ {
if (action != ACTION_CONSUME || dying) if (action == ACTION_CONSUME && !_dying)
{ {
return; _isEating = true;
me->SetSpeed(MOVE_RUN, 45.f / 7.f); // From sniffs
me->SetReactState(REACT_PASSIVE);
_scheduler.DelayAll(6s);
} }
isEating = true; if (action == ACTION_EXPLODE && _dying)
me->SetSpeed(MOVE_RUN, 45.f/7.f); // From sniffs {
me->SetReactState(REACT_PASSIVE); DoCastSelf(SPELL_BLOODY_DEATH);
_dying = false;
}
} }
void MovementInform(uint32 type, uint32 id) override void MovementInform(uint32 type, uint32 id) override
@@ -145,12 +151,18 @@ public:
me->GetMotionMaster()->MoveIdle(); me->GetMotionMaster()->MoveIdle();
me->SetSpeed(MOVE_RUN, 15.f/7.f); // From sniffs me->SetSpeed(MOVE_RUN, 15.f/7.f); // From sniffs
DoCastSelf(SPELL_FULL_HEAL, true); DoCastSelf(SPELL_FULL_HEAL, true);
DoResetThreat(); if (me->GetThreatMgr().GetThreatListSize())
isEating = false; DoResetThreat();
if (Creature* dying = instance->GetCreature(_creatureDying))
{
dying->AI()->DoAction(ACTION_EXPLODE);
me->SetTarget(dying->GetGUID());
}
_scheduler.Schedule(4s, [this](TaskContext /*context*/) _scheduler.Schedule(2s, [this](TaskContext /*context*/)
{ {
me->SetReactState(REACT_AGGRESSIVE); me->SetReactState(REACT_AGGRESSIVE);
_isEating = false;
if (Unit* target = me->GetVictim()) if (Unit* target = me->GetVictim())
{ {
me->GetMotionMaster()->Clear(); me->GetMotionMaster()->Clear();
@@ -170,12 +182,11 @@ public:
{ {
BossAI::Reset(); BossAI::Reset();
_scheduler.CancelAll(); _scheduler.CancelAll();
dying = false; _dying = false;
isEating = false; _isEating = false;
_creatureDying = 0;
instance->SetData(DATA_BUG_TRIO_DEATH, 0); instance->SetData(DATA_BUG_TRIO_DEATH, 0);
me->SetSpeed(MOVE_RUN, 15.f / 7.f); // From sniffs me->SetSpeed(MOVE_RUN, 15.f / 7.f); // From sniffs
me->SetStandState(UNIT_STAND_STATE_STAND);
me->SetControlled(false, UNIT_STATE_ROOT);
if (me->GetEntry() == NPC_VEM) if (me->GetEntry() == NPC_VEM)
{ {
@@ -185,66 +196,71 @@ public:
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
if (!UpdateVictim() || isEating || !CheckInRoom()) if (!UpdateVictim() || !CheckInRoom())
return; return;
_scheduler.Update(diff, [this] _scheduler.Update(diff, [this]
{ {
DoMeleeAttackIfReady(); if (!_dying && !_isEating)
DoMeleeAttackIfReady();
}); });
} }
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
{ {
if (me->HealthBelowPctDamaged(1, damage) && instance->GetData(DATA_BUG_TRIO_DEATH) < 2 && who->GetGUID() != me->GetGUID() && !dying) if (_dying && who->GetGUID() != me->GetGUID())
damage = 0;
if (me->HealthBelowPctDamaged(0, damage) && instance->GetData(DATA_BUG_TRIO_DEATH) < 2 && !_dying)
{ {
damage = 0; damage = 0;
if (isEating) if (_isEating)
return; return;
_scheduler.CancelAll(); _scheduler.CancelAll();
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetReactState(REACT_PASSIVE); me->SetReactState(REACT_PASSIVE);
me->SetControlled(true, UNIT_STATE_ROOT); _dying = true;
dying = true; float x, y, z;
DoFinalSpell();
// Move the other bugs to this bug position // Move the other bugs to this bug position
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM))) if (Creature* vem = instance->GetCreature(DATA_VEM))
{ {
if (vem->GetGUID() != me->GetGUID()) if (vem->GetGUID() != me->GetGUID())
{ {
vem->AI()->DoAction(ACTION_CONSUME); if (vem->IsAlive())
vem->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); {
vem->AI()->DoAction(ACTION_CONSUME);
me->GetRandomContactPoint(vem, x, y, z);
vem->GetMotionMaster()->MovePoint(POINT_CONSUME, x, y, z);
}
} }
else _creatureDying = DATA_VEM;
} }
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI))) if (Creature* kri = instance->GetCreature(DATA_KRI))
{ {
if (kri->GetGUID() != me->GetGUID()) if (kri->GetGUID() != me->GetGUID())
{ {
kri->AI()->DoAction(ACTION_CONSUME); if (kri->IsAlive())
kri->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); {
kri->AI()->DoAction(ACTION_CONSUME);
me->GetRandomContactPoint(kri, x, y, z);
kri->GetMotionMaster()->MovePoint(POINT_CONSUME, x, y, z);
}
} }
else _creatureDying = DATA_KRI;
} }
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ))) if (Creature* yauj = instance->GetCreature(DATA_YAUJ))
{ {
if (yauj->GetGUID() != me->GetGUID()) if (yauj->GetGUID() != me->GetGUID())
{ {
yauj->AI()->DoAction(ACTION_CONSUME); if (yauj->IsAlive())
yauj->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); {
yauj->AI()->DoAction(ACTION_CONSUME);
me->GetRandomContactPoint(yauj, x, y, z);
yauj->GetMotionMaster()->MovePoint(POINT_CONSUME, x, y, z);
}
} }
else _creatureDying = DATA_YAUJ;
} }
_scheduler.Schedule(4s, [this](TaskContext /*context*/)
{
if (!me->IsInEvadeMode() && instance->GetData(DATA_BUG_TRIO_DEATH) < 2)
{
DoCastSelf(SPELL_BLOODY_DEATH, true);
Talk(EMOTE_DEVOURED);
me->DespawnOrUnsummon(1000);
}
});
} }
} }
@@ -274,10 +290,13 @@ public:
void JustDied(Unit* killer) override void JustDied(Unit* killer) override
{ {
if (killer->GetGUID() == me->GetGUID()) instance->SetData(DATA_BUG_TRIO_DEATH, 1);
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 3)
{ {
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE); me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
DoFinalSpell();
Talk(EMOTE_DEVOURED);
me->DespawnOrUnsummon(3000);
return; return;
} }
@@ -285,10 +304,13 @@ public:
} }
TaskScheduler _scheduler; TaskScheduler _scheduler;
bool dying; bool _dying;
bool isEating; bool _isEating;
static uint32 _creatureDying;
}; };
uint32 boss_bug_trio::_creatureDying = 0;
struct boss_kri : public boss_bug_trio struct boss_kri : public boss_bug_trio
{ {
boss_kri(Creature* creature) : boss_bug_trio(creature) boss_kri(Creature* creature) : boss_bug_trio(creature)
@@ -299,20 +321,20 @@ struct boss_kri : public boss_bug_trio
{ {
EnterCombatWithTrio(who); EnterCombatWithTrio(who);
_scheduler.Schedule(4s, 8s, [this](TaskContext context) _scheduler.Schedule(7s, 18s, [this](TaskContext context)
{ {
DoCastVictim(SPELL_CLEAVE); DoCastVictim(SPELL_CLEAVE);
context.Repeat(5s, 12s); context.Repeat();
}) })
.Schedule(6s, 30s, [this](TaskContext context) .Schedule(8s, 17s, [this](TaskContext context)
{ {
DoCastVictim(SPELL_TOXIC_VOLLEY); DoCastVictim(SPELL_TOXIC_VOLLEY);
context.Repeat(10s, 25s); context.Repeat();
}) })
.Schedule(6s, [this](TaskContext context) .Schedule(7s, 16s, [this](TaskContext context)
{ {
DoCastVictim(SPELL_THRASH); DoCastVictim(SPELL_THRASH);
context.Repeat(2s, 6s); context.Repeat();
}); });
} }
}; };
@@ -343,25 +365,17 @@ struct boss_vem : public boss_bug_trio
{ {
DoCast(target, SPELL_CHARGE); DoCast(target, SPELL_CHARGE);
} }
context.Repeat(8s, 16s); context.Repeat();
}) })
.Schedule(10s, 20s, [this](TaskContext context) .Schedule(10s, 24s, [this](TaskContext context)
{ {
DoCastVictim(SPELL_KNOCKBACK); DoCastVictim(SPELL_KNOCKBACK);
context.Repeat(10s, 20s); context.Repeat();
}) })
.Schedule(5s, 8s, [this](TaskContext context) .Schedule(10s, 23s, [this](TaskContext context)
{ {
DoCastVictim(SPELL_KNOCKDOWN); DoCastVictim(SPELL_KNOCKDOWN);
context.Repeat(15s, 20s); context.Repeat();
})
.Schedule(1s, [this](TaskContext context)
{
if (instance->GetData(DATA_BUG_TRIO_DEATH) == 2 && !me->HasAura(SPELL_VENGEANCE)) // Vem is the only one left.
{
DoCastSelf(SPELL_VENGEANCE, true);
}
context.Repeat(1s);
}); });
} }
}; };
@@ -376,7 +390,7 @@ struct boss_yauj : public boss_bug_trio
{ {
EnterCombatWithTrio(who); EnterCombatWithTrio(who);
_scheduler.Schedule(20s, 30s, [this](TaskContext context) _scheduler.Schedule(12100ms, [this](TaskContext context)
{ {
if (me->GetHealthPct() <= 93.f) if (me->GetHealthPct() <= 93.f)
{ {
@@ -386,18 +400,20 @@ struct boss_yauj : public boss_bug_trio
{ {
DoCast(friendly, SPELL_HEAL); DoCast(friendly, SPELL_HEAL);
} }
context.Repeat(10s, 30s); context.Repeat();
})
.Schedule(12s, 24s, [this](TaskContext context)
{
DoCastAOE(SPELL_FEAR);
DoResetThreat();
context.Repeat(20s);
}) })
.Schedule(12s, [this](TaskContext context) .Schedule(12s, [this](TaskContext context)
{ {
DoCastVictim(SPELL_RAVAGE); DoCastAOE(SPELL_FEAR);
context.Repeat(10s, 15s); DoResetThreat();
context.Repeat(20600ms);
})
.Schedule(11s, 14500ms, [this](TaskContext context)
{
if (DoCastVictim(SPELL_RAVAGE) == SPELL_CAST_OK)
context.Repeat(10s, 15s);
else
context.Repeat(1200ms);
}) })
.Schedule(10s, 30s, [this](TaskContext context) .Schedule(10s, 30s, [this](TaskContext context)
{ {
@@ -24,6 +24,9 @@
ObjectData const creatureData[] = ObjectData const creatureData[] =
{ {
{ NPC_VEM, DATA_VEM },
{ NPC_KRI, DATA_KRI },
{ NPC_YAUJ, DATA_YAUJ },
{ NPC_SARTURA, DATA_SARTURA }, { NPC_SARTURA, DATA_SARTURA },
{ NPC_CTHUN, DATA_CTHUN }, { NPC_CTHUN, DATA_CTHUN },
{ NPC_EYE_OF_CTHUN, DATA_EYE_OF_CTHUN }, { NPC_EYE_OF_CTHUN, DATA_EYE_OF_CTHUN },
@@ -62,9 +65,6 @@ public:
} }
ObjectGuid SkeramGUID; ObjectGuid SkeramGUID;
ObjectGuid VemGUID;
ObjectGuid KriGUID;
ObjectGuid YaujGUID;
ObjectGuid CThunGUID; ObjectGuid CThunGUID;
GuidVector CThunGraspGUIDs; GuidVector CThunGraspGUIDs;
@@ -86,15 +86,6 @@ public:
case NPC_SKERAM: case NPC_SKERAM:
SkeramGUID = creature->GetGUID(); SkeramGUID = creature->GetGUID();
break; break;
case NPC_VEM:
VemGUID = creature->GetGUID();
break;
case NPC_KRI:
KriGUID = creature->GetGUID();
break;
case NPC_YAUJ:
YaujGUID = creature->GetGUID();
break;
case NPC_OURO_SPAWNER: case NPC_OURO_SPAWNER:
if (GetBossState(DATA_OURO) != DONE) if (GetBossState(DATA_OURO) != DONE)
creature->Respawn(); creature->Respawn();
@@ -194,12 +185,6 @@ public:
{ {
case DATA_SKERAM: case DATA_SKERAM:
return SkeramGUID; return SkeramGUID;
case DATA_VEM:
return VemGUID;
case DATA_KRI:
return KriGUID;
case DATA_YAUJ:
return YaujGUID;
} }
return ObjectGuid::Empty; return ObjectGuid::Empty;
} }