Harden participant and map ownership and validate bounded physical flight

This commit is contained in:
2026-09-19 12:17:01 +02:00
parent dfd7cc49e2
commit 4125018d04
120 changed files with 20043 additions and 47 deletions
@@ -18,6 +18,8 @@ modded class ERR_GameMode
protected bool m_ERRTestHQResponse;
protected bool m_ERRTestMortar;
protected bool m_ERRTestMortarFire;
protected bool m_ERRTestMapOwnership;
protected ref ERRM_NativeMapOwnershipProbe m_ERRMapOwnership;
protected bool m_ERRTestMortarSalvo;
protected ref ERR_NativeMortarSalvoProbe m_ERRMortarSalvo;
protected bool m_ERRTestMortarCourier;
@@ -40,6 +42,7 @@ modded class ERR_GameMode
m_ERRTestRadioNetwork = outcome == "radio-network";
m_ERRTestHQResponse = outcome == "hq-response";
m_ERRTestMortar = outcome == "mortar-inventory";
m_ERRTestMapOwnership = outcome == "map-ownership";
m_ERRTestMortarFire = outcome == "mortar-fire" || outcome == "mortar-expiry";
m_ERRTestMortarCourier = outcome == "mortar-courier";
m_ERRTestMortarSalvo = outcome == "mortar-salvo" || outcome == "mortar-refresh";
@@ -69,6 +72,7 @@ modded class ERR_GameMode
}
protected void ERR_StopHQPatrol()
{
if (m_ERRMapOwnership) m_ERRMapOwnership.Stop();
if (m_ERRHQResponseProof) m_ERRHQResponseProof.Stop();
if (m_ERRMortarSalvo) m_ERRMortarSalvo.Stop();
if (m_ERRMortarCourier) m_ERRMortarCourier.Stop();
@@ -109,6 +113,15 @@ modded class ERR_GameMode
protected void ERR_SmokePhase(ERR_Phase previous, ERR_Phase current)
{
if (m_ERRSmokeDone || !ERR_MissionRules.Terminal(current)) return;
if (m_ERRTestMapOwnership)
{
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 201, "native map ownership probe cleaned up before explicit reset")) return;
m_ERRSmokeDone = true;
GetGame().GetCallqueue().Remove(ERR_SmokeTick);
ERR_StopHQPatrol();
Print("ERR SMOKE COMPLETE: native replacement map/config/root ownership and spare deletion; camera authorization observed, render flag not measured");
return;
}
if (m_ERRTestMortarSalvo)
{
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 191, "native configured salvo and unchanged-report replay observation complete before reset")) return;
@@ -207,6 +220,13 @@ modded class ERR_GameMode
if (m_ERRSmokeDone) return;
if (now > m_ERRSmokeDeadline) { ERR_Check(false, "timeout at step " + m_ERRSmokeStep.ToString()); return; }
if (now < m_ERRSmokeWait) return;
if (m_ERRSmokeStep == 200)
{
int result = m_ERRMapOwnership.Tick(now);
if (result < 0) { ERR_Check(false, "native map ownership fixture"); return; }
if (result == 1) { m_ERRSmokeStep = 201; Transition(ERR_Phase.DEFEAT); }
return;
}
if (m_ERRSmokeStep == 190)
{
int result = m_ERRMortarSalvo.Tick(now);
@@ -267,6 +287,13 @@ modded class ERR_GameMode
m_ERRSmokeStep = 130;
return;
}
if (m_ERRTestMapOwnership)
{
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
m_ERRMapOwnership = new ERRM_NativeMapOwnershipProbe();
m_ERRSmokeStep = 200;
return;
}
if (m_ERRTestMortarSalvo)
{
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
@@ -425,6 +452,16 @@ modded class ERR_GameMode
if (!ERR_Check(battery.CountShells() == 27, "mortar starts with exactly 27 physical HE shells")) return;
array<AIAgent> agents = {};
battery.Group.GetAgents(agents);
array<IEntity> intelCrew = {};
foreach (AIAgent intelAgent : agents)
{
IEntity intelActor;
if (intelAgent) intelActor = intelAgent.GetControlledEntity();
if (!ERR_Check(intelActor && !intelCrew.Contains(intelActor), "mortar Intel observation uses distinct actual crew actors")) return;
if (!ERR_Check(m_Intel && m_Intel.ERR_ProbeWasRolled(intelActor), "ready mortar crew actor reached its one optional Intel carrying roll")) return;
intelCrew.Insert(intelActor);
}
if (!ERR_Check(intelCrew.Count() == 4, "all four original ready physical crew reached Intel without forcing documents or changing carrying chance")) return;
foreach (AIAgent agent : agents)
{
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(agent.GetControlledEntity().FindComponent(InventoryStorageManagerComponent));