fix(Scripts/SunwellPlateau): Fix Felmyst air phase (#21637)

This commit is contained in:
Andrew
2025-03-02 16:07:43 -03:00
committed by GitHub
parent 9e4c74bab1
commit c60b294228
2 changed files with 160 additions and 148 deletions
@@ -0,0 +1,2 @@
--
UPDATE `creature_text` SET `Type` = 41, `BroadcastTextId` = 24548 WHERE `CreatureId` = 25038 AND `GroupId` = 6;
@@ -66,12 +66,14 @@ enum Misc
// Misc // Misc
ACTION_START_EVENT = 1, ACTION_START_EVENT = 1,
POINT_GROUND = 1, POINT_GROUND = 1,
POINT_AIR = 2, POINT_TAKEOFF = 2,
POINT_AIR_BREATH_START1 = 3, POINT_AIR = 3,
POINT_AIR_BREATH_END1 = 4, POINT_AIR_UP = 4,
POINT_AIR_BREATH_START2 = 5, POINT_LANE = 5,
POINT_AIR_BREATH_END2 = 6, POINT_AIR_BREATH_START1 = 6,
POINT_MISC = 7, POINT_AIR_BREATH_END = 7,
POINT_AIR_BREATH_START2 = 8,
POINT_MISC = 9,
POINT_KALECGOS = 1, POINT_KALECGOS = 1,
@@ -79,9 +81,28 @@ enum Misc
GROUP_BREATH = 1, GROUP_BREATH = 1,
NPC_FOG_TRIGGER = 23472, NPC_FOG_TRIGGER = 23472,
NPC_KALECGOS_FELMYST = 24844 // Same as Magister's Terrace NPC_KALECGOS_FELMYST = 24844, // Same as Magister's Terrace
NPC_WORLD_TRIGGER_RIGHT = 25358
}; };
const Position LeftSideLanes[3] =
{
{ 1494.745f, 704.0001f, 50.084652f, 4.7472f }, // top
{ 1469.923f, 703.23914f, 50.08592f, 4.7472f }, // middle
{ 1446.5154f, 701.5184f, 50.085438f, 4.7472f } // bottom
};
const Position RightSideLanes[3] =
{
{ 1492.82f, 515.668f, 50.0833f, 1.4486f }, // top
{ 1466.7322f, 515.5953f, 50.571518f, 1.4486f }, // middle
{ 1441.64f, 520.52f, 50.0833f, 1.4486f } // bottom
};
const Position RightSide = { 1458.5555f, 502.1995f, 59.899513f, 1.605702f };
const Position LeftSide = { 1469.0642f, 729.5854f, 59.823853f, 4.6774f };
const Position LandingPos = { 1476.77f, 665.094f, 20.6423f };
class CorruptTriggers : public BasicEvent class CorruptTriggers : public BasicEvent
{ {
public: public:
@@ -103,7 +124,7 @@ private:
struct boss_felmyst : public BossAI struct boss_felmyst : public BossAI
{ {
boss_felmyst(Creature* creature) : BossAI(creature, DATA_FELMYST) { } boss_felmyst(Creature* creature) : BossAI(creature, DATA_FELMYST), _currentLane(0), _strafeCount(0) { }
void InitializeAI() override void InitializeAI() override
{ {
@@ -127,25 +148,24 @@ struct boss_felmyst : public BossAI
void Reset() override void Reset() override
{ {
BossAI::Reset(); BossAI::Reset();
me->m_Events.KillAllEvents(false);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FOG_OF_CORRUPTION_CHARM); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FOG_OF_CORRUPTION_CHARM);
_currentLane = 0;
_strafeCount = 0;
me->SetCombatMovement(false);
} }
void JustEngagedWith(Unit* who) override void JustEngagedWith(Unit* who) override
{ {
BossAI::JustEngagedWith(who); BossAI::JustEngagedWith(who);
me->m_Events.AddEventAtOffset([&] { ScheduleEnrageTimer(SPELL_BERSERK, 10min, YELL_BERSERK);
Talk(YELL_BERSERK);
DoCastSelf(SPELL_BERSERK, true);
}, 10min);
me->GetMotionMaster()->Clear(); me->GetMotionMaster()->Clear();
Position landPos = who->GetPosition(); Position landPos = who->GetPosition();
me->m_Events.AddEventAtOffset([&, landPos] { me->m_Events.AddEventAtOffset([&, landPos] {
me->GetMotionMaster()->MoveLand(POINT_GROUND, landPos); me->GetMotionMaster()->MoveLand(POINT_GROUND, landPos);
}, 2s); }, 1s);
} }
void KilledUnit(Unit* victim) override void KilledUnit(Unit* victim) override
@@ -166,153 +186,139 @@ struct boss_felmyst : public BossAI
kalec->GetMotionMaster()->MovePoint(POINT_KALECGOS, 1474.2347f, 624.0703f, 29.32589f, false, true); kalec->GetMotionMaster()->MovePoint(POINT_KALECGOS, 1474.2347f, 624.0703f, 29.32589f, false, true);
} }
void ScheduleGroundAbilities()
{
ScheduleTimedEvent(7500ms, [&] {
DoCastVictim(SPELL_CLEAVE);
}, 7500ms);
ScheduleTimedEvent(12s, [&] {
DoCastVictim(SPELL_CORROSION);
}, 20s);
ScheduleTimedEvent(18s, [&] {
Talk(YELL_BREATH);
DoCastSelf(SPELL_GAS_NOVA);
}, 20s);
ScheduleTimedEvent(25s, [&] {
DoCastRandomTarget(SPELL_ENCAPSULATE_CHANNEL, 0, 50.0f);
}, 25s);
me->m_Events.AddEventAtOffset([&] {
Talk(YELL_TAKEOFF);
scheduler.CancelAll();
me->SetReactState(REACT_PASSIVE);
me->SetTarget();
me->AttackStop();
me->SetCombatMovement(false);
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveIdle();
me->SetCanFly(true);
me->SetDisableGravity(true);
me->SendMovementFlagUpdate();
SetInvincibility(true);
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
me->GetMotionMaster()->MovePoint(POINT_TAKEOFF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 20.0f);
}, 1min);
}
void MovementInform(uint32 type, uint32 point) override void MovementInform(uint32 type, uint32 point) override
{ {
if (type != EFFECT_MOTION_TYPE && type != POINT_MOTION_TYPE) if (type != EFFECT_MOTION_TYPE && type != POINT_MOTION_TYPE)
return; return;
if (point == POINT_GROUND) switch (point)
{ {
if (!me->HasAura(SPELL_NOXIOUS_FUMES)) case POINT_GROUND:
DoCastSelf(SPELL_NOXIOUS_FUMES, true);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); if (!me->HasAura(SPELL_NOXIOUS_FUMES))
me->SetCanFly(false); DoCastSelf(SPELL_NOXIOUS_FUMES, true);
me->SetDisableGravity(false);
me->SendMovementFlagUpdate();
SetInvincibility(false);
me->m_Events.AddEventAtOffset([&] { me->GetMotionMaster()->MoveIdle();
me->SetReactState(REACT_AGGRESSIVE); me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->SetCanFly(false);
if (me->GetVictim()) me->SetDisableGravity(false);
me->SetTarget(me->GetVictim()->GetGUID()); me->SendMovementFlagUpdate();
SetInvincibility(false);
me->ResumeChasingVictim();
}, 2s);
ScheduleTimedEvent(7500ms, [&] {
DoCastVictim(SPELL_CLEAVE);
}, 7500ms);
ScheduleTimedEvent(12s, [&] {
DoCastVictim(SPELL_CORROSION);
}, 20s);
ScheduleTimedEvent(18s, [&] {
DoCastSelf(SPELL_GAS_NOVA);
}, 20s);
ScheduleTimedEvent(25s, [&] {
DoCastRandomTarget(SPELL_ENCAPSULATE_CHANNEL, 0, 50.0f);
}, 25s);
me->m_Events.AddEventAtOffset([&] {
scheduler.CancelAll();
me->SetReactState(REACT_PASSIVE);
me->StopMoving();
me->GetMotionMaster()->Clear();
me->m_Events.AddEventAtOffset([&] { me->m_Events.AddEventAtOffset([&] {
ScheduleFlightSequence(); me->SetReactState(REACT_AGGRESSIVE);
}, 1s);
}, 1min); if (me->GetVictim())
} me->SetTarget(me->GetVictim()->GetGUID());
else if (point == POINT_AIR_BREATH_START1)
{ me->ResumeChasingVictim();
me->SetTarget(); me->SetCombatMovement(true);
me->SetFacingTo(4.71f); }, 5s);
ScheduleFlightAbilities(point);
} ScheduleGroundAbilities();
else if (point == POINT_AIR_BREATH_END1) break;
{ case POINT_TAKEOFF:
me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST);
me->SetFacingTo(1.57f);
if (!scheduler.IsGroupScheduled(GROUP_BREATH))
{
me->m_Events.AddEventAtOffset([&] { me->m_Events.AddEventAtOffset([&] {
Position pos = { 1447.0f + urand(0, 2) * 25.0f, 515.0f, 50.0f, 1.57f }; me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true);
me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START2, pos, false, true); }, 5s);
me->m_Events.AddEventAtOffset([&] {
me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true);
}, 17s);
scheduler.Schedule(27s, GROUP_BREATH, [this](TaskContext)
{
me->GetMotionMaster()->MovePoint(POINT_AIR_UP, RightSide);
});
break;
case POINT_AIR_UP:
me->m_Events.AddEventAtOffset([&] {
if (_strafeCount >= 3)
{
_strafeCount = 0;
me->GetMotionMaster()->MoveLand(POINT_GROUND, LandingPos);
return;
}
++_strafeCount;
_currentLane = urand(0, 2);
if (me->FindNearestCreature(NPC_WORLD_TRIGGER_RIGHT, 30.0f))
me->GetMotionMaster()->MovePoint(POINT_LANE, RightSideLanes[_currentLane], false);
else
me->GetMotionMaster()->MovePoint(POINT_LANE, LeftSideLanes[_currentLane], false);
}, 2s); }, 2s);
} break;
case POINT_LANE:
Talk(EMOTE_BREATH);
me->m_Events.AddEventAtOffset([&] {
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(0));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(500));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1000));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1500));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2000));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2500));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3000));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3500));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(4000));
}, 5s);
me->m_Events.AddEventAtOffset([&] {
DoCastSelf(SPELL_FELMYST_SPEED_BURST, true);
if (me->FindNearestCreature(NPC_WORLD_TRIGGER_RIGHT, 30.0f))
me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END, LeftSideLanes[_currentLane], false);
else
me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END, RightSideLanes[_currentLane], false);
}, 5s);
break;
case POINT_AIR_BREATH_END:
me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST);
me->m_Events.AddEventAtOffset([&] {
if (me->FindNearestCreature(NPC_WORLD_TRIGGER_RIGHT, 30.0f))
me->GetMotionMaster()->MovePoint(POINT_AIR_UP, RightSide, false);
else
me->GetMotionMaster()->MovePoint(POINT_AIR_UP, LeftSide, false);
}, 2s);
break;
} }
else if (point == POINT_AIR_BREATH_START2)
{
me->SetTarget();
me->SetFacingTo(1.57f);
ScheduleFlightAbilities(point);
}
else if (point == POINT_AIR_BREATH_END2)
{
me->RemoveAurasDueToSpell(SPELL_FELMYST_SPEED_BURST);
me->SetFacingTo(4.71f);
}
}
void ScheduleFlightSequence()
{
Talk(YELL_TAKEOFF);
me->SetTarget();
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
me->SetDisableGravity(true);
me->SendMovementFlagUpdate();
SetInvincibility(true);
me->m_Events.AddEventAtOffset([&] {
me->GetMotionMaster()->MovePoint(POINT_AIR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 15.0f, false, true);
}, 2s);
me->m_Events.AddEventAtOffset([&] {
me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true);
}, 8s);
me->m_Events.AddEventAtOffset([&] {
me->CastCustomSpell(SPELL_SUMMON_DEMONIC_VAPOR, SPELLVALUE_MAX_TARGETS, 1, me, true);
}, 21s);
scheduler.Schedule(35s, GROUP_BREATH, [this](TaskContext)
{
Position pos = { 1447.0f + urand(0, 2) * 25.0f, 705.0f, 50.0f, 4.71f };
me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START1, pos, false, true);
});
scheduler.Schedule(72s, GROUP_BREATH, [this](TaskContext)
{
Position pos = { 1447.0f + urand(0, 2) * 25.0f, 705.0f, 50.0f, 4.71f };
me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_START1, pos, false, true);
});
me->m_Events.AddEventAtOffset([&] {
me->GetMotionMaster()->MovePoint(POINT_GROUND, 1500.0f, 552.8f, 26.52f, false, true);
}, 86s);
}
void ScheduleFlightAbilities(uint8 point)
{
me->m_Events.AddEventAtOffset([&] {
Talk(EMOTE_BREATH);
}, 2s);
me->m_Events.AddEventAtOffset([&] {
Talk(YELL_BREATH);
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(0));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(500));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1000));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1500));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2000));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2500));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3000));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3500));
me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(4000));
}, 5s);
me->m_Events.AddEventAtOffset([this, point] {
DoCastSelf(SPELL_FELMYST_SPEED_BURST, true);
if (point == POINT_AIR_BREATH_START1)
me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END1, me->GetPositionX(), me->GetPositionY() - 200.0f, me->GetPositionZ() + 5.0f, false, true);
else if (point == POINT_AIR_BREATH_START2)
me->GetMotionMaster()->MovePoint(POINT_AIR_BREATH_END2, me->GetPositionX(), me->GetPositionY() + 200.0f, me->GetPositionZ() + 5.0f, false, true);
}, 5s);
} }
void StartIntro() void StartIntro()
@@ -346,6 +352,10 @@ struct boss_felmyst : public BossAI
if (!me->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) if (!me->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY))
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
private:
uint8 _currentLane = 0;
uint8 _strafeCount = 0;
}; };
struct npc_demonic_vapor : public NullCreatureAI struct npc_demonic_vapor : public NullCreatureAI