mirror of
https://gitcode.com/GitHub_Trending/az/azerothcore-wotlk.git
synced 2026-10-10 07:06:38 +08:00
fix(Scripts/MagtheridonsLair): anchor the release countdown to the Channeler pull (#27600)
Co-authored-by: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -72,22 +72,25 @@ enum Groups
|
||||
|
||||
struct boss_magtheridon : public BossAI
|
||||
{
|
||||
boss_magtheridon(Creature* creature) : BossAI(creature, DATA_MAGTHERIDON)
|
||||
boss_magtheridon(Creature* creature) : BossAI(creature, DATA_MAGTHERIDON),
|
||||
_castingQuake(false), _magReleased(false), _currentPhase(0)
|
||||
{ }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
// State first: BossAI::Reset() calls back into this AI through the instance.
|
||||
_currentPhase = 0;
|
||||
_castingQuake = false;
|
||||
_magReleased = false;
|
||||
|
||||
BossAI::Reset();
|
||||
_interruptScheduler.CancelAll();
|
||||
scheduler.Schedule(90s, [this](TaskContext context)
|
||||
{
|
||||
if (!me->IsEngaged())
|
||||
{
|
||||
// Engaged from the Channeler pull, so key the idle taunt on the release, not on combat.
|
||||
if (!_magReleased)
|
||||
Talk(SAY_TAUNT);
|
||||
}
|
||||
|
||||
context.Repeat(90s);
|
||||
});
|
||||
DoCastSelf(SPELL_SHADOW_CAGE, true);
|
||||
@@ -166,6 +169,7 @@ struct boss_magtheridon : public BossAI
|
||||
context.Repeat(56300ms, 64300ms);
|
||||
}).Schedule(55650ms, [this](TaskContext context)
|
||||
{
|
||||
Talk(SAY_EMOTE_NOVA);
|
||||
DoCastSelf(SPELL_BLAST_NOVA);
|
||||
scheduler.DelayAll(10s);
|
||||
context.Repeat(54350ms, 55400ms);
|
||||
@@ -175,27 +179,31 @@ struct boss_magtheridon : public BossAI
|
||||
});
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
// Both release paths land here: the 2 minute timer and the last Channeler dying.
|
||||
void ReleaseMagtheridon()
|
||||
{
|
||||
if (action == ACTION_RELEASE_MAGTHERIDON)
|
||||
{
|
||||
if (_magReleased)
|
||||
return;
|
||||
if (_magReleased)
|
||||
return;
|
||||
|
||||
Talk(SAY_EMOTE_FREE);
|
||||
Talk(SAY_FREE);
|
||||
scheduler.CancelGroup(GROUP_EARLY_RELEASE_CHECK); //cancel regular countdown
|
||||
_magReleased = true;
|
||||
scheduler.Schedule(3s, [this](TaskContext)
|
||||
{
|
||||
ScheduleCombatEvents();
|
||||
});
|
||||
}
|
||||
else if (action == ACTION_BANISH_SELF)
|
||||
_magReleased = true;
|
||||
Talk(SAY_EMOTE_FREE);
|
||||
Talk(SAY_FREE);
|
||||
scheduler.Schedule(3s, [this](TaskContext /*context*/)
|
||||
{
|
||||
Talk(SAY_BANISH);
|
||||
me->CastSpell(me, SPELL_SHADOW_CAGE_STUN, true);
|
||||
}
|
||||
ScheduleCombatEvents();
|
||||
});
|
||||
}
|
||||
|
||||
// Caged, he keeps UNIT_FLAG_IMMUNE_TO_PC, so every threat reference from the instance's
|
||||
// SetInCombatWithZone() lands offline (ThreatReference::ShouldBeOffline) and the threat manager
|
||||
// never engages him. Engage off the combat reference itself, so the encounter anchors to the
|
||||
// Channeler pull and not to his release.
|
||||
void JustEnteredCombat(Unit* who) override
|
||||
{
|
||||
if (IsEngaged())
|
||||
return;
|
||||
|
||||
EngagementStart(who);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
@@ -208,15 +216,67 @@ struct boss_magtheridon : public BossAI
|
||||
Talk(SAY_EMOTE_NEARLY);
|
||||
}).Schedule(120s, GROUP_EARLY_RELEASE_CHECK, [this](TaskContext /*context*/)
|
||||
{
|
||||
Talk(SAY_EMOTE_FREE);
|
||||
Talk(SAY_FREE);
|
||||
_magReleased = true;
|
||||
}).Schedule(123s, GROUP_EARLY_RELEASE_CHECK, [this](TaskContext /*context*/)
|
||||
{
|
||||
ScheduleCombatEvents();
|
||||
ReleaseMagtheridon();
|
||||
});
|
||||
}
|
||||
|
||||
// Caged, he is engaged but never fights, so a wipe gets here through his own UpdateVictim() or
|
||||
// through the instance, whichever creature updates first. BossAI's evade would trip
|
||||
// CREATURE_FLAG_EXTRA_HARD_RESET and despawn him for 20s in front of the raid. Reset in place
|
||||
// instead. Released, the normal boss evade applies.
|
||||
void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER) override
|
||||
{
|
||||
if (_magReleased)
|
||||
{
|
||||
BossAI::EnterEvadeMode(why);
|
||||
return;
|
||||
}
|
||||
|
||||
// Also covers the re-entry from Reset() via instance->SetBossState(NOT_STARTED):
|
||||
// EngagementOver() already ran.
|
||||
if (!IsEngaged())
|
||||
return;
|
||||
|
||||
me->CombatStop(true);
|
||||
// BossAI::_Reset() bails while engaged, so end the engagement first. Reset() then drops the
|
||||
// countdown through scheduler.CancelAll().
|
||||
EngagementOver();
|
||||
// He never walks home, so clear what BossAI::_JustReachedHome() would have.
|
||||
me->setActive(false);
|
||||
Reset();
|
||||
}
|
||||
|
||||
// Read by the instance: IsImmuneToPC() lags the release by the 3s until ScheduleCombatEvents().
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
return type == DATA_MAGTHERIDON_RELEASED ? uint32(_magReleased) : 0;
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_RELEASE_MAGTHERIDON:
|
||||
// Channelers died before the timer ran out. Drop the rest of it, or the 60s task
|
||||
// still calls him nearly free after he is free.
|
||||
scheduler.CancelGroup(GROUP_EARLY_RELEASE_CHECK);
|
||||
ReleaseMagtheridon();
|
||||
break;
|
||||
case ACTION_BANISH_SELF:
|
||||
Talk(SAY_BANISH);
|
||||
DoCastSelf(SPELL_SHADOW_CAGE_STUN, true);
|
||||
break;
|
||||
case ACTION_RESET_ENCOUNTER:
|
||||
// Wipe signal from the instance. UpdateVictim() catches most wipes on its own, but
|
||||
// not a survivor outside the room still holding him in combat. Freed, he fights on.
|
||||
if (!_magReleased)
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
scheduler.Update(diff);
|
||||
|
||||
+18
-4
@@ -106,9 +106,17 @@ public:
|
||||
|
||||
void OnCreatureEvade(Creature* creature) override
|
||||
{
|
||||
// Phase-1 wipe signal: Mag is ImmuneToPC so BossAI evade does not fire; a Channeler evade is the trigger.
|
||||
if (creature->GetEntry() == NPC_HELLFIRE_CHANNELER && GetBossState(DATA_MAGTHERIDON) == IN_PROGRESS)
|
||||
SetBossState(DATA_MAGTHERIDON, NOT_STARTED);
|
||||
if (creature->GetEntry() != NPC_HELLFIRE_CHANNELER || GetBossState(DATA_MAGTHERIDON) != IN_PROGRESS)
|
||||
return;
|
||||
|
||||
// Only a Channeler-phase wipe resets the encounter. Past the 2 minute auto-release he is
|
||||
// loose with Channelers still up, and a reset there would disable the Manticron Cubes and
|
||||
// open the door mid-fight.
|
||||
if (Creature* magtheridon = instance->GetCreature(_magtheridonGUID))
|
||||
if (magtheridon->AI()->GetData(DATA_MAGTHERIDON_RELEASED))
|
||||
return;
|
||||
|
||||
SetBossState(DATA_MAGTHERIDON, NOT_STARTED);
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
@@ -191,6 +199,10 @@ public:
|
||||
for (ObjectGuid const& guid : _burningAbyssalsSet)
|
||||
if (Creature* abyssal = instance->GetCreature(guid))
|
||||
abyssal->DespawnOrUnsummon();
|
||||
|
||||
// Reset a still-caged Magtheridon: he is engaged from the Channeler pull on.
|
||||
if (Creature* magtheridon = instance->GetCreature(_magtheridonGUID))
|
||||
magtheridon->AI()->DoAction(ACTION_RESET_ENCOUNTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,7 +214,9 @@ public:
|
||||
switch (type)
|
||||
{
|
||||
case DATA_CHANNELER_COMBAT:
|
||||
// Force the encounter start: Mag is ImmuneToPC so SetInCombatWithZone alone may miss JustEngagedWith.
|
||||
// Start the encounter on the Channeler pull. The combat references this creates
|
||||
// engage Magtheridon (boss_magtheridon::JustEnteredCombat), which anchors his
|
||||
// release countdown here and not to when players can first hit him.
|
||||
if (GetBossState(DATA_MAGTHERIDON) != IN_PROGRESS)
|
||||
{
|
||||
SetBossState(DATA_MAGTHERIDON, IN_PROGRESS);
|
||||
|
||||
@@ -30,7 +30,8 @@ enum DataTypes
|
||||
|
||||
DATA_CHANNELER_COMBAT = 10,
|
||||
DATA_ACTIVATE_CUBES = 11,
|
||||
DATA_COLLAPSE = 12
|
||||
DATA_COLLAPSE = 12,
|
||||
DATA_MAGTHERIDON_RELEASED = 13
|
||||
};
|
||||
|
||||
enum NpcIds
|
||||
@@ -46,7 +47,8 @@ enum NpcIds
|
||||
enum MagtheridonActions
|
||||
{
|
||||
ACTION_RELEASE_MAGTHERIDON = 1,
|
||||
ACTION_BANISH_SELF = 2
|
||||
ACTION_BANISH_SELF = 2,
|
||||
ACTION_RESET_ENCOUNTER = 3
|
||||
};
|
||||
|
||||
enum GoIds
|
||||
|
||||
Reference in New Issue
Block a user