FIX BLOQUANT (signalement #16) : les 2 scenarios narratifs recoivent le triple fix du runner
Cause racine : une invocation faite par la MAP (instance->SummonCreature) n herite d AUCUNE phase, contrairement a un summon fait par une creature. Les joueurs etant mis en phase 169 par OnPlayerEnter, toutes les vagues et PNJ de ces 2 scenarios etaient invisibles/intangibles => etape 1 infranchissable (joueur Argus bloque sur la map 1460). Ce defaut avait ete trouve par le harnais bot le 26/07 et corrige dans le runner d artefacts UNIQUEMENT ; les 2 scenarios narratifs, ecrits avant, ne l avaient jamais recu. - Rive Brisee : helpers Summon/SummonAt centralises -> phase 169 + Z cale au sol ; aggro forcee sur les vagues de demons (compteur d etape) ; allies non touches - Moine Serenity s End : helper SummonPhased (phase + Z), 22 appels map rediriges Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -161,15 +161,36 @@ struct scenario_broken_shore_intro : public InstanceScript
|
|||||||
scenario->CompleteCurrStep();
|
scenario->CompleteCurrStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cale le Z au sol : les ancres officielles sont sures mais les offsets peuvent sortir du terrain.
|
||||||
|
void SnapToGround(Position& pos) const
|
||||||
|
{
|
||||||
|
float gz = instance->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 8.0f, true, 60.0f);
|
||||||
|
if (gz > INVALID_HEIGHT && gz - pos.GetPositionZ() < 60.0f && pos.GetPositionZ() - gz < 60.0f)
|
||||||
|
pos.m_positionZ = gz + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toute invocation doit partager la phase des joueurs (OnPlayerEnter les met en 169),
|
||||||
|
// sinon elle est invisible/intangible : cible de quete introuvable, vague intuable.
|
||||||
|
// (defaut systemique detecte par le harnais bot le 26/07, deja corrige dans le runner d artefacts)
|
||||||
|
TempSummon* FinalizeSummon(TempSummon* summon) const
|
||||||
|
{
|
||||||
|
if (summon)
|
||||||
|
PhasingHandler::AddPhase(summon, PHASE_NORMAL, true);
|
||||||
|
return summon;
|
||||||
|
}
|
||||||
|
|
||||||
TempSummon* Summon(uint32 entry, Position const& pos)
|
TempSummon* Summon(uint32 entry, Position const& pos)
|
||||||
{
|
{
|
||||||
return instance->SummonCreature(entry, pos);
|
Position p = pos;
|
||||||
|
SnapToGround(p);
|
||||||
|
return FinalizeSummon(instance->SummonCreature(entry, p));
|
||||||
}
|
}
|
||||||
|
|
||||||
TempSummon* SummonAt(uint32 entry, Position const& base, float dx, float dy)
|
TempSummon* SummonAt(uint32 entry, Position const& base, float dx, float dy)
|
||||||
{
|
{
|
||||||
Position pos = { base.GetPositionX() + dx, base.GetPositionY() + dy, base.GetPositionZ(), base.GetOrientation() };
|
Position pos = { base.GetPositionX() + dx, base.GetPositionY() + dy, base.GetPositionZ(), base.GetOrientation() };
|
||||||
return instance->SummonCreature(entry, pos);
|
SnapToGround(pos);
|
||||||
|
return FinalizeSummon(instance->SummonCreature(entry, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SummonWave(Position const& base, uint8 count)
|
void SummonWave(Position const& base, uint8 count)
|
||||||
@@ -179,7 +200,12 @@ struct scenario_broken_shore_intro : public InstanceScript
|
|||||||
{
|
{
|
||||||
float dx = (i % 4) * 7.0f - 10.5f + (i >= 4 ? 3.5f : 0.0f);
|
float dx = (i % 4) * 7.0f - 10.5f + (i >= 4 ? 3.5f : 0.0f);
|
||||||
float dy = (i / 4) * 8.0f - 8.0f;
|
float dy = (i / 4) * 8.0f - 8.0f;
|
||||||
SummonAt(demons[i % 5], base, dx + 15.0f, dy + 15.0f);
|
if (TempSummon* demon = SummonAt(demons[i % 5], base, dx + 15.0f, dy + 15.0f))
|
||||||
|
{
|
||||||
|
// les TempSummon de Map n aggro pas seules : on engage la vague explicitement
|
||||||
|
demon->SetReactState(REACT_AGGRESSIVE);
|
||||||
|
demon->SetInCombatWithZone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,16 +138,38 @@ struct scenario_monk_serenitys_end : public InstanceScript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cale le Z au sol (les offsets peuvent sortir du terrain sur les terrasses du pic).
|
||||||
|
void SnapToGround(Position& pos) const
|
||||||
|
{
|
||||||
|
float gz = instance->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 8.0f, true, 60.0f);
|
||||||
|
if (gz > INVALID_HEIGHT && gz - pos.GetPositionZ() < 60.0f && pos.GetPositionZ() - gz < 60.0f)
|
||||||
|
pos.m_positionZ = gz + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Une invocation faite par la MAP n herite d aucune phase (contrairement a un summon
|
||||||
|
// fait par une creature) : sans ca elle est invisible/intangible pour le joueur, qui est
|
||||||
|
// place en phase 169 par OnPlayerEnter -> PNJ de quete introuvable, vague intuable.
|
||||||
|
// (defaut systemique detecte par le harnais bot le 26/07, deja corrige dans le runner d artefacts)
|
||||||
|
TempSummon* SummonPhased(uint32 entry, Position const& pos)
|
||||||
|
{
|
||||||
|
Position p = pos;
|
||||||
|
SnapToGround(p);
|
||||||
|
TempSummon* summon = instance->SummonCreature(entry, p);
|
||||||
|
if (summon)
|
||||||
|
PhasingHandler::AddPhase(summon, PHASE_NORMAL, true);
|
||||||
|
return summon;
|
||||||
|
}
|
||||||
|
|
||||||
void SummonCouncil()
|
void SummonCouncil()
|
||||||
{
|
{
|
||||||
if (Creature* hight = instance->SummonCreature(NPC_MASTER_HIGHT_COUNCIL, PosHight))
|
if (Creature* hight = SummonPhased(NPC_MASTER_HIGHT_COUNCIL, PosHight))
|
||||||
hightGUID = hight->GetGUID();
|
hightGUID = hight->GetGUID();
|
||||||
instance->SummonCreature(NPC_IRON_BODY_PONSHU, PosPonshu);
|
SummonPhased(NPC_IRON_BODY_PONSHU, PosPonshu);
|
||||||
instance->SummonCreature(NPC_JIA_COUNCIL, PosJiaCouncil);
|
SummonPhased(NPC_JIA_COUNCIL, PosJiaCouncil);
|
||||||
instance->SummonCreature(NPC_MASTER_CHANG, PosChang);
|
SummonPhased(NPC_MASTER_CHANG, PosChang);
|
||||||
instance->SummonCreature(NPC_MASTER_HWANG, PosHwang);
|
SummonPhased(NPC_MASTER_HWANG, PosHwang);
|
||||||
instance->SummonCreature(NPC_ASPIRING_MONK, PosMonkA);
|
SummonPhased(NPC_ASPIRING_MONK, PosMonkA);
|
||||||
instance->SummonCreature(NPC_ASPIRING_MONK, PosMonkB);
|
SummonPhased(NPC_ASPIRING_MONK, PosMonkB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompleteStep()
|
void CompleteStep()
|
||||||
@@ -173,13 +195,13 @@ struct scenario_monk_serenitys_end : public InstanceScript
|
|||||||
hight->AI()->Talk(1);
|
hight->AI()->Talk(1);
|
||||||
hight->GetScheduler().Schedule(Seconds(8), [this](TaskContext /*context*/)
|
hight->GetScheduler().Schedule(Seconds(8), [this](TaskContext /*context*/)
|
||||||
{
|
{
|
||||||
if (Creature* chuang = instance->SummonCreature(NPC_INITIATE_CHUANG, PosChuang))
|
if (Creature* chuang = SummonPhased(NPC_INITIATE_CHUANG, PosChuang))
|
||||||
chuang->AI()->Talk(0);
|
chuang->AI()->Talk(0);
|
||||||
}).Schedule(Seconds(12), [this](TaskContext /*context*/)
|
}).Schedule(Seconds(12), [this](TaskContext /*context*/)
|
||||||
{
|
{
|
||||||
if (Creature* hight2 = instance->GetCreature(hightGUID))
|
if (Creature* hight2 = instance->GetCreature(hightGUID))
|
||||||
hight2->AI()->Talk(2);
|
hight2->AI()->Talk(2);
|
||||||
if (Creature* destroyer = instance->SummonCreature(NPC_INFERNAL_DESTROYER, PosDestroyer))
|
if (Creature* destroyer = SummonPhased(NPC_INFERNAL_DESTROYER, PosDestroyer))
|
||||||
destroyer->SetInCombatWithZone();
|
destroyer->SetInCombatWithZone();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -193,20 +215,20 @@ struct scenario_monk_serenitys_end : public InstanceScript
|
|||||||
hight->AI()->Talk(3);
|
hight->AI()->Talk(3);
|
||||||
for (uint8 i = 0; i < 3; ++i)
|
for (uint8 i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
instance->SummonCreature(i < 2 ? NPC_CHAOS_MINION : NPC_EYE_OF_KELETRESS, PosPackA[i]);
|
SummonPhased(i < 2 ? NPC_CHAOS_MINION : NPC_EYE_OF_KELETRESS, PosPackA[i]);
|
||||||
instance->SummonCreature(i < 2 ? NPC_CHAOS_MINION : NPC_FELBLADE_DESTROYER, PosPackB[i]);
|
SummonPhased(i < 2 ? NPC_CHAOS_MINION : NPC_FELBLADE_DESTROYER, PosPackB[i]);
|
||||||
}
|
}
|
||||||
if (Creature* keletress = instance->SummonCreature(NPC_LADY_KELETRESS, PosKeletress))
|
if (Creature* keletress = SummonPhased(NPC_LADY_KELETRESS, PosKeletress))
|
||||||
{
|
{
|
||||||
keletressGUID = keletress->GetGUID();
|
keletressGUID = keletress->GetGUID();
|
||||||
keletress->SetCanFly(true);
|
keletress->SetCanFly(true);
|
||||||
keletress->SetDisableGravity(true);
|
keletress->SetDisableGravity(true);
|
||||||
keletress->AI()->Talk(0);
|
keletress->AI()->Talk(0);
|
||||||
}
|
}
|
||||||
if (Creature* jia = instance->SummonCreature(NPC_JIA_CRANE, PosJiaCrane))
|
if (Creature* jia = SummonPhased(NPC_JIA_CRANE, PosJiaCrane))
|
||||||
{
|
{
|
||||||
jiaGUID = jia->GetGUID();
|
jiaGUID = jia->GetGUID();
|
||||||
if (Creature* vizznak = instance->SummonCreature(NPC_VIZZNAK, PosVizznak))
|
if (Creature* vizznak = SummonPhased(NPC_VIZZNAK, PosVizznak))
|
||||||
{
|
{
|
||||||
jia->AI()->Talk(0);
|
jia->AI()->Talk(0);
|
||||||
jia->AI()->AttackStart(vizznak);
|
jia->AI()->AttackStart(vizznak);
|
||||||
@@ -229,20 +251,20 @@ struct scenario_monk_serenitys_end : public InstanceScript
|
|||||||
{
|
{
|
||||||
stage = DATA_STAGE_TIGER;
|
stage = DATA_STAGE_TIGER;
|
||||||
CompleteStep();
|
CompleteStep();
|
||||||
if (Creature* chen = instance->SummonCreature(NPC_CHEN_STORMSTOUT, PosChen))
|
if (Creature* chen = SummonPhased(NPC_CHEN_STORMSTOUT, PosChen))
|
||||||
{
|
{
|
||||||
chenGUID = chen->GetGUID();
|
chenGUID = chen->GetGUID();
|
||||||
chen->AI()->Talk(0);
|
chen->AI()->Talk(0);
|
||||||
}
|
}
|
||||||
for (uint8 i = 0; i < 3; ++i)
|
for (uint8 i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
instance->SummonCreature(NPC_JUNIOR_TRAINEE, PosTrainees[i]);
|
SummonPhased(NPC_JUNIOR_TRAINEE, PosTrainees[i]);
|
||||||
if (Creature* hound = instance->SummonCreature(NPC_FELBLOOD_PACKHOUND, PosHounds[i]))
|
if (Creature* hound = SummonPhased(NPC_FELBLOOD_PACKHOUND, PosHounds[i]))
|
||||||
if (Creature* chen = instance->GetCreature(chenGUID))
|
if (Creature* chen = instance->GetCreature(chenGUID))
|
||||||
hound->AI()->AttackStart(chen);
|
hound->AI()->AttackStart(chen);
|
||||||
}
|
}
|
||||||
instance->SummonCreature(NPC_EREDAR_SUMMONER, PosSummoner);
|
SummonPhased(NPC_EREDAR_SUMMONER, PosSummoner);
|
||||||
instance->SummonCreature(NPC_MORVATH_THE_REAVER, PosMorvath);
|
SummonPhased(NPC_MORVATH_THE_REAVER, PosMorvath);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DATA_MORVATH_DEAD: // stage 4 -> 5 (escort back)
|
case DATA_MORVATH_DEAD: // stage 4 -> 5 (escort back)
|
||||||
@@ -268,9 +290,9 @@ struct scenario_monk_serenitys_end : public InstanceScript
|
|||||||
CompleteStep();
|
CompleteStep();
|
||||||
if (Creature* keletress = GetKeletress())
|
if (Creature* keletress = GetKeletress())
|
||||||
keletress->AI()->Talk(2);
|
keletress->AI()->Talk(2);
|
||||||
if (Creature* hight = instance->SummonCreature(NPC_MASTER_HIGHT_PORTAL, PosHightPortal))
|
if (Creature* hight = SummonPhased(NPC_MASTER_HIGHT_PORTAL, PosHightPortal))
|
||||||
hightPortalGUID = hight->GetGUID();
|
hightPortalGUID = hight->GetGUID();
|
||||||
if (Creature* jorvinax = instance->SummonCreature(NPC_PORTAL_MASTER_JORVINAX, PosJorvinax))
|
if (Creature* jorvinax = SummonPhased(NPC_PORTAL_MASTER_JORVINAX, PosJorvinax))
|
||||||
jorvinax->SetInCombatWithZone();
|
jorvinax->SetInCombatWithZone();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -280,7 +302,7 @@ struct scenario_monk_serenitys_end : public InstanceScript
|
|||||||
CompleteStep();
|
CompleteStep();
|
||||||
if (Creature* hight = instance->GetCreature(hightPortalGUID))
|
if (Creature* hight = instance->GetCreature(hightPortalGUID))
|
||||||
hight->AI()->Talk(0);
|
hight->AI()->Talk(0);
|
||||||
instance->SummonCreature(NPC_MASTER_FEL_STONE, PosFelStone);
|
SummonPhased(NPC_MASTER_FEL_STONE, PosFelStone);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DATA_FEL_STONE_DEAD: // scenario complete -> wake up at the Wandering Isle
|
case DATA_FEL_STONE_DEAD: // scenario complete -> wake up at the Wandering Isle
|
||||||
|
|||||||
Reference in New Issue
Block a user