Advance standalone admission, finite artillery and native validation

This commit is contained in:
2026-09-19 09:02:31 +02:00
parent af5146a317
commit 40a474934c
532 changed files with 56456 additions and 199 deletions
+4
View File
@@ -5,3 +5,7 @@ __pycache__/
.build/ .build/
.local/ .local/
profiles/ profiles/
# Preserve exact raw dedicated diagnostic evidence, outside release addons.
!docs/evidence/**/*.log
!docs/evidence/**/resourceDatabase.rdb
+2 -2
View File
@@ -4,7 +4,7 @@ An independently authored replacement for the abandoned Escapists base mission,
The current base supplies prison spawning, two independent scavenging/clue routes, finite medical and outpost stock, an optional ground vehicle, physical radio documents, named discovery markers, native objectives, a separate radio-defence service, capacity-checked helicopter extraction, identity-based partial results, early helicopter-loss defeat, saved mission time/speed, defeat/restart, identity-based lives and local spectator following. Authored site definitions and an injected vanilla faction/asset catalog own the initial physical population. Core provides administration and startup diagnostics; the optional AI, Intel, Chat and Map addons extend its interfaces. HQ coordinates enemy responses through physical radios and available forces. The current base supplies prison spawning, two independent scavenging/clue routes, finite medical and outpost stock, an optional ground vehicle, physical radio documents, named discovery markers, native objectives, a separate radio-defence service, capacity-checked helicopter extraction, identity-based partial results, early helicopter-loss defeat, saved mission time/speed, defeat/restart, identity-based lives and local spectator following. Authored site definitions and an injected vanilla faction/asset catalog own the initial physical population. Core provides administration and startup diagnostics; the optional AI, Intel, Chat and Map addons extend its interfaces. HQ coordinates enemy responses through physical radios and available forces.
See [current development status](docs/current-status.md) for verified checkpoints and the prioritized remaining work. Ordinary-game startup and ground-to-helicopter casualty loading have retained native failures; manual gameplay, real multiplayer, complete physical HQ support, measured FPS improvement and release qualification remain unfinished. The [original responsibility inventory](docs/original-feature-coverage.md) is a scope map, not proof that every original behavior has been replaced. See [current development status](docs/current-status.md) for verified checkpoints and the prioritized remaining work. Ordinary Core and companion startup now admit a real local prisoner cleanly; focused casualty-loading and physical mortar tests also pass. A later companion restart retains support-station cleanup errors. Manual gameplay, real multiplayer, complete HQ support, measured FPS improvement and release qualification remain unfinished. The [original responsibility inventory](docs/original-feature-coverage.md) is a scope map, not proof that every original behavior has been replaced.
## Projects and scenarios ## Projects and scenarios
@@ -27,6 +27,6 @@ python3 tools/check.py
For bounded hidden, muted local native tests, see [runtime testing](docs/runtime-testing.md). Recorded Workbench checkpoints include Core-only and companion-loaded escape/restart, finite stock and document-loss recovery, twelve physical prisoner/seat fixtures, real medical treatment, local result/objective widgets, patrol movement and HQ preemption/resumption. Clean environment/restart evidence exists after narrowing the vanilla vehicle catalogs; it does not qualify subsequent source changes. For bounded hidden, muted local native tests, see [runtime testing](docs/runtime-testing.md). Recorded Workbench checkpoints include Core-only and companion-loaded escape/restart, finite stock and document-loss recovery, twelve physical prisoner/seat fixtures, real medical treatment, local result/objective widgets, patrol movement and HQ preemption/resumption. Clean environment/restart evidence exists after narrowing the vanilla vehicle catalogs; it does not qualify subsequent source changes.
These scripted local fixtures manipulate positions and selected native states. They do not establish ordinary-game startup, manual escape/piloting, real remote reconnects, twelve connected players or improved FPS. [Current status](docs/current-status.md) separates those gaps from demonstrated development behavior. [Validation evidence](docs/validation.md) preserves exact source checkpoints and failed iterations; `docs/acceptance.json` keeps unverified release requirements pending. These scripted local fixtures manipulate positions and selected native states. They do not establish manual escape/piloting, real remote reconnects, twelve connected players or improved FPS. Separate regular-game runs establish standalone startup/admission; an isolated native Linux run establishes empty-server preparation, with inherited resource errors reproduced by a vanilla control. [Current status](docs/current-status.md) separates those gaps from demonstrated development behavior. [Validation evidence](docs/validation.md) preserves exact source checkpoints and failed iterations; `docs/acceptance.json` keeps unverified release requirements pending.
No release package has been published. No release package has been published.
@@ -0,0 +1,31 @@
// The stored geometry is the command actually emitted to the native aiming
// tree, never a chain of refreshed approximations. Entity/report/node links
// are weak; cancellation and physical projectile observation clear ownership.
class ERR_MortarAimSolution
{
IEntity Gun;
ERR_HQReport Report;
int OrderId;
int Shot;
vector GunOrigin;
vector Impact;
vector AimTarget;
vector SalvoOffset;
int Charge;
float FlightTime;
bool Matches(ERR_MortarBattery battery, ERR_HQReport report)
{
return battery && Gun && Gun == battery.Gun && Report && Report == report && OrderId == battery.OrderId && Shot == battery.OrderShots;
}
}
class ERR_MortarAimRules
{
// Three-dimensional tolerances include terrain/aim-height changes. These are
// equivalence limits, not permission to move the gun or redirect its barrel.
static bool Equivalent(int commandedCharge, int updatedCharge, vector commandedOrigin, vector updatedOrigin, vector commandedImpact, vector updatedImpact, vector commandedAim, vector updatedAim, float commandedFlight, float updatedFlight)
{
return commandedCharge >= 0 && commandedCharge == updatedCharge && commandedFlight > 0 && updatedFlight > 0 && vector.Distance(commandedOrigin, updatedOrigin) <= 0.05 && vector.Distance(commandedImpact, updatedImpact) <= 0.1 && vector.Distance(commandedAim, updatedAim) <= 0.1 && Math.AbsFloat(commandedFlight - updatedFlight) <= 0.05;
}
}
+86 -72
View File
@@ -33,12 +33,20 @@ class ERR_MortarBattery
ref ERR_HQReport Report; ref ERR_HQReport Report;
ref ERR_HQRoute RadioOrder; ref ERR_HQRoute RadioOrder;
ref ERR_HQReport PendingRadioReport; ref ERR_HQReport PendingRadioReport;
ref ERR_HQReport PendingSupplyReport;
protected ref ERR_MortarReadiness m_Readiness;
protected ref ERR_MortarSupplyTransfer m_Transfer;
protected ref array<IEntity> m_AttemptedShells = {};
protected bool m_Stopped;
protected ref ERR_MortarReportLedger m_ReportLedger = new ERR_MortarReportLedger();
vector Position; vector Position;
vector Impact; vector Impact;
vector AimOffset; vector AimOffset;
int AimedShot = -1; int AimedShot = -1;
float FlightTime; float FlightTime;
float AimedAt = -1; float AimedAt = -1;
SCR_AIGetArtilleryAimDistanceCompensation AimSolver;
ref ERR_MortarAimSolution AimSolution;
float AirspaceUntil; float AirspaceUntil;
vector AirspaceImpact; vector AirspaceImpact;
float AirspaceRadius = 600; float AirspaceRadius = 600;
@@ -94,6 +102,7 @@ class ERR_MortarBattery
string OperationalReason() string OperationalReason()
{ {
if (m_Stopped) return "battery stopped";
if (!Gun) return "gun missing"; if (!Gun) return "gun missing";
if (!SpawnFailure.IsEmpty()) return SpawnFailure; if (!SpawnFailure.IsEmpty()) return SpawnFailure;
if (!Group || !Group.GetGroupUtilityComponent()) return "crew group missing"; if (!Group || !Group.GetGroupUtilityComponent()) return "crew group missing";
@@ -105,8 +114,13 @@ class ERR_MortarBattery
return ""; return "";
} }
void BeginRequest(ERR_HQReport report, float now) bool CanRequest(ERR_HQReport report, float now)
{ {
return !m_Stopped && ERR_MortarPrediction.Fresh(report, now) && m_ReportLedger.Available(report.MessageId, report.ObservedAt, now);
}
bool BeginRequest(ERR_HQReport report, float now)
{
if (!CanRequest(report, now) || !m_ReportLedger.Claim(report.MessageId, report.ObservedAt, now)) return false;
Cancel("superseded by new HQ order"); Cancel("superseded by new HQ order");
FlushTraces(); FlushTraces();
OrderId++; OrderId++;
@@ -118,6 +132,7 @@ class ERR_MortarBattery
OrderedAt = now; OrderedAt = now;
LastFailure = ""; LastFailure = "";
Audit("COMMAND", string.Format("requested rounds=%1 HE radius=%2m; %3", ERR_MortarSalvo.ROUNDS, ERR_MortarSalvo.RADIUS_METRES, report.Description(now))); Audit("COMMAND", string.Format("requested rounds=%1 HE radius=%2m; %3", ERR_MortarSalvo.ROUNDS, ERR_MortarSalvo.RADIUS_METRES, report.Description(now)));
return true;
} }
void ObserveProjectile(IEntity projectileEntity, IEntity firingCharacter, bool playerGunner) void ObserveProjectile(IEntity projectileEntity, IEntity firingCharacter, bool playerGunner)
@@ -134,6 +149,8 @@ class ERR_MortarBattery
// Only a physical projectile unlocks the next load. It must be aimed again. // Only a physical projectile unlocks the next load. It must be aimed again.
Released = false; Released = false;
AimedAt = -1; AimedAt = -1;
AimSolver = null;
AimSolution = null;
Audit("FIRED", string.Format("physical projectile=%1 origin=%2 order shots=%3 total shots=%4 predicted impact=%5 predicted flight=%6s gunner=%7 (impact not observed)", projectileEntity, projectileEntity.GetOrigin(), OrderShots, TotalShots, Impact, FlightTime, firingCharacter)); Audit("FIRED", string.Format("physical projectile=%1 origin=%2 order shots=%3 total shots=%4 predicted impact=%5 predicted flight=%6s gunner=%7 (impact not observed)", projectileEntity, projectileEntity.GetOrigin(), OrderShots, TotalShots, Impact, FlightTime, firingCharacter));
} }
else else
@@ -234,10 +251,11 @@ class ERR_MortarBattery
Position = gun.GetOrigin(); Position = gun.GetOrigin();
SpawnedAt = now; SpawnedAt = now;
Claimed = true; Claimed = true;
m_Readiness = new ERR_MortarReadiness(this);
} }
protected int InventoryShells(InventoryStorageManagerComponent inventory) int InventoryShells(InventoryStorageManagerComponent inventory)
{ {
if (!inventory) if (!inventory)
return 0; return 0;
@@ -252,36 +270,41 @@ class ERR_MortarBattery
return count; return count;
} }
protected void Equip(IEntity soldier) bool Stopped() { return m_Stopped; }
bool SupplyPending() { return m_Transfer && m_Transfer.Unresolved(); }
bool SupplyAuthorized(float now)
{ {
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(soldier.FindComponent(InventoryStorageManagerComponent)); if (!Replication.IsServer() || m_Stopped || !StartupActivated || !Operational() || !CommandOpen || !ERR_HQ.MissionActive()) return false;
if (!inventory) ERR_MortarSystem system = ERR_MortarSystem.Get();
{ if (!system || system.FindGun(Gun) != this) return false;
Audit("EQUIP FAILED", string.Format("crew=%1 inventory missing", soldier)); ERR_HQReport suppliedReport = Report;
return; if (!suppliedReport) suppliedReport = PendingSupplyReport;
return ERR_MortarPrediction.Fresh(suppliedReport, now);
} }
if (soldier == RadioOperator) void Stop()
{ {
int capability = ERR_HQRadio.Capability(soldier); if (m_Stopped) return;
Audit("RADIO EQUIP", string.Format("operator=%1 capability=%2 (2=physical manpack); next HQ radio index verifies route", soldier, capability)); m_Stopped = true;
return; Cancel("HQ stopped");
} if (m_Readiness) m_Readiness.Stop();
if (ERR_HQRadio.Capability(soldier) == 0 && !inventory.TrySpawnPrefabToStorage("{E1A5D4B878AA8980}Prefabs/Items/Equipment/Radios/Radio_R148.et"))
Print("Rereintroduced AI [mortar]: crew radio did not fit; HQ handoff required", LogLevel.WARNING);
// Native mortar-crew backpacks carry three EMPTY three-round boxes.
// Fill them once. No infinite ammunition or replacement after casualties.
for (int i = InventoryShells(inventory); i < 9; i++)
{
if (!inventory.TrySpawnPrefabToStorage(SHELL, purpose: EStoragePurpose.PURPOSE_DEPOSIT))
break;
}
Audit("EQUIP", string.Format("crew=%1 inventory HE=%2 requested=9 radio capability=%3 (0=none)", soldier, InventoryShells(inventory), ERR_HQRadio.Capability(soldier)));
} }
bool SupplyGunner() ERR_MortarSupplyState SupplyState(float now)
{ {
if (!Operational()) // Observe an existing native operation even after its order was canceled.
return SupplyFailed(OperationalReason()); // No second request may race an unresolved transfer on this battery.
if (m_Transfer)
{
ERR_MortarSupplyState observed = m_Transfer.Poll(now);
if (m_Transfer.CapturedOrder() == OrderId)
{
if (observed == ERR_MortarSupplyState.READY) m_Transfer = null;
return observed;
}
if (m_Transfer.Unresolved()) return ERR_MortarSupplyState.FAILED;
m_Transfer = null;
}
if (!SupplyAuthorized(now)) return SupplyStateFailed("current HQ order, crew or report is unavailable");
SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(Gun.FindComponent(SCR_AIVehicleUsageComponent)); SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(Gun.FindComponent(SCR_AIVehicleUsageComponent));
IEntity gunner; IEntity gunner;
if (usage && usage.GetTurretCompartmentSlot()) if (usage && usage.GetTurretCompartmentSlot())
@@ -303,15 +326,15 @@ class ERR_MortarBattery
} }
} }
} }
if (!gunner) return SupplyFailed("no fighting gunner found"); if (!gunner) return SupplyStateFailed("no fighting gunner found");
if (ERR_Actors.Group(gunner) != Group) return SupplyFailed("turret occupant belongs to another group"); if (ERR_Actors.Group(gunner) != Group) return SupplyStateFailed("turret occupant belongs to another group");
if (!ERR_Actors.CanFight(gunner)) return SupplyFailed("gunner cannot fight"); if (!ERR_Actors.CanFight(gunner)) return SupplyStateFailed("gunner cannot fight");
InventoryStorageManagerComponent destination = InventoryStorageManagerComponent.Cast(gunner.FindComponent(InventoryStorageManagerComponent)); InventoryStorageManagerComponent destination = InventoryStorageManagerComponent.Cast(gunner.FindComponent(InventoryStorageManagerComponent));
if (!destination) if (!destination)
return SupplyFailed("gunner inventory missing"); return SupplyStateFailed("gunner inventory missing");
if (InventoryShells(destination) > 0) if (InventoryShells(destination) > 0)
return true; return ERR_MortarSupplyState.READY;
int nearbyDonors, donorShells, storageRejected, moveRejected; int nearbyDonors, donorShells, storageRejected;
array<IEntity> consideredShells = {}; array<IEntity> consideredShells = {};
foreach (AIAgent bearer : agents) foreach (AIAgent bearer : agents)
{ {
@@ -330,20 +353,27 @@ class ERR_MortarBattery
{ {
if (!item || !item.GetPrefabData() || item.GetPrefabData().GetPrefabName() != SHELL) if (!item || !item.GetPrefabData() || item.GetPrefabData().GetPrefabName() != SHELL)
continue; continue;
if (consideredShells.Contains(item)) continue; if (consideredShells.Contains(item) || m_AttemptedShells.Contains(item)) continue;
consideredShells.Insert(item); consideredShells.Insert(item);
donorShells++; donorShells++;
BaseInventoryStorageComponent storage = destination.FindStorageForItem(item, EStoragePurpose.PURPOSE_DEPOSIT); BaseInventoryStorageComponent storage = destination.FindStorageForItem(item, EStoragePurpose.PURPOSE_DEPOSIT);
if (!storage) { storageRejected++; continue; } if (!storage) { storageRejected++; continue; }
if (inventory.TryMoveItemToStorage(item, storage)) m_AttemptedShells.Insert(item); // even rejected/ambiguous requests are never retried
m_Transfer = new ERR_MortarSupplyTransfer(this, donor, gunner, item, storage, now);
if (!m_Transfer.Begin(now)) return SupplyStateFailed("exact shell transfer request rejected; no retry");
Audit("AMMO TRANSFER", string.Format("one exact-item move pending donor=%1 gunner=%2 shell=%3 order=%4; awaiting callback AND physical destination", donor, gunner, item, OrderId));
return ERR_MortarSupplyState.PENDING;
}
}
return SupplyStateFailed(string.Format("gunner empty; fighting donors within 12m=%1 unattempted HE=%2 destination storage rejected=%3", nearbyDonors, donorShells, storageRejected));
}
// Compatibility for existing native callers; request acceptance is NOT ready.
bool SupplyGunner() { return SupplyState(GetGame().GetWorld().GetWorldTime()) == ERR_MortarSupplyState.READY; }
protected ERR_MortarSupplyState SupplyStateFailed(string reason)
{ {
Audit("AMMO TRANSFER", string.Format("request accepted donor=%1 gunner=%2 shell=%3; inventory move is not a fired shot", donor, gunner, item)); SupplyFailed(reason);
return true; return ERR_MortarSupplyState.FAILED;
}
moveRejected++;
}
}
return SupplyFailed(string.Format("gunner empty; fighting donors with inventory within 12m=%1 donor HE=%2 destination storage rejected=%3 native move rejected=%4", nearbyDonors, donorShells, storageRejected, moveRejected));
} }
bool SupplyFailed(string reason) bool SupplyFailed(string reason)
@@ -363,8 +393,12 @@ class ERR_MortarBattery
CommandOpen = false; CommandOpen = false;
RadioOrder = null; RadioOrder = null;
PendingRadioReport = null; PendingRadioReport = null;
PendingSupplyReport = null;
if (m_Transfer) m_Transfer.Invalidate();
Report = null; Report = null;
AimedAt = -1; AimedAt = -1;
AimSolver = null;
AimSolution = null;
if (Activity) if (Activity)
Activity.Complete(); Activity.Complete();
Activity = null; Activity = null;
@@ -399,42 +433,21 @@ class ERR_MortarBattery
void Update(float now) void Update(float now)
{ {
if (m_Stopped) return;
if (!StartupActivated)
{
if (!SpawnFailure.IsEmpty()) return;
if (!m_Readiness) { SpawnFailed("initial support readiness owner missing"); return; }
ERR_MortarSupplyState startup = m_Readiness.Poll(now);
if (startup != ERR_MortarSupplyState.READY) return;
StartupActivated = true;
}
if (m_Transfer) m_Transfer.Poll(now);
if (!Operational()) if (!Operational())
{ {
Cancel(OperationalReason()); Cancel(OperationalReason());
return; return;
} }
if (!StartupActivated && now - SpawnedAt >= 10000)
{
SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(Gun.FindComponent(SCR_AIVehicleUsageComponent));
if (!usage || !Group.GetGroupUtilityComponent().m_VehicleMgr || !Group.GetGroupUtilityComponent().m_VehicleMgr.TryAddVehicle(usage))
{
SpawnFailure = "native gun registration failed";
Cancel(SpawnFailure);
return;
}
array<AIAgent> initialCrew = {};
Group.GetAgents(initialCrew);
foreach (AIAgent initialAgent : initialCrew)
{
IEntity initialActor = initialAgent.GetControlledEntity();
if (initialActor && initialActor.GetPrefabData() && initialActor.GetPrefabData().GetPrefabName() == RADIO_OPERATOR) RadioOperator = initialActor;
}
StartupActivated = true;
Audit("CREW ACTIVATE", "startup delay elapsed; activating and equipping crew");
Group.ActivateAI();
array<AIAgent> agents = {};
Group.GetAgents(agents);
foreach (AIAgent agent : agents)
{
if (agent && ERR_Actors.CanFight(agent.GetControlledEntity()))
{
agent.SetPermanentLOD(0);
agent.ActivateAI();
Equip(agent.GetControlledEntity());
}
}
}
if (Activity) if (Activity)
{ {
Trace("ACTIVITY", string.Format("native state=%1", Activity.GetActionState()), string.Format("age=%1s aim age=%2s committed=%3 shots=%4", (now - OrderedAt) / 1000, (now - AimedAt) / 1000, Released, OrderShots)); Trace("ACTIVITY", string.Format("native state=%1", Activity.GetActionState()), string.Format("age=%1s aim age=%2s committed=%3 shots=%4", (now - OrderedAt) / 1000, (now - AimedAt) / 1000, Released, OrderShots));
@@ -448,6 +461,7 @@ class ERR_MortarBattery
void Order(ERR_HQReport report, float now) void Order(ERR_HQReport report, float now)
{ {
if (m_Stopped || !StartupActivated || !Operational() || !CommandOpen || Activity || !ERR_MortarPrediction.Fresh(report, now)) return;
Report = report.Snapshot(); Report = report.Snapshot();
OrderedAt = now; OrderedAt = now;
NextOrder = now + 30000; NextOrder = now + 30000;
+84 -28
View File
@@ -36,6 +36,8 @@ modded class SCR_AIGetArtilleryAimDistanceCompensation
if (!battery) if (!battery)
return super.EOnTaskSimulate(owner, dt); return super.EOnTaskSimulate(owner, dt);
battery.AimedAt = -1; battery.AimedAt = -1;
battery.AimSolver = null;
battery.AimSolution = null;
float now = GetGame().GetWorld().GetWorldTime(); float now = GetGame().GetWorld().GetWorldTime();
ERR_HQReport report = system.Latest(battery, now); ERR_HQReport report = system.Latest(battery, now);
if (!ERR_HQ.MissionActive()) { system.Withhold(battery, "aim: mission inactive"); return ENodeResult.FAIL; } if (!ERR_HQ.MissionActive()) { system.Withhold(battery, "aim: mission inactive"); return ENodeResult.FAIL; }
@@ -43,13 +45,56 @@ modded class SCR_AIGetArtilleryAimDistanceCompensation
if (battery.Released) { system.Withhold(battery, "aim: waiting for committed projectile"); return ENodeResult.FAIL; } if (battery.Released) { system.Withhold(battery, "aim: waiting for committed projectile"); return ENodeResult.FAIL; }
if (!report) { system.Withhold(battery, "aim: " + system.ContactFailure(battery)); return ENodeResult.FAIL; } if (!report) { system.Withhold(battery, "aim: " + system.ContactFailure(battery)); return ENodeResult.FAIL; }
battery.Trace("AIM START", "solving moving intercept", string.Format("latest source=M%1; %2", report.MessageId, report.Description(now))); battery.Trace("AIM START", "solving moving intercept", string.Format("latest source=M%1; %2", report.MessageId, report.Description(now)));
ERR_MortarAimSolution solution = ERR_Solve(battery, system, report, now);
if (!solution) return ENodeResult.FAIL;
battery.Impact = solution.Impact;
battery.AimOffset = solution.SalvoOffset;
battery.AimedShot = battery.OrderShots;
battery.FlightTime = solution.FlightTime;
battery.AimSolution = solution;
battery.AimSolver = this; // weak: do not retain a destroyed native behavior tree
battery.AimedAt = now;
battery.LastFailure = "";
battery.Trace("AIM SOLUTION", "ready", string.Format("predicted impact=%1 flight=%2s charge index=%3 aim target=%4 latest source=M%5", solution.Impact, solution.FlightTime, solution.Charge, solution.AimTarget, report.MessageId));
SetVariableOut(PORT_AIM_POS, solution.AimTarget);
SetVariableOut(PORT_INIT_SPEED_ID, solution.Charge);
return ENodeResult.SUCCESS;
}
// Reuse this exact native node's coefficient/elevation APIs. A slow native
// barrel can keep its command only if a NEW solve still matches that command.
bool ERR_RevalidateAim(ERR_MortarBattery battery, ERR_MortarSystem system, ERR_HQReport report, float now)
{
IEntity gun;
ResourceName ammo;
GetVariableIn(PORT_ARTILLERY_ENTITY, gun);
GetVariableIn(PORT_AMMO_PREFAB, ammo);
ERR_MortarAimSolution commanded = battery.AimSolution;
if (battery.AimSolver != this || !commanded || !commanded.Matches(battery, report) || gun != battery.Gun || ammo != ERR_MortarBattery.SHELL)
return system.Withhold(battery, "original aim solver or command no longer available");
if (!ERR_MortarPrediction.Fresh(report, now)) return system.Withhold(battery, system.ContactFailure(battery));
ERR_MortarAimSolution updated = ERR_Solve(battery, system, report, now);
if (!updated) return false;
if (!ERR_MortarAimRules.Equivalent(commanded.Charge, updated.Charge, commanded.GunOrigin, updated.GunOrigin, commanded.Impact, updated.Impact, commanded.AimTarget, updated.AimTarget, commanded.FlightTime, updated.FlightTime))
return system.Withhold(battery, "new ballistic solution requires native re-aim", string.Format("gun drift=%1m impact drift=%2m aim drift=%3m charge=%4/%5 flight=%6/%7s", vector.Distance(commanded.GunOrigin, updated.GunOrigin), vector.Distance(commanded.Impact, updated.Impact), vector.Distance(commanded.AimTarget, updated.AimTarget), commanded.Charge, updated.Charge, commanded.FlightTime, updated.FlightTime));
// Keep the ORIGINAL command/impact/flight. Comparing successive refreshed
// solutions would allow a moving target to drift away in small increments.
battery.AimedAt = now;
battery.Trace("AIM REVALIDATED", "same native command", string.Format("fresh ballistic solve matched original; source=M%1 observed age=%2s", report.MessageId, (now - report.ObservedAt) / 1000));
return true;
}
protected ERR_MortarAimSolution ERR_Solve(ERR_MortarBattery battery, ERR_MortarSystem system, ERR_HQReport report, float now)
{
IEntity gun = battery.Gun;
vector gunOrigin = gun.GetOrigin();
ResourceName ammo; ResourceName ammo;
GetVariableIn(PORT_AMMO_PREFAB, ammo); GetVariableIn(PORT_AMMO_PREFAB, ammo);
if (ammo != ERR_MortarBattery.SHELL) { system.Withhold(battery, "unsupported ammunition prefab", ammo); return ENodeResult.FAIL; } if (ammo != ERR_MortarBattery.SHELL) { system.Withhold(battery, "unsupported ammunition prefab", ammo); return null; }
Resource resource = Resource.Load(ammo); Resource resource = Resource.Load(ammo);
if (!resource || !resource.IsValid() || !resource.GetResource()) { system.Withhold(battery, "shell resource load failed", ammo); return ENodeResult.FAIL; } if (!resource || !resource.IsValid() || !resource.GetResource()) { system.Withhold(battery, "shell resource load failed", ammo); return null; }
IEntitySource source = resource.GetResource().ToEntitySource(); IEntitySource source = resource.GetResource().ToEntitySource();
if (!source) { system.Withhold(battery, "shell resource has no entity source", ammo); return ENodeResult.FAIL; } if (!source) { system.Withhold(battery, "shell resource has no entity source", ammo); return null; }
array<float> coefficients = {}; array<float> coefficients = {};
GetAmmoInitialSpeedCoefficients(ammo, coefficients); GetAmmoInitialSpeedCoefficients(ammo, coefficients);
if (coefficients.IsEmpty()) if (coefficients.IsEmpty())
@@ -66,13 +111,13 @@ modded class SCR_AIGetArtilleryAimDistanceCompensation
// Reject non-convergence rather than fire with an arbitrary lead time. // Reject non-convergence rather than fire with an arbitrary lead time.
for (int iteration = 0; iteration < 4; iteration++) for (int iteration = 0; iteration < 4; iteration++)
{ {
if (!ERR_MortarPrediction.Predict(report, now, flight + 2, impact)) { system.Withhold(battery, "aim prediction: " + ERR_MortarPrediction.FailureReason, string.Format("flight lead=%1s; %2", flight + 2, report.Description(now))); return ENodeResult.FAIL; } if (!ERR_MortarPrediction.Predict(report, now, flight + 2, impact)) { system.Withhold(battery, "aim prediction: " + ERR_MortarPrediction.FailureReason, string.Format("flight lead=%1s; %2", flight + 2, report.Description(now))); return null; }
if (!system.OutsideSettlements(impact)) { system.Withhold(battery, "aim target inside settlement exclusion", system.SettlementReason); return ENodeResult.FAIL; } if (!system.OutsideSettlements(impact)) { system.Withhold(battery, "aim target inside settlement exclusion", system.SettlementReason); return null; }
impact += salvoOffset; impact += salvoOffset;
impact[1] = SCR_TerrainHelper.GetTerrainY(impact); impact[1] = SCR_TerrainHelper.GetTerrainY(impact);
float distance = vector.DistanceXZ(gun.GetOrigin(), impact); float distance = vector.DistanceXZ(gunOrigin, impact);
float altitude = impact[1] - gun.GetOrigin()[1]; float altitude = impact[1] - gunOrigin[1];
if (distance < 350 || distance > 4000) { system.Withhold(battery, "predicted impact out of range", string.Format("iteration=%1 distance=%2m impact=%3 allowed=350..4000m", iteration, distance, impact)); return ENodeResult.FAIL; } if (distance < 350 || distance > 4000) { system.Withhold(battery, "predicted impact out of range", string.Format("iteration=%1 distance=%2m impact=%3 allowed=350..4000m", iteration, distance, impact)); return null; }
bool reachable; bool reachable;
float calculated; float calculated;
for (int i = 0; i < coefficients.Count(); i++) for (int i = 0; i < coefficients.Count(); i++)
@@ -86,25 +131,26 @@ modded class SCR_AIGetArtilleryAimDistanceCompensation
reachable = true; reachable = true;
break; break;
} }
if (!reachable) { system.Withhold(battery, "no native ballistic solution within elevation/flight-time limits", string.Format("iteration=%1 distance=%2 altitude=%3 charges=%4 elevation radians=%5..%6 flight limit=75s", iteration, distance, altitude, coefficients.Count(), minimum, maximum)); return ENodeResult.FAIL; } if (!reachable) { system.Withhold(battery, "no native ballistic solution within elevation/flight-time limits", string.Format("iteration=%1 distance=%2 altitude=%3 charges=%4 elevation radians=%5..%6 flight limit=75s", iteration, distance, altitude, coefficients.Count(), minimum, maximum)); return null; }
converged = Math.AbsFloat(calculated - flight) < 1; converged = Math.AbsFloat(calculated - flight) < 1;
flight = calculated; flight = calculated;
if (converged) if (converged)
break; break;
} }
if (!converged) { system.Withhold(battery, "moving intercept did not converge in four iterations"); return ENodeResult.FAIL; } if (!converged) { system.Withhold(battery, "moving intercept did not converge in four iterations"); return null; }
if (!system.Safe(battery, impact, flight + 2)) { system.Withhold(battery, "aim impact safety rejected", system.SafetyReason); return ENodeResult.FAIL; } if (!system.Safe(battery, impact, flight + 2)) { system.Withhold(battery, "aim impact safety rejected", system.SafetyReason); return null; }
battery.Impact = impact; ERR_MortarAimSolution solution = new ERR_MortarAimSolution();
battery.AimOffset = salvoOffset; solution.Gun = gun;
battery.AimedShot = battery.OrderShots; solution.Report = report;
battery.FlightTime = flight; solution.OrderId = battery.OrderId;
battery.AimedAt = now; solution.Shot = battery.OrderShots;
battery.LastFailure = ""; solution.GunOrigin = gunOrigin;
battery.Trace("AIM SOLUTION", "ready", string.Format("predicted impact=%1 flight=%2s charge index=%3 aim height offset=%4m latest source=M%5", impact, flight, charge, offset, report.MessageId)); solution.Impact = impact;
vector aim = impact + Vector(0, offset, 0); solution.AimTarget = impact + Vector(0, offset, 0);
SetVariableOut(PORT_AIM_POS, aim); solution.SalvoOffset = salvoOffset;
SetVariableOut(PORT_INIT_SPEED_ID, charge); solution.Charge = charge;
return ENodeResult.SUCCESS; solution.FlightTime = flight;
return solution;
} }
} }
@@ -204,17 +250,27 @@ modded class SCR_AIStaticArtilleryBehavior_ShootingLogic
} }
if (battery) if (battery)
{ {
if (!battery.CommandOpen) return ENodeResult.FAIL; int gate = ERR_MortarSupplyRules.CycleGate(battery.CommandOpen, battery.OrderShots, behavior.GetShotCount(), ERR_MortarSalvo.ROUNDS, ERR_MortarSupplyState.READY);
// Loading can outlast the native pause. Count confirmed shells only. if (gate < 0) return ENodeResult.FAIL;
if (battery.OrderShots <= behavior.GetShotCount()) return ENodeResult.RUNNING; if (gate == 0) return ENodeResult.RUNNING;
// Native super increments the behavior counter. Wait BEFORE calling it,
// so repeated pending ticks cannot count the same projectile twice.
if (battery.OrderShots < ERR_MortarSalvo.ROUNDS)
{
ERR_MortarSupplyState supply = battery.SupplyState(GetGame().GetWorld().GetWorldTime());
if (supply == ERR_MortarSupplyState.PENDING) return ENodeResult.RUNNING;
if (supply == ERR_MortarSupplyState.FAILED)
{
ERR_MortarSystem system = ERR_MortarSystem.Get();
if (system) system.Withhold(battery, "next native load lacks confirmed physical gunner ammunition");
return ENodeResult.FAIL;
}
}
} }
ENodeResult result = super.EOnTaskSimulate(owner, dt); ENodeResult result = super.EOnTaskSimulate(owner, dt);
if (battery && result == ENodeResult.SUCCESS) if (battery && result == ENodeResult.SUCCESS)
{ {
SetVariableOut(PORT_AIMING_NEEDED, true); SetVariableOut(PORT_AIMING_NEEDED, true);
// Transfer existing nearby crew ammunition before the next native load.
if (battery.CommandOpen && battery.OrderShots < ERR_MortarSalvo.ROUNDS)
battery.SupplyGunner();
} }
return result; return result;
} }
@@ -0,0 +1,177 @@
enum ERR_MortarSupplyState { FAILED = -1, PENDING, READY }
class ERR_MortarSupplyRules
{
static int CycleGate(bool commandOpen, int confirmedShots, int behaviorShots, int limit, int supplyState)
{
if (!commandOpen) return -1;
if (confirmedShots <= behaviorShots) return 0;
if (confirmedShots < limit) return supplyState;
return 1;
}
}
class ERR_MortarInitialItem : ScriptedInventoryOperationCallback
{
bool Finished;
bool Succeeded;
protected void Finish(bool success) { if (!Finished) { Finished = true; Succeeded = success; } }
protected override void OnComplete() { Finish(true); }
protected override void OnFailed() { Finish(false); }
protected override void OnAllComplete() { Finish(true); }
protected override void OnAllFailed() { Finish(false); }
void Rejected() { Finish(false); }
}
// One finite allocation, after the ENTIRE original support crew exists. Failed
// or stopped setup retains physical assets and retires only its pending spawn intent.
class ERR_MortarReadiness
{
protected ERR_MortarBattery m_Battery;
protected ref array<IEntity> m_Members = {};
protected ref array<ref ERR_MortarInitialItem> m_Operations = {};
protected bool m_Allocated;
protected bool m_Ready;
protected bool m_Stopped;
protected bool m_Retired;
protected int m_RequestedShells;
void ERR_MortarReadiness(ERR_MortarBattery battery) { m_Battery = battery; }
static ERR_MortarSupplyState Population(int physical, int gunners, int operators, bool complete, bool expired)
{
if (physical > 4 || gunners > 3 || operators > 1) return ERR_MortarSupplyState.FAILED;
if (physical == 4 && gunners == 3 && operators == 1 && complete && !expired) return ERR_MortarSupplyState.READY;
if (expired) return ERR_MortarSupplyState.FAILED;
return ERR_MortarSupplyState.PENDING;
}
static bool AllocationValid(int shells) { return shells >= 0 && shells <= 9; }
int RequestedShells() { return m_RequestedShells; }
bool Ready() { return m_Ready && !m_Stopped; }
void Stop()
{
if (m_Stopped) return;
m_Stopped = true;
if (m_Ready || m_Retired || !m_Battery || !m_Battery.Group || !Replication.IsServer()) return;
m_Retired = true;
// As in Core initial guard cleanup: stopping the current request alone does
// not retire the native group's still-authored future expansion intent.
RetireGroup(m_Battery.Group);
}
static void RetireGroup(SCR_AIGroup group)
{
if (!group || !Replication.IsServer()) return;
group.SetSpawnImmediately(false);
group.m_aUnitPrefabSlots = new array<ResourceName>();
if (!GetGame()) return;
ChimeraAIWorld world = ChimeraAIWorld.Cast(GetGame().GetAIWorld());
if (world) world.PurgeSpawnRequestsForGroup(group);
}
protected ERR_MortarSupplyState Fail(string reason)
{
m_Battery.SpawnFailed(reason);
Stop();
return ERR_MortarSupplyState.FAILED;
}
protected bool Allocate()
{
m_Allocated = true; // before native requests; never refill or retry a failure
foreach (IEntity actor : m_Members)
{
if (actor == m_Battery.RadioOperator) continue;
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(actor.FindComponent(InventoryStorageManagerComponent));
int existing = m_Battery.InventoryShells(inventory);
if (!AllocationValid(existing)) return false;
if (ERR_HQRadio.Capability(actor) == 0 && !inventory.TrySpawnPrefabToStorage("{E1A5D4B878AA8980}Prefabs/Items/Equipment/Radios/Radio_R148.et"))
m_Battery.Audit("RADIO EQUIP", "optional crew handset did not fit; dedicated manpack remains required");
for (int i = existing; i < 9; i++)
{
ERR_MortarInitialItem operation = new ERR_MortarInitialItem();
m_Operations.Insert(operation);
m_RequestedShells++;
if (!inventory.TrySpawnPrefabToStorage(ERR_MortarBattery.SHELL, purpose: EStoragePurpose.PURPOSE_DEPOSIT, cb: operation))
{
operation.Rejected();
return false;
}
}
}
return true;
}
ERR_MortarSupplyState Poll(float now)
{
if (m_Stopped || !Replication.IsServer() || !m_Battery || m_Battery.Stopped()) return ERR_MortarSupplyState.FAILED;
if (m_Ready) return ERR_MortarSupplyState.READY;
SCR_AIGroup group = m_Battery.Group;
ERR_GameMode mode = ERR_GameMode.Get();
if (!mode || !group || !m_Battery.Gun || group.GetFaction() != mode.EnemyFaction() || group.GetPlayerCount(true) > 0) return Fail("initial support group/gun/faction changed");
DamageManagerComponent damage = DamageManagerComponent.Cast(m_Battery.Gun.FindComponent(DamageManagerComponent));
if (!damage || damage.IsDestroyed()) return Fail("initial support gun missing damage manager or destroyed");
bool expired = now < m_Battery.SpawnedAt || now - m_Battery.SpawnedAt >= 90000;
array<AIAgent> agents = {}; group.GetAgents(agents);
array<IEntity> physical = {};
int gunners, operators;
IEntity operatorActor;
foreach (AIAgent agent : agents)
{
if (!agent || !agent.GetControlledEntity()) continue;
IEntity actor = agent.GetControlledEntity();
if (physical.Contains(actor)) return Fail("initial support group reports duplicate physical actor");
physical.Insert(actor);
if (!ERR_Actors.CanFight(actor) || SCR_FactionManager.SGetFaction(actor) != mode.EnemyFaction() || !actor.GetPrefabData()) return Fail("initial support actor unavailable or has wrong faction/resource");
ResourceName prefab = actor.GetPrefabData().GetPrefabName();
if (prefab == ERR_MortarBattery.CREW) gunners++;
else if (prefab == ERR_MortarBattery.RADIO_OPERATOR) { operators++; operatorActor = actor; }
else return Fail("initial support actor does not belong to authored crew catalog");
}
ERR_MortarSupplyState population = Population(physical.Count(), gunners, operators, group.IsExpandComplete(), expired);
if (population == ERR_MortarSupplyState.FAILED) return Fail("initial four-person support population incomplete/invalid within 90 seconds");
if (population == ERR_MortarSupplyState.PENDING) return population;
if (m_Allocated)
{
foreach (IEntity original : m_Members)
if (!physical.Contains(original)) return Fail("initial support member replaced after finite allocation");
}
foreach (IEntity member : physical)
{
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(member.FindComponent(InventoryStorageManagerComponent));
if (!inventory) return ERR_MortarSupplyState.PENDING;
if (!m_Allocated && member != operatorActor && m_Battery.InventoryShells(inventory) < 9 && !inventory.CanInsertResource(ERR_MortarBattery.SHELL, EStoragePurpose.PURPOSE_DEPOSIT)) return ERR_MortarSupplyState.PENDING;
}
if (ERR_HQRadio.Capability(operatorActor) != 2) return ERR_MortarSupplyState.PENDING;
// Preserve the existing earliest activation delay, but it is not readiness.
if (now - m_Battery.SpawnedAt < 10000) return ERR_MortarSupplyState.PENDING;
if (!m_Allocated)
{
if (!group.GetGroupUtilityComponent() || !group.GetGroupUtilityComponent().m_VehicleMgr) return ERR_MortarSupplyState.PENDING;
SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(m_Battery.Gun.FindComponent(SCR_AIVehicleUsageComponent));
if (!usage || !group.GetGroupUtilityComponent().m_VehicleMgr.TryAddVehicle(usage)) return Fail("native support gun registration failed");
m_Members.Copy(physical); m_Battery.RadioOperator = operatorActor;
if (!Allocate()) return Fail("finite initial support shell allocation rejected; no retry");
return ERR_MortarSupplyState.PENDING; // never accept mutation-frame readiness
}
foreach (ERR_MortarInitialItem operation : m_Operations)
{
if (!operation.Finished) return ERR_MortarSupplyState.PENDING;
if (!operation.Succeeded) return Fail("finite initial support shell operation failed; no retry");
}
foreach (IEntity equipped : m_Members)
{
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(equipped.FindComponent(InventoryStorageManagerComponent));
int shells = m_Battery.InventoryShells(inventory);
if (equipped == operatorActor)
{
if (shells != 0) return Fail("dedicated initial manpack operator unexpectedly carries mortar shells");
}
else if (shells != 9) return ERR_MortarSupplyState.PENDING;
}
if (m_Battery.CountShells() != 27) return ERR_MortarSupplyState.PENDING;
m_Ready = true;
group.ActivateAI();
foreach (AIAgent readyAgent : agents)
{
if (readyAgent) { readyAgent.SetPermanentLOD(0); readyAgent.ActivateAI(); }
}
m_Battery.Audit("CREW READY", string.Format("four original physical members, one manpack, 27 confirmed HE; new shell requests=%1; allocation permanently closed", m_RequestedShells));
return ERR_MortarSupplyState.READY;
}
}
@@ -0,0 +1,20 @@
// One finite response per delivered observation at this battery. Cancellation
// does not turn the same radio message into new ammunition authorization.
class ERR_MortarReportLedger
{
protected ref map<int, float> m_Attempts = new map<int, float>();
bool Available(int messageId, float observedAt, float now)
{
if (messageId <= 0 || observedAt < 0 || now < observedAt || now - observedAt > ERR_MortarPrediction.MAX_REPORT_AGE_MS) return false;
for (int i = m_Attempts.Count() - 1; i >= 0; i--)
if (now - m_Attempts.GetElement(i) > ERR_MortarPrediction.MAX_REPORT_AGE_MS) m_Attempts.Remove(m_Attempts.GetKey(i));
return !m_Attempts.Contains(messageId) && m_Attempts.Count() < 128;
}
bool Claim(int messageId, float observedAt, float now)
{
if (!Available(messageId, observedAt, now)) return false;
m_Attempts.Insert(messageId, observedAt);
return true;
}
}
@@ -0,0 +1,108 @@
class ERR_MortarSupplyCallback : ScriptedInventoryOperationCallback
{
ERR_MortarSupplyTransfer Transfer;
protected override void OnComplete() { if (Transfer) Transfer.Acknowledge(true); }
protected override void OnFailed() { if (Transfer) Transfer.Acknowledge(false); }
}
// Exact-item native transaction. Callbacks only record outcomes; the HQ tick
// authorizes progress after checking actual inventory ownership and the order.
class ERR_MortarSupplyTransfer
{
protected ERR_MortarBattery m_Battery;
protected IEntity m_Gun;
protected SCR_AIGroup m_Group;
protected IEntity m_Donor;
protected IEntity m_Gunner;
protected IEntity m_Shell;
protected InventoryStorageManagerComponent m_Source;
protected InventoryStorageManagerComponent m_Destination;
protected BaseInventoryStorageComponent m_Storage;
protected ref ERR_MortarSupplyCallback m_Callback;
protected int m_Order;
protected int m_Acknowledgement;
protected float m_Deadline;
protected bool m_Accepted;
protected bool m_Invalidated;
protected bool m_Resolved;
protected bool m_Ready;
void ERR_MortarSupplyTransfer(ERR_MortarBattery battery, IEntity donor, IEntity gunner, IEntity shell, BaseInventoryStorageComponent storage, float now)
{
m_Battery = battery; m_Gun = battery.Gun; m_Group = battery.Group;
m_Donor = donor; m_Gunner = gunner; m_Shell = shell; m_Storage = storage;
m_Order = battery.OrderId; m_Deadline = now + 8000;
m_Source = InventoryStorageManagerComponent.Cast(donor.FindComponent(InventoryStorageManagerComponent));
m_Destination = InventoryStorageManagerComponent.Cast(gunner.FindComponent(InventoryStorageManagerComponent));
}
static bool Authority(bool valid, bool invalidated, int capturedOrder, int currentOrder)
{
return valid && !invalidated && capturedOrder == currentOrder;
}
static bool Proven(bool callbackComplete, bool sourceContains, bool destinationContains, bool exactSlot)
{
return callbackComplete && !sourceContains && destinationContains && exactSlot;
}
protected bool Contains(InventoryStorageManagerComponent inventory)
{
if (!inventory || !m_Shell) return false;
array<IEntity> items = {}; ERR_Inventory.Items(inventory, items);
return items.Contains(m_Shell);
}
protected bool Valid(float now)
{
if (!m_Battery || !Authority(m_Battery.SupplyAuthorized(now), m_Invalidated, m_Order, m_Battery.OrderId)) return false;
if (m_Battery.Gun != m_Gun || m_Battery.Group != m_Group || !m_Donor || !m_Gunner || m_Donor == m_Gunner || !m_Shell || !m_Source || !m_Destination || !m_Storage) return false;
if (!ERR_Actors.CanFight(m_Donor) || !ERR_Actors.CanFight(m_Gunner) || ERR_Actors.Group(m_Donor) != m_Group || ERR_Actors.Group(m_Gunner) != m_Group) return false;
Faction faction = m_Group.GetFaction();
if (SCR_FactionManager.SGetFaction(m_Donor) != faction || SCR_FactionManager.SGetFaction(m_Gunner) != faction || vector.Distance(m_Donor.GetOrigin(), m_Gunner.GetOrigin()) > 12) return false;
SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(m_Gun.FindComponent(SCR_AIVehicleUsageComponent));
if (!usage || !usage.GetTurretCompartmentSlot()) return false;
IEntity occupant = usage.GetTurretCompartmentSlot().GetOccupant();
return !occupant || occupant == m_Gunner;
}
void Acknowledge(bool success)
{
if (m_Acknowledgement != 0) return;
if (success) m_Acknowledgement = 1;
else m_Acknowledgement = -1;
}
bool Begin(float now)
{
if (m_Callback || !Replication.IsServer() || !Valid(now) || !Contains(m_Source) || Contains(m_Destination)) return false;
m_Callback = new ERR_MortarSupplyCallback(); m_Callback.Transfer = this;
// Do not use callback.GetItem(): the native contract excludes Move operations.
m_Accepted = m_Source.TryMoveItemToStorage(m_Shell, m_Storage, -1, m_Callback);
if (!m_Accepted) { Acknowledge(false); m_Resolved = true; }
return m_Accepted;
}
void Invalidate() { m_Invalidated = true; m_Ready = false; }
bool Unresolved() { return m_Accepted && !m_Resolved; }
int CapturedOrder() { return m_Order; }
ERR_MortarSupplyState Poll(float now)
{
if (!Replication.IsServer()) return ERR_MortarSupplyState.FAILED;
bool valid = Valid(now);
bool sourceContains = Contains(m_Source);
bool destinationContains = Contains(m_Destination);
bool exactSlot;
InventoryItemComponent item;
if (m_Shell) item = InventoryItemComponent.Cast(m_Shell.FindComponent(InventoryItemComponent));
if (item && item.GetParentSlot()) exactSlot = item.GetParentSlot().GetStorage() == m_Storage;
bool proven = Proven(m_Acknowledgement == 1, sourceContains, destinationContains, exactSlot);
if (proven || m_Acknowledgement < 0) m_Resolved = true;
// A successful callback without physical destination proof is ambiguous.
// Keep it reserved through timeout/cancellation; never start a second move.
if (!valid || now >= m_Deadline)
{
m_Invalidated = true; m_Ready = false;
return ERR_MortarSupplyState.FAILED;
}
if (proven)
{
m_Ready = true;
return ERR_MortarSupplyState.READY;
}
if (m_Acknowledgement < 0 || !m_Accepted) return ERR_MortarSupplyState.FAILED;
return ERR_MortarSupplyState.PENDING;
}
}
+41 -11
View File
@@ -36,12 +36,14 @@ class ERR_MortarSystem
if (!gun || !group) if (!gun || !group)
{ {
ERR_Actors.DeleteSpawned(gun); ERR_Actors.DeleteSpawned(gun);
ERR_MortarReadiness.RetireGroup(group);
ERR_Actors.DeleteSpawned(group); ERR_Actors.DeleteSpawned(group);
return false; return false;
} }
if (group.GetFaction() != ERR_GameMode.Get().EnemyFaction()) if (group.GetFaction() != ERR_GameMode.Get().EnemyFaction())
{ {
ERR_Actors.DeleteSpawned(gun); ERR_Actors.DeleteSpawned(gun);
ERR_MortarReadiness.RetireGroup(group);
ERR_Actors.DeleteSpawned(group); ERR_Actors.DeleteSpawned(group);
return false; return false;
} }
@@ -125,13 +127,19 @@ class ERR_MortarSystem
bool AllowShot(ERR_MortarBattery battery) bool AllowShot(ERR_MortarBattery battery)
{ {
float now = GetGame().GetWorld().GetWorldTime(); float now = GetGame().GetWorld().GetWorldTime();
if (!ERR_HQ.MissionActive()) return Withhold(battery, "mission inactive"); if (m_Stopped || !ERR_HQ.MissionActive()) return Withhold(battery, "mission inactive or HQ stopped");
if (!battery.Operational()) return Withhold(battery, battery.OperationalReason()); if (!battery.Operational()) return Withhold(battery, battery.OperationalReason());
if (!battery.CommandOpen || battery.OrderShots >= ERR_MortarSalvo.ROUNDS) return Withhold(battery, "salvo complete or order closed"); if (!battery.CommandOpen || battery.OrderShots >= ERR_MortarSalvo.ROUNDS) return Withhold(battery, "salvo complete or order closed");
if (battery.Released) return Withhold(battery, "waiting for committed projectile"); if (battery.Released) return Withhold(battery, "waiting for committed projectile");
if (battery.AimedShot != battery.OrderShots || battery.AimedAt < 0 || now - battery.AimedAt > 10000) return Withhold(battery, "fresh aim solution required"); if (battery.AimedShot != battery.OrderShots || battery.AimedAt < 0 || now < battery.AimedAt) return Withhold(battery, "fresh aim solution required");
ERR_HQReport report = Latest(battery, now); ERR_HQReport report = Latest(battery, now);
if (!report) return Withhold(battery, ContactFailure(battery)); if (!report) return Withhold(battery, ContactFailure(battery));
if (!battery.AimSolution || !battery.AimSolution.Matches(battery, report)) return Withhold(battery, "aim command does not match delivered order");
if (now - battery.AimedAt > 10000)
{
if (!battery.AimSolver) return Withhold(battery, "original native aim solver no longer available");
if (!battery.AimSolver.ERR_RevalidateAim(battery, this, report, now)) return false;
}
vector updated; vector updated;
if (!ERR_MortarPrediction.Predict(report, now, battery.FlightTime, updated)) return Withhold(battery, ERR_MortarPrediction.FailureReason); if (!ERR_MortarPrediction.Predict(report, now, battery.FlightTime, updated)) return Withhold(battery, ERR_MortarPrediction.FailureReason);
updated += battery.AimOffset; updated += battery.AimOffset;
@@ -142,20 +150,41 @@ class ERR_MortarSystem
} }
protected void AdvanceOrder(ERR_MortarBattery battery, float now) protected void AdvanceOrder(ERR_MortarBattery battery, float now)
{ {
if (!battery.RadioOrder) return; if (battery.RadioOrder)
int state = battery.RadioOrder.Advance(now, m_HQ.Journal()); {
if (state == 0) return; int deliveredState = battery.RadioOrder.Advance(now, m_HQ.Journal());
if (deliveredState == 0) return;
ERR_HQReport delivered = battery.PendingRadioReport; ERR_HQReport delivered = battery.PendingRadioReport;
battery.RadioOrder = null; battery.RadioOrder = null;
battery.PendingRadioReport = null; battery.PendingRadioReport = null;
if (state < 0 || !ERR_MortarPrediction.Fresh(delivered, now) || !battery.Operational() || battery.Activity || !battery.SupplyGunner()) if (deliveredState < 0 || !ERR_MortarPrediction.Fresh(delivered, now) || !battery.Operational() || battery.Activity || !battery.CommandOpen)
{ {
battery.Cancel("radio delivery, report freshness or gunner availability failed"); battery.Cancel("radio delivery, report freshness or battery availability failed");
battery.NextOrder = now + 10000; battery.NextOrder = now + 10000;
return; return;
} }
battery.Order(delivered, now); battery.PendingSupplyReport = delivered;
} }
if (!battery.PendingSupplyReport) return;
if (!battery.CommandOpen || !ERR_MortarPrediction.Fresh(battery.PendingSupplyReport, now) || !battery.Operational() || battery.Activity)
{
battery.Cancel("delivered order expired or became unavailable while awaiting physical ammunition");
battery.NextOrder = now + 10000;
return;
}
ERR_MortarSupplyState supply = battery.SupplyState(now);
if (supply == ERR_MortarSupplyState.PENDING) return;
if (supply == ERR_MortarSupplyState.FAILED)
{
battery.Cancel("physical gunner ammunition unavailable or transfer failed");
battery.NextOrder = now + 10000;
return;
}
ERR_HQReport ready = battery.PendingSupplyReport;
battery.PendingSupplyReport = null;
battery.Order(ready, now);
}
void Tick(float now) void Tick(float now)
{ {
if (m_Stopped || !Replication.IsServer()) return; if (m_Stopped || !Replication.IsServer()) return;
@@ -179,9 +208,10 @@ class ERR_MortarSystem
float distance = float.MAX; float distance = float.MAX;
foreach (ERR_MortarBattery battery : m_Batteries) foreach (ERR_MortarBattery battery : m_Batteries)
{ {
if (!battery.StartupActivated || !battery.Operational() || battery.Activity || battery.RadioOrder || now < battery.NextOrder || battery.CountShells() == 0) continue; if (!battery.StartupActivated || !battery.Operational() || battery.Activity || battery.RadioOrder || battery.PendingSupplyReport || battery.SupplyPending() || now < battery.NextOrder || battery.CountShells() == 0) continue;
foreach (ERR_HQReport report : reports) foreach (ERR_HQReport report : reports)
{ {
if (!battery.CanRequest(report, now)) continue;
float candidate = vector.DistanceXZ(battery.Position, report.Position); float candidate = vector.DistanceXZ(battery.Position, report.Position);
if (candidate < 350 || candidate > 4000 || candidate >= distance || !OutsideSettlements(report.Position)) continue; if (candidate < 350 || candidate > 4000 || candidate >= distance || !OutsideSettlements(report.Position)) continue;
selected = battery; selected = battery;
@@ -192,7 +222,7 @@ class ERR_MortarSystem
if (!selected || !target) return; if (!selected || !target) return;
ERR_HQRoute route = m_HQ.Downlink(selected.Group, "MORTAR ORDER", target.Description(now), target.MessageId); ERR_HQRoute route = m_HQ.Downlink(selected.Group, "MORTAR ORDER", target.Description(now), target.MessageId);
if (!route) return; if (!route) return;
selected.BeginRequest(target, now); if (!selected.BeginRequest(target, now)) return;
selected.RadioId = route.MessageId; selected.RadioId = route.MessageId;
selected.RadioOrder = route; selected.RadioOrder = route;
selected.PendingRadioReport = target.Snapshot(); selected.PendingRadioReport = target.Snapshot();
@@ -216,6 +246,6 @@ class ERR_MortarSystem
void Stop() void Stop()
{ {
m_Stopped = true; m_Stopped = true;
foreach (ERR_MortarBattery battery : m_Batteries) battery.Cancel("HQ stopped"); foreach (ERR_MortarBattery battery : m_Batteries) battery.Stop();
} }
} }
@@ -0,0 +1,330 @@
#ifdef WORKBENCH
// Explicit synthetic observation only. Delivery, HQ scheduling and native fire
// are unchanged; this helper never writes directly into the HQ contact list.
modded class ERR_HQ
{
int ERR_QueueMortarFixtureReport(SCR_AIGroup source, IEntity target, vector position, float now)
{
if (!ERR_NativeMortarFiringProbe.Enabled() || !target || !m_Contacts.IsEmpty()) return 0;
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.Group != source || !unit.ReservedForSupport || !unit.Radio || unit.Uplink || unit.PendingReport) continue;
ERR_HQRoute route = m_Network.Route(unit.Radio);
if (!route || route.Nodes.IsEmpty()) return 0;
ERR_HQReport report = new ERR_HQReport();
report.MessageId = m_Journal.Message(); report.Target = target; report.Source = source;
report.Position = position; report.ObservedAt = now; report.DetailsObservedAt = now;
report.HasVelocity = true; report.Velocity = vector.Zero;
report.TravelMode = "on foot"; report.SeenEscapists = 1; report.SeenWeapons = "fixture observation";
route.MessageId = report.MessageId; route.Payload = "EXPLICIT SYNTHETIC OBSERVATION: " + report.Description(now);
unit.PendingReport = report; unit.Uplink = route;
m_Journal.Write("FIXTURE REPORT", route.Payload, report.MessageId);
return report.MessageId;
}
return 0;
}
void ERR_RemoveMortarFixtureReport(IEntity target)
{
if (!target) return;
for (int i = m_Contacts.Count() - 1; i >= 0; i--)
if (m_Contacts[i].Target == target) m_Contacts.Remove(i);
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.PendingReport && unit.PendingReport.Target == target) { unit.PendingReport = null; unit.Uplink = null; }
if ((unit.PendingOrder && unit.PendingOrder.Target == target) || (unit.Assignment && unit.Assignment.Target == target)) unit.Release();
}
}
}
// Production sets Released immediately before reserving shell airspace, then
// invokes native inventory transfer. Observe that existing commit boundary so
// even a synchronous native projectile has a prior recorded authorization.
modded class ERR_MortarBattery
{
override void ReserveShellAirspace(float now)
{
super.ReserveShellAirspace(now);
ERR_NativeMortarFiringProbe probe = ERR_NativeMortarFiringProbe.Active();
if (probe) probe.NativeCommit(this, now);
}
override void Cancel(string reason = "cancel requested")
{
ERR_NativeMortarFiringProbe probe = ERR_NativeMortarFiringProbe.Active();
if (probe) probe.NativeClosing(this, reason, LastFailure);
super.Cancel(reason);
}
}
class ERR_NativeMortarEvidenceRules
{
static bool CommitFresh(float observed, float expectedObserved, float committed)
{
return observed == expectedObserved && observed >= 0 && committed >= observed && committed - observed <= ERR_MortarPrediction.MAX_REPORT_AGE_MS;
}
static bool EventBound(bool pending, int order, int currentOrder, int shot, int currentShot, float committed, float emitted)
{
// The fixture has its own overall deadline. A committed shell does not gain
// a second authorization expiry while native physical transfer completes.
return pending && order == currentOrder && shot == currentShot && emitted >= committed;
}
static bool ExpiredClosure(float observed, float closed, string failure)
{
return observed >= 0 && closed > observed + ERR_MortarPrediction.MAX_REPORT_AGE_MS && (failure.Contains("delivered target report expired") || failure.Contains("observation older than 60s"));
}
}
// Observe only the actual native event. Node SUCCESS, accepted inventory moves
// and committed shell loading are never counted as physical projectiles.
modded class SCR_MortarMuzzleComponent
{
override void OnWeaponFired(IEntity effectEntity, BaseMuzzleComponent muzzle, IEntity projectileEntity)
{
ERR_NativeMortarFiringProbe probe = ERR_NativeMortarFiringProbe.Active();
if (probe) probe.NativeProjectile(GetOwner(), projectileEntity);
super.OnWeaponFired(effectEntity, muzzle, projectileEntity);
}
}
class ERR_NativeMortarFiringProbe
{
protected static ERR_NativeMortarFiringProbe s_Active;
protected ERR_GameMode m_Mode;
protected ERR_MortarBattery m_Battery;
protected IEntity m_Gun;
protected SCR_AIGroup m_Group;
protected IEntity m_Target;
protected vector m_Impact;
protected ref array<IEntity> m_Crew = {};
protected ref array<IEntity> m_InitialShells = {};
protected ref array<IEntity> m_Projectiles = {};
protected int m_Source;
protected int m_Order;
protected int m_Step;
protected int m_Events;
protected int m_StoppedShells;
protected float m_Deadline;
protected float m_NextDiagnostic;
protected float m_StopUntil;
protected float m_ObservedAt;
protected bool m_WaitForExpiry;
protected int m_FinalEvents;
protected bool m_CommitPending;
protected float m_CommittedAt;
protected int m_CommitOrder;
protected int m_CommitShot;
protected int m_Commits;
protected bool m_ClosureSeen;
protected bool m_ClosureExpired;
protected bool m_ClosureComplete;
protected bool m_Unsafe;
protected bool m_BadProjectile;
protected bool m_SawUplink;
protected bool m_SawDownlink;
protected bool m_SawActivity;
protected bool m_Stopped;
protected string m_BadReason;
static bool Enabled()
{
string enabled, outcome;
return Replication.IsServer() && System.GetCLIParam("errSmoke", enabled) && enabled == "1" && System.GetCLIParam("errSmokeOutcome", outcome) && (outcome == "mortar-fire" || outcome == "mortar-expiry");
}
static ERR_NativeMortarFiringProbe Active() { return s_Active; }
void ERR_NativeMortarFiringProbe(ERR_GameMode mode)
{
m_Mode = mode;
string outcome; System.GetCLIParam("errSmokeOutcome", outcome); m_WaitForExpiry = outcome == "mortar-expiry";
m_Deadline = GetGame().GetWorld().GetWorldTime() + 180000;
if (Enabled() && !s_Active) s_Active = this;
}
protected bool Check(bool condition, string detail)
{
if (condition) { Print("ERR SMOKE PASS: mortar firing " + detail); return true; }
Print("ERR SMOKE FAIL: mortar firing " + detail, LogLevel.ERROR); Stop(); return false;
}
protected void Shells(out array<IEntity> shells)
{
shells.Clear();
foreach (IEntity actor : m_Crew)
{
if (!actor) continue;
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(actor.FindComponent(InventoryStorageManagerComponent));
array<IEntity> items = {}; ERR_Inventory.Items(inventory, items);
foreach (IEntity item : items)
if (item && item.GetPrefabData() && item.GetPrefabData().GetPrefabName() == ERR_MortarBattery.SHELL && !shells.Contains(item)) shells.Insert(item);
}
}
protected bool CheckNoOccupants(IEntity entity)
{
if (ChimeraCharacter.Cast(entity) || Vehicle.Cast(entity)) { m_Unsafe = true; return false; }
return true;
}
protected bool EmptyImpact(vector position)
{
m_Unsafe = false;
GetGame().GetWorld().QueryEntitiesByAABB(position - "200 5000 200", position + "200 5000 200", CheckNoOccupants, null, EQueryEntitiesFlags.ALL);
return !m_Unsafe;
}
protected bool SelectImpact(ERR_MortarSystem system)
{
// Bounded candidate survey: no clearance assumption from coordinates alone.
array<vector> offsets = {"-800 0 -600", "-600 0 -800", "0 0 -1000", "600 0 -800", "-1000 0 0", "800 0 -600", "-800 0 600", "0 0 1000"};
foreach (vector offset : offsets)
{
vector candidate = ERR_Actors.Ground(m_Battery.Position + offset);
if (candidate[1] < 1 || !EmptyImpact(candidate) || !system.Safe(m_Battery, candidate, 75)) continue;
bool clear = true;
for (int shot = 0; shot < ERR_MortarSalvo.ROUNDS; shot++)
{
vector spread = ERR_Actors.Ground(candidate + ERR_MortarSalvo.Offset(m_Battery.SiteId, m_Battery.OrderId + 1, shot));
if (!system.Safe(m_Battery, spread, 75)) { clear = false; break; }
}
if (!clear) continue;
m_Impact = candidate;
PrintFormat("ERR MORTAR FIXTURE IMPACT: position=%1 batteryDistance=%2; no characters/vehicles in 400m square; production settlement/friendly exclusions passed", candidate, vector.DistanceXZ(candidate, m_Battery.Position));
return true;
}
return false;
}
protected void Diagnose(float now)
{
if (now < m_NextDiagnostic) return;
m_NextDiagnostic = now + 5000;
if (!m_Battery) { Print("ERR MORTAR FIXTURE: waiting for one authored battery"); return; }
PrintFormat("ERR MORTAR FIXTURE: step=%1 startup=%2 source=M%3 observedEvents=%4 ready=%5 failure=%6", m_Step, m_Battery.StartupActivated, m_Source, m_Events, m_Battery.Operational(), m_Battery.SpawnFailure);
m_Battery.SiteStatus(now);
}
void NativeCommit(ERR_MortarBattery battery, float now)
{
if (m_Stopped || battery != m_Battery) return;
if ((m_Step != 1 && m_Step != 3) || m_CommitPending || !battery.CommandOpen || !battery.Released || battery.SourceId != m_Source || battery.OrderId != m_Order || !battery.Report || battery.Report.MessageId != m_Source || !ERR_NativeMortarEvidenceRules.CommitFresh(battery.Report.ObservedAt, m_ObservedAt, now) || battery.AimedAt < 0 || now < battery.AimedAt || now - battery.AimedAt > 10000 || battery.FlightTime <= 0)
{ m_BadProjectile = true; m_BadReason = "physical commit lacks immutable fresh report/current order/native aim, or duplicates pending commit"; return; }
m_CommitPending = true; m_CommittedAt = now; m_CommitOrder = battery.OrderId; m_CommitShot = battery.OrderShots; m_Commits++;
PrintFormat("ERR MORTAR FIXTURE COMMIT: count=%1 order=%2 shot=%3 source=M%4 observedAge=%5; recorded before native inventory transfer", m_Commits, m_CommitOrder, m_CommitShot, m_Source, now - m_ObservedAt);
}
void NativeClosing(ERR_MortarBattery battery, string reason, string failure)
{
if (m_Stopped || !m_WaitForExpiry || battery != m_Battery || !battery.CommandOpen || battery.SourceId != m_Source || m_Source <= 0) return;
float now = GetGame().GetWorld().GetWorldTime();
m_ClosureSeen = true;
m_ClosureComplete = battery.OrderShots == ERR_MortarSalvo.ROUNDS && m_Events == ERR_MortarSalvo.ROUNDS;
m_ClosureExpired = ERR_NativeMortarEvidenceRules.ExpiredClosure(m_ObservedAt, now, failure);
PrintFormat("ERR MORTAR FIXTURE CLOSURE: order=%1 observedAge=%2 reason=%3 lastFailure=%4 complete=%5 expiredWithheld=%6", battery.OrderId, now - m_ObservedAt, reason, failure, m_ClosureComplete, m_ClosureExpired);
if (battery.Stopped() || battery.OrderId != m_Order || (!m_ClosureExpired && !m_ClosureComplete))
{ m_BadProjectile = true; m_BadReason = "expiry evidence interrupted by Stop or unrelated/incomplete order closure"; }
}
void NativeProjectile(IEntity gun, IEntity projectile)
{
if (m_Stopped || !m_Battery || gun != m_Gun) return;
if (!projectile) { m_BadProjectile = true; m_BadReason = "native fired event has no physical projectile"; return; }
if (m_Projectiles.Contains(projectile)) { m_BadProjectile = true; m_BadReason = "same physical projectile observed twice"; return; }
m_Projectiles.Insert(projectile); m_Events++;
float now = GetGame().GetWorld().GetWorldTime();
if ((m_Step != 1 && m_Step != 3) || !m_Battery.Released || m_Battery.SourceId != m_Source || !ERR_NativeMortarEvidenceRules.EventBound(m_CommitPending, m_CommitOrder, m_Battery.OrderId, m_CommitShot, m_Battery.OrderShots, m_CommittedAt, now))
{ m_BadProjectile = true; m_BadReason = "projectile lacks the recorded fresh physical commit for its current order/shot"; }
m_CommitPending = false;
PrintFormat("ERR MORTAR FIXTURE PROJECTILE: event=%1 entity=%2 origin=%3 order=%4 source=M%5 aimAge=%6 flight=%7; impact is not measured", m_Events, projectile, projectile.GetOrigin(), m_Battery.OrderId, m_Battery.SourceId, now - m_Battery.AimedAt, m_Battery.FlightTime);
}
int Tick(float now)
{
if (m_Stopped) return -1;
if (!Enabled() || s_Active != this || !m_Mode || !m_Mode.Active()) { Check(false, "explicit active fixture context retained"); return -1; }
ERR_HQ hq = ERR_HQ.Get();
ERR_MortarSystem system;
if (hq) system = hq.Mortars();
if (!system) { Check(false, "real HQ mortar service available"); return -1; }
if (!m_Battery)
{
array<IEntity> guns = {}; system.AppendGuns(guns);
if (guns.Count() == 1) { m_Gun = guns[0]; m_Battery = system.FindGun(m_Gun); }
}
Diagnose(now);
if (now >= m_Deadline) { Check(false, "bounded deadline; inspect readiness/route/activity/aim diagnostics"); return -1; }
if (m_BadProjectile) { Check(false, m_BadReason); return -1; }
if (!m_Battery) return 0;
if (!m_Battery.SpawnFailure.IsEmpty()) { Check(false, "battery startup failed: " + m_Battery.SpawnFailure); return -1; }
if (m_Step == 0)
{
if (!m_Battery.StartupActivated || !m_Battery.Operational() || !hq.MortarConnected(m_Battery.Group)) return 0;
m_Group = m_Battery.Group;
if (!Check(m_Group && m_Group.IsExpandComplete() && m_Group.GetAgentsCount() == 4 && m_Battery.TotalShots == 0 && m_Battery.OrderId == 0 && !m_Battery.CommandOpen && !m_Battery.Activity && !m_Battery.RadioOrder, "untasked original gun and complete four-person crew start without shots")) return -1;
array<AIAgent> agents = {}; m_Group.GetAgents(agents);
foreach (AIAgent agent : agents)
{
IEntity actor; if (agent) actor = agent.GetControlledEntity();
if (!Check(ERR_Actors.CanFight(actor) && !m_Crew.Contains(actor), "initial physical crew member is conscious and unique")) return -1;
m_Crew.Insert(actor);
}
if (!Check(m_Battery.RadioOperator && ERR_HQRadio.Capability(m_Battery.RadioOperator) == 2, "dedicated actual manpack supplies the radio route")) return -1;
Shells(m_InitialShells);
if (!Check(m_InitialShells.Count() == 27 && m_Battery.CountShells() == 27, "exactly 27 distinct physical initial HE shells")) return -1;
if (!Check(SelectImpact(system), "bounded candidate survey finds an unoccupied production-safe impact area")) return -1;
m_Target = ERR_Actors.Spawn(ERR_Resources.IntelFolder(), m_Impact);
if (!Check(m_Target != null, "fixture-owned inert report identity exists; no enemy perception is claimed")) return -1;
m_Source = hq.ERR_QueueMortarFixtureReport(m_Group, m_Target, m_Impact, now);
if (!Check(m_Source > 0, "synthetic observation enters actual existing radio uplink once")) return -1;
m_ObservedAt = now; m_SawUplink = true; m_Deadline = now + 90000; m_Step = 1; return 0;
}
if (m_WaitForExpiry && m_Battery.Stopped()) { Check(false, "battery must remain running throughout natural expiry observation"); return -1; }
if (m_Battery.Report && (m_Battery.Report.MessageId != m_Source || m_Battery.Report.ObservedAt != m_ObservedAt)) { Check(false, "delivered report identity and original observation timestamp remain immutable"); return -1; }
if (m_Battery.Gun != m_Gun || m_Battery.Group != m_Group) { Check(false, "original gun and crew identity retained"); return -1; }
if (!EmptyImpact(m_Impact)) { Check(false, "impact exclusion stays unoccupied before native firing/cancellation"); return -1; }
array<IEntity> remaining = {}; Shells(remaining);
foreach (IEntity item : remaining)
if (!m_InitialShells.Contains(item)) { Check(false, "no replacement HE shell appears after initialization"); return -1; }
if (m_Step == 1)
{
if (m_Battery.RadioOrder && m_Battery.SourceId == m_Source) { m_SawDownlink = true; m_Order = m_Battery.OrderId; }
if (m_Battery.Activity && m_Battery.Report && m_Battery.Report.MessageId == m_Source) m_SawActivity = true;
if (m_Battery.OrderId > 1 || (m_Battery.SourceId != 0 && m_Battery.SourceId != m_Source)) { Check(false, "one unchanged fixture source creates only one HQ order"); return -1; }
if (m_Events == 0) return 0;
if (!Check(m_Events == 1 && m_Battery.TotalShots == 1 && m_Battery.OrderShots == 1 && !m_Battery.Released && m_SawUplink && m_SawDownlink && m_SawActivity && m_Order == 1, "one physical projectile follows real uplink/downlink, native activity and fresh aim")) return -1;
if (!Check(remaining.Count() == 26 && m_Battery.CountShells() == 26, "one fired projectile consumes one of 27 original inventory shells")) return -1;
if (m_WaitForExpiry)
{
m_Step = 3; m_Deadline = m_ObservedAt + ERR_MortarPrediction.MAX_REPORT_AGE_MS + 50000;
return 0;
}
m_FinalEvents = m_Events;
// Cancel on this later fixture tick, never reentrantly inside the firing node.
hq.ERR_RemoveMortarFixtureReport(m_Target);
system.Stop(); system.Stop();
if (!Check(!m_Battery.CommandOpen && !m_Battery.Activity && !m_Battery.RadioOrder, "explicit support Stop closes native order and route idempotently")) return -1;
m_StoppedShells = remaining.Count(); m_StopUntil = now + 12000; m_Deadline = m_StopUntil + 2000; m_Step = 2; return 0;
}
if (m_Step == 3)
{
if (m_Battery.OrderId != m_Order || m_Battery.SourceId != m_Source) { Check(false, "unchanged delivered observation received a second order"); return -1; }
if (m_Events > ERR_MortarSalvo.ROUNDS || m_Battery.TotalShots > ERR_MortarSalvo.ROUNDS) { Check(false, "single observation cannot exceed finite salvo"); return -1; }
if (now < m_ObservedAt + ERR_MortarPrediction.MAX_REPORT_AGE_MS + 25000) return 0;
if (!Check(m_ClosureSeen && (m_ClosureExpired || m_ClosureComplete) && !m_CommitPending && m_Commits == m_Events && m_Events >= 1 && m_Battery.TotalShots == m_Events && m_Battery.OrderShots == m_Events && remaining.Count() == 27 - m_Events && !m_Battery.CommandOpen && !m_Battery.Activity && !m_Battery.RadioOrder && !m_Battery.Report, "explicit expired-withheld closure or complete finite salvo, with only fresh commits and observed physical shells consumed")) return -1;
m_FinalEvents = m_Events;
// Keep HQ running and the expired contact present throughout this next wait.
m_StoppedShells = remaining.Count(); m_StopUntil = now + 12000; m_Deadline = m_StopUntil + 2000; m_Step = 4;
return 0;
}
if (now < m_StopUntil) return 0;
if (!Check(m_Battery.TotalShots == m_FinalEvents && m_Events == m_FinalEvents && m_Battery.OrderId == m_Order && remaining.Count() == m_StoppedShells && !m_Battery.CommandOpen && !m_Battery.Activity && !m_Battery.RadioOrder, "closed order issues no duplicate order, projectile or replenishment over 12 seconds")) return -1;
array<AIAgent> finalCrew = {}; m_Group.GetAgents(finalCrew);
if (!Check(finalCrew.Count() == 4 && m_Battery.Gun == m_Gun, "original group and gun retain four crew")) return -1;
foreach (AIAgent finalAgent : finalCrew)
if (!Check(finalAgent && m_Crew.Contains(finalAgent.GetControlledEntity()) && ERR_Actors.CanFight(finalAgent.GetControlledEntity()), "final conscious crew entity belongs to original physical roster")) return -1;
if (m_WaitForExpiry) { hq.ERR_RemoveMortarFixtureReport(m_Target); system.Stop(); system.Stop(); }
Stop(); return 1;
}
void Stop()
{
if (m_Stopped) return;
m_Stopped = true;
ERR_HQ hq = ERR_HQ.Get();
if (hq)
{
hq.ERR_RemoveMortarFixtureReport(m_Target);
if (m_Battery && m_Battery.SourceId == m_Source && m_Source > 0) m_Battery.Cancel("mortar firing fixture cleanup");
}
ERR_Actors.DeleteSpawned(m_Target); m_Target = null;
if (s_Active == this) s_Active = null;
}
void ~ERR_NativeMortarFiringProbe() { Stop(); }
}
#endif
@@ -0,0 +1,383 @@
#ifdef WORKBENCH
// Mechanism-only fixture: radio delivery and automatic artillery scheduling are
// explicitly bypassed. All ammunition and inventory operations remain physical.
modded class ERR_MortarSystem
{
protected ERR_NativeMortarTransferProbe m_ERRTransferFixture;
bool ERR_HoldForTransfer(ERR_NativeMortarTransferProbe owner)
{
if (!ERR_NativeMortarTransferProbe.Enabled() || m_Stopped || m_ERRTransferFixture || !owner) return false;
m_ERRTransferFixture = owner; return true;
}
void ERR_ReleaseTransferHold(ERR_NativeMortarTransferProbe owner)
{
if (m_ERRTransferFixture == owner) m_ERRTransferFixture = null;
}
override void Tick(float now)
{
if (m_ERRTransferFixture) return;
super.Tick(now);
}
ERR_MortarBattery ERR_TransferBattery()
{
if (m_Batteries.Count() != 1) return null;
return m_Batteries[0];
}
}
modded class ERR_MortarBattery
{
ERR_MortarSupplyTransfer ERR_TransferForProbe() { return m_Transfer; }
int ERR_TransferAttempts() { return m_AttemptedShells.Count(); }
}
modded class ERR_MortarSupplyTransfer
{
int ERR_CallbackState() { return m_Acknowledgement; }
IEntity ERR_TransferredShell() { return m_Shell; }
IEntity ERR_TransferRecipient() { return m_Gunner; }
bool ERR_RequestAccepted() { return m_Accepted; }
}
class ERR_NativeMortarMoveCallback : ScriptedInventoryOperationCallback
{
int Result;
protected override void OnComplete() { if (Result == 0) Result = 1; }
protected override void OnFailed() { if (Result == 0) Result = -1; }
}
class ERR_NativeMortarShellOwner
{
IEntity Shell;
IEntity OriginalOwner;
}
class ERR_NativeMortarTransferProbe
{
protected ERR_GameMode m_Mode;
protected ERR_MortarSystem m_System;
protected ERR_MortarBattery m_Battery;
protected IEntity m_Gunner;
protected BaseCompartmentSlot m_Seat;
protected ref array<IEntity> m_Crew = {};
protected ref array<IEntity> m_Boxes = {};
protected ref array<BaseInventoryStorageComponent> m_Stores = {};
protected ref array<ref ERR_NativeMortarShellOwner> m_Original = {};
protected ref ERR_NativeMortarMoveCallback m_MoveCallback;
protected IEntity m_MoveShell;
protected BaseInventoryStorageComponent m_MoveDestination;
protected float m_MoveDeadline;
protected ref ERR_MortarSupplyTransfer m_ObservedTransfer;
protected IEntity m_FirstShell;
protected IEntity m_SecondShell;
protected int m_AttemptsAtStart;
protected int m_ShotsAtStart;
protected int m_CallbackAtCancel;
protected int m_CancelOrder;
protected int m_Step;
protected float m_Deadline;
protected float m_StepDeadline;
protected float m_Wait;
protected bool m_Held;
protected bool m_Stopped;
protected bool m_Complete;
static const ResourceName STORE = "{EBBC859CCD94D96D}Prefabs/Props/EmptyStorages/USSR_AmmoBox_empty.et";
static bool Enabled()
{
string enabled, outcome;
return Replication.IsServer() && System.GetCLIParam("errSmoke", enabled) && enabled == "1" && System.GetCLIParam("errSmokeOutcome", outcome) && outcome == "mortar-transfer";
}
void ERR_NativeMortarTransferProbe(ERR_GameMode mode)
{
m_Mode = mode; m_Deadline = GetGame().GetWorld().GetWorldTime() + 180000;
}
protected bool Check(bool condition, string detail)
{
if (condition) { Print("ERR SMOKE PASS: mortar transfer " + detail); return true; }
Print("ERR SMOKE FAIL: mortar transfer " + detail, LogLevel.ERROR); Stop(); return false;
}
protected bool IsShell(IEntity item)
{
return item && item.GetPrefabData() && item.GetPrefabData().GetPrefabName() == ERR_MortarBattery.SHELL;
}
protected InventoryStorageManagerComponent Inventory(IEntity actor)
{
if (!actor) return null;
return InventoryStorageManagerComponent.Cast(actor.FindComponent(InventoryStorageManagerComponent));
}
protected bool Has(IEntity actor, IEntity item)
{
array<IEntity> items = {}; ERR_Inventory.Items(Inventory(actor), items);
return item && items.Contains(item);
}
protected IEntity CrewOwner(IEntity item)
{
foreach (IEntity actor : m_Crew) if (Has(actor, item)) return actor;
return null;
}
protected IEntity OriginalOwner(IEntity item)
{
foreach (ERR_NativeMortarShellOwner entry : m_Original) if (entry.Shell == item) return entry.OriginalOwner;
return null;
}
protected bool InStore(IEntity item)
{
foreach (BaseInventoryStorageComponent storage : m_Stores) if (storage && storage.Contains(item)) return true;
return false;
}
static bool Conservation(int originals, int actual, bool allOriginal, bool singleOwner)
{
return originals == 27 && actual == originals && allOriginal && singleOwner;
}
protected bool Conserved()
{
array<IEntity> actual = {};
foreach (IEntity actor : m_Crew)
{
array<IEntity> items = {}; ERR_Inventory.Items(Inventory(actor), items);
foreach (IEntity item : items) if (IsShell(item) && !actual.Contains(item)) actual.Insert(item);
}
foreach (BaseInventoryStorageComponent storage : m_Stores)
{
if (!storage) return false;
array<IEntity> items = {}; storage.GetAll(items);
foreach (IEntity item : items) if (IsShell(item) && !actual.Contains(item)) actual.Insert(item);
}
bool allOriginal = true;
bool singleOwner = true;
foreach (ERR_NativeMortarShellOwner entry : m_Original)
{
if (!entry.Shell || !actual.Contains(entry.Shell)) allOriginal = false;
int owners;
foreach (IEntity actor : m_Crew) if (Has(actor, entry.Shell)) owners++;
foreach (BaseInventoryStorageComponent storage : m_Stores) if (storage && storage.Contains(entry.Shell)) owners++;
if (owners != 1) singleOwner = false;
}
return Conservation(m_Original.Count(), actual.Count(), allOriginal, singleOwner);
}
protected IEntity FirstGunnerShell()
{
array<IEntity> items = {}; ERR_Inventory.Items(Inventory(m_Gunner), items);
foreach (IEntity item : items) if (IsShell(item)) return item;
return null;
}
protected bool BeginMove(IEntity shell, BaseInventoryStorageComponent destination, float now)
{
if (!shell || !destination || m_MoveCallback) return false;
IEntity current = CrewOwner(shell);
// A vanilla empty box has storage but no inventory manager. The original
// recipient manager performs its explicit pickup from the external storage.
if (!current) current = OriginalOwner(shell);
InventoryStorageManagerComponent manager = Inventory(current);
if (!manager) return false;
m_MoveShell = shell; m_MoveDestination = destination;
m_MoveCallback = new ERR_NativeMortarMoveCallback(); m_MoveDeadline = now + 8000;
if (!manager.TryMoveItemToStorage(shell, destination, -1, m_MoveCallback)) return false;
return true;
}
protected int MoveResult(float now)
{
if (!m_MoveCallback) return 1;
if (m_MoveCallback.Result < 0 || now >= m_MoveDeadline) return -1;
if (m_MoveCallback.Result == 0 || !m_MoveShell || !m_MoveDestination || !m_MoveDestination.Contains(m_MoveShell)) return 0;
InventoryItemComponent item = InventoryItemComponent.Cast(m_MoveShell.FindComponent(InventoryItemComponent));
if (!item || !item.GetParentSlot() || item.GetParentSlot().GetStorage() != m_MoveDestination) return 0;
m_MoveCallback = null; m_MoveShell = null; m_MoveDestination = null;
return 1;
}
protected bool Stash(IEntity shell, float now)
{
foreach (BaseInventoryStorageComponent storage : m_Stores)
if (storage && storage.GetEstimatedCountFitForItem(shell) > 0) return BeginMove(shell, storage, now);
return false;
}
protected void StageOrder(float now)
{
ERR_HQReport report = new ERR_HQReport();
report.Target = GetGame().GetPlayerController().GetControlledEntity();
report.Source = m_Battery.Group;
report.Position = m_Battery.Gun.GetOrigin() + "700 0 0";
report.ObservedAt = now; report.DetailsObservedAt = now;
report.TravelMode = "on foot"; report.MessageId = 900001 + m_Battery.OrderId;
m_Battery.BeginRequest(report, now);
m_Battery.PendingSupplyReport = report.Snapshot();
PrintFormat("ERR MORTAR TRANSFER FIXTURE: synthetic supply order=%1; radio bypassed; scheduler held; no artillery activity authorized", m_Battery.OrderId);
}
protected bool NoFire()
{
return m_Battery && m_Battery.TotalShots == m_ShotsAtStart && !m_Battery.Activity && !m_Battery.RadioOrder && !m_Battery.Released;
}
void Stop()
{
if (m_Stopped) return;
m_Stopped = true;
if (m_Battery) m_Battery.Cancel("native transfer fixture stopped");
if (m_System)
{
m_System.Stop(); // do not resume automatic fire while test items may be stored
if (m_Held) m_System.ERR_ReleaseTransferHold(this);
}
m_Held = false;
// Never delete a box containing borrowed shells or an outstanding operation.
// Failure preserves it for diagnosis/normal round-owned cleanup.
if (!m_MoveCallback)
{
foreach (IEntity box : m_Boxes)
{
if (!box) continue;
BaseInventoryStorageComponent storage = BaseInventoryStorageComponent.Cast(box.FindComponent(BaseInventoryStorageComponent));
array<IEntity> items = {}; if (storage) storage.GetAll(items);
if (storage && items.IsEmpty()) ERR_Actors.DeleteSpawned(box);
}
}
}
int Tick(float now)
{
if (m_Complete) return 1;
if (m_Stopped) return -1;
if (!Enabled() || now > m_Deadline) { Check(false, "enabled server fixture and bounded 180-second deadline"); return -1; }
if (now < m_Wait) return 0;
if (m_MoveCallback)
{
int moved = MoveResult(now);
if (moved < 0) { Check(false, "fixture inventory move completed with exact destination before deadline; borrowed shells retained"); return -1; }
if (moved == 0) return 0;
if (!Check(Conserved(), "all original 27 shell identities conserved after fixture move")) return -1;
}
if (m_Step == 0)
{
m_System = ERR_MortarSystem.Get();
if (!m_System) return 0;
m_Battery = m_System.ERR_TransferBattery();
if (!m_Battery || !m_Battery.StartupActivated) return 0;
if (!Check(m_Battery.Operational() && m_Battery.CountShells() == 27 && !m_Battery.Activity && !m_Battery.RadioOrder && !m_Battery.CommandOpen, "actual initialized idle battery has finite 27 shells")) return -1;
if (!Check(m_System.ERR_HoldForTransfer(this), "opt-in mechanism fixture holds automatic mortar scheduler")) return -1;
m_Held = true; m_AttemptsAtStart = m_Battery.ERR_TransferAttempts(); m_ShotsAtStart = m_Battery.TotalShots;
array<AIAgent> agents = {}; m_Battery.Group.GetAgents(agents);
foreach (AIAgent agent : agents)
{
if (!agent || !ERR_Actors.CanFight(agent.GetControlledEntity())) continue;
IEntity actor = agent.GetControlledEntity(); if (m_Crew.Contains(actor)) continue;
m_Crew.Insert(actor);
array<IEntity> items = {}; ERR_Inventory.Items(Inventory(actor), items);
foreach (IEntity item : items)
{
if (!IsShell(item)) continue;
ERR_NativeMortarShellOwner entry = new ERR_NativeMortarShellOwner(); entry.Shell = item; entry.OriginalOwner = actor; m_Original.Insert(entry);
}
if (!m_Gunner && actor != m_Battery.RadioOperator) m_Gunner = actor;
}
if (!Check(m_Crew.Count() == 4 && m_Original.Count() == 27 && m_Gunner != null, "four real crew and original shell-owner identities captured")) return -1;
SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(m_Battery.Gun.FindComponent(SCR_AIVehicleUsageComponent));
if (usage) m_Seat = usage.GetTurretCompartmentSlot();
if (m_Seat && m_Seat.GetOccupant())
{
IEntity occupant = m_Seat.GetOccupant();
if (!Check(m_Crew.Contains(occupant) && occupant != m_Battery.RadioOperator && ERR_Actors.CanFight(occupant), "existing native seat occupant is original fighting gunner")) return -1;
m_Gunner = occupant;
}
else
{
CompartmentAccessComponent access = CompartmentAccessComponent.Cast(m_Gunner.FindComponent(CompartmentAccessComponent));
if (!Check(m_Seat && access && access.GetInVehicle(m_Battery.Gun, m_Seat, true, -1, ECloseDoorAfterActions.INVALID, false), "native seating request selects actual original crew gunner")) return -1;
}
if (!Check(m_Battery.InventoryShells(Inventory(m_Gunner)) == 9, "selected actual gunner owns its original nine physical shells")) return -1;
for (int i = 0; i < 2; i++)
{
IEntity box = ERR_Actors.Spawn(STORE, ERR_Actors.Ground(m_Battery.Gun.GetOrigin() + Vector(3 + i * 2, 0, 3)));
if (!Check(box != null, "fixture-owned empty vanilla storage created")) return -1;
m_Boxes.Insert(box); m_Mode.Own(box);
BaseInventoryStorageComponent storage = BaseInventoryStorageComponent.Cast(box.FindComponent(BaseInventoryStorageComponent));
if (!Check(storage != null, "real vanilla storage component available without attaching it to gunner inventory")) return -1;
m_Stores.Insert(storage);
}
m_Step = 1; m_StepDeadline = now + 8000; m_Wait = now + 500; return 0;
}
if (!NoFire()) { Check(false, "no artillery activity, committed load or physical projectile during inventory mechanism test"); return -1; }
if (m_Step == 1)
{
if (m_Seat.GetOccupant() != m_Gunner)
{
if (now >= m_StepDeadline) { Check(false, "actual original gunner occupies native mortar seat"); return -1; }
return 0;
}
if (!Check(Conserved(), "27 original shells have exactly one observed owner each")) return -1;
m_Step = 2;
}
if (m_Step == 2 || m_Step == 5)
{
IEntity shell = FirstGunnerShell();
if (shell)
{
if (!Check(Stash(shell, now), "one existing gunner shell move to vanilla store accepted; no shell minted")) return -1;
return 0;
}
if (!Check(m_Battery.InventoryShells(Inventory(m_Gunner)) == 0 && Conserved(), "actual gunner empty while all 27 original shells remain in crew or fixture storage")) return -1;
StageOrder(now);
ERR_MortarSupplyState started = m_Battery.SupplyState(now);
m_ObservedTransfer = m_Battery.ERR_TransferForProbe();
if (!Check(started == ERR_MortarSupplyState.PENDING && m_ObservedTransfer && m_ObservedTransfer.ERR_RequestAccepted() && m_ObservedTransfer.ERR_TransferRecipient() == m_Gunner && m_ObservedTransfer.CapturedOrder() == m_Battery.OrderId, "production exact-shell request accepted once with captured current order and real gunner")) return -1;
if (m_Step == 2)
{
m_FirstShell = m_ObservedTransfer.ERR_TransferredShell();
m_Step = 3;
}
else
{
m_SecondShell = m_ObservedTransfer.ERR_TransferredShell(); m_CallbackAtCancel = m_ObservedTransfer.ERR_CallbackState(); m_CancelOrder = m_Battery.OrderId;
m_Battery.Cancel("native fixture cancels authorization immediately after accepted inventory request");
if (!Check(m_SecondShell && m_SecondShell != m_FirstShell && !m_Battery.CommandOpen && m_Battery.SupplyState(now) == ERR_MortarSupplyState.FAILED, "canceled current order cannot report supply READY or issue another request")) return -1;
PrintFormat("ERR MORTAR TRANSFER CANCEL: callbackBeforeCancel=%1 order=%2; accepted native move is not retracted", m_CallbackAtCancel, m_CancelOrder);
m_Step = 6;
}
m_StepDeadline = now + 8000; m_Wait = now + 250; return 0;
}
if (m_Step == 3)
{
ERR_MortarSupplyState state = m_Battery.SupplyState(now);
if (state == ERR_MortarSupplyState.FAILED || now >= m_StepDeadline) { Check(false, "production transfer completes within its bounded deadline"); return -1; }
if (state == ERR_MortarSupplyState.PENDING) return 0;
if (!Check(m_ObservedTransfer.ERR_CallbackState() == 1 && Has(m_Gunner, m_FirstShell) && !Has(OriginalOwner(m_FirstShell), m_FirstShell) && Conserved() && m_Battery.ERR_TransferAttempts() == m_AttemptsAtStart + 1, "successful native callback and exact donor-to-gunner ownership, one attempt, original 27 conserved")) return -1;
if (!Check(m_Battery.SupplyState(now) == ERR_MortarSupplyState.READY && m_Battery.ERR_TransferAttempts() == m_AttemptsAtStart + 1, "repeated supply check reuses actual inventory without another move")) return -1;
m_Battery.Cancel("native success subcase finished; no artillery activity requested");
m_Step = 5; return 0;
}
if (m_Step == 6)
{
if (m_Battery.SupplyState(now) != ERR_MortarSupplyState.FAILED || m_Battery.OrderId != m_CancelOrder || m_Battery.ERR_TransferAttempts() != m_AttemptsAtStart + 2) { Check(false, "canceled order/generation remains failed with exactly two total move attempts"); return -1; }
if (m_ObservedTransfer.ERR_CallbackState() == 0 || m_ObservedTransfer.Unresolved())
{
if (now >= m_StepDeadline) { Check(false, "accepted canceled operation reached definite native outcome; no ambiguous retry"); return -1; }
return 0;
}
if (!Check(m_ObservedTransfer.ERR_CallbackState() == 1 && Has(m_Gunner, m_SecondShell) && Conserved(), "canceled accepted native move has definite physical outcome with exactly two attempts and original 27 conserved")) return -1;
if (m_CallbackAtCancel == 0) Print("ERR SMOKE PASS: mortar transfer actual native completion observed after authorization cancellation");
else Print("ERR MORTAR TRANSFER LIMIT: native callback completed synchronously before cancellation; late callback timing not exercised");
m_Step = 7; return 0;
}
if (m_Step == 7)
{
// Return foreign shells first, leaving room for each original nine-round kit.
IEntity misplaced;
foreach (ERR_NativeMortarShellOwner entry : m_Original)
if (Has(m_Gunner, entry.Shell) && entry.OriginalOwner != m_Gunner) { misplaced = entry.Shell; break; }
if (!misplaced)
foreach (ERR_NativeMortarShellOwner entry : m_Original) if (InStore(entry.Shell)) { misplaced = entry.Shell; break; }
if (misplaced)
{
InventoryStorageManagerComponent recipient = Inventory(OriginalOwner(misplaced));
BaseInventoryStorageComponent destination;
if (recipient) destination = recipient.FindStorageForItem(misplaced, EStoragePurpose.PURPOSE_DEPOSIT);
if (!Check(destination && BeginMove(misplaced, destination, now), "one borrowed shell return to its original crew owner accepted")) return -1;
return 0;
}
foreach (ERR_NativeMortarShellOwner entry : m_Original)
if (!Check(Has(entry.OriginalOwner, entry.Shell), "original shell identity returned to original crew inventory")) return -1;
if (!Check(Conserved() && m_Battery.CountShells() == 27 && NoFire(), "all original ammunition restored; no minted/deleted shell or shot")) return -1;
foreach (BaseInventoryStorageComponent storage : m_Stores)
{
array<IEntity> items = {}; storage.GetAll(items);
if (!Check(items.IsEmpty(), "borrowed-ammunition fixture storage empty before deletion")) return -1;
}
Stop(); m_Complete = true; return 1;
}
return 0;
}
}
#endif
@@ -0,0 +1,284 @@
#ifdef WORKBENCH
// Read-only evidence hooks. Every production method delegates unchanged.
modded class ERR_HQ
{
void ERR_ResponseUnits(out array<ERR_HQUnit> units)
{
units.Clear();
if (!ERR_NativeHQResponseProof.Enabled()) return;
foreach (ERR_HQUnit unit : m_Units) units.Insert(unit);
}
protected override void Observe(ERR_HQUnit unit, float now)
{
ERR_HQReport previous = unit.PendingReport;
super.Observe(unit, now);
ERR_NativeHQResponseProof proof = ERR_NativeHQResponseProof.Active();
if (proof && unit.PendingReport && unit.PendingReport != previous) proof.Observed(this, unit, now);
}
protected override void Accept(ERR_HQReport report, float now)
{
super.Accept(report, now);
ERR_NativeHQResponseProof proof = ERR_NativeHQResponseProof.Active();
if (!proof || !report) return;
foreach (ERR_HQReport accepted : m_Contacts)
if (accepted.MessageId == report.MessageId) { proof.Accepted(this, accepted, now); break; }
}
protected override void DeliverOrder(ERR_HQUnit unit, float now)
{
ERR_HQReport order = unit.PendingOrder;
ERR_HQRoute route = unit.Downlink;
super.DeliverOrder(unit, now);
ERR_NativeHQResponseProof proof = ERR_NativeHQResponseProof.Active();
if (proof && order && route && unit.Assignment == order && unit.Waypoint) proof.Delivered(this, unit, route, now);
}
}
modded class ERR_HQJournal
{
override void Write(string kind, string message, int messageId = 0)
{
super.Write(kind, message, messageId);
ERR_NativeHQResponseProof proof = ERR_NativeHQResponseProof.Active();
if (proof) proof.JournalEvent(this, kind, message, messageId);
}
}
modded class SCR_AIGroupUtilityComponent
{
IEntity ERR_ResponseVisualObserver(ERR_HQReport report, float now)
{
foreach (SCR_AIInfoComponent info : m_aInfoComponents)
{
if (!info || !info.m_Perception) continue;
AIAgent agent = AIAgent.Cast(info.GetOwner());
if (!agent || !ERR_Actors.CanFight(agent.GetControlledEntity())) continue;
array<BaseTarget> targets = {}; info.m_Perception.GetTargetsList(targets, ETargetCategory.ENEMY);
foreach (BaseTarget target : targets)
{
ERR_HQVisualContact sample = ERR_HQObservation.Capture(target, now);
if (sample && sample.Entity == report.Target && sample.Escapist && Math.AbsFloat(sample.ObservedAt - report.ObservedAt) < 1 && vector.Distance(sample.Position, report.Position) < 0.1) return agent.GetControlledEntity();
}
}
return null;
}
}
class ERR_NativeResponseUnit
{
ERR_HQUnit Unit;
SCR_AIGroup Group;
IEntity Radio;
ref array<IEntity> Actors = {};
}
class ERR_NativeResponseJournal
{
bool Report;
bool Transmit;
bool HQReceive;
bool HQTransmit;
bool UnitReceive;
bool Delivered;
}
class ERR_NativeResponseLineage
{
ref ERR_HQReport Report;
ERR_HQUnit Source;
IEntity Observer;
IEntity SourceRadio;
ref ERR_HQRoute Uplink;
bool Accepted;
float AcceptedAt;
ERR_HQUnit Recipient;
IEntity RecipientRadio;
int DeliveryId;
AIWaypoint Waypoint;
IEntity MovingActor;
vector DeliveredOrigin;
float DeliveredAt;
}
class ERR_NativeHQResponseProof
{
protected static ERR_NativeHQResponseProof s_Active;
protected ERR_GameMode m_Mode;
protected ERR_HQ m_HQ;
protected IEntity m_Player;
protected SCR_PlayerController m_Controller;
protected ERR_PlayerLife m_Life;
protected ERR_HQUnit m_Source;
protected DamageManagerComponent m_Damage;
protected bool m_DamageWasEnabled;
protected bool m_Protected;
protected bool m_Started;
protected bool m_Stopped;
protected bool m_Failed;
protected string m_Failure;
protected float m_Deadline;
protected float m_NextDiagnostic;
protected ref array<ref ERR_NativeResponseUnit> m_Units = {};
protected ref array<IEntity> m_Forces = {};
protected ref array<ref ERR_NativeResponseLineage> m_Reports = {};
protected ref map<int, ref ERR_NativeResponseJournal> m_Journal = new map<int, ref ERR_NativeResponseJournal>();
static bool Enabled()
{
string enabled, outcome;
return Replication.IsServer() && System.GetCLIParam("errSmoke", enabled) && enabled == "1" && System.GetCLIParam("errSmokeOutcome", outcome) && outcome == "hq-response";
}
static ERR_NativeHQResponseProof Active() { return s_Active; }
void ERR_NativeHQResponseProof(ERR_GameMode mode, IEntity player)
{
m_Mode = mode; m_Player = player; m_HQ = ERR_HQ.Get(); m_Deadline = GetGame().GetWorld().GetWorldTime() + 140000;
if (Enabled() && !s_Active) s_Active = this;
}
protected bool Fail(string reason) { m_Failed = true; m_Failure = reason; return false; }
protected bool Check(bool condition, string detail)
{
if (condition) { Print("ERR SMOKE PASS: HQ response " + detail); return true; }
Print("ERR SMOKE FAIL: HQ response " + detail, LogLevel.ERROR); Stop(); return false;
}
protected ERR_NativeResponseUnit Original(ERR_HQUnit unit)
{
foreach (ERR_NativeResponseUnit original : m_Units) if (original.Unit == unit && original.Group == unit.Group) return original;
return null;
}
protected ERR_NativeResponseLineage Report(int id)
{
foreach (ERR_NativeResponseLineage report : m_Reports) if (report.Report.MessageId == id) return report;
return null;
}
protected bool Canonical()
{
return m_Player && m_Controller && m_Life && m_Mode.Players().CurrentActor(m_Player) == m_Life && m_Controller == GetGame().GetPlayerController() && m_Controller.GetControlledEntity() == m_Player && m_Life.Actor == m_Player && m_Life.Connected && m_Life.UsedLife;
}
protected bool UnchangedForces()
{
array<ERR_HQUnit> current = {}; m_HQ.ERR_ResponseUnits(current);
if (current.Count() != m_Units.Count()) return false;
foreach (ERR_HQUnit unit : current)
{
ERR_NativeResponseUnit original = Original(unit);
if (!original) return false;
array<AIAgent> agents = {}; unit.Group.GetAgents(agents);
if (agents.Count() != original.Actors.Count()) return false;
foreach (AIAgent agent : agents) if (!agent || !original.Actors.Contains(agent.GetControlledEntity())) return false;
}
array<IEntity> forces = {}; m_HQ.PhysicalForces(forces);
if (forces.Count() != m_Forces.Count()) return false;
foreach (IEntity entity : forces) if (!m_Forces.Contains(entity)) return false;
return true;
}
protected bool Arrange()
{
array<ERR_HQUnit> units = {}; m_HQ.ERR_ResponseUnits(units);
foreach (ERR_HQUnit unit : units)
{
if (!unit.Group || !unit.Utility || !unit.Radio || ERR_HQRadio.Capability(unit.Radio) != 2) return false;
array<AIAgent> agents = {}; unit.Group.GetAgents(agents);
if (agents.IsEmpty() || !unit.Group.IsExpandComplete()) return false;
ERR_NativeResponseUnit original = new ERR_NativeResponseUnit(); original.Unit = unit; original.Group = unit.Group; original.Radio = unit.Radio;
foreach (AIAgent agent : agents)
{
if (!agent || !ERR_Actors.CanFight(agent.GetControlledEntity())) return false;
original.Actors.Insert(agent.GetControlledEntity());
}
m_Units.Insert(original);
if (!m_Source && !unit.ReservedForSupport) m_Source = unit;
}
if (!m_Source || m_Units.Count() < 2) return false;
m_HQ.PhysicalForces(m_Forces);
m_Controller = SCR_PlayerController.Cast(GetGame().GetPlayerController()); m_Life = m_Mode.Players().CurrentActor(m_Player);
if (!Canonical()) return false;
m_Damage = DamageManagerComponent.Cast(m_Player.FindComponent(DamageManagerComponent));
if (!m_Damage) return false;
m_DamageWasEnabled = m_Damage.IsDamageHandlingEnabled(); m_Damage.EnableDamageHandling(false); m_Protected = true;
// Preserve the established fixture arrangement: move only the real prisoner.
// Native perception must discover him; neither targets nor reports are seeded.
vector position = ERR_Actors.Ground(m_Source.Group.GetOrigin() + "0 0 20");
vector transform[4]; m_Player.GetWorldTransform(transform); transform[3] = position;
ChimeraCharacter.Cast(m_Player).Teleport(transform);
m_Started = true;
PrintFormat("ERR HQ RESPONSE ARRANGEMENT: canonical prisoner moved to=%1 near original source group=%2; temporary player damage protection=%3; no AI/report/radio cadence changes", position, m_Source.Id, m_Protected);
return true;
}
void JournalEvent(ERR_HQJournal journal, string kind, string message, int messageId)
{
if (!m_Started || m_Stopped || !m_HQ || journal != m_HQ.Journal() || messageId <= 0) return;
ERR_NativeResponseJournal entry = m_Journal.Get(messageId);
if (!entry)
{
if (m_Journal.Count() >= 128) { Fail("bounded journal evidence map exhausted"); return; }
entry = new ERR_NativeResponseJournal(); m_Journal.Insert(messageId, entry);
}
if (kind == "REPORT") entry.Report = true;
if (kind == "TRANSMIT") { entry.Transmit = true; if (message.StartsWith("HQ -> ")) entry.HQTransmit = true; }
if (kind == "RECEIVE") { if (message.StartsWith("HQ received from ")) entry.HQReceive = true; else if (message.StartsWith("unit ")) entry.UnitReceive = true; }
if (kind == "ORDER DELIVERED") entry.Delivered = true;
}
void Observed(ERR_HQ hq, ERR_HQUnit unit, float now)
{
if (!m_Started || m_Stopped || hq != m_HQ || unit != m_Source || unit.PendingReport.Target != m_Player) return;
ERR_HQReport report = unit.PendingReport;
ERR_NativeResponseUnit original = Original(unit);
IEntity observer = unit.Utility.ERR_ResponseVisualObserver(report, now);
if (!Canonical() || !original || !original.Actors.Contains(observer) || !unit.Uplink || unit.Uplink.Nodes.IsEmpty() || unit.Uplink.Nodes[0].Carrier != unit.Radio || unit.Uplink.MessageId != report.MessageId || unit.Radio != original.Radio || !original.Actors.Contains(unit.Radio) || report.Source != original.Group || report.ObservedAt > now || Report(report.MessageId)) { Fail("real observed report lacks canonical original observer/radio/source lineage"); return; }
if (m_Reports.Count() >= 32) { Fail("bounded report evidence exhausted"); return; }
ERR_NativeResponseLineage proof = new ERR_NativeResponseLineage(); proof.Report = report.Snapshot(); proof.Source = unit; proof.Observer = observer; proof.SourceRadio = unit.Radio; proof.Uplink = unit.Uplink; m_Reports.Insert(proof);
PrintFormat("ERR HQ RESPONSE SIGHTING: source=%1 report=M%2 observer=%3 radio=%4 target=%5 observedAt=%6; actual native visual sample", unit.Id, report.MessageId, observer, unit.Radio, m_Player, report.ObservedAt);
}
void Accepted(ERR_HQ hq, ERR_HQReport report, float now)
{
if (!m_Started || m_Stopped || hq != m_HQ) return;
ERR_NativeResponseLineage proof = Report(report.MessageId); if (!proof) return;
if (report.Target != m_Player || report.Source != proof.Report.Source || report.ObservedAt != proof.Report.ObservedAt || vector.Distance(report.Position, proof.Report.Position) > 0.01 || !proof.Uplink || proof.Uplink.Failed || proof.Uplink.Sending || proof.Uplink.Cursor < proof.Uplink.Nodes.Count()) { Fail("accepted report lacks completed actual uplink or immutable observed time"); return; }
proof.Accepted = true; proof.AcceptedAt = now;
}
void Delivered(ERR_HQ hq, ERR_HQUnit unit, ERR_HQRoute route, float now)
{
if (!m_Started || m_Stopped || hq != m_HQ || !unit.Assignment) return;
ERR_NativeResponseLineage proof = Report(unit.Assignment.MessageId); if (!proof || proof.Recipient) return;
ERR_NativeResponseUnit original = Original(unit);
if (!proof.Accepted || !original || unit == proof.Source || !unit.Assignment || unit.Assignment.Target != m_Player || unit.Assignment.Source != proof.Report.Source || unit.Assignment.ObservedAt != proof.Report.ObservedAt || vector.Distance(unit.Assignment.Position, proof.Report.Position) > 0.01 || unit.Radio != original.Radio || !original.Actors.Contains(unit.Radio) || !route.Downlink || route.Nodes.IsEmpty() || route.Nodes[route.Nodes.Count() - 1].Carrier != unit.Radio || route.Failed || route.Sending || route.Cursor != route.Nodes.Count() - 1 || !unit.Waypoint) { Fail("delivered response lacks immutable accepted report and original physical recipient/downlink"); return; }
proof.Recipient = unit; proof.RecipientRadio = unit.Radio; proof.DeliveryId = route.MessageId; proof.Waypoint = unit.Waypoint; proof.DeliveredAt = now;
foreach (IEntity actor : original.Actors) if (ERR_Actors.CanFight(actor)) { proof.MovingActor = actor; break; }
if (proof.MovingActor) proof.DeliveredOrigin = proof.MovingActor.GetOrigin();
PrintFormat("ERR HQ RESPONSE DELIVERED: report=M%1 downlink=M%2 source=%3 recipient=%4 radio=%5 waypoint=%6 observedAt=%7", proof.Report.MessageId, route.MessageId, proof.Source.Id, unit.Id, unit.Radio, unit.Waypoint, unit.Assignment.ObservedAt);
}
int Tick(float now)
{
if (m_Stopped) return -1;
if (!Enabled() || s_Active != this || !m_Mode || !m_Mode.Active() || !m_HQ || now > m_Deadline || m_Failed) { Check(false, "bounded active evidence context: " + m_Failure); return -1; }
if (!m_Started)
{
if (!m_HQ.ERR_ProbeSquadsReady()) return 0;
array<IEntity> guns = {}; m_HQ.Mortars().AppendGuns(guns);
foreach (IEntity gun : guns) { ERR_MortarBattery battery = m_HQ.Mortars().FindGun(gun); if (!battery || !battery.StartupActivated || !battery.Operational() || !m_HQ.MortarConnected(battery.Group)) return 0; }
if (!Check(Arrange(), "original physical force, RTOs and canonical prisoner captured before arranged sighting")) return -1;
return 0;
}
if (!Canonical() || !UnchangedForces()) { Check(false, "canonical player and all original physical group/actor identities retained without added force"); return -1; }
if (now >= m_NextDiagnostic)
{
PrintFormat("ERR HQ RESPONSE PROOF: observed source reports=%1; %2", m_Reports.Count(), m_HQ.ERR_ProbePerception()); m_NextDiagnostic = now + 10000;
}
foreach (ERR_NativeResponseLineage proof : m_Reports)
{
if (!proof.Recipient || !proof.MovingActor) continue;
if (proof.Recipient.Waypoint != proof.Waypoint || !proof.Recipient.Assignment || proof.Recipient.Assignment.MessageId != proof.Report.MessageId) continue;
ERR_NativeResponseJournal uplink = m_Journal.Get(proof.Report.MessageId);
ERR_NativeResponseJournal downlink = m_Journal.Get(proof.DeliveryId);
if (!uplink || !downlink || !uplink.Report || !uplink.Transmit || !uplink.HQReceive || !downlink.HQTransmit || !downlink.UnitReceive || !downlink.Delivered) continue;
if (proof.Recipient.Group.GetCurrentWaypoint() != proof.Waypoint || vector.DistanceXZ(proof.MovingActor.GetOrigin(), proof.DeliveredOrigin) < 3) continue;
if (vector.DistanceXZ(proof.MovingActor.GetOrigin(), proof.Report.Position) >= vector.DistanceXZ(proof.DeliveredOrigin, proof.Report.Position) - 1) continue;
if (!Check(proof.SourceRadio && proof.RecipientRadio && m_HQ.ERR_ProbeUniqueAssignments(), "actual sighting/report/uplink/HQ receipt/downlink journal lineage reaches distinct original infantry with bounded unique waypoints")) return -1;
if (!Check(UnchangedForces(), "original recipient physically moves toward its native Search waypoint with no replacement or additional force")) return -1;
Stop(); return 1;
}
return 0;
}
void Stop()
{
if (m_Stopped) return;
m_Stopped = true;
if (m_Protected && m_Damage) m_Damage.EnableDamageHandling(m_DamageWasEnabled);
m_Protected = false;
if (s_Active == this) s_Active = null;
}
void ~ERR_NativeHQResponseProof() { Stop(); }
}
#endif
+62 -18
View File
@@ -17,8 +17,13 @@ modded class ERR_GameMode
protected bool m_ERRTestRadioNetwork; protected bool m_ERRTestRadioNetwork;
protected bool m_ERRTestHQResponse; protected bool m_ERRTestHQResponse;
protected bool m_ERRTestMortar; protected bool m_ERRTestMortar;
protected bool m_ERRTestMortarFire;
protected bool m_ERRTestMortarTransfer;
protected ref ERR_NativeMortarTransferProbe m_ERRMortarTransfer;
protected ref ERR_NativeMortarFiringProbe m_ERRMortarFire;
protected float m_ERRNextProbeLog; protected float m_ERRNextProbeLog;
protected ref ERR_NativeRadioProbe m_ERRRadioProbe; protected ref ERR_NativeRadioProbe m_ERRRadioProbe;
protected ref ERR_NativeHQResponseProof m_ERRHQResponseProof;
protected ref array<IEntity> m_ERRCacheFolders = {}; protected ref array<IEntity> m_ERRCacheFolders = {};
protected override void EOnInit(IEntity owner) protected override void EOnInit(IEntity owner)
@@ -31,9 +36,13 @@ modded class ERR_GameMode
m_ERRTestRadioNetwork = outcome == "radio-network"; m_ERRTestRadioNetwork = outcome == "radio-network";
m_ERRTestHQResponse = outcome == "hq-response"; m_ERRTestHQResponse = outcome == "hq-response";
m_ERRTestMortar = outcome == "mortar-inventory"; m_ERRTestMortar = outcome == "mortar-inventory";
m_ERRTestMortarFire = outcome == "mortar-fire" || outcome == "mortar-expiry";
m_ERRTestMortarTransfer = outcome == "mortar-transfer";
m_ERRTestPatrolHQ = outcome == "patrol-hq"; m_ERRTestPatrolHQ = outcome == "patrol-hq";
m_ERRTestPlayerDeath = outcome == "player-death" || m_ERRTestRadioNetwork || m_ERRTestHQResponse || m_ERRTestMortar; m_ERRTestPlayerDeath = outcome == "player-death" || m_ERRTestRadioNetwork || m_ERRTestHQResponse || m_ERRTestMortar;
m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 150000; m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 150000;
if (m_ERRTestMortarTransfer) m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 330000;
if (m_ERRTestMortarFire) m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 330000;
if (m_ERRTestPatrolHQ) m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 420000; if (m_ERRTestPatrolHQ) m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 420000;
OnStop().Insert(ERR_StopHQPatrol); OnStop().Insert(ERR_StopHQPatrol);
OnPhaseChanged().Insert(ERR_SmokePhase); OnPhaseChanged().Insert(ERR_SmokePhase);
@@ -52,6 +61,9 @@ modded class ERR_GameMode
} }
protected void ERR_StopHQPatrol() protected void ERR_StopHQPatrol()
{ {
if (m_ERRHQResponseProof) m_ERRHQResponseProof.Stop();
if (m_ERRMortarTransfer) m_ERRMortarTransfer.Stop();
if (m_ERRMortarFire) m_ERRMortarFire.Stop();
if (m_ERRHQPatrolMovement) m_ERRHQPatrolMovement.Stop(); if (m_ERRHQPatrolMovement) m_ERRHQPatrolMovement.Stop();
if (m_ERRHQPatrolOrder) m_ERRHQPatrolOrder.Stop(); if (m_ERRHQPatrolOrder) m_ERRHQPatrolOrder.Stop();
} }
@@ -87,6 +99,24 @@ modded class ERR_GameMode
protected void ERR_SmokePhase(ERR_Phase previous, ERR_Phase current) protected void ERR_SmokePhase(ERR_Phase previous, ERR_Phase current)
{ {
if (m_ERRSmokeDone || !ERR_MissionRules.Terminal(current)) return; if (m_ERRSmokeDone || !ERR_MissionRules.Terminal(current)) return;
if (m_ERRTestMortarTransfer)
{
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 161, "native exact shell transfers and original-owner restoration complete before explicit reset")) return;
m_ERRSmokeDone = true;
GetGame().GetCallqueue().Remove(ERR_SmokeTick);
ERR_StopHQPatrol();
Print("ERR SMOKE COMPLETE: native exact mortar inventory transfer, accepted-operation cancellation and original-owner restoration; radio bypassed; fixture reset requested");
return;
}
if (m_ERRTestMortarFire)
{
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 151, "native mortar first shot and stop complete before explicit reset")) return;
m_ERRSmokeDone = true;
GetGame().GetCallqueue().Remove(ERR_SmokeTick);
ERR_StopHQPatrol();
Print("ERR SMOKE COMPLETE: native HQ radio mortar projectile and configured cancellation/expiry; fixture reset requested");
return;
}
if (m_ERRTestPatrolHQ) if (m_ERRTestPatrolHQ)
{ {
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 133, "HQ patrol preemption and physical resumption before explicit reset")) return; if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 133, "HQ patrol preemption and physical resumption before explicit reset")) return;
@@ -149,6 +179,20 @@ modded class ERR_GameMode
if (m_ERRSmokeDone) return; if (m_ERRSmokeDone) return;
if (now > m_ERRSmokeDeadline) { ERR_Check(false, "timeout at step " + m_ERRSmokeStep.ToString()); return; } if (now > m_ERRSmokeDeadline) { ERR_Check(false, "timeout at step " + m_ERRSmokeStep.ToString()); return; }
if (now < m_ERRSmokeWait) return; if (now < m_ERRSmokeWait) return;
if (m_ERRSmokeStep == 160)
{
int result = m_ERRMortarTransfer.Tick(now);
if (result < 0) { ERR_Check(false, "native mortar exact-shell transfer fixture"); return; }
if (result == 1) { m_ERRSmokeStep = 161; Transition(ERR_Phase.DEFEAT); }
return;
}
if (m_ERRSmokeStep == 150)
{
int result = m_ERRMortarFire.Tick(now);
if (result < 0) { ERR_Check(false, "native mortar firing probe failed; see diagnostics"); return; }
if (result == 1) { m_ERRSmokeStep = 151; Transition(ERR_Phase.DEFEAT); }
return;
}
if (m_ERRSmokeStep == 130 || m_ERRSmokeStep == 132) if (m_ERRSmokeStep == 130 || m_ERRSmokeStep == 132)
{ {
int result = m_ERRHQPatrolMovement.Tick(now); int result = m_ERRHQPatrolMovement.Tick(now);
@@ -181,6 +225,20 @@ modded class ERR_GameMode
m_ERRSmokeStep = 130; m_ERRSmokeStep = 130;
return; return;
} }
if (m_ERRTestMortarTransfer)
{
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
m_ERRMortarTransfer = new ERR_NativeMortarTransferProbe(this);
m_ERRSmokeStep = 160;
return;
}
if (m_ERRTestMortarFire)
{
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
m_ERRMortarFire = new ERR_NativeMortarFiringProbe(this);
m_ERRSmokeStep = 150;
return;
}
if (m_ERRTestMortar) if (m_ERRTestMortar)
{ {
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false); DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
@@ -189,7 +247,7 @@ modded class ERR_GameMode
} }
if (m_ERRTestHQResponse) if (m_ERRTestHQResponse)
{ {
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false); m_ERRHQResponseProof = new ERR_NativeHQResponseProof(this, m_ERRSmokePlayer);
m_ERRSmokeStep = 110; m_ERRSmokeStep = 110;
return; return;
} }
@@ -343,23 +401,9 @@ modded class ERR_GameMode
} }
else if (m_ERRSmokeStep == 110) else if (m_ERRSmokeStep == 110)
{ {
ERR_HQ hq = ERR_HQ.Cast(Command()); int result = m_ERRHQResponseProof.Tick(now);
if (!hq || !hq.ERR_ProbeSquadsReady()) return; if (result < 0) { ERR_Check(false, "native HQ response evidence failed; inspect report lineage diagnostics"); return; }
ERR_MovePlayer(hq.ERR_ProbeResponseOrigin()); if (result == 0) return;
m_ERRSmokeStep = 111;
m_ERRSmokeWait = now + 1000;
}
else if (m_ERRSmokeStep == 111)
{
ERR_HQ hq = ERR_HQ.Cast(Command());
if (now >= m_ERRNextProbeLog)
{
Print("ERR HQ PROBE: " + hq.ERR_ProbePerception());
m_ERRNextProbeLog = now + 10000;
}
if (!hq.ERR_ProbeDeliveredResponse()) return;
if (!ERR_Check(true, "native visual contact reaches HQ and orders a different existing squad")) return;
if (!ERR_Check(hq.ERR_ProbeUniqueAssignments(), "HQ uses distinct waypoints within the existing force and order limits")) return;
m_ERRSmokeStep = 9; m_ERRSmokeStep = 9;
SCR_CharacterDamageManagerComponent damage = SCR_CharacterDamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(SCR_CharacterDamageManagerComponent)); SCR_CharacterDamageManagerComponent damage = SCR_CharacterDamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(SCR_CharacterDamageManagerComponent));
damage.EnableDamageHandling(true); damage.EnableDamageHandling(true);
@@ -1,3 +1,26 @@
// Discovery markers are authored objective information, not player annotations.
// Native local insertion overwrites owner ID before OnCreateMarker; clear it at
// that boundary so native edit/drag cannot move a discovered objective.
class ERR_DiscoveryMarker : SCR_MapMarkerBase
{
void ERR_DiscoveryMarker() { SetCanBeRemovedByOwner(false); }
override void OnCreateMarker(bool skipProfanityFilter = false)
{
SetMarkerOwnerID(-1);
// Text is scenario-authored, never user input. Avoid delayed UGC callbacks
// overwriting a newer discovery label after the location becomes identified.
super.OnCreateMarker(true);
}
override void SetCustomText(string text)
{
super.SetCustomText(text);
// Native SetCustomText updates data only; an already-open map needs its
// existing widget updated too. Closed maps use the saved text on creation.
SCR_MapMarkerWidgetComponent widget = GetMarkerComponent();
if (GetRootWidget() && widget) widget.SetText(text, true);
}
}
// Read replicated discovery locally. A server-wide marker list never leaks // Read replicated discovery locally. A server-wide marker list never leaks
// locations which have not been recovered through gameplay. // locations which have not been recovered through gameplay.
modded class ERR_LocationComponent modded class ERR_LocationComponent
@@ -17,15 +40,6 @@ modded class ERR_LocationComponent
if (!GetGame().GetPlayerController() || Knowledge() <= 0 || (Knowledge() == m_ERRShown && Label() == m_ERRShownLabel)) return; if (!GetGame().GetPlayerController() || Knowledge() <= 0 || (Knowledge() == m_ERRShown && Label() == m_ERRShownLabel)) return;
SCR_MapMarkerManagerComponent manager = SCR_MapMarkerManagerComponent.GetInstance(); SCR_MapMarkerManagerComponent manager = SCR_MapMarkerManagerComponent.GetInstance();
if (!manager || !manager.GetMarkerConfig()) return; if (!manager || !manager.GetMarkerConfig()) return;
if (!m_ERRMarker)
{
m_ERRMarker = new SCR_MapMarkerBase();
m_ERRMarker.SetType(SCR_EMapMarkerType.PLACED_CUSTOM);
vector p = Position();
m_ERRMarker.SetWorldPos(Math.Round(p[0]), Math.Round(p[2]));
m_ERRMarker.SetMarkerConfigID(0);
manager.InsertStaticMarker(m_ERRMarker, true);
}
string label = "Unknown location"; string label = "Unknown location";
if (Knowledge() == 2) if (Knowledge() == 2)
{ {
@@ -36,6 +50,16 @@ modded class ERR_LocationComponent
else if (Kind() == ERR_LocationKind.PRISON) label = "Prison"; else if (Kind() == ERR_LocationKind.PRISON) label = "Prison";
else label = Id(); else label = Id();
} }
if (!m_ERRMarker)
{
m_ERRMarker = new ERR_DiscoveryMarker();
m_ERRMarker.SetType(SCR_EMapMarkerType.PLACED_CUSTOM);
vector p = Position();
m_ERRMarker.SetWorldPos(Math.Round(p[0]), Math.Round(p[2]));
m_ERRMarker.SetMarkerConfigID(0);
m_ERRMarker.SetCustomText(label);
manager.InsertStaticMarker(m_ERRMarker, true);
}
m_ERRMarker.SetCustomText(label); m_ERRMarker.SetCustomText(label);
m_ERRShown = Knowledge(); m_ERRShown = Knowledge();
m_ERRShownLabel = Label(); m_ERRShownLabel = Label();
@@ -0,0 +1,107 @@
// A round-local roster identity is not a Bohemia/platform identity. Only the
// real native admission callback may select it for the sole offline controller.
class ERR_LocalAdmissionRules
{
static bool Context(bool server, int sessionMode, int count, bool connected, bool sameLocal, bool sameManager, int connection, int controllerId)
{
return server && sessionMode == RplMode.None && count == 1 && connected && sameLocal && sameManager && connection > 0 && controllerId == connection;
}
}
class ERR_LocalAdmission
{
protected ERR_GameMode m_Mode;
protected SCR_PlayerController m_Controller;
protected int m_Connection;
protected UUID m_Key;
protected bool m_Selected;
protected bool m_OfflineMode;
protected bool m_LocalKey;
protected bool m_Failed;
protected bool m_Stopped;
protected bool m_RefusalLogged;
void ERR_LocalAdmission(ERR_GameMode mode) { m_Mode = mode; m_OfflineMode = RplSession.Mode() == RplMode.None; }
bool OfflineMode() { return m_OfflineMode; }
bool Selected() { return m_Selected; }
bool LocalKey() { return m_LocalKey; }
protected bool Context(ERR_GameMode mode, int connection, SCR_PlayerController controller)
{
if (!GetGame()) return false;
PlayerManager manager = GetGame().GetPlayerManager();
bool ownedMode = mode && mode == m_Mode && mode == ERR_GameMode.Get();
int count = -1;
bool connected, sameManager;
if (manager)
{
count = manager.GetPlayerCount();
connected = manager.IsPlayerConnected(connection);
sameManager = controller && manager.GetPlayerController(connection) == controller;
}
bool sameLocal = controller && controller == GetGame().GetPlayerController();
int controllerId;
if (controller) controllerId = controller.GetPlayerId();
bool valid = ownedMode && manager && controller && ERR_LocalAdmissionRules.Context(Replication.IsServer(), RplSession.Mode(), count, connected, sameLocal, sameManager, connection, controllerId);
if (!valid && !m_RefusalLogged)
{
string project;
if (System.GetCLIParam("errOrdinaryScenario", project) && (project == "core" || project == "chat"))
{
m_RefusalLogged = true;
PrintFormat("ERR ORDINARY LOCAL CONTEXT: server=%1 sessionMode=%2 count=%3 connected=%4 sameLocal=%5 sameManager=%6 positiveMatchingId=%7 ownedMode=%8 controllerPresent=%9", Replication.IsServer(), RplSession.Mode(), count, connected, sameLocal, sameManager, connection > 0 && controllerId == connection, ownedMode, controller != null);
}
}
return valid;
}
UUID Resolve(ERR_GameMode mode, int connection, SCR_PlayerController controller, UUID nativeIdentity)
{
// This helper is inert for modes created as Listen/Dedicated, even after Stop.
if (!m_OfflineMode) return nativeIdentity;
if (m_Failed || m_Stopped) return UUID.NULL_UUID;
if (m_Selected)
{
// A late backend value or name change never grants another local life.
if (mode != m_Mode || connection != m_Connection || controller != m_Controller || !Validate()) { m_Failed = true; return UUID.NULL_UUID; }
return m_Key;
}
if (!Context(mode, connection, controller)) { m_Failed = true; return UUID.NULL_UUID; }
m_Controller = controller; m_Connection = connection; m_Key = nativeIdentity;
m_Selected = true;
if (m_Key.IsNull()) { m_Key = UUID.GenV4(); m_LocalKey = true; }
if (m_Key.IsNull()) { m_Failed = true; return UUID.NULL_UUID; }
if (m_LocalKey) Print("Rereintroduced [admission]: sole offline controller uses a generated local-round roster key; backend identity and permissions unchanged.");
return m_Key;
}
bool Validate()
{
if (!m_OfflineMode) return true;
if (m_Failed || m_Stopped) return false;
if (!m_Selected) return true;
if (!Context(m_Mode, m_Connection, m_Controller)) m_Failed = true;
return !m_Failed;
}
bool Disconnected(int connection)
{
if (!m_Selected || m_Stopped || connection != m_Connection) return false;
m_Failed = true;
return true;
}
void Stop()
{
m_Stopped = true;
m_Controller = null;
m_Key = UUID.NULL_UUID;
// Keep selection/failure latched: this object cannot admit a replacement.
}
}
modded class ERR_GameMode
{
void ERR_FailLocalAdmission()
{
if (!Replication.IsServer()) return;
string reason = "The offline player context changed. Start a new scenario to establish a fresh session.";
if (Phase() == ERR_Phase.PREPARING) { FailPreparation(reason); return; }
if (!Active()) return;
m_EndReason = reason;
Transition(ERR_Phase.DEFEAT);
}
}
@@ -17,11 +17,14 @@ modded class ERR_GameMode
protected ref ERR_NativeCasualtyServiceProbe m_ERRCasualtyServiceProbe; protected ref ERR_NativeCasualtyServiceProbe m_ERRCasualtyServiceProbe;
protected ref ERR_NativePrisonerProbe m_ERRPrisonerProbe; protected ref ERR_NativePrisonerProbe m_ERRPrisonerProbe;
protected ref ERR_NativeGuardCancelProbe m_ERRGuardCancelProbe; protected ref ERR_NativeGuardCancelProbe m_ERRGuardCancelProbe;
protected ref ERR_NativeLocalAdmissionProbe m_ERRLocalAdmissionProbe;
protected ref ERR_NativePoweredFlightProbe m_ERRPoweredFlightProbe;
protected ref ERR_NativeObjectiveLossProbe m_ERRObjectiveLossProbe; protected ref ERR_NativeObjectiveLossProbe m_ERRObjectiveLossProbe;
protected ref ERR_NativeMedicalProbe m_ERRBaseMedicalProbe; protected ref ERR_NativeMedicalProbe m_ERRBaseMedicalProbe;
protected ref ERR_NativeCasualtyLoadProbe m_ERRCasualtyLoadProbe; protected ref ERR_NativeCasualtyLoadProbe m_ERRCasualtyLoadProbe;
protected ref ERR_NativeEnvironmentProbe m_ERRBaseEnvironmentProbe; protected ref ERR_NativeEnvironmentProbe m_ERRBaseEnvironmentProbe;
protected bool m_ERRCatalogChecked; protected bool m_ERRCatalogChecked;
protected bool m_ERRDiscoveryMapChecked;
protected ref ERR_NativePatrolProbe m_ERRPatrolEast; protected ref ERR_NativePatrolProbe m_ERRPatrolEast;
protected ref ERR_NativePatrolProbe m_ERRPatrolWest; protected ref ERR_NativePatrolProbe m_ERRPatrolWest;
protected int m_ERRBaseStep; protected int m_ERRBaseStep;
@@ -79,12 +82,15 @@ modded class ERR_GameMode
} }
protected void ERR_StopHealthProbes() protected void ERR_StopHealthProbes()
{ {
ERR_NativeDiscoveryMapProbe.Stop();
if (m_ERRPatrolEast) m_ERRPatrolEast.Stop(); if (m_ERRPatrolEast) m_ERRPatrolEast.Stop();
if (m_ERRPatrolWest) m_ERRPatrolWest.Stop(); if (m_ERRPatrolWest) m_ERRPatrolWest.Stop();
if (m_ERRBaseEnvironmentRestartProbe) m_ERRBaseEnvironmentRestartProbe.Stop(); if (m_ERRBaseEnvironmentRestartProbe) m_ERRBaseEnvironmentRestartProbe.Stop();
if (m_ERRBaseEnvironmentProbe) m_ERRBaseEnvironmentProbe.Stop(); if (m_ERRBaseEnvironmentProbe) m_ERRBaseEnvironmentProbe.Stop();
if (m_ERRPrisonerProbe) m_ERRPrisonerProbe.Stop(); if (m_ERRPrisonerProbe) m_ERRPrisonerProbe.Stop();
if (m_ERRGuardCancelProbe) m_ERRGuardCancelProbe.Stop(); if (m_ERRGuardCancelProbe) m_ERRGuardCancelProbe.Stop();
if (m_ERRLocalAdmissionProbe) m_ERRLocalAdmissionProbe.Stop();
if (m_ERRPoweredFlightProbe) m_ERRPoweredFlightProbe.Stop();
if (m_ERRCasualtyServiceProbe) m_ERRCasualtyServiceProbe.Stop(); if (m_ERRCasualtyServiceProbe) m_ERRCasualtyServiceProbe.Stop();
if (m_ERRObjectiveLossProbe) m_ERRObjectiveLossProbe.Stop(); if (m_ERRObjectiveLossProbe) m_ERRObjectiveLossProbe.Stop();
if (m_ERRBaseMedicalProbe) m_ERRBaseMedicalProbe.Stop(); if (m_ERRBaseMedicalProbe) m_ERRBaseMedicalProbe.Stop();
@@ -156,6 +162,20 @@ modded class ERR_GameMode
{ {
if (!ERR_MissionRules.Terminal(current)) return; if (!ERR_MissionRules.Terminal(current)) return;
GetGame().GetCallqueue().Remove(ERR_BaseTick); GetGame().GetCallqueue().Remove(ERR_BaseTick);
if (m_ERRExtractionCase == "powered-flight")
{
if (!ERR_BaseCheck(current == ERR_Phase.DEFEAT && m_ERRBaseStep == 1802, "native powered-flight fixture finished before explicit test reset")) return;
ERR_StopHealthProbes();
Print("ERR SMOKE COMPLETE: native pilot-input powered takeoff, hover, contact landing and shutdown; isolated mechanism fixture reset");
return;
}
if (m_ERRExtractionCase == "local-admission")
{
// Completion is emitted by the calling tick after synchronous teardown and
// its post-transition invariants; a terminal event alone is insufficient.
ERR_BaseCheck(current == ERR_Phase.DEFEAT && m_ERRBaseStep == 1700, "local admission fixture received its production fail-closed transition");
return;
}
if (m_ERRExtractionCase == "early-helicopter-loss") if (m_ERRExtractionCase == "early-helicopter-loss")
{ {
if (!ERR_BaseCheck(current == ERR_Phase.DEFEAT && m_ERRBaseStep == 201 && Players().HasSurvivor() && Extraction().State() == ERR_ExtractionState.LOST, "lost helicopter ends prison phase despite a living prisoner")) return; if (!ERR_BaseCheck(current == ERR_Phase.DEFEAT && m_ERRBaseStep == 201 && Players().HasSurvivor() && Extraction().State() == ERR_ExtractionState.LOST, "lost helicopter ends prison phase despite a living prisoner")) return;
@@ -285,6 +305,25 @@ modded class ERR_GameMode
Print("ERR SMOKE COMPLETE: expected startup-failure"); Print("ERR SMOKE COMPLETE: expected startup-failure");
return; return;
} }
if (m_ERRBaseStep == 1800)
{
int result = m_ERRPoweredFlightProbe.Tick(now);
if (result < 0) { ERR_BaseCheck(false, "native powered-flight feasibility fixture"); return; }
if (result == 1) { m_ERRBaseStep = 1802; Transition(ERR_Phase.DEFEAT); }
return;
}
if (m_ERRBaseStep == 1700)
{
int result = m_ERRLocalAdmissionProbe.Tick(now);
if (result < 0) { ERR_StopHealthProbes(); GetGame().GetCallqueue().Remove(ERR_BaseTick); return; }
if (result == 1)
{
m_ERRBaseStep = 1702;
GetGame().GetCallqueue().Remove(ERR_BaseTick);
Print("ERR SMOKE COMPLETE: native local admission callback replay and fail-closed method injection; not multiplayer evidence");
}
return;
}
if (m_ERRBaseStep == 1400) if (m_ERRBaseStep == 1400)
{ {
int result = m_ERRCasualtyServiceProbe.Tick(now); int result = m_ERRCasualtyServiceProbe.Tick(now);
@@ -423,6 +462,25 @@ modded class ERR_GameMode
if (!ERR_NativeFactionCatalogProbe.Run(this)) { GetGame().GetCallqueue().Remove(ERR_BaseTick); return; } if (!ERR_NativeFactionCatalogProbe.Run(this)) { GetGame().GetCallqueue().Remove(ERR_BaseTick); return; }
m_ERRCatalogChecked = true; m_ERRCatalogChecked = true;
} }
if (!m_ERRDiscoveryMapChecked)
{
if (!ERR_NativeDiscoveryMapProbe.Run()) { GetGame().GetCallqueue().Remove(ERR_BaseTick); return; }
m_ERRDiscoveryMapChecked = true;
}
if (m_ERRExtractionCase == "powered-flight")
{
DamageManagerComponent.Cast(m_ERRBasePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
m_ERRPoweredFlightProbe = new ERR_NativePoweredFlightProbe(this);
m_ERRBaseDeadline = now + 250000;
m_ERRBaseStep = 1800;
return;
}
if (m_ERRExtractionCase == "local-admission")
{
m_ERRLocalAdmissionProbe = new ERR_NativeLocalAdmissionProbe(this);
m_ERRBaseStep = 1700;
return;
}
if (m_ERRExtractionCase == "casualty-service") if (m_ERRExtractionCase == "casualty-service")
{ {
m_ERRCasualtyServiceProbe = new ERR_NativeCasualtyServiceProbe(this); m_ERRCasualtyServiceProbe = new ERR_NativeCasualtyServiceProbe(this);
@@ -0,0 +1,140 @@
#ifdef WORKBENCH
// Opt-in hidden native-widget comparison; no discovery, inventory or mission
// state is changed, and no map menu or player input is fabricated.
// Separate owned subclasses preserve the vanilla base RPC serializer identity.
// Their small widget adapters are repeated to compare the unchanged native
// setter against the real successor subclass without modding a replicated type.
class ERR_NativePlainMapMarker : SCR_MapMarkerBase
{
bool ERR_ProbeAttachMapWidget()
{
ERR_ProbeDetachMapWidget();
SCR_MapMarkerManagerComponent manager = SCR_MapMarkerManagerComponent.GetInstance();
if (!manager || !manager.GetMarkerConfig()) return false;
m_ConfigEntry = manager.GetMarkerConfig().GetMarkerEntryConfigByType(GetType());
if (!m_ConfigEntry) return false;
m_wRoot = GetGame().GetWorkspace().CreateWidgets(m_ConfigEntry.GetMarkerLayout());
if (!m_wRoot) return false;
m_wRoot.SetVisible(false);
m_MarkerWidgetComp = SCR_MapMarkerWidgetComponent.Cast(m_wRoot.FindHandler(SCR_MapMarkerWidgetComponent));
if (!m_MarkerWidgetComp) return false;
m_MarkerWidgetComp.SetMarkerObject(this);
m_ConfigEntry.InitClientSettings(this, m_MarkerWidgetComp, true);
return m_wRoot.FindAnyWidget("MarkerText") != null;
}
string ERR_ProbeMapText()
{
if (!m_wRoot) return "";
TextWidget text = TextWidget.Cast(m_wRoot.FindAnyWidget("MarkerText"));
if (!text) return "";
return text.GetText();
}
void ERR_ProbeDetachMapWidget()
{
// Remove only this probe object's native subscriptions/widgets.
SCR_MapEntity.GetOnMapClose().Remove(OnMapClosed);
SCR_MapEntity.GetOnLayerChanged().Remove(OnMapLayerChanged);
if (m_wRoot) m_wRoot.RemoveFromHierarchy();
m_wRoot = null;
m_MarkerWidgetComp = null;
}
}
class ERR_NativeObjectiveMapMarker : ERR_DiscoveryMarker
{
bool ERR_ProbeAttachMapWidget()
{
ERR_ProbeDetachMapWidget();
SCR_MapMarkerManagerComponent manager = SCR_MapMarkerManagerComponent.GetInstance();
if (!manager || !manager.GetMarkerConfig()) return false;
m_ConfigEntry = manager.GetMarkerConfig().GetMarkerEntryConfigByType(GetType());
if (!m_ConfigEntry) return false;
m_wRoot = GetGame().GetWorkspace().CreateWidgets(m_ConfigEntry.GetMarkerLayout());
if (!m_wRoot) return false;
m_wRoot.SetVisible(false);
m_MarkerWidgetComp = SCR_MapMarkerWidgetComponent.Cast(m_wRoot.FindHandler(SCR_MapMarkerWidgetComponent));
if (!m_MarkerWidgetComp) return false;
m_MarkerWidgetComp.SetMarkerObject(this);
m_ConfigEntry.InitClientSettings(this, m_MarkerWidgetComp, true);
return m_wRoot.FindAnyWidget("MarkerText") != null;
}
string ERR_ProbeMapText()
{
if (!m_wRoot) return "";
TextWidget text = TextWidget.Cast(m_wRoot.FindAnyWidget("MarkerText"));
if (!text) return "";
return text.GetText();
}
void ERR_ProbeDetachMapWidget()
{
// Remove only this probe object's native subscriptions/widgets.
SCR_MapEntity.GetOnMapClose().Remove(OnMapClosed);
SCR_MapEntity.GetOnLayerChanged().Remove(OnMapLayerChanged);
if (m_wRoot) m_wRoot.RemoveFromHierarchy();
m_wRoot = null;
m_MarkerWidgetComp = null;
}
}
class ERR_NativeDiscoveryMapProbe
{
protected static ref ERR_NativePlainMapMarker s_Plain;
protected static ref ERR_NativeObjectiveMapMarker s_Objective;
static void Stop()
{
SCR_MapMarkerManagerComponent manager = SCR_MapMarkerManagerComponent.GetInstance();
if (s_Plain)
{
s_Plain.ERR_ProbeDetachMapWidget();
if (manager) manager.RemoveStaticMarker(s_Plain);
}
if (s_Objective)
{
s_Objective.ERR_ProbeDetachMapWidget();
if (manager) manager.RemoveStaticMarker(s_Objective);
}
s_Plain = null;
s_Objective = null;
}
protected static bool Check(bool success, string detail)
{
if (success) { Print("ERR SMOKE PASS: discovery map " + detail); return true; }
Print("ERR SMOKE FAIL: discovery map " + detail, LogLevel.ERROR);
Stop();
return false;
}
// Invoke once after ordinary fixture admission and native map manager init.
static bool Run()
{
Stop();
SCR_MapMarkerManagerComponent manager = SCR_MapMarkerManagerComponent.GetInstance();
if (!Check(manager && manager.GetMarkerConfig() && GetGame().GetPlayerController(), "native local controller and marker manager available")) return false;
int originalCount = manager.GetStaticMarkers().Count();
s_Plain = new ERR_NativePlainMapMarker();
s_Plain.SetType(SCR_EMapMarkerType.PLACED_CUSTOM);
s_Plain.SetMarkerConfigID(0);
s_Plain.SetCustomText("Unknown location");
manager.InsertStaticMarker(s_Plain, true);
if (!Check(s_Plain.ERR_ProbeAttachMapWidget() && s_Plain.ERR_ProbeMapText() == "Unknown location", "native baseline label rendered in actual hidden marker layout")) return false;
s_Plain.SetCustomText("Radio station");
if (!Check(s_Plain.GetCustomText() == "Radio station" && s_Plain.ERR_ProbeMapText() == "Unknown location", "native data-only setter reproduces stale already-open label")) return false;
if (!Check(s_Plain.CanBeRemovedByOwner() && SCR_MapMarkersUI.IsOwnedMarker(s_Plain), "plain local marker exposes native delete/edit/drag eligibility")) return false;
s_Objective = new ERR_NativeObjectiveMapMarker();
s_Objective.SetType(SCR_EMapMarkerType.PLACED_CUSTOM);
s_Objective.SetMarkerConfigID(0);
s_Objective.SetCustomText("Unknown location");
manager.InsertStaticMarker(s_Objective, true);
if (!Check(s_Objective.GetMarkerOwnerID() == -1 && !SCR_MapMarkersUI.IsOwnedMarker(s_Objective) && !s_Objective.CanBeRemovedByOwner(), "local insertion retains objective identity and disables native edit/drag/delete eligibility")) return false;
if (!Check(s_Objective.ERR_ProbeAttachMapWidget() && s_Objective.ERR_ProbeMapText() == "Unknown location", "objective first label rendered through actual native layout")) return false;
Widget originalWidget = s_Objective.GetRootWidget();
s_Objective.SetCustomText("Radio station");
if (!Check(s_Objective.GetRootWidget() == originalWidget && s_Objective.ERR_ProbeMapText() == "Radio station", "identification refreshes existing native widget without recreating marker")) return false;
if (!Check(manager.GetStaticMarkers().Count() == originalCount + 2, "label change creates no additional marker")) return false;
s_Objective.ERR_ProbeDetachMapWidget();
s_Objective.SetCustomText("Initial helicopter pickup site");
if (!Check(!s_Objective.GetRootWidget() && s_Objective.GetCustomText() == "Initial helicopter pickup site", "closed widget accepts data-only update safely")) return false;
if (!Check(s_Objective.ERR_ProbeAttachMapWidget() && s_Objective.ERR_ProbeMapText() == "Initial helicopter pickup site", "new native widget renders latest saved label")) return false;
Stop();
return Check(manager.GetStaticMarkers().Count() == originalCount, "owned probe widgets and markers removed; mission markers preserved");
}
}
#endif
@@ -0,0 +1,129 @@
#ifdef WORKBENCH
[BaseContainerProps(category: "Respawn")]
modded class ERR_SpawnLogic
{
ERR_LocalAdmission ERR_LocalProbeHelper()
{
if (!ERR_NativeLocalAdmissionProbe.Enabled()) return null;
return m_LocalAdmission;
}
bool ERR_LocalProbeIdle(int connection)
{
return ERR_NativeLocalAdmissionProbe.Enabled() && !m_Attempts.Contains(connection) && !m_Retries.Contains(connection) && !m_Pending.Contains(connection) && !m_AuthorizedPositions.Contains(connection) && m_SpawnTickets.IsEmpty();
}
bool ERR_LocalProbeClosed()
{
return ERR_NativeLocalAdmissionProbe.Enabled() && m_AdmissionsStopped && m_LocalAdmissionFailed;
}
bool ERR_LocalProbeRefuseController(int connection)
{
if (!ERR_NativeLocalAdmissionProbe.Enabled() || !m_LocalAdmission || !m_LocalAdmission.OfflineMode() || !m_LocalAdmission.Selected() || !m_Identities.Contains(connection)) return false;
// Deliberately invalid METHOD ARGUMENT, not a fabricated native disconnect or
// replacement controller. The real controller and backend remain untouched.
UUID rejected = m_LocalAdmission.Resolve(ERR_GameMode.Get(), connection, null, m_Identities.Get(connection));
if (!rejected.IsNull()) return false;
return !CheckLocalAdmissionContext();
}
}
class ERR_NativeLocalAdmissionProbe
{
protected ERR_GameMode m_Mode;
protected SCR_PlayerController m_Controller;
protected IEntity m_Actor;
protected ERR_SpawnLogic m_Logic;
protected ERR_LocalAdmission m_Helper;
protected ERR_PlayerLife m_Life;
protected UUID m_Key;
protected int m_Connection;
protected int m_Participants;
protected int m_Changes;
protected int m_Step;
protected float m_Deadline;
protected float m_Wait;
protected bool m_Listening;
protected bool m_Stopped;
static bool Enabled()
{
string enabled, outcome;
return Replication.IsServer() && System.GetCLIParam("errBaseSmoke", enabled) && enabled == "1" && System.GetCLIParam("errSmokeOutcome", outcome) && outcome == "local-admission";
}
void ERR_NativeLocalAdmissionProbe(ERR_GameMode mode)
{
m_Mode = mode; m_Deadline = GetGame().GetWorld().GetWorldTime() + 15000;
}
protected bool Check(bool condition, string detail)
{
if (condition) { Print("ERR SMOKE PASS: local admission " + detail); return true; }
Print("ERR SMOKE FAIL: local admission " + detail, LogLevel.ERROR); Stop(); return false;
}
protected void Changed(int connection) { m_Changes++; }
protected int Participants()
{
array<ref ERR_PlayerLife> lives = {}; m_Mode.Players().Participants(lives); return lives.Count();
}
protected bool Unchanged()
{
return m_Controller && m_Actor && m_Life && m_Mode.Players().Get(m_Connection) == m_Life && m_Mode.Players().CurrentActor(m_Actor) == m_Life && m_Life.AccountId == m_Key && m_Life.Connected && m_Life.UsedLife && m_Life.Actor == m_Actor && m_Controller.GetControlledEntity() == m_Actor && GetGame().GetPlayerManager().GetPlayerController(m_Connection) == m_Controller && Participants() == m_Participants && !m_Mode.Players().CanEnter(m_Connection, ERR_Phase.PRISON) && m_Logic.ERR_LocalProbeIdle(m_Connection);
}
protected bool DisposableHelpers()
{
ERR_LocalAdmission disconnected = new ERR_LocalAdmission(m_Mode);
if (!Check(disconnected.Resolve(m_Mode, m_Connection, m_Controller, m_Key) == m_Key && disconnected.Validate() && !disconnected.LocalKey(), "disposable helper accepts actual sole native controller using existing round key")) return false;
// Opaque alternative input only: no backend read/write, roster bind or login.
UUID alternative = "00e77500-0000-0000-0000-000000000001";
if (!Check(disconnected.Resolve(m_Mode, m_Connection, m_Controller, alternative) == m_Key && disconnected.Resolve(m_Mode, m_Connection, m_Controller, UUID.NULL_UUID) == m_Key, "late opaque identity input and null input retain the selected key")) return false;
if (!Check(!disconnected.Disconnected(m_Connection + 1) && disconnected.Validate(), "unrelated disconnect argument does not close helper")) return false;
if (!Check(disconnected.Disconnected(m_Connection) && !disconnected.Validate() && disconnected.Resolve(m_Mode, m_Connection, m_Controller, m_Key).IsNull(), "matching disconnect argument latches disposable helper closed")) return false;
disconnected.Stop();
if (!Check(!disconnected.Validate() && disconnected.Resolve(m_Mode, m_Connection, m_Controller, m_Key).IsNull(), "stopped disposable helper cannot reopen with the genuine controller")) return false;
ERR_LocalAdmission invalid = new ERR_LocalAdmission(m_Mode);
if (!Check(invalid.Resolve(m_Mode, m_Connection, null, m_Key).IsNull() && invalid.Resolve(m_Mode, m_Connection, m_Controller, m_Key).IsNull() && !invalid.Selected(), "invalid controller argument before selection fails closed without selecting another life")) return false;
invalid.Stop();
Print("ERR LOCAL ADMISSION LIMIT: disposable method-argument fault injection; no native disconnect or replacement occurred; Listen/Dedicated pass-through remains source-policy coverage, not multiplayer evidence");
return true;
}
void Stop()
{
if (m_Stopped) return;
m_Stopped = true;
if (m_Listening && m_Mode) m_Mode.Players().OnChanged().Remove(Changed);
m_Listening = false;
}
int Tick(float now)
{
if (m_Stopped) return -1;
if (!Enabled() || now > m_Deadline) { Check(false, "explicit enabled fixture completes within fifteen seconds"); return -1; }
if (now < m_Wait) return 0;
if (m_Step == 0)
{
m_Controller = SCR_PlayerController.Cast(GetGame().GetPlayerController());
SCR_RespawnSystemComponent respawn = SCR_RespawnSystemComponent.GetInstance();
if (respawn) m_Logic = ERR_SpawnLogic.Cast(respawn.GetSpawnLogic());
if (!Check(RplSession.Mode() == RplMode.None && m_Controller && m_Logic && GetGame().GetPlayerManager().GetPlayerCount() == 1, "actual standalone session has one native local controller and successor spawn logic")) return -1;
m_Connection = m_Controller.GetPlayerId(); m_Actor = m_Controller.GetControlledEntity();
m_Life = m_Mode.Players().Get(m_Connection); m_Helper = m_Logic.ERR_LocalProbeHelper();
if (!Check(m_Actor && m_Life && m_Helper && m_Helper.OfflineMode() && m_Helper.Selected() && m_Helper.Validate(), "real native admission already created the local controlled prisoner and selected helper")) return -1;
m_Key = m_Life.AccountId; m_Participants = Participants();
if (!Check(!m_Key.IsNull() && Unchanged(), "existing prisoner has one spent life and no pending spawn metadata")) return -1;
if (!DisposableHelpers()) return -1;
m_Mode.Players().OnChanged().Insert(Changed); m_Listening = true;
Print("ERR LOCAL ADMISSION REPLAY: invoking existing callback twice for already admitted real controller; this does not represent new native authentication/audits");
m_Logic.OnPlayerAuditSuccess_S(m_Connection);
m_Logic.OnPlayerAuditSuccess_S(m_Connection);
if (!Check(Unchanged() && m_Changes == 0, "replayed callbacks preserve exact roster object, used life, key, actor and no roster-change event")) return -1;
m_Step = 1; m_Wait = now + 1500; return 0;
}
if (m_Step == 1)
{
if (!Check(Unchanged() && m_Changes == 0 && m_Helper.Validate(), "native update interval after replay creates no replacement actor, life or pending request")) return -1;
if (!Check(m_Logic.ERR_LocalProbeRefuseController(m_Connection), "live helper rejects invalid controller argument through production context guard")) return -1;
// The guard has synchronously entered the real terminal transition and
// stopped services. No second callback, login, UUID or actor is introduced.
if (!Check(m_Mode.Phase() == ERR_Phase.DEFEAT && m_Mode.EndReason().Contains("offline player context changed") && m_Logic.ERR_LocalProbeClosed() && !m_Helper.Validate() && Unchanged(), "production failure closes admission and ends round while preserving original used life and controlled actor")) return -1;
Stop(); m_Step = 2; return 1;
}
return 0;
}
}
#endif
@@ -0,0 +1,321 @@
#ifdef WORKBENCH
// New native-input feasibility experiment. No original Escapists flight code.
// Only the exact fixture-owned AI pilot and helicopter receive these hooks.
modded class SCR_CharacterControllerComponent
{
override void OnPrepareControls(IEntity owner, ActionManager am, float dt, bool player)
{
super.OnPrepareControls(owner, am, dt, player);
ERR_NativePoweredFlightProbe probe = ERR_NativePoweredFlightProbe.Current();
if (probe && !player) probe.PreparePilot(this, owner, dt);
}
}
modded class SCR_HelicopterControllerComponent
{
protected override event void OnPrepareControls()
{
super.OnPrepareControls();
ERR_NativePoweredFlightProbe probe = ERR_NativePoweredFlightProbe.Current();
if (probe) probe.PrepareHelicopter(this);
}
}
class ERR_PoweredFlightRules
{
static bool Authority(bool server, bool enabled, bool stopped, bool ownedPilot, bool ownedSeat, bool playerPresent, bool alive, bool fueled)
{
return server && enabled && !stopped && ownedPilot && ownedSeat && !playerPresent && alive && fueled;
}
static float ClampInput(float value, float limit = 1)
{
return Math.Clamp(value, -limit, limit);
}
static float DesiredVertical(float height, bool landing)
{
float target = 8;
if (landing) target = 0;
return Math.Clamp((target - height) * 0.6, -0.8, 1.5);
}
static bool Hover(float height, float speed, float vertical, float upright, float drift)
{
return height >= 7 && height <= 9 && speed < 1.5 && Math.AbsFloat(vertical) < 0.5 && upright > 0.98 && drift < 8;
}
static bool Landed(bool contact, float height, float speed, float angular, float upright)
{
return contact && height < 1 && height > -1 && speed < 0.5 && angular < 0.1 && upright > 0.98;
}
}
class ERR_NativePoweredFlightProbe
{
protected static ERR_NativePoweredFlightProbe s_Current;
protected ERR_GameMode m_Mode;
protected Vehicle m_Aircraft;
protected SCR_AIGroup m_Group;
protected IEntity m_Pilot;
protected HelicopterControllerComponent m_Controller;
protected CharacterControllerComponent m_Character;
protected CharacterInputContext m_Input;
protected VehicleHelicopterSimulation m_Simulation;
protected FuelManagerComponent m_Fuel;
protected PilotCompartmentSlot m_Seat;
protected CollectiveMode m_OriginalMode;
protected vector m_Home;
protected float m_Heading;
protected float m_Deadline;
protected float m_StageDeadline;
protected float m_Stable = -1;
protected float m_PreviousTick = -1;
protected float m_NextLog;
protected float m_InitialFuel;
protected float m_Collective = -1;
protected float m_LastControl;
protected int m_Stage;
protected int m_Wakes;
protected int m_StartRequests;
protected int m_ControlUpdates;
protected int m_HelicopterUpdates;
protected bool m_Bound;
protected bool m_ModeSaved;
protected bool m_Stopped;
protected bool m_Complete;
protected bool m_ReadbackOK = true;
static const ResourceName AIRCRAFT = "{DF5CCB7C0FF049F4}Prefabs/Vehicles/Helicopters/Mi8MT/Mi8MT_unarmed_transport.et";
static const ResourceName GROUP = "{8DE0C0830FE0C33D}Prefabs/Groups/OPFOR/Group_USSR_Base.et";
static const ResourceName PILOT = "{86E565387A634103}Prefabs/Characters/Campaign/Final/OPFOR/USSR_Army/Regular/Campaign_USSR_Player_MortarCrew.et";
static bool Enabled()
{
string enabled, outcome;
return Replication.IsServer() && System.GetCLIParam("errBaseSmoke", enabled) && enabled == "1" && System.GetCLIParam("errSmokeOutcome", outcome) && outcome == "powered-flight";
}
static ERR_NativePoweredFlightProbe Current() { return s_Current; }
void ERR_NativePoweredFlightProbe(ERR_GameMode mode)
{
m_Mode = mode; m_Deadline = GetGame().GetWorld().GetWorldTime() + 240000;
if (Enabled() && !s_Current) s_Current = this;
else m_Stopped = true;
}
protected bool Check(bool condition, string detail)
{
if (condition) { Print("ERR SMOKE PASS: powered-flight " + detail); return true; }
Print("ERR SMOKE FAIL: powered-flight " + detail, LogLevel.ERROR); Stop(); return false;
}
protected bool PlayerPresent()
{
if (!m_Aircraft || !m_Group || m_Group.GetPlayerCount(true) > 0) return true;
array<int> ids = {}; GetGame().GetPlayerManager().GetPlayers(ids);
foreach (int id : ids)
{
IEntity actor = GetGame().GetPlayerManager().GetPlayerControlledEntity(id);
if (actor && (actor == m_Pilot || CompartmentAccessComponent.GetVehicleIn(actor) == m_Aircraft)) return true;
}
return false;
}
protected bool OwnPilot()
{
return m_Pilot && m_Group && ERR_Actors.Group(m_Pilot) == m_Group && !ERR_Actors.Player(m_Pilot);
}
protected bool PoweredAuthority()
{
bool occupied = m_Seat && m_Seat.GetOccupant() == m_Pilot && m_Controller && m_Controller.GetPilotCompartmentSlot() == m_Seat && CompartmentAccessComponent.GetVehicleIn(m_Pilot) == m_Aircraft;
bool alive = ERR_Actors.Alive(m_Aircraft) && ERR_Actors.CanFight(m_Pilot);
SCR_VehicleDamageManagerComponent damage;
if (m_Aircraft) damage = SCR_VehicleDamageManagerComponent.Cast(m_Aircraft.FindComponent(SCR_VehicleDamageManagerComponent));
alive = alive && damage && damage.GetEngineFunctional() && damage.GetMovementDamage() < 1 && !damage.IsOnFire();
if (m_Simulation)
for (int rotor = 0; rotor < m_Simulation.RotorCount(); rotor++) if (m_Simulation.RotorGetState(rotor) == RotorState.DESTROYED) alive = false;
return ERR_PoweredFlightRules.Authority(Replication.IsServer(), Enabled(), m_Stopped, OwnPilot(), occupied, PlayerPresent(), alive, m_Fuel && m_Fuel.HasFuel());
}
void PrepareHelicopter(HelicopterControllerComponent controller)
{
if (!m_Bound || controller != m_Controller || !PoweredAuthority()) return;
// Native SCR controller normally reapplies device preferences every update.
// Override only this owned fixture controller, never global/user settings.
controller.SetCollectiveMode(CollectiveMode.Direct); m_HelicopterUpdates++;
}
void PreparePilot(CharacterControllerComponent controller, IEntity owner, float dt)
{
if (!m_Bound || controller != m_Character || owner != m_Pilot || !PoweredAuthority() || !m_Input || !m_Simulation || dt <= 0 || dt > 0.2) return;
vector transform[4]; m_Simulation.GetWorldTransform(transform);
vector velocity = m_Simulation.GetVelocity();
vector angular = m_Simulation.GetAngularVelocityLocal();
float height = transform[3][1] - m_Home[1];
float forward, aside, torque;
float collective = -1;
if (m_Stage >= 4 && m_Stage <= 6 && m_Controller.IsEngineOn())
{
float desiredVertical = ERR_PoweredFlightRules.DesiredVertical(height, m_Stage == 6);
float error = desiredVertical - velocity[1];
m_Collective = Math.Clamp(m_Collective + error * dt * 0.12, -0.95, 0.8);
collective = Math.Clamp(m_Collective + error * 0.12, -1, 0.9);
vector offset = m_Home - transform[3]; offset[1] = 0;
vector acceleration = offset * 0.08 - velocity * 0.3; acceleration[1] = 0;
// Small local cyclic corrections counter drift/tilt through native inputs.
// Sign/gain and native Direct-mode response remain experimental evidence.
forward = ERR_PoweredFlightRules.ClampInput((vector.Dot(acceleration, transform[2]) / 9.81 + transform[2][1]) * 0.8 - angular[0] * 0.3, 0.15);
aside = ERR_PoweredFlightRules.ClampInput((vector.Dot(acceleration, transform[0]) / 9.81 + transform[0][1]) * 0.8 + angular[2] * 0.3, 0.15);
float headingError = m_Heading - m_Aircraft.GetAngles()[0];
while (headingError > 180) headingError -= 360;
while (headingError < -180) headingError += 360;
torque = ERR_PoweredFlightRules.ClampInput(headingError * 0.01 - angular[1] * 0.3, 0.3);
if (m_Stage == 6 && ERR_PoweredFlightRules.Landed(m_Simulation.HasAnyGroundContact(), height, velocity.Length(), angular.Length(), transform[1][1])) collective = -1;
}
m_Input.SetVehicleThrottle(1);
m_Input.SetVehicleCollective(collective);
m_Input.SetVehicleCyclicForward(forward);
m_Input.SetVehicleCyclicAside(aside);
m_Input.SetVehicleAntiTorque(torque);
m_ReadbackOK = m_ReadbackOK && Math.AbsFloat(m_Input.GetVehicleCollective() - collective) < 0.001 && Math.AbsFloat(m_Input.GetVehicleCyclicForward() - forward) < 0.001 && Math.AbsFloat(m_Input.GetVehicleCyclicAside() - aside) < 0.001 && Math.AbsFloat(m_Input.GetVehicleAntiTorque() - torque) < 0.001;
m_ControlUpdates++; m_LastControl = GetGame().GetWorld().GetWorldTime();
}
protected bool FindPad(out vector result)
{
vector anchor = m_Mode.ExtractionVehicle().GetOrigin();
for (int index = 0; index < 12; index++)
{
float angle = index * Math.PI / 6;
vector candidate = ERR_Actors.Ground(anchor + Vector(Math.Cos(angle) * 120, 0, Math.Sin(angle) * 120));
if (candidate[1] < 2) continue;
bool flat = true;
for (int edge = 0; edge < 4; edge++)
{
float side = edge * Math.PI / 2;
vector point = candidate + Vector(Math.Cos(side) * 14, 0, Math.Sin(side) * 14);
if (Math.AbsFloat(SCR_TerrainHelper.GetTerrainY(point) - candidate[1]) > 0.8) flat = false;
}
if (!flat || !SCR_WorldTools.TraceCilinderUtil(candidate + "0 2.5 0", 15, 4, TraceFlags.ENTS)) continue;
TraceBox clearance = new TraceBox(); clearance.Start = candidate + "0 3 0"; clearance.End = candidate + "0 35 0";
clearance.Mins = "-15 -1 -15"; clearance.Maxs = "15 1 15"; clearance.Flags = TraceFlags.ENTS | TraceFlags.WORLD;
if (GetGame().GetWorld().TraceMove(clearance, null) < 1) continue;
result = candidate; return true;
}
return false;
}
protected void Diagnostic(float now)
{
if (!m_Simulation || !m_Aircraft || now < m_NextLog) return;
m_NextLog = now + 2000;
vector transform[4]; m_Simulation.GetWorldTransform(transform);
PrintFormat("ERR POWERED FLIGHT: stage=%1 height=%2 drift=%3 speed=%4 vertical=%5 up=%6 groundContact=%7 fuel=%8 engine=%9", m_Stage, transform[3][1] - m_Home[1], vector.DistanceXZ(transform[3], m_Home), m_Simulation.GetVelocity().Length(), m_Simulation.GetVelocity()[1], transform[1][1], m_Simulation.HasAnyGroundContact(), m_Fuel.GetTotalFuel(), m_Controller.IsEngineOn());
PrintFormat("ERR POWERED INPUT: pilotHooks=%1 vehicleHooks=%2 readback=%3 collective=%4 cyclicF=%5 cyclicR=%6 antiTorque=%7 rotorRPM=%8 targetRPM=%9", m_ControlUpdates, m_HelicopterUpdates, m_ReadbackOK, m_Input.GetVehicleCollective(), m_Input.GetVehicleCyclicForward(), m_Input.GetVehicleCyclicAside(), m_Input.GetVehicleAntiTorque(), m_Simulation.RotorGetRPM(0), m_Simulation.RotorGetRPMTarget(0));
}
void Stop()
{
if (m_Stopped) return;
// Input cleanup is confined to the same unclaimed test pilot/aircraft.
bool ours = m_Bound && OwnPilot() && !PlayerPresent();
m_Stopped = true; m_Bound = false;
if (s_Current == this) s_Current = null;
if (ours && m_Input)
{
m_Input.SetVehicleCollective(0); m_Input.SetVehicleThrottle(0);
m_Input.SetVehicleCyclicForward(0); m_Input.SetVehicleCyclicAside(0); m_Input.SetVehicleAntiTorque(0);
if (m_Controller && m_ModeSaved) m_Controller.SetCollectiveMode(m_OriginalMode);
}
if (m_Group && m_Group.GetPlayerCount(true) == 0) m_Group.SetPermanentLOD(-1);
// Keep real airborne/failed test actors for diagnosis and mode-owned cleanup.
// Stop never repairs, stabilizes, teleports, refuels or replaces them.
}
int Tick(float now)
{
if (m_Complete) return 1;
if (m_Stopped) return -1;
if (!Enabled() || !m_Mode || now >= m_Deadline || ERR_MissionRules.Terminal(m_Mode.Phase())) { Check(false, "server fixture active within 240-second bound"); return -1; }
if (m_PreviousTick >= 0 && (now < m_PreviousTick || now - m_PreviousTick > 1500)) m_Stable = -1;
m_PreviousTick = now;
if (m_Stage == 0)
{
if (!m_Mode.ExtractionVehicle()) return 0;
vector pad;
if (!Check(FindPad(pad), "separate clear flat test pad found; extraction vehicle untouched")) return -1;
m_Aircraft = Vehicle.Cast(ERR_Actors.Spawn(AIRCRAFT, pad));
m_Group = SCR_AIGroup.Cast(ERR_Actors.Spawn(GROUP, pad + "20 0 0"));
m_Mode.Own(m_Aircraft); m_Mode.Own(m_Group);
if (!Check(m_Aircraft && m_Group, "one stock unarmed airframe and own empty group created once")) return -1;
m_Group.SetPermanentLOD(0); m_Group.ActivateAI();
m_Controller = HelicopterControllerComponent.Cast(m_Aircraft.FindComponent(HelicopterControllerComponent));
if (m_Controller) { m_Simulation = m_Controller.GetSimulation(); m_Seat = m_Controller.GetPilotCompartmentSlot(); }
m_Fuel = FuelManagerComponent.Cast(m_Aircraft.FindComponent(FuelManagerComponent));
if (!Check(m_Simulation && m_Seat && !m_Seat.GetOccupant() && m_Fuel && m_Fuel.HasFuel(), "native flight simulation, actual active pilot seat and finite fuel present")) return -1;
AIGroup nativeGroup = m_Group;
m_Pilot = m_Seat.SpawnCharacterInCompartment(PILOT, nativeGroup, GROUP);
if (!Check(m_Pilot && nativeGroup == m_Group, "one existing vanilla character spawned through native pilot-seat mechanism")) return -1;
m_Mode.Own(m_Pilot);
m_Stage = 1; m_StageDeadline = now + 30000; return 0;
}
if (m_Stage == 1)
{
Physics physics = m_Aircraft.GetPhysics();
if (physics && physics.IsDynamic() && m_Simulation.IsValid() && m_Wakes == 0) { m_Wakes = 1; physics.SetActive(ActiveState.ACTIVE); m_Stable = -1; return 0; }
if (now >= m_StageDeadline) { Check(false, "initial native seating and ground settling complete in 30 seconds"); return -1; }
if (!m_Wakes || !OwnPilot() || m_Seat.GetOccupant() != m_Pilot || !ERR_CasualtyLoadingRules.AircraftReady(m_Aircraft)) { m_Stable = -1; return 0; }
if (m_Stable < 0) m_Stable = now;
if (now - m_Stable < 1000) return 0;
m_Character = CharacterControllerComponent.Cast(m_Pilot.FindComponent(CharacterControllerComponent));
if (m_Character) m_Input = m_Character.GetInputContext();
if (!Check(m_Input && m_Group.GetAgentsCount() == 1 && PoweredAuthority(), "one living native AI pilot physically occupies its own fueled helicopter")) return -1;
m_Home = m_Aircraft.GetOrigin(); m_Heading = m_Aircraft.GetAngles()[0];
m_OriginalMode = m_Controller.GetCollectiveMode(); m_ModeSaved = true;
m_InitialFuel = m_Fuel.GetTotalFuel(); m_Bound = true;
m_Stage = 2; m_StageDeadline = now + 5000; return 0;
}
Diagnostic(now);
if (!PoweredAuthority() || !m_ReadbackOK) { Check(false, "current owned conscious pilot, fuel, rotors and exact input readback remain valid"); return -1; }
if (m_Stage == 2)
{
if (now >= m_StageDeadline) { Check(false, "native AI input and helicopter preparation hooks execute before engine start"); return -1; }
if (m_ControlUpdates < 3 || m_HelicopterUpdates < 3) return 0;
if (!Check(m_Controller.GetCollectiveMode() == CollectiveMode.Direct && m_Input.GetVehicleCollective() == -1, "owned native input hooks apply minimum collective in Direct mode")) return -1;
m_StartRequests = 1;
bool started = m_Controller.StartEngine();
PrintFormat("ERR POWERED ENGINE REQUEST: StartEngine returned=%1; normal procedure, no force-start or simulation EngineStart", started);
m_Stage = 3; m_StageDeadline = now + 65000; return 0;
}
if (now - m_LastControl > 1000) { Check(false, "native control callback remains live during test flight"); return -1; }
vector transform[4]; m_Simulation.GetWorldTransform(transform);
float height = transform[3][1] - m_Home[1];
float speed = m_Simulation.GetVelocity().Length();
float drift = vector.DistanceXZ(transform[3], m_Home);
if (height > 18 || height < -3 || drift > 22 || transform[1][1] < 0.85) { Check(false, "physical test stays inside height, drift and tilt safety envelope"); return -1; }
if (m_Stage == 3)
{
if (now >= m_StageDeadline) { Check(false, "normal engine startup and native rotor RPM complete within 65 seconds"); return -1; }
float targetRPM = m_Simulation.RotorGetRPMTarget(0);
if (!m_Controller.IsEngineOn() || targetRPM <= 0 || m_Simulation.RotorGetRPM(0) < targetRPM * 0.9 || m_Fuel.GetTotalFuel() >= m_InitialFuel) return 0;
if (!Check(m_StartRequests == 1 && m_Fuel.GetTotalFuel() < m_InitialFuel, "single normal engine start spins physical rotor and consumes native fuel")) return -1;
m_Collective = -0.8; m_Stage = 4; m_StageDeadline = now + 65000; m_Stable = -1; return 0;
}
if (m_Stage >= 4 && m_Stage <= 6 && !m_Controller.IsEngineOn()) { Check(false, "powered flight retains real running engine"); return -1; }
if (m_Stage == 4 || m_Stage == 5)
{
bool hover = !m_Simulation.HasAnyGroundContact() && ERR_PoweredFlightRules.Hover(height, speed, m_Simulation.GetVelocity()[1], transform[1][1], drift);
if (!hover) m_Stable = -1;
if (hover && m_Stable < 0) m_Stable = now;
if (now >= m_StageDeadline) { Check(false, "actual powered takeoff and five-second stable hover reached in 65 seconds"); return -1; }
if (m_Stable >= 0 && now - m_Stable >= 5000)
{
if (!Check(m_ControlUpdates > 100 && m_Fuel.GetTotalFuel() < m_InitialFuel - 0.05, "actual 7–9 metre powered hover stable five seconds with native fuel consumption")) return -1;
m_Stage = 6; m_StageDeadline = now + 65000; m_Stable = -1;
}
return 0;
}
if (m_Stage == 6)
{
bool landed = ERR_PoweredFlightRules.Landed(m_Simulation.HasAnyGroundContact(), height, speed, m_Simulation.GetAngularVelocity().Length(), transform[1][1]);
if (!landed) m_Stable = -1;
if (landed && m_Stable < 0) m_Stable = now;
if (now >= m_StageDeadline) { Check(false, "actual native contact landing reached within 65 seconds"); return -1; }
if (m_Stable < 0 || now - m_Stable < 2000) return 0;
if (!Check(drift < 8 && m_Fuel.GetTotalFuel() < m_InitialFuel - 0.05 && m_Wakes == 1 && m_StartRequests == 1, "same physical aircraft and living AI pilot land with stable ground contact after powered hover")) return -1;
m_Controller.StopEngine(false);
m_Stage = 7; m_StageDeadline = now + 15000; return 0;
}
if (m_Stage == 7)
{
if (now >= m_StageDeadline) { Check(false, "normal engine shutdown completed on actual ground"); return -1; }
if (m_Controller.IsEngineOn()) return 0;
if (!Check(ERR_PoweredFlightRules.Landed(m_Simulation.HasAnyGroundContact(), height, speed, m_Simulation.GetAngularVelocity().Length(), transform[1][1]) && PoweredAuthority(), "native engine off after contact landing; no transform/velocity/health/fuel correction")) return -1;
Stop(); m_Complete = true; return 1;
}
return 0;
}
}
#endif
@@ -67,7 +67,7 @@ modded class SCR_BaseItemSupportStationComponent
ownerName = owner.GetName(); ownerName = owner.GetName();
if (owner.GetPrefabData()) prefab = owner.GetPrefabData().GetPrefabName(); if (owner.GetPrefabData()) prefab = owner.GetPrefabData().GetPrefabName();
} }
SCR_EntityCatalogManagerComponent catalog = SCR_EntityCatalogManagerComponent.GetInstance(); bool globalCatalogPresent = SCR_EntityCatalogManagerComponent.GetInstance() != null;
SCR_BaseGameMode baseMode; SCR_BaseGameMode baseMode;
if (GetGame()) baseMode = SCR_BaseGameMode.Cast(GetGame().GetGameMode()); if (GetGame()) baseMode = SCR_BaseGameMode.Cast(GetGame().GetGameMode());
int gameState = -1; int gameState = -1;
@@ -80,7 +80,7 @@ modded class SCR_BaseItemSupportStationComponent
ERR_GameMode mode = ERR_GameMode.Cast(baseMode); ERR_GameMode mode = ERR_GameMode.Cast(baseMode);
if (mode) phase = mode.Phase(); if (mode) phase = mode.Phase();
} }
string detail = string.Format("ERR STATION TEARDOWN DIAG: n=%1 owner=%2 prefab=%3 cachedCatalog=%4 globalCatalog=%5", s_ERRStationTeardownLines, ownerName, prefab, m_EntityCatalogManager != null, catalog != null); string detail = string.Format("ERR STATION TEARDOWN DIAG: n=%1 owner=%2 prefab=%3 cachedCatalog=%4 globalCatalog=%5", s_ERRStationTeardownLines, ownerName, prefab, m_EntityCatalogManager != null, globalCatalogPresent);
detail += string.Format(" modePresent=%1 gameState=%2 errPhase=%3 endData=%4 call=OnDelete/InitValidSetup", baseMode != null, gameState, phase, hasEndData); detail += string.Format(" modePresent=%1 gameState=%2 errPhase=%3 endData=%4 call=OnDelete/InitValidSetup", baseMode != null, gameState, phase, hasEndData);
detail += string.Format(" initSeen=%1 initMode=%2 initMainWorld=%3 initSiteOwned=%4 initInInventory=%5 initParentPrefab=%6", m_ERRStationInitSeen, m_ERRStationInitModePresent, m_ERRStationInitMainWorld, m_ERRStationInitSiteOwned, m_ERRStationInitInInventory, m_ERRStationInitParentPrefab); detail += string.Format(" initSeen=%1 initMode=%2 initMainWorld=%3 initSiteOwned=%4 initInInventory=%5 initParentPrefab=%6", m_ERRStationInitSeen, m_ERRStationInitModePresent, m_ERRStationInitMainWorld, m_ERRStationInitSiteOwned, m_ERRStationInitInInventory, m_ERRStationInitParentPrefab);
bool deleteMainWorld; bool deleteMainWorld;
@@ -111,4 +111,20 @@ modded class ArmaReforgerScripted
super.OnBeforeWorldCleanup(); super.OnBeforeWorldCleanup();
} }
} }
// Observe normal finalized admission; this never creates a body or identity.
modded class ERR_GameMode
{
override void PlayerSpawned(int id, IEntity actor)
{
super.PlayerSpawned(id, actor);
string project;
if (!System.GetCLIParam("errOrdinaryScenario", project) || (project != "core" && project != "chat")) return;
PlayerController local = GetGame().GetPlayerController();
if (!local || local.GetPlayerId() != id || local.GetControlledEntity() != actor || !ERR_Actors.Alive(actor)) return;
if (!Players().CurrentActor(actor) || Phase() != ERR_Phase.PRISON) return;
PrintFormat("ERR ORDINARY: local participant verified project=%1 phase=prison", project);
}
}
#endif #endif
+55 -4
View File
@@ -10,6 +10,8 @@ class ERR_SpawnLogic : SCR_SpawnLogic
protected ref array<ref ERR_SpawnTicket> m_SpawnTickets = {}; protected ref array<ref ERR_SpawnTicket> m_SpawnTickets = {};
protected ERR_GameMode m_LifecycleMode; protected ERR_GameMode m_LifecycleMode;
protected bool m_AdmissionsStopped; protected bool m_AdmissionsStopped;
protected ref ERR_LocalAdmission m_LocalAdmission;
protected bool m_LocalAdmissionFailed;
protected void BindLifecycle(ERR_GameMode mode) protected void BindLifecycle(ERR_GameMode mode)
{ {
@@ -18,11 +20,17 @@ class ERR_SpawnLogic : SCR_SpawnLogic
{ {
m_LifecycleMode.OnPhaseChanged().Remove(AdmissionPhaseChanged); m_LifecycleMode.OnPhaseChanged().Remove(AdmissionPhaseChanged);
m_LifecycleMode.OnStop().Remove(StopAdmissions); m_LifecycleMode.OnStop().Remove(StopAdmissions);
m_LifecycleMode.OnTick().Remove(CheckLocalAdmissionTick);
} }
if (m_LocalAdmission && m_LocalAdmission.OfflineMode()) { StopAdmissions(); m_Identities.Clear(); }
if (m_LocalAdmission) m_LocalAdmission.Stop();
m_LocalAdmission = new ERR_LocalAdmission(mode);
m_LocalAdmissionFailed = false;
m_AdmissionsStopped = false; m_AdmissionsStopped = false;
m_LifecycleMode = mode; m_LifecycleMode = mode;
mode.OnPhaseChanged().Insert(AdmissionPhaseChanged); mode.OnPhaseChanged().Insert(AdmissionPhaseChanged);
mode.OnStop().Insert(StopAdmissions); mode.OnStop().Insert(StopAdmissions);
mode.OnTick().Insert(CheckLocalAdmissionTick);
} }
override void OnPlayerAuditSuccess_S(int playerId) override void OnPlayerAuditSuccess_S(int playerId)
@@ -40,20 +48,47 @@ class ERR_SpawnLogic : SCR_SpawnLogic
ERR_GameMode mode = ERR_GameMode.Get(); ERR_GameMode mode = ERR_GameMode.Get();
BindLifecycle(mode); BindLifecycle(mode);
SCR_PlayerController resultController = SCR_PlayerController.Cast(GetGame().GetPlayerManager().GetPlayerController(playerId)); SCR_PlayerController resultController = SCR_PlayerController.Cast(GetGame().GetPlayerManager().GetPlayerController(playerId));
if (resultController) resultController.ERR_ResetEscapeResult(); if (resultController && (!m_LocalAdmission || !m_LocalAdmission.OfflineMode())) resultController.ERR_ResetEscapeResult();
#ifndef WORKBENCH #ifndef WORKBENCH
string diagnosticProject; string diagnosticProject;
if (System.GetCLIParam("errOrdinaryScenario", diagnosticProject)) if (System.GetCLIParam("errOrdinaryScenario", diagnosticProject) && (diagnosticProject == "core" || diagnosticProject == "chat"))
{
PrintFormat("ERR ORDINARY ADMISSION: server=%1 sessionMode=%2 modePresent=%3 controllerPresent=%4 identityPresent=%5 nameLength=%6", Replication.IsServer(), RplSession.Mode(), mode != null, resultController != null, !identity.IsNull(), GetGame().GetPlayerManager().GetPlayerName(playerId).Length()); PrintFormat("ERR ORDINARY ADMISSION: server=%1 sessionMode=%2 modePresent=%3 controllerPresent=%4 identityPresent=%5 nameLength=%6", Replication.IsServer(), RplSession.Mode(), mode != null, resultController != null, !identity.IsNull(), GetGame().GetPlayerManager().GetPlayerName(playerId).Length());
// Read cached native identity metadata only. Never print identity/name bytes,
// override cached backend identity or change its native utility.
string rawIdentity;
int rawLength = -1;
BackendApi backend = GetGame().GetBackendApi();
if (backend)
{
rawIdentity = backend.GetPlayerIdentityId(playerId);
rawLength = rawIdentity.Length();
}
UUID rawUUID = rawIdentity;
PrintFormat("ERR ORDINARY IDENTITY: rawLength=%1 rawEmpty=%2 rawNull=%3 rawFormatValid=%4 rawNullSentinel=%5 helperLength=%6 helperFormatValid=%7 dedicated=%8", rawLength, rawIdentity.IsEmpty(), rawUUID.IsNull(), UUID.IsUUID(rawIdentity), rawIdentity == UUID.NULL_UUID, identity.Length(), UUID.IsUUID(identity), RplSession.Mode() == RplMode.Dedicated);
}
#endif #endif
if (m_LocalAdmission) identity = m_LocalAdmission.Resolve(mode, playerId, resultController, identity);
if (!CheckLocalAdmissionContext()) return;
// Repeated real callbacks retain the existing attempt/body/life and result.
if (m_LocalAdmission && m_LocalAdmission.Selected() && m_Identities.Contains(playerId))
{
if (m_Identities.Get(playerId) != identity) { m_LocalAdmission.Disconnected(playerId); CheckLocalAdmissionContext(); return; }
if (resultController) resultController.ERR_PublishEscapeResult(mode.Players(), mode.Extraction());
return;
}
if (!mode || !mode.Players().Bind(playerId, identity)) if (!mode || !mode.Players().Bind(playerId, identity))
{ {
Print("Rereintroduced: player identity could not be bound; spawn withheld", LogLevel.ERROR); Print("Rereintroduced: player identity could not be bound; spawn withheld", LogLevel.ERROR);
return; return;
} }
if (resultController) resultController.ERR_PublishEscapeResult(mode.Players(), mode.Extraction()); if (resultController)
{
if (m_LocalAdmission && m_LocalAdmission.OfflineMode()) resultController.ERR_ResetEscapeResult();
resultController.ERR_PublishEscapeResult(mode.Players(), mode.Extraction());
}
m_Identities.Set(playerId, identity); m_Identities.Set(playerId, identity);
if (ResolveReconnection(playerId)) if ((!m_LocalAdmission || !m_LocalAdmission.LocalKey()) && ResolveReconnection(playerId))
{ {
mode.PlayerSpawned(playerId, GetGame().GetPlayerManager().GetPlayerControlledEntity(playerId)); mode.PlayerSpawned(playerId, GetGame().GetPlayerManager().GetPlayerControlledEntity(playerId));
SCR_PlayerController.Cast(GetGame().GetPlayerManager().GetPlayerController(playerId)).ERR_SetObserver(ERR_ObserverReason.NONE); SCR_PlayerController.Cast(GetGame().GetPlayerManager().GetPlayerController(playerId)).ERR_SetObserver(ERR_ObserverReason.NONE);
@@ -68,6 +103,7 @@ class ERR_SpawnLogic : SCR_SpawnLogic
ERR_GameMode mode = ERR_GameMode.Get(); ERR_GameMode mode = ERR_GameMode.Get();
SCR_PlayerController controller = SCR_PlayerController.Cast(GetGame().GetPlayerManager().GetPlayerController(playerId)); SCR_PlayerController controller = SCR_PlayerController.Cast(GetGame().GetPlayerManager().GetPlayerController(playerId));
if (!controller || !mode || m_AdmissionsStopped || !m_Identities.Contains(playerId) || !m_Attempts.Contains(playerId) || m_Pending.Contains(playerId)) return; if (!controller || !mode || m_AdmissionsStopped || !m_Identities.Contains(playerId) || !m_Attempts.Contains(playerId) || m_Pending.Contains(playerId)) return;
if (!CheckLocalAdmissionContext()) return;
if (controller.GetControlledEntity()) return; if (controller.GetControlledEntity()) return;
if (ERR_MissionRules.Terminal(mode.Phase())) return; if (ERR_MissionRules.Terminal(mode.Phase())) return;
if (!mode.PreparationError().IsEmpty()) { Observe(playerId, ERR_ObserverReason.SPAWN_UNAVAILABLE); return; } if (!mode.PreparationError().IsEmpty()) { Observe(playerId, ERR_ObserverReason.SPAWN_UNAVAILABLE); return; }
@@ -150,6 +186,7 @@ class ERR_SpawnLogic : SCR_SpawnLogic
{ {
ERR_GameMode mode = ERR_GameMode.Get(); ERR_GameMode mode = ERR_GameMode.Get();
if (!Replication.IsServer() || m_AdmissionsStopped || !mode || !ticket || ticket.Mode != mode || !ticket.Actor || !ticket.Request || !ticket.Controller) return false; if (!Replication.IsServer() || m_AdmissionsStopped || !mode || !ticket || ticket.Mode != mode || !ticket.Actor || !ticket.Request || !ticket.Controller) return false;
if (!CheckLocalAdmissionContext()) return false;
ERR_PlayerLife life = mode.Players().Get(ticket.ConnectionId); ERR_PlayerLife life = mode.Players().Get(ticket.ConnectionId);
if (!life || !m_Identities.Contains(ticket.ConnectionId)) return false; if (!life || !m_Identities.Contains(ticket.ConnectionId)) return false;
PlayerController controller = GetGame().GetPlayerManager().GetPlayerController(ticket.ConnectionId); PlayerController controller = GetGame().GetPlayerManager().GetPlayerController(ticket.ConnectionId);
@@ -197,10 +234,21 @@ class ERR_SpawnLogic : SCR_SpawnLogic
CancelAdmission(playerId, reason); CancelAdmission(playerId, reason);
} }
} }
protected bool CheckLocalAdmissionContext()
{
if (!m_LocalAdmission || m_LocalAdmission.Validate()) return true;
if (m_LocalAdmissionFailed || m_AdmissionsStopped) return false;
m_LocalAdmissionFailed = true;
StopAdmissions();
if (m_LifecycleMode) m_LifecycleMode.ERR_FailLocalAdmission();
return false;
}
protected void CheckLocalAdmissionTick(float now) { CheckLocalAdmissionContext(); }
protected void StopAdmissions() protected void StopAdmissions()
{ {
if (!Replication.IsServer()) return; if (!Replication.IsServer()) return;
m_AdmissionsStopped = true; m_AdmissionsStopped = true;
if (m_LocalAdmission) m_LocalAdmission.Stop();
array<int> pending = {}; array<int> pending = {};
foreach (int id, vector position : m_AuthorizedPositions) pending.Insert(id); foreach (int id, vector position : m_AuthorizedPositions) pending.Insert(id);
foreach (ERR_SpawnTicket ticket : m_SpawnTickets) foreach (ERR_SpawnTicket ticket : m_SpawnTickets)
@@ -277,6 +325,7 @@ class ERR_SpawnLogic : SCR_SpawnLogic
} }
override void OnPlayerDisconnected_S(int playerId, KickCauseCode cause, int timeout) override void OnPlayerDisconnected_S(int playerId, KickCauseCode cause, int timeout)
{ {
if (m_LocalAdmission && m_LocalAdmission.Disconnected(playerId)) CheckLocalAdmissionContext();
CancelAdmission(playerId, ERR_ObserverReason.NONE); CancelAdmission(playerId, ERR_ObserverReason.NONE);
m_Identities.Remove(playerId); m_Identities.Remove(playerId);
ERR_GameMode mode = ERR_GameMode.Get(); ERR_GameMode mode = ERR_GameMode.Get();
@@ -287,6 +336,7 @@ class ERR_SpawnLogic : SCR_SpawnLogic
{ {
ERR_GameMode mode = ERR_GameMode.Get(); ERR_GameMode mode = ERR_GameMode.Get();
if (!Replication.IsServer() || m_AdmissionsStopped || !mode || !data || !m_Identities.Contains(playerId) || !mode.Players().CanEnter(playerId, mode.Phase())) return false; if (!Replication.IsServer() || m_AdmissionsStopped || !mode || !data || !m_Identities.Contains(playerId) || !mode.Players().CanEnter(playerId, mode.Phase())) return false;
if (!CheckLocalAdmissionContext()) return false;
ERR_PlayerLife life = mode.Players().Get(playerId); ERR_PlayerLife life = mode.Players().Get(playerId);
if (!life || life.AccountId != m_Identities.Get(playerId)) return false; if (!life || life.AccountId != m_Identities.Get(playerId)) return false;
if (!m_Pending.Contains(playerId) || !m_AuthorizedPositions.Contains(playerId) || data.GetPrefab() != mode.Factions().PrisonerPrefab) return false; if (!m_Pending.Contains(playerId) || !m_AuthorizedPositions.Contains(playerId) || data.GetPrefab() != mode.Factions().PrisonerPrefab) return false;
@@ -300,6 +350,7 @@ class ERR_SpawnLogic : SCR_SpawnLogic
{ {
m_LifecycleMode.OnPhaseChanged().Remove(AdmissionPhaseChanged); m_LifecycleMode.OnPhaseChanged().Remove(AdmissionPhaseChanged);
m_LifecycleMode.OnStop().Remove(StopAdmissions); m_LifecycleMode.OnStop().Remove(StopAdmissions);
m_LifecycleMode.OnTick().Remove(CheckLocalAdmissionTick);
} }
GetGame().GetCallqueue().Remove(RetrySpawn); GetGame().GetCallqueue().Remove(RetrySpawn);
GetGame().GetCallqueue().Remove(ObserveAfterLoss); GetGame().GetCallqueue().Remove(ObserveAfterLoss);
+74
View File
@@ -501,6 +501,80 @@
"docs/evidence/native-2026-09-19-073806/source-sha256.json", "docs/evidence/native-2026-09-19-073806/source-sha256.json",
"docs/evidence/native-2026-09-19-073806/source-provenance.json" "docs/evidence/native-2026-09-19-073806/source-provenance.json"
] ]
},
"scripted_casualty_loading": {
"status": "passed",
"scope": "87 clean native assertions. Actual local controlled casualty, real five-second action completion boundary, owner handshake, native reservation and observed child-seat occupancy; synthetic helper admission and direct completion only, no held input or remote RPC qualification.",
"evidence": [
"docs/evidence/native-2026-09-19-075514/report.json",
"docs/evidence/native-2026-09-19-075514/console.log.txt",
"docs/evidence/native-2026-09-19-075514/source-sha256.json"
]
},
"scripted_casualty_removal": {
"status": "passed",
"scope": "66 clean native assertions. Actual inherited vanilla removal action, authored exterior door, real exit event, vacant bench and live incapacitated grounded body. Direct completion only, no ordinary held input, remote transit or post-removal extraction result assertion.",
"evidence": [
"docs/evidence/native-2026-09-19-080058/report.json",
"docs/evidence/native-2026-09-19-080058/console.log.txt",
"docs/evidence/native-2026-09-19-080058/source-sha256.json"
]
},
"scripted_mortar_inventory_current": {
"status": "passed",
"scope": "37 clean companion-loaded native assertions. Four physical crew, real manpack operator, exactly 27 distinct HE shells, finite depletion and permanent gun/crew loss. No firing or later readiness/transfer source qualification.",
"evidence": [
"docs/evidence/native-2026-09-19-080226/report.json",
"docs/evidence/native-2026-09-19-080226/console.log.txt",
"docs/evidence/native-2026-09-19-080226/source-sha256.json"
]
},
"ordinary_core_startup": {
"status": "passed",
"scope": "Regular Game without Workbench; matching Core header/MissionSystems; genuine local controller and canonical living prisoner after native audit/finalization; 15-second settle and cleanup, zero captured failures. Standalone round-local key, diagnostic noSplash, no held input, full escape, normal splash or multiplayer claim. This is not a Workbench smoke qualification.",
"evidence": [
"docs/evidence/game-2026-09-19-082733/report.json",
"docs/evidence/game-2026-09-19-082733/console.log.txt",
"docs/evidence/game-2026-09-19-082733/game-startup-report.json.txt",
"docs/evidence/game-2026-09-19-082733/source-sha256.json"
]
},
"ordinary_companion_startup": {
"status": "passed",
"scope": "Regular Game without Workbench; matching Chat header and vanilla MissionSystems; normal native audit/finalization yields actual local canonical living prisoner with all companion addons. Fifteen-second ready interval, cleanup, zero captured failures. Standalone round-local key and diagnostic noSplash only; no full escape, normal splash or multiplayer claim.",
"evidence": [
"docs/evidence/game-2026-09-19-082938/report.json",
"docs/evidence/game-2026-09-19-082938/console.log.txt",
"docs/evidence/game-2026-09-19-082938/source-sha256.json",
"docs/evidence/game-2026-09-19-082938/game-startup-report.json.txt"
]
},
"scripted_mortar_first_projectile": {
"status": "passed",
"scope": "48 clean native assertions. Synthetic stationary observation enters actual RTO uplink, HQ scheduling and downlink, native activity/ballistic aiming and actual projectile callback; exactly one of 27 original physical shells consumed. Explicit Stop followed by twelve seconds without duplicate orders, firing or replenishment. Immutable original-command ballistic revalidation handles native aiming delay without renewing observation age. No perception, impact accuracy, full salvo or multiplayer claim.",
"evidence": [
"docs/evidence/2026-09-19-mortar-first-shot/report.json",
"docs/evidence/2026-09-19-mortar-first-shot/console.log.txt",
"docs/evidence/2026-09-19-mortar-first-shot/source-sha256.json"
]
},
"scripted_mortar_exact_transfer": {
"status": "passed",
"scope": "119 clean local native assertions. Explicit scheduler/radio bypass fixture moves real existing HE shell donor-to-gunner, verifies callback plus exact source/destination identity, cancels a second accepted operation, permits no new request/readiness, conserves all 27 original shells and restores each original owner. Native callback completed synchronously before cancellation; late callback timing is untested. No firing or remote ownership claim.",
"evidence": [
"docs/evidence/native-2026-09-19-083810/report.json",
"docs/evidence/native-2026-09-19-083810/console.log.txt",
"docs/evidence/native-2026-09-19-083810/source-sha256.json"
]
},
"scripted_standalone_admission_replay": {
"status": "passed",
"scope": "54 clean native assertions using real sole local controller/body/life. Callback replay retains canonical state and idle spawn metadata; disclosed helper argument faults latch closed, and live invalid-controller injection triggers normal defeat with original spent life/body retained. No genuine network disconnect, authentication, or remote mode proof.",
"evidence": [
"docs/evidence/native-2026-09-19-085048/report.json",
"docs/evidence/native-2026-09-19-085048/console.log.txt",
"docs/evidence/native-2026-09-19-085048/source-sha256.json"
]
} }
} }
} }
+6
View File
@@ -64,3 +64,9 @@ The native end-data connection ID list is retained only as a framework adapter.
`ERR_ObjectiveText` supplies hints and native task descriptions from the same mission state. Radio identification can update local guidance within the search phase, and extraction instructions use the configured replicated radius. `ERR_ObjectiveDetails` subscribes open successor task details directly to native display-data changes; it removes that subscription on task switch and widget detach. Detach also removes native global task-event callbacks, and pending overflow work is cancelled before assignee labels are deleted. Other task types retain their native behavior. See [objective widget lifecycle](objective-widget-lifecycle.md). `ERR_ObjectiveText` supplies hints and native task descriptions from the same mission state. Radio identification can update local guidance within the search phase, and extraction instructions use the configured replicated radius. `ERR_ObjectiveDetails` subscribes open successor task details directly to native display-data changes; it removes that subscription on task switch and widget detach. Detach also removes native global task-event callbacks, and pending overflow work is cancelled before assignee labels are deleted. Other task types retain their native behavior. See [objective widget lifecycle](objective-widget-lifecycle.md).
Optional ground transport belongs to the existing site definition/service and its rollback path. It has bounded parking checks, actual native fuel and compartments, and no replacement/refill loop. See [ground transport](ground-transport.md). Optional ground transport belongs to the existing site definition/service and its rollback path. It has bounded parking checks, actual native fuel and compartments, and no replacement/refill loop. See [ground transport](ground-transport.md).
## Standalone admission and finite mortar orders
`ERR_LocalAdmission` supplies a round-local roster key only for the sole genuine local controller in native `RplMode.None`. It is selected through normal audited spawn admission, pinned to that controller/context and closed on invalidation. It is not an account identity and never replaces native identity handling in Listen, Dedicated or Client modes. [Design and evidence](local-singleplayer-admission.md).
HQ owns each finite mortar battery, its readiness, delivered order and exact shell transactions. Initial expansion and inventory callbacks must resolve to the actual original crew and 27 distinct HE shells. Resupply moves one exact existing shell; acceptance alone is not readiness. Re-aim validation recomputes native ballistics against the immutable original command while retaining the original report's expiry. The per-battery report ledger prevents a cancelled/completed radio observation from becoming another order; only newly delivered observations can authorize new attempts. [Operations](finite-mortar-operations.md), [aim renewal](mortar-aim-renewal.md), [report deduplication](mortar-report-deduplication.md).
+3 -3
View File
@@ -21,7 +21,7 @@ An already committed native movement is not rolled back if conditions subsequent
The mode adapter owns Tick/Stop/roster subscriptions and replicates only the current extraction-aircraft reference for client action presentation. Roster events run cleanup even when the ordinary mission tick returns early on an empty server. PREPARING roster callbacks are no-ops and cannot permanently stop the service. Terminal/explicit Stop latches before notifying subscribers, releases owned tickets and removes subscriptions. No new persistent settings, public entity-selection RPC, automatic spawning or original Escapists resource is introduced. The mode adapter owns Tick/Stop/roster subscriptions and replicates only the current extraction-aircraft reference for client action presentation. Roster events run cleanup even when the ordinary mission tick returns early on an empty server. PREPARING roster callbacks are no-ops and cannot permanently stop the service. Terminal/explicit Stop latches before notifying subscribers, releases owned tickets and removes subscriptions. No new persistent settings, public entity-selection RPC, automatic spawning or original Escapists resource is introduced.
## Merge and checks ## Integration and checks
New production files: New production files:
@@ -30,7 +30,7 @@ New production files:
- `addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingGameMode.c` - `addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingGameMode.c`
- `addons/core/Scripts/Game/ERR/ERR_LoadCasualtyAction.c` - `addons/core/Scripts/Game/ERR/ERR_LoadCasualtyAction.c`
Copy this document and `tests/test_casualty_loading_policy.py`, then apply `casualty-production-integration.patch` for `Prisoner.et` and `tools/check.py`. No existing GameMode source or native probe is replaced. The action reuses the existing Prisoner resource identity; new nested action/UI component IDs are successor-authored. The successor Prisoner prefab owns the action and `tools/check.py` includes the casualty policy regression. The action reuses the existing Prisoner resource identity; new nested action/UI component IDs are successor-authored.
Offline checks execute production timing/range/aircraft-motion policy bodies and the complete repository suite. Native work must inspect the real spawned action and inherited medicine actions, show strict rejection for nonparticipants/old bodies/wrong phase, then exercise genuine two-player authorization and physical movement. Test cancellation during action progress, recovery during progress, duplicate callers, last-seat contention, native refusal, loss of replication visibility, delayed/reordered/expired handshake, disconnect/reconnect, aircraft loss and terminal transition. Confirm native seat reservation cleanup and actual single occupancy. Do not count synthetic fixture roster identities as proof of remote controller ownership. Offline checks execute production timing/range/aircraft-motion policy bodies and the complete repository suite. Native work must inspect the real spawned action and inherited medicine actions, show strict rejection for nonparticipants/old bodies/wrong phase, then exercise genuine two-player authorization and physical movement. Test cancellation during action progress, recovery during progress, duplicate callers, last-seat contention, native refusal, loss of replication visibility, delayed/reordered/expired handshake, disconnect/reconnect, aircraft loss and terminal transition. Confirm native seat reservation cleanup and actual single occupancy. Do not count synthetic fixture roster identities as proof of remote controller ownership.
@@ -40,7 +40,7 @@ Offline checks execute production timing/range/aircraft-motion policy bodies and
The fixture deliberately advances legal mission phases to reach extraction; it does not claim a completed radio objective. It checks a fresh settling window, native external bench reservations, a physical successor wall blocking sight, the real action's completion boundary, duplicate requests, actual player occupancy, reservation release, preserved target identity and idempotent Stop. It does not simulate holding action input, remote packet timing or Stop during an in-flight command. It retains inherited medical-action presence. On completion the normal test reset ends the round; cleanup deletes only the helper/obstacle and releases fixture-owned reservations, with no forced recovery, seated-player teleport, body deletion or unrelated health restoration. The fixture deliberately advances legal mission phases to reach extraction; it does not claim a completed radio objective. It checks a fresh settling window, native external bench reservations, a physical successor wall blocking sight, the real action's completion boundary, duplicate requests, actual player occupancy, reservation release, preserved target identity and idempotent Stop. It does not simulate holding action input, remote packet timing or Stop during an in-flight command. It retains inherited medical-action presence. On completion the normal test reset ends the round; cleanup deletes only the helper/obstacle and releases fixture-owned reservations, with no forced recovery, seated-player teleport, body deletion or unrelated health restoration.
The WORKBENCH mode override routes owner callbacks to the helper adapter only during this explicit case. Add the new fixture source, then use `casualty-service-base-snippets.md` for parent-owned smoke/runner integration. [075514](evidence/native-2026-09-19-075514/report.json) completes this local fixture with 87 passing assertions and zero engine or script/VM errors. The production one-shot initial placement lets the original aircraft settle naturally; separate raised, tilted and moving aircraft are rejected. A single actual native damage request incapacitates the controlled player, then the real action completion boundary and owner-controller handshake load that living body into the selected child bench exactly once. External reservations and physical obstruction reject requests; successful loading releases the reservation, retains player identity and survives idempotent Stop without another completion. The WORKBENCH mode override routes owner callbacks to the helper adapter only during this explicit case. Core smoke and the hidden runner expose the opt-in `casualty-service` case. [075514](evidence/native-2026-09-19-075514/report.json) completes this local fixture with 87 passing assertions and zero engine or script/VM errors. The production one-shot initial placement lets the original aircraft settle naturally; separate raised, tilted and moving aircraft are rejected. A single actual native damage request incapacitates the controlled player, then the real action completion boundary and owner-controller handshake load that living body into the selected child bench exactly once. External reservations and physical obstruction reject requests; successful loading releases the reservation, retains player identity and survives idempotent Stop without another completion.
The real local controller takes the server/local fast path; this does not exercise remote Owner/Server RPC transit. Only the helper membership is adapted, and action completion is invoked directly rather than holding input for five seconds. The fixture requests its own reset after loading, without a complete radio-to-extraction playthrough. Real two-player input, latency/reordering, disconnect/death while pending, last-seat contention and entity-removal cleanup remain separate requirements. Earlier contact and damage-fixture failures are preserved in the validation log. The real local controller takes the server/local fast path; this does not exercise remote Owner/Server RPC transit. Only the helper membership is adapted, and action completion is invoked directly rather than holding input for five seconds. The fixture requests its own reset after loading, without a complete radio-to-extraction playthrough. Real two-player input, latency/reordering, disconnect/death while pending, last-seat contention and entity-removal cleanup remain separate requirements. Earlier contact and damage-fixture failures are preserved in the validation log.
+20 -22
View File
@@ -1,35 +1,33 @@
# Current development status # Current development status
Evidence checkpoint: 19 September 2026, through archived run `080058`. Later running tests are not included. The primary deliverable is an independently authored replacement for the abandoned Escapists base mission, with the existing companion behavior integrated through its interfaces. The first release targets vanilla Everon and up to twelve players. It must complete prison → scavenging/intel → radio defence → helicopter extraction without the original mod or dependent extensions loaded. Evidence checkpoint: 19 September 2026, through the archived 084026 companion restart run and separate 084040 vanilla dedicated control. Later running tests are not included. The primary deliverable remains an independently authored replacement for the abandoned Escapists base mission, integrating companion behavior through its interfaces. The first release targets vanilla Everon and up to twelve players, completing prison → scavenging/intel → radio defence → helicopter extraction without the original mod or dependent extensions.
The successor has its own five addon projects, scenario/resource identities, authored Everon sites and vanilla asset references. The base loop and several failure paths have passed scripted local Workbench checkpoints. This is a development implementation, not a released or fully accepted replacement. [Acceptance](acceptance.json) remains pending for manual gameplay, real multiplayer, performance and release qualification. The successor has five independent addon projects, its own scenario/resource identities, authored Everon sites and vanilla asset references. Ordinary Core and companion startup now work with real local admission. Scripted base-loop checkpoints and focused physical support tests exist, but this is not a released or fully accepted replacement. All seventeen release cases remain pending in [acceptance](acceptance.json); development checks record narrower evidence.
## Established development checkpoints ## Established development checkpoints
| Area | What the recorded evidence establishes | Important limit | | Area | Recorded evidence | Limit |
| --- | --- | --- | | --- | --- | --- |
| Independent base loop | Core-only and companion-loaded scripted escape, interrupted radio defence, extraction, defeat and restart have completed. Native task details and personal result widgets have focused lifecycle checks. | Historical runs exercise their recorded sources; they do not qualify later changes or manual play. See [validation](validation.md). | | Ordinary game admission | Regular, non-Workbench [Core](evidence/game-2026-09-19-082733/game-startup-report.json.txt) and [all-companion](evidence/game-2026-09-19-082938/game-startup-report.json.txt) runs load their headers/MissionSystems and admit the genuine local controller to a living canonical prisoner, with a fifteen-second ready interval and zero captured errors. | Diagnostic noSplash and standalone round-local roster key; no ordinary full route, normal splash, network identity or manual input qualification. [Admission design](local-singleplayer-admission.md). |
| Prison, equipment and medicine | [Prisoner fixture](evidence/native-2026-09-19-063949/report.json) places one controlled player and eleven physical characters inside the prison, verifies explicit starter inventory and real clue transfers. [Medical fixture](evidence/native-2026-09-19-062406/report.json) demonstrates blood-loss treatment, consumed supplies and native consciousness recovery. | These are not twelve connected clients or ordinary treatment input/animation tests. Five initial pistols are a balance choice to evaluate in play; the count alone is not a demonstrated defect. | | Independent base loop | [Two Core rounds](evidence/native-2026-09-19-080656/report.json) pass 564 assertions, including radio feedback, extraction and restart, with zero errors. | That snapshot predates the standalone admission helper. The later [two companion rounds](evidence/native-2026-09-19-084026-restart-station-error/report.json) complete 96 assertions but retain two support-station catalog errors during restart; they are a failed runtime result. |
| Scavenging and discovery | Finite stock/lost containers remain depleted; two independent clue caches support progression. [Document-loss fixture](evidence/native-2026-09-19-071654/report.json) verifies close physical radio discovery after partial knowledge and loss of all documents. | Manual route visibility, travel, inventory interaction and threat balance remain unqualified. | | Prison, equipment and medicine | [Prisoner fixture](evidence/native-2026-09-19-063949/report.json) places one controlled player and eleven physical characters inside the prison with exact kits and real clue transfers. [Medical fixture](evidence/native-2026-09-19-062406/report.json) demonstrates blood-loss treatment, consumed supplies and native consciousness recovery. | Physical actors are not twelve connected clients. Ordinary treatment input, animations, supply balance and navigation remain unqualified. The medical snapshot retains historical catalog errors. |
| Player lifecycle and extraction | Native admission/finalization, local observer cleanup, physical helicopter seat capacity and identity-based results have focused checks. [Recovery fixture](evidence/native-2026-09-19-064406/report.json) preserves incapacitated survivors and verifies explicit authorized abandonment. | [Casualty-loading fixture](evidence/native-2026-09-19-075514/report.json) now loads the real local incapacitated player from the ground into a reserved bench and releases the reservation. Its helper identity is synthetic; remote reconnect and two-client rescue remain unproved. | | Discovery and radio | [Partial document loss](evidence/native-2026-09-19-071654/report.json) verifies close physical discovery after partial knowledge and loss of all documents. Radio feedback/continuous defence and interruption have complete Core-loop checks. | Manual discovery, travel, inventory interaction, combat balance and remote feedback remain unqualified. No replacement clues are spawned after loss. |
| Existing physical forces | [Patrol fixture](evidence/native-2026-09-19-070919/report.json) demonstrates real cyclic movement. [Companion fixture](evidence/native-2026-09-19-072838/report.json) verifies HQ Search preemption and physical patrol resumption without creating response forces. [Cancellation fixture](evidence/native-2026-09-19-073601/report.json) verifies stopped incomplete groups do not dispatch late members. | The delivered-order patrol test bypasses radio transit. Broader reports, combat, support and losses need integrated qualification. | | Player lifecycle and extraction | [Lifecycle](evidence/native-2026-09-19-081601/report.json), [recovery](evidence/native-2026-09-19-064406/report.json), [casualty loading](evidence/native-2026-09-19-075514/report.json) and [stock removal](evidence/native-2026-09-19-080058/report.json) have focused native checks. The actual local incapacitated body can be loaded into a reserved bench and removed alive beside the authored door. | Direct completion/helper admission is disclosed. Held input, remote owner handshake, competing rescuers, disconnect/death/deletion during loading and real reconnect remain unproved. |
| Environment and native errors | [Environment/restart fixture](evidence/native-2026-09-19-065351/report.json) passes two real rounds with zero native errors after restricting vehicle catalogs to required assets. | Earlier vehicle-schema errors are historical, not evidence every current run fails. Intermittent medical-kit teardown attribution remains unresolved; a later [full-loop checkpoint](evidence/native-2026-09-19-073806/report.json) also passes two rounds without native errors. Subsequent initial-placement changes still need their own qualification. | | Physical infantry | [Patrol](evidence/native-2026-09-19-070919/report.json), [HQ preemption/resumption](evidence/native-2026-09-19-072838/report.json) and [pending-spawn cancellation](evidence/native-2026-09-19-073601/report.json) pass without creating response forces. | The delivered-order patrol test bypasses radio transit. Integrated perception/combat, interrupted reports and support losses need broader qualification. |
| Physical mortar | [First projectile](evidence/2026-09-19-mortar-first-shot/report.json) passes 48 assertions through the actual uplink/HQ/downlink/native activity path, consuming one original HE shell and stopping without duplicates. [Exact inventory transfer](evidence/native-2026-09-19-083810/report.json) passes 119 assertions and restores all 27 original shells to their original owners. | Observation is synthetic; impact is unmeasured. Transfer fixture bypasses radio/scheduling and observed a synchronous callback. Full salvo, post-expiry authorization, genuine late callback, perception and remote ownership are separate. |
| Dedicated compilation | [Regular Linux server](evidence/dedicated-2026-09-19-083213/review.json) compiles Core and reaches prison phase with zero players/36 AI inside a network namespace without external routes. | Four resource errors remain; [vanilla-only control](evidence/dedicated-2026-09-19-084040-vanilla/review.json) reproduces all four. No participant joined. This local-server route is diagnostic-only; public/authenticated hosting is not configured or qualified. |
## Immediate blockers and next work ## Immediate work
1. **Resolve the remaining ordinary-game errors and establish player admission.** The [scenario-header launch](evidence/game-2026-09-19-080004/report.json) compiles production Game without WORKBENCH/ENF_WB, verifies the Core header and vanilla MissionSystems, and reaches `phase 0 -> 1` without the earlier guard-spawn crash being captured. It remains a failed run: vanilla splash `SCR_WidgetExportRuleRoot` errors persist and the local player's identity cannot be bound, so spawning is withheld. Preserve identity validation while diagnosing the offline launch/admission path. This is partial startup evidence, not clean startup or a playable session. [Runner details](ordinary-game-startup.md). 1. **Finish current-source regressions and investigate restart cleanup.** The companion loop reaches both victories but emits two `SCR_BaseResupplySupportStationComponent` catalog errors between rounds. Preserve that failure and obtain the existing bounded teardown diagnostics before deciding whether a scoped lifecycle correction is warranted. Current Core regression must include the new standalone helper; focused callback replay/fail-closed probing is now implemented and awaits native execution.
2. **Qualify casualty loading beyond the local success.** [075514](evidence/native-2026-09-19-075514/report.json) passes the complete local service fixture with no native errors: naturally settled helicopter, actual incapacitation, completion-time authorization, external reservations, blocked sight, one owner-handshake load into the selected bench, identity retention and cleanup. Earlier parked-contact and fixture-damage failures remain archived. [Stock removal fixture](evidence/native-2026-09-19-080058/report.json) also verifies the inherited door action clears the bench and leaves a living incapacitated body beside its authored exit. Real action input, remote ownership/RPC timing, competing rescuers, disconnect/death during a pending load and entity-deletion cleanup still need their own tests. [Casualty service](casualty-loading.md), [support investigation](casualty-ground-support.md). 2. **Close physical support gaps.** A report ledger now prevents a cancelled/completed observation from repeatedly allocating mortar orders. A new expiry fixture and its native run must verify this while HQ remains active. Aircraft support needs a newly written flight driver: the extension inherited its flight base from original Escapists, so a namespace-only migration is insufficient. Installed native pilot input APIs have been identified; powered flight, actual fuel use and safe landing remain feasibility work. Logistics and rearming must retain finite physical stocks and losses.
3. **Rerun the current integrated base and companions.** Guard cancellation and replicated radio feedback have clean evidence from [two complete Core rounds](evidence/native-2026-09-19-073806/report.json); the later placement/casualty changes now have a focused local pass. A full current-source escape/restart regression must still exercise those changes together with discovery/task presentation, ordinary victory, early aircraft loss, death and abandonment. Keep failed iterations and source/log provenance; do not substitute earlier clean snapshots. 3. **Qualify the ordinary playable route.** Check gate/equipment access, medical actions, finding the radio without fixture knowledge, defend/recover behavior, ground travel, real boarding/piloting/navigation and partial escape. Review authored layout and finite supplies from actual play. Preserve vanilla unconscious recovery and explicit administrator abandonment.
4. **Establish genuine multiplayer evidence.** The private dedicated runtime is installed and native empty-server startup is demonstrated. Real accepted client identities, joins/reconnects, remote ownership and replication remain outstanding; local bodies/callback injections are not substitutes.
4. **Play the complete route with ordinary input.** Validate prison gate/equipment access, scavenging and medical interactions, finding the radio without fixture knowledge, defend/recover behavior, ground-vehicle route, manual helicopter boarding/takeoff/navigation and partial escape. Tune the authored layout and finite supplies from actual play. The implemented all-incapacitated policy is preserved vanilla recovery plus explicit administrator abandonment; no automatic recovery is promised. ## First-release qualification
5. **Finish and qualify physical HQ support.** Infantry observation/report/order paths and patrol integration exist. Operational mortar firing, aircraft support, transport/rearming and depot/logistics behavior remain incomplete. Preserve a single HQ coordinator, radio-delivered reports, finite physical forces/ammunition and loss retention; cover interrupted reports, stale contacts and duplicate-order prevention. The [responsibility inventory](original-feature-coverage.md) remains a scope map, not behavioral proof.
## First-release qualification still required Cover simultaneous/late joins in each phase, preload cancellation, reconnect and connection-ID reuse, reserved bodies, spent lives, death/unconsciousness/treatment, spectators and streaming cleanup. Verify remote task/map/radio/result updates, settings authorization, seat contention, partial escape, empty-server behavior, defeat and repeated restart with up to twelve connected players.
Establish a dedicated-server test environment and real clients, then cover concurrent/late joins in each phase, preload cancellation, reconnect and connection-ID reuse, reserved bodies, spent lives, death/unconsciousness/treatment, spectators and streaming cleanup. Verify remote task/map/radio/result updates, settings authorization, seat contention, partial escape, empty-server behavior, defeat and repeated restart with up to twelve connected players. Local fixtures narrow these risks but do not close them. Collect matched original/successor workloads with repeated client-frame and server-tick measurements. No FPS improvement is demonstrated; the [comparison tool](performance-comparison.md) currently has synthetic regression evidence only. Complete provenance/dependency review, build/test the package under successor identities and satisfy the [release checker](release-qualification.md) with applicable source-bound evidence. No release package is published.
Collect real matched original/successor workloads with repeated client-frame and server-tick recordings. No FPS improvement has been demonstrated; the [comparison tool](performance-comparison.md) currently has synthetic regression evidence only. Original mission sources remain read-only. Hidden test displays, private profiles/prefixes and muted test audio keep engine work off the user's monitors. RHS, additional terrains, full original feature parity, alternate starts and distant-unit simulation remain later scope. Historical audits and evidence describe their own snapshots; the [validation ledger](validation.md) records both failures and subsequent fixes.
Finally complete provenance/dependency review, build and test the package under the successor's own identities, and satisfy the [release checker](release-qualification.md) with current source-bound evidence. No release package has been published. RHS, additional terrains, complete original parity, alternate starts and distant-unit simulation remain later scope.
Older audits such as [base gameplay gaps](base-gameplay-gaps.md) preserve findings made before subsequent implementations. Read their update notes and linked native evidence before treating an old missing-feature statement as a current defect. This status page consolidates priorities; the evidence ledger remains authoritative for individual recorded checks.
+51
View File
@@ -0,0 +1,51 @@
# Isolated native Linux dedicated startup diagnostic
The stable Linux `ArmaReforgerServer` successfully compiled the frozen successor Core game scripts, loaded its scenario header and native MissionSystems, and reached prison phase during the 2026-09-19 08:32:13 local diagnostic. This establishes server compilation and empty-server mission preparation. It does **not** establish multiplayer, authentication, client replication, ordinary input, graceful shutdown, comparative performance or release readiness. Four native installed-asset resource errors remain; this was not an entirely error-free run.
## Safe diagnostic route
The official [startup parameter documentation](https://community.bistudio.com/wiki/Arma_Reforger%3AStartup_Parameters) documents `-server` with local `-addons`/`-addonsDir`, separately from `-config`. It describes `-worldSystemsConfig` as diagnostic-executable only. Installed `GameStateTransitions.RequestScenarioChangeTransition` accepts either a mission header or world resource. The bounded experiment confirmed that this regular dedicated executable also accepts the successor `.conf` header as the `-server` value; no special header flag or JSON configuration was necessary.
`tools/dedicated_native.py` is exclusively a disconnected diagnostic launcher. Its immutable command selections cannot add a JSON configuration, clients, credentials, public hosting, Workshop downloads or validation-disabling options. The native local-server route nevertheless logged **`0.0.0.0:2001, fastValidation=false`**, despite CLI bind hints. These are native local-test defaults, not safe hosting configuration. Never remove the mandatory namespace isolation or repurpose this command for public/authenticated hosting. The separate review-only dedicated preflight plan retains its own `fastValidation=true` and BattlEye configuration; this experiment does not validate that configuration route.
The runner masks host home, `/tmp` and `/run`, clears inherited environment, mounts host root and runtime read-only, and exposes only private source/profile/home/temp paths for engine writes. Networking, PID, IPC and UTS namespaces are isolated. A native namespace-aware Python probe requires a different network namespace, only `lo`, no IPv4 routes and no non-loopback IPv6 route. It runs both before launch and immediately before `exec`; any failure prevents server launch. Reading `/sys/class/net` alone is insufficient because a read-only host sysfs mount can show host interfaces even inside a separate network namespace.
Each run owns a new process group and private PID namespace. It records the exact command, binary hash, source manifest before/after, raw stdout and native logs; its timeout terminates only that owned group. Runtime can be bounded to 1–110 seconds, followed by at most ten seconds cleanup. A lock prevents concurrent instances of this diagnostic. Backend is explicitly disabled and the network namespace independently prevents external traffic. No displays, audio server sockets, Steam account profile or original missions are exposed for writes.
Example after reviewing the source and installed private runtime:
```sh
python3 tools/dedicated_native.py \
--source /tmp/frozen-successor \
--runtime /tmp/erri-dedicated-runtime/server \
--archive /tmp/erri-dedicated-attempt-new \
--route header --seconds 90
```
The source, archive and runtime must be separate resolved `/tmp` paths. Archive must be new. Exit zero means bounded diagnostic collection finished, **not** that compilation or acceptance passed. Inspect raw errors and positive mission evidence. The separately enumerated `vanilla-everon` control route loads installed `Missions/21_GM_Eden.conf` without successor addon arguments; see [the resource diagnosis](dedicated-resource-audit.md). The alternative `diag-world` route remains available for a different bounded question but was not needed or executed in this result; it cannot establish ordinary-header startup by itself.
## Archived observations
[Development archive](evidence/dedicated-2026-09-19-083213/review.json). Native log: `profile/logs/logs_2026-09-19_08-32-13/console.log`. The engine ran unmodified copied sources: 277 source/resource/document/tool files, all unchanged after the run. Binary SHA-256: `91fdf333ec49c266d309be358aabab4244a93a2f9cfa11853a600e026104001f` (stable server app 1874900, private installed public payload).
Evidence from the native log:
- Line 61: backend services disabled.
- Line 94: game successfully created after native Game compilation; no `SCRIPT (E)` entries captured.
- Line 100: native SaveGameManager starts `{AD62322D5213C440}Missions/ERR_Everon_Base.conf`.
- Line 109: native world systems initialize `{C50579A2EC48E8EF}Configs/Systems/MissionSystems.conf`.
- Line 157: native RPL server starts inside the isolated namespace, with the local-test defaults described above.
- Line 307: successor transitions from preparation phase 0 to prison phase 1.
- Subsequent native statistics report zero players and 36 physical AI characters. The capped empty-server FPS is not a comparative performance benchmark.
The four captured `(E)` lines concern vanilla editor-helper resources: `TransparentMat.emat` referenced from installed Calvary content, `Gizmo3D/sphere.xob` referenced from installed `Blast_small_Invisible_Trigger.et`, and the resulting material-not-found/default-material pair. Raw surrounding resource stacks remain in the archive. No assets/errors were suppressed or replaced. Core preparation nevertheless completed; whether these packed-runtime resource errors affect any visible or released use still requires investigation.
The 90-second deadline ended via supervisor SIGTERM (`exit=-15`), not native mission-completion shutdown. A separate read-only host check confirmed the owned supervisor absent and no remaining `ArmaReforgerServer` executable process. The source manifest did not change. No real participant joined and no direct scripted `RplSession.Mode` observation was added to this frozen-source run.
Earlier failed isolation checks are preserved. The sandbox-local network namespace attempt returned NETLINK permission denied before any engine; the host namespace-only verification succeeded. Attempt 01 then failed before engine launch because a new mount destination could not be created under read-only root. Attempt 02 corrected destinations beneath private `/tmp`; both its preflight and immediate pre-exec probe passed. No isolation check was bypassed.
## Source-local regression scope
`python3 tests/test_dedicated_native.py` exercises the actual pre-exec isolation gate with substituted namespace/interface/routes and proves refusal happens before `exec`, detects source mutation and rejects linked sources, and checks header versus diagnostic-world CLI separation. It does not execute a server or simulate multiplayer. The native archive separately establishes that the observed regular server startup accepted the header and initialized the mission.
The subsequent vanilla-only control reproduced all four initial asset errors without successor addons. This attributes those specific errors to the installed vanilla content; it does not make the first run entirely error-free or close other acceptance requirements. Exact stacks and control limitations are recorded in [the resource audit](dedicated-resource-audit.md).
+34
View File
@@ -0,0 +1,34 @@
# Private dedicated-server preparation
`tools/dedicated_preflight.py` inspects files and prepares a reviewable configuration/evidence plan. It never installs software, executes the server, starts a listener, authenticates a player or changes Steam/Wine state. A zero exit status means inspection succeeded, not that runtime or multiplayer acceptance passed. Every plan explicitly keeps `launch_allowed` and `multiplayer_passed` false.
The intended runtime is stable native Linux Arma Reforger Server, Steam app **1874900**, in `/tmp/erri-dedicated-runtime/server`. Stable client/Tools apps 1874880/1874910 are already installed separately. Experimental apps and server 1890870 are not substitutes: the official [hosting guide](https://community.bistudio.com/wiki/Arma_Reforger:Server_Hosting) distinguishes the branches and documents anonymous SteamCMD installation of the Linux server. Server and client Steam build IDs belong to different apps and need not equal; compare actual engine versions before native tests.
The private preparation downloaded Valve's SteamCMD bootstrap from `https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz`, the installer address used by the official [SteamCMD documentation](https://developer.valvesoftware.com/wiki/SteamCMD). The direct documentation fetch returned HTTP403 during this audit; the Bohemia hosting guide was available. Runtime provenance is in `runtime-origin.json`, and raw SteamCMD app-info/install logs stay outside Git alongside the runtime.
SteamCMD ran anonymously inside a bubblewrap filesystem sandbox: original home was masked by `private-home`, `/tmp` and `/run` were private, the host root was read-only and only the private runtime was writable. Its displayed `/home/jakub/Steam/logs` path referred to that masked private home, not the user's Steam data. No environment HOME value, installed Steam app, shared Wine prefix, original mission or global package was changed. SteamCMD can update its own private installation. The payload remains outside the successor repository and should not be committed. `/tmp` is tmpfs on this host; inspect both free space and available RAM before allocating another copy.
To inspect without writing:
```sh
python3 tools/dedicated_preflight.py --source /home/jakub/devel/escapistsrereintroduced --runtime /tmp/erri-dedicated-runtime --project core
```
To write a new review bundle, add `--write-plan /tmp/erri-dedicated-runtime/review-core`. It must be a new direct child of the marked private runtime; existing evidence is never overwritten. The bundle contains:
- `preflight.json`: exact selected addon/header/world/systems, binary/app manifest metadata, limitations and required evidence.
- `server-config.review.json`: loopback-only game bind/public address, two-player capacity, no public listing, unchanged native fast validation/BattlEye, crash reporting disabled; no configured RCON or A2S.
- `source-manifest.json`: exact authored source/resource hashes, with its file SHA-256 bound in the preflight report.
- `REVIEW.txt`: explicit no-launch status and remaining prerequisites.
The configuration is a review draft, not a ready launcher. The official [server configuration](https://community.bistudio.com/wiki/Arma_Reforger:Server_Config) uses `game.scenarioId`; unpublished local-addon selection/authenticated configuration compatibility still needs verification. The documented local-mod `-server` route and `-config` route must not be combined blindly: the installed startup code reports `-config cannot be used together with addons!`. The plan records the local addon directory and selected GUID separately and leaves `game.mods` empty rather than inventing Workshop revisions. It does not publish addons or trigger Workshop downloads. Native header/MissionSystems loading must be verified for whichever reviewed route is chosen.
A real multiplayer run needs two genuine accepted player identities and two native client controllers. Two copied profiles, two actor entities, two fake connection IDs or two clients sharing one account do not establish this. The current ordinary runner deliberately refuses any existing game process; a separate multi-process supervisor would need explicit ownership of all its children and separate prefixes, profiles, headless displays and audio routing while continuing to protect unrelated games. A second licensed/authenticated client on another machine avoids local account/runtime contention. Loopback-only preparation cannot serve that second machine until an explicitly reviewed LAN configuration exists.
Eight synthetic-file regressions cover missing/wrong/linked runtime binaries, stable-app selection, actual ELF architecture, strict loopback configuration, header/source bindings, immutable evidence outputs and no process execution. Native library compatibility, engine startup, player authentication, replication and FPS remain separate tests.
## Installation observed on 2026-09-19
Anonymous installation completed with SteamCMD exit 0 and its successful-install marker. App 1874900 is fully installed (`StateFlags=4`), public build **24870635**, with shared depot 1874901 manifest 8361215099969594635 and Linux depot 1874902 manifest 3259094621086219309. Installed payload is **10,278,170,614 bytes**. The server is an executable x86-64 ELF; its exact NUL-terminated version strings include **1.8.0.13**. Passive `readelf` inspection found the interpreter and all seven declared native libraries in the host library cache. This is file-level compatibility evidence, not executed-server validation.
`/tmp/erri-dedicated-runtime/installation-inspection.json` binds the bootstrap, app-info log, installation log, app manifest and server binary with SHA-256. The completed Core review bundle is `/tmp/erri-dedicated-runtime/review-core`; its source snapshot is the repository state at bundle creation, and must be recaptured after later source changes. No server/listener was launched during that preparation step. Subsequent [isolated native diagnostics](dedicated-native-diagnostic.md) established regular-server header loading and empty-server preparation; authentication and multiplayer behavior remain untested.
+41
View File
@@ -0,0 +1,41 @@
# Dedicated resource error diagnosis
The four error lines from the first successor Linux dedicated startup have two missing-resource causes in installed vanilla prefabs. No corresponding successor-authored helper entity or direct reference was found. A minimal successor gameplay patch is not justified by the source evidence: it would require changing inherited terrain content, replacing normal particle definitions or shadowing vanilla identities.
## Exact installed references
The read-only extraction uses the installed stable server's `addons/data/data002.pak`, not original Escapists content:
| Native error | Installed source evidence | Successor relationship |
| --- | --- | --- |
| Wrong GUID/name for `TransparentMat.emat` | `Prefabs/Structures/Cultural/Calvaries/CalvaryLarge_01.et:8`, `MeshObject` material assignment for `SourceMaterial "Decal"` refers to `{45ECF6B1797D3CD9}system/wbdata/PreviewWindow/TransparentMat.emat`. | Successor `Worlds/ERR_Everon.ent:2` inherits installed `worlds/Eden/Eden.ent`. Native stack identifies inherited Calvary entity 1104061 at approximately 8831/2673, outside the authored escape route. |
| Material file missing and default-material fallback | The same inherited Calvary's native creation subsequently requests that same missing material. | These are the third and fourth error messages for the first missing resource, not two independent successor defects. |
| Wrong GUID/name for `Gizmo3D/sphere.xob` | `Prefabs/Particles/Blasts/Blast_small_Invisible_Trigger.et:4–6` has a `MeshObject` with `Enabled 0`, but still sets `Object` to `{FF35BE9795BA3797}system/wbdata/Gizmo3D/sphere.xob`. | Installed vehicle/helicopter explosions, rotor destruction, grenade effects and mortar effects reference this particle contact trigger. The native log observes resource preloading, not creation of an authored visible editor sphere. |
The disabled mesh is paired with a real `SCR_ParticleContactComponent` configured for BLAST effects at lines 8–13. Removing the entire trigger would remove intended particle-contact behavior. A disabled mesh property does not prevent the resource resolver from validating its reference, as the actual native error demonstrates.
The installed particle scan found direct trigger references in `Particles/Vehicle/Helicopter/Helicopter_Explosion.ptc:1059`, `Helicopter_MI8_rotor_destruction.ptc:1394`, `Particles/Vehicle/Vehicle_explosion_small_01.ptc:914`, `Particles/Weapon/Explosion_RGD5.ptc:180` and `Particles/Weapon/Muzzle_Mortar.ptc:292`, among others. The source scan does not establish which one caused the first shared preload; the native stack names only the shared trigger.
All seven installed server PAK indices were searched. Neither `system/wbdata/PreviewWindow/TransparentMat.emat` nor `system/wbdata/Gizmo3D/sphere.xob` is present. Both referenced prefab files themselves are present with exact source hashes in the audit. Thus this is a packaged-runtime dependency mismatch, not merely a guessed wrong material name.
## Successor audit boundary
A scan of 133 frozen addon text files (`.c`, `.ent`, `.layer`, `.et`, `.conf`, `.layout`, `.emat`, `.gproj`) found no direct `system/wbdata`, Calvary, shared blast-trigger or affected GUID reference. The authored Everon layer has only seven top-level mission services: game mode, AI world, perception, factions, loadouts, radio manager and chat. Dynamic successor compositions are not implicated by the direct reference scan. Parent-world and vanilla prefab inheritance remain intentional.
The frozen sources and native log already prove these exact references are vanilla. The separate no-successor native control reproduced the same errors in the installed Everon Game Master scenario. This distinction matters: merely identifying a vanilla parent does not prove that a particular successor request could not have exposed a previously unused path.
Scan metadata is archived in [the resource audit](evidence/dedicated-resource-audit/installed-reference-scan.json). Extracted vendor assets remain outside Git under `/tmp/erri-dedicated-native-build/resource-audit`: read-only extracted source, `installed-reference-scan.json`, `authored-source-audit.json`, and the scanner. Raw first-run errors remain untouched in `attempt-02-header/profile/logs/logs_2026-09-19_08-32-13/console.log`. Copied vendor assets are evidence only and are not successor release resources.
## Repair decision
No gameplay/resource patch is made. Do not delete inherited Calvaries, replace broad explosion graphs, reassign vanilla GUIDs, add Workbench as a production dependency or suppress resource errors to obtain a clean-looking result. An upstream corrected runtime asset reference would address the common cause. If a future scoped compatibility replacement is necessary, it needs separate ownership/resource design and visual/particle validation; it is not an implied harmless fix from these logs.
## Vanilla control result
[The vanilla control log](evidence/dedicated-2026-09-19-084040-vanilla/profile/logs/logs_2026-09-19_08-40-40/console.log) records the regular Linux dedicated executable with no `-addons` or `-addonsDir`. Lines 29–31 list only native core `5614BBCCBB55ED1C` and ArmaReforger `58D0FB3206B6F859`; no successor project is loaded. Line 86 resolves installed `Missions/21_GM_Eden.conf` to header GUID `59AD59368755F41A`. Line 98 initializes its authored `GameMasterSystems.conf`. This control uses the vanilla scenario's systems, not successor MissionSystems.
The same missing material and sphere references reproduce at lines 92 and 95, with the same Calvary and blast-trigger prefab stacks. Lines 120–121 reproduce the material-not-found/default-material pair. Native mode enters GAME with zero players. The control also logs additional vanilla vehicle-property and empty-resource errors; those remain in the complete raw log and are not claimed to be successor errors or an entirely clean control.
The enumerated `vanilla-everon` route in the disconnected runner uses only `-server Missions/21_GM_Eden.conf` alongside the normal private profile/backend-disabled/native diagnostic options. It does not change JSON hosting, enable networking, override world systems or load successor source. Both preflight and immediate pre-exec namespace checks remain mandatory. Four source-local launcher tests pass, including rejection of network escape conditions and ensuring the vanilla control has no successor-loading arguments.
The control reached its 90-second supervision deadline and exited via owned-group SIGTERM. The follow-up host check found no owned supervisor or native server process remaining. The archived source-copy manifest was unchanged. All 21 control `(E)` lines are retained; four match the original two missing-resource causes exactly.
+15
View File
@@ -0,0 +1,15 @@
# Discovery markers during ordinary play
`ERR_DiscoveryMap.c` now creates successor-owned objective markers with their label already set, refreshes the existing native text widget when knowledge changes, and prevents native annotation editing/dragging/deletion from altering objective facts. Discovery knowledge and location coordinates remain server-owned; local marker presentation adds no synchronization or mission progress authority.
The installed native implementation establishes the defects:
- `SCR_MapMarkerManagerComponent.InsertStaticMarker:169–175` assigns a local player owner and synchronously calls `OnCreateMarker`.
- `SCR_MapMarkerBase.SetCustomText:198–201` changes only stored data. `OnCreateMarker:344–378` initializes a widget from that data; `OnUpdate:409–431` updates position, not label text. Previously a map already open during discovery could show a blank newly-created marker or retain `Unknown location` after identification until reopening.
- `SCR_MapMarkersUI.IsOwnedMarker:114–123` controls editing and dragging at lines 1080,1287,1303. Its deletion entry and quickbind check `CanBeRemovedByOwner` at lines947,1049. Previously objective markers passed all these native checks, so a player could remove a discovery marker permanently or move it to a false coordinate; the successor's cached knowledge prevented restoration.
The new `ERR_DiscoveryMarker` subclass changes only these authored local markers. It clears the insertion-assigned owner at the native creation boundary and marks itself nonremovable. Its label is scenario-authored rather than a player annotation, so its own creation and label updates use the native synchronous text path; unrelated player marker filtering and behavior remain unchanged. Label updates while closed retain model data for native recreation without creating duplicate markers.
`ERR_NativeDiscoveryMapProbe.Run()` is an opt-in WORKBENCH check, to invoke once after a real local fixture participant and native marker manager exist. It creates two owned hidden native marker widgets: the unchanged vanilla marker demonstrates the stale text and user-annotation eligibility; the successor marker demonstrates immediate label refresh and protected ownership. It then detaches/recreates its own widget and checks retained text and exact marker-count cleanup. No mission locations, discovery state, inventories, map menus or player input are altered. Invoke `Stop()` from fixture cleanup if interrupted. The probe has not been run by this agent; native compilation and the actual result remain pending centrally. `python3 tools/check.py` passed after these changes.
The audit also inspected native prison gate inheritance/context, stock `SCR_OpenStorageAction`, radio tuning phase/knowledge checks and native helicopter/result presentation. Source alone does not establish held-input reachability, collision clearance while walking through the gate, dragging stock in a real inventory window or manual boarding/flying. These remain ordinary-play tests; direct completion fixtures cannot substitute for them. A separate inherited-gate destruction/progression vulnerability was reported for follow-up, without changing gate health in this marker patch.
@@ -0,0 +1,636 @@
---------------------------------------------
Log Z:\tmp\erri-workbench-profile\logs\logs_2026-09-19_08-33-52\console.log started at 2026-09-19 08:33:52 (2026-09-19 06:33:52 UTC)
08:33:52.277 ENGINE : FileSystem: Adding relative directory 'Z:\tmp\erri-workbench-profile\logs\logs_2026-09-19_08-33-52' to filesystem under name logs
08:33:52.277 ENGINE : FileSystem: Adding relative directory 'Z:\tmp\erri-workbench-profile\profile' to filesystem under name profile
08:33:52.277 ENGINE : FileSystem: Current working directory: 'Z:\home\jakub\.local\share\Steam\steamapps\common\Arma Reforger Tools\Workbench\'
08:33:52.279 PROFILING : Workbench Create Engine took: 10.057300 ms
08:33:53.325 INIT : INIT : Workbench Init Engine
08:33:53.325 ENGINE : Initializing engine, version 192142
08:33:53.325 ENGINE : CLI Params: -gproj Z:/home/jakub/devel/escapistsrereintroduced/addons/chat/addon.gproj -addonsDir Z:/home/jakub/devel/escapistsrereintroduced/addons -profile Z:/tmp/erri-workbench-profile -logconsole -wbModule WorldEditor -load Worlds/ERR_Everon.ent -plugin ERR_ValidateWorldPlugin -errPlay 1 -errSmoke 1 -errSmokeOutcome mortar-fire -noThrow -disableCrashReporter
08:33:53.335 ENGINE : Addon dirs:
08:33:53.335 ENGINE : dir: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/chat/'
08:33:53.335 ENGINE : dir: 'Z:/home/jakub/devel/escapistsrereintroduced/addons'
08:33:53.335 ENGINE : dir: './addons'
08:33:53.335 ENGINE : dir: 'Z:/tmp/erri-workbench-profile/addons'
08:33:53.335 ENGINE : Available addons:
08:33:53.335 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/chat/addon.gproj' guid: 'FA804F411BDDF2C6'
08:33:53.335 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/ai/addon.gproj' guid: '5192138CB9D5B911'
08:33:53.335 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/core/addon.gproj' guid: '2528466DE220D91C'
08:33:53.335 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/intel/addon.gproj' guid: 'D31039C7C53E348A'
08:33:53.335 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/map/addon.gproj' guid: '9AAEE9041D79809E'
08:33:53.335 ENGINE : gproj: './addons/core/core.gproj' guid: '5614BBCCBB55ED1C' (packed)
08:33:53.335 ENGINE : gproj: 'Z:/tmp/erri-workbench-profile/addons/ArmaReforger/ArmaReforger.gproj' guid: '58D0FB3206B6F859' (packed)
08:33:53.335 ENGINE : FileSystem: Adding relative directory 'Z:\home\jakub\devel\escapistsrereintroduced\addons\chat' to filesystem under name ERR_Chat
08:33:53.335 ENGINE : FileSystem: Adding relative directory 'Z:\home\jakub\devel\escapistsrereintroduced\addons\map' to filesystem under name ERR_Map
08:33:53.336 ENGINE : FileSystem: Adding relative directory 'Z:\home\jakub\devel\escapistsrereintroduced\addons\intel' to filesystem under name ERR_Intel
08:33:53.336 ENGINE : FileSystem: Adding relative directory 'Z:\home\jakub\devel\escapistsrereintroduced\addons\ai' to filesystem under name ERR_Ai
08:33:53.336 ENGINE : FileSystem: Adding relative directory 'Z:\home\jakub\devel\escapistsrereintroduced\addons\core' to filesystem under name ERR_Core
08:33:53.451 ENGINE : FileSystem: Adding package 'Z:/tmp/erri-workbench-profile/addons/ArmaReforger/' (pak count: 14) to filesystem under name ArmaReforger
08:33:53.454 ENGINE : FileSystem: Adding package './addons/core/' (pak count: 2) to filesystem under name core
08:33:53.454 ENGINE : CPU vendor : AuthenticAMD
08:33:53.454 ENGINE : CPU type : 2
08:33:53.454 ENGINE : CPU name : AMD Ryzen 7 3800XT 8-Core Processor
08:33:53.454 ENGINE : CPU cache info : L1 [Inst 32KB, Data 32KB], L2 [Unif 512KB], L3 [Unif 16384KB]
08:33:53.454 ENGINE : CPU count logical : 16
08:33:53.454 ENGINE : CPU count physical : 8
08:33:53.454 ENGINE : CPU features : mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 popcnt aesni pclmulqdq osxsave avx sha avx2
08:33:53.454 RESOURCES : ResourceDB: loading cache (id=0 name=ERR_Chat path=Z:\home\jakub\devel\escapistsrereintroduced\addons\chat/resourceDatabase.rdb)
08:33:53.454 RESOURCES : ResourceDB: loading cache (id=1 name=ERR_Map path=Z:\home\jakub\devel\escapistsrereintroduced\addons\map/resourceDatabase.rdb)
08:33:53.455 RESOURCES : ResourceDB: loading cache (id=2 name=ERR_Intel path=Z:\home\jakub\devel\escapistsrereintroduced\addons\intel/resourceDatabase.rdb)
08:33:53.455 RESOURCES : ResourceDB: loading cache (id=3 name=ERR_Ai path=Z:\home\jakub\devel\escapistsrereintroduced\addons\ai/resourceDatabase.rdb)
08:33:53.455 RESOURCES : ResourceDB: loading cache (id=4 name=ERR_Core path=Z:\home\jakub\devel\escapistsrereintroduced\addons\core/resourceDatabase.rdb)
08:33:53.456 RESOURCES : ResourceDB: loading cache (id=5 name=ArmaReforger path=Z:/tmp/erri-workbench-profile/addons/ArmaReforger/resourceDatabase.rdb)
08:33:53.588 RESOURCES : ResourceDB: loading cache (id=6 name=core path=./addons/core/resourceDatabase.rdb)
08:33:53.589 RESOURCES : ResourceDB: loading cache (id=7 name=profile path=Z:\tmp\erri-workbench-profile\profile/resourceDatabase.rdb)
08:33:53.589 RESOURCES : ResourceDB: loading cache (id=8 name=logs path=Z:\tmp\erri-workbench-profile\logs\logs_2026-09-19_08-33-52/resourceDatabase.rdb)
08:33:53.745 RESOURCES : RESOURCES : ResourceDB: full scan
08:33:53.749 RESOURCES : RESOURCES : scanning...
08:33:53.749 RESOURCES : RESOURCES : scanning @"ERR_Chat"
08:33:53.751 RESOURCES : RESOURCES : scanning @"ERR_Map"
08:33:53.753 RESOURCES : RESOURCES : scanning @"ERR_Intel"
08:33:53.753 RESOURCES : RESOURCES : scanning @"ERR_Ai"
08:33:53.754 RESOURCES : RESOURCES : scanning @"ERR_Core"
08:33:53.759 RESOURCES : RESOURCES : scanning @"ArmaReforger"
08:33:53.906 RESOURCES : RESOURCES : scanning @"core"
08:33:53.910 RESOURCES : RESOURCES : scanning @"profile"
08:33:53.911 RESOURCES : RESOURCES : scanning @"logs"
08:33:53.911 RESOURCES : RESOURCES : processing meta-files...
08:33:53.973 RESOURCES : RESOURCES : processing files...
08:33:53.984 INIT : Workbench startup
08:33:53.984 INIT : Workbench Init Engine
08:33:53.984 RESOURCES : ResourceDB: full scan
08:33:53.984 RESOURCES : processing files...
08:33:53.984 RESOURCES (W): resource not registered: @"$profile:rereintroduced.json". Setting null GUID
08:33:53.984 RESOURCES (W): resource not registered: @"$logs:launch-source-sha256.json". Setting null GUID
08:33:53.984 RESOURCES (W): resource not registered: @"$logs:launch-source.json". Setting null GUID
08:33:53.984 RESOURCES : RESOURCES : processing folders...
08:33:53.990 RESOURCES : RESOURCES : creating GUID-item mapping...
08:33:54.006 RESOURCES : RESOURCES : building tree...
08:33:54.056 PROFILING : ResourceDB: full scan took: 311.260500 ms
08:33:54.057 RESOURCES : ResourceDB: saving cache (id=0 name=ERR_Chat path=Z:\home\jakub\devel\escapistsrereintroduced\addons\chat/resourceDatabase.rdb)
08:33:54.059 RESOURCES : ResourceDB: written 741/741 bytes
08:33:54.059 RESOURCES : ResourceDB: cache successfully saved
08:33:54.059 RESOURCES : ResourceDB: saving cache (id=1 name=ERR_Map path=Z:\home\jakub\devel\escapistsrereintroduced\addons\map/resourceDatabase.rdb)
08:33:54.060 RESOURCES : ResourceDB: written 750/750 bytes
08:33:54.060 RESOURCES : ResourceDB: cache successfully saved
08:33:54.060 RESOURCES : ResourceDB: saving cache (id=2 name=ERR_Intel path=Z:\home\jakub\devel\escapistsrereintroduced\addons\intel/resourceDatabase.rdb)
08:33:54.062 RESOURCES : ResourceDB: written 227/227 bytes
08:33:54.062 RESOURCES : ResourceDB: cache successfully saved
08:33:54.062 RESOURCES : ResourceDB: saving cache (id=3 name=ERR_Ai path=Z:\home\jakub\devel\escapistsrereintroduced\addons\ai/resourceDatabase.rdb)
08:33:54.063 RESOURCES : ResourceDB: written 1356/1356 bytes
08:33:54.063 RESOURCES : ResourceDB: cache successfully saved
08:33:54.064 RESOURCES : ResourceDB: saving cache (id=4 name=ERR_Core path=Z:\home\jakub\devel\escapistsrereintroduced\addons\core/resourceDatabase.rdb)
08:33:54.065 RESOURCES : ResourceDB: written 6203/6203 bytes
08:33:54.065 RESOURCES : ResourceDB: cache successfully saved
08:33:54.065 RESOURCES : ResourceDB: saving cache (id=7 name=profile path=Z:\tmp\erri-workbench-profile\profile/resourceDatabase.rdb)
08:33:54.067 RESOURCES : ResourceDB: written 206/206 bytes
08:33:54.067 RESOURCES : ResourceDB: cache successfully saved
08:33:54.067 RESOURCES : ResourceDB: saving cache (id=8 name=logs path=Z:\tmp\erri-workbench-profile\logs\logs_2026-09-19_08-33-52/resourceDatabase.rdb)
08:33:54.069 RESOURCES : ResourceDB: written 162/162 bytes
08:33:54.069 RESOURCES : ResourceDB: cache successfully saved
08:33:54.069 ENGINE : GameProject load
08:33:54.069 ENGINE : Loaded addons:
08:33:54.069 ENGINE : gproj: './addons/core/core.gproj' guid: '5614BBCCBB55ED1C'
08:33:54.069 ENGINE : gproj: 'Z:/tmp/erri-workbench-profile/addons/ArmaReforger/ArmaReforger.gproj' guid: '58D0FB3206B6F859'
08:33:54.069 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/core/addon.gproj' guid: '2528466DE220D91C'
08:33:54.069 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/ai/addon.gproj' guid: '5192138CB9D5B911'
08:33:54.069 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/intel/addon.gproj' guid: 'D31039C7C53E348A'
08:33:54.069 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/map/addon.gproj' guid: '9AAEE9041D79809E'
08:33:54.069 ENGINE : gproj: 'Z:/home/jakub/devel/escapistsrereintroduced/addons/chat/addon.gproj' guid: 'FA804F411BDDF2C6'
08:33:54.071 ENGINE : Loading custom engine user config '$profile:.save/app1874910_user76561198020202999/settings/ReforgerEngineSettings.conf'
08:33:54.071 INIT : GameProject engine user settings load @"$profile:.save/app1874910_user76561198020202999/settings/ReforgerEngineSettings.conf"
08:33:54.071 ENGINE : Engine user settings config loaded
08:33:54.071 PROFILING : Settings changed took: 0.001700 ms
08:33:54.176 RENDER : (OK) Adapter 'AMD Radeon RX 6950 XT (RADV NAVI21)' supports feature level 12_0
08:33:54.178 RENDER : Basic screen setup:
08:33:54.178 RENDER : Back buffer format : TEXFMT_R8G8B8A8_SRGB (29)
08:33:54.178 RENDER : MSAA : none
08:33:54.191 RENDER : AMD AGS library initialized, version 6.1.0 x DLL 6.1.0
08:33:54.191 RENDER : Extendeded AMD info for AMD Radeon RX 6950 XT (RADV NAVI21) (primary device)
08:33:54.191 RENDER : * architecture RDNA2, 80 CUs, 40 WGPs (for RDNA), 64 ROPs
08:33:54.191 RENDER : * core clocks 2720 MHz, memory 1124 MHz
08:33:54.191 RENDER : * TFlops 27.9, memory bandwidth (562.0 GB/s)
08:33:54.191 RENDER : AMD AGS correctly initialized
08:33:54.191 RENDER : GPU_ATI (0x1002) (AMD Radeon RX 6950 XT (RADV NAVI21)) with 1 GPU detected, VRAM 16128MB (fast 0MB), shared 64362MB, driver version 99.19.02-230831a-396538C-AMD-Software-Adrenalin-Edition
08:33:54.191 RENDER : Detected output devices:
08:33:54.191 RENDER : * 1 device/s connected to AMD Radeon RX 6950 XT (RADV NAVI21):
08:33:54.191 RENDER : Generic Non-PnP Monitor (\\.\DISPLAY1), 1280x720 (offset 0x0), 30Hz
08:33:54.191 RENDER : Concurrent frames limit 2
08:33:54.267 RENDER : DX12 device successfully created by AMD AGS library
08:33:54.267 RENDER : * user markers not supported in this version AMD SW
08:33:54.267 RENDER : Graphics device features
08:33:54.267 RENDER : Needed:
08:33:54.267 RENDER : * Highest supported shader model: 6.8 (6.0 needed)
08:33:54.267 RENDER : Optional:
08:33:54.267 RENDER : * Allow tearing (VSYNC) : 1
08:33:54.267 RENDER : * 16 bits : 1
08:33:54.267 RENDER : * Resource heap tier : 3
08:33:54.267 RENDER : * Persistent heaps (DRED) : 1
08:33:54.267 RENDER : * DRED 1.2 is supported by compiler
08:33:54.290 RENDER : Main RT format setup.
08:33:54.290 RENDER : Main RT format for quality 0 : TEXFMT_R11G11B10_FLOAT (26)
08:33:54.290 RENDER : Main RT format for quality 1 : TEXFMT_R16G16B16A16_FLOAT (10)
08:33:54.292 ENGINE : Job system settings: coreCount=16, shortJobContextCount=16, shortJobThreadCount=15, longJobThreadCount=16
08:33:54.321 PROFILING : Settings changed took: 0.016100 ms
08:33:54.866 AUDIO : Endpoint: Speakers (PulseAudio Output)
08:33:54.866 AUDIO : Format: Channels: 2, Sample rate: 48kHz, Avg. bytes: 384kB, Sample bits: 32, Block align: 8B
08:33:54.866 AUDIO : Audio client:
08:33:54.866 AUDIO : Format: Channels: 2, Sample rate: 48kHz, Buffer size: 1536B, Frame: 512
08:33:54.870 RENDER : RENDER : Reload shaders
08:33:54.870 RENDER : Enfusion shader version 13
08:33:54.870 INIT : INIT : ShaderListReload
08:33:54.870 PROFILING : ShaderListReload took: 0.000400 ms
08:33:55.009 AUDIO : Endpoint: Speakers (PulseAudio Output)
08:33:55.009 AUDIO : Format: Channels: 2, Sample rate: 48kHz, Avg. bytes: 384kB, Sample bits: 32, Block align: 8B
08:33:55.009 AUDIO : Audio client:
08:33:55.009 AUDIO : Format: Channels: 2, Sample rate: 48kHz, Buffer size: 1536B, Frame: 512
08:33:55.229 RENDER : Loaded 3752 newer shader binaries
08:33:55.229 PROFILING : Reload shaders took: 359.116800 ms
08:33:55.229 ENGINE : Initializing inputs.
08:33:55.241 NETWORK : Initializing networking.
08:33:55.241 NETWORK : Using new GameRplScheduler.
08:33:55.241 SCRIPT : SCRIPT : Initializing scripts
08:33:55.242 SCRIPT : SCRIPT : ScriptProjectManager init
08:33:57.366 PROFILING : ScriptProjectManager init took: 2123.952000 ms
08:33:57.449 PROFILING : Initializing scripts took: 2207.344500 ms
08:33:57.466 ENGINE : Enfusion engine successfully created.
08:33:57.466 PROFILING : Workbench Init Engine took: 4140.769900 ms
08:33:57.466 INIT : INIT : Workbench Create Game
08:33:57.478 GUI : Using default language (en_us)
08:33:57.478 GUI : Loading 'en_us' localization file.
08:33:57.478 INIT : INIT : Loading StringTable
08:33:57.504 PROFILING : Loading StringTable took: 26.700800 ms
08:33:57.504 SCRIPT : SCRIPT : Compiling GameLib scripts
08:33:57.574 SCRIPT : Module: Workbench; loaded 18x files; 36x classes; used 125K of static memory; defines: "ENF_WB,WORKBENCH,PLATFORM_WINDOWS,ENABLE_DIAG,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE"; CRC32: 90ce0460
08:33:57.574 SCRIPT : Module: GameLib; loaded 466x files; 648x classes; used 828K of static memory; defines: "ENF_WB,WORKBENCH,PLATFORM_WINDOWS,ENABLE_DIAG,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE"; CRC32: d66caacb
08:33:57.575 PROFILING : Compiling GameLib scripts took: 70.223300 ms
08:33:57.575 SCRIPT : SCRIPT : Compiling Game scripts
08:33:58.882 INIT : Workbench Create Game
08:33:58.882 SCRIPT : Compiling Game scripts
08:33:58.882 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,785": 'GetPlayerPlatformKind' is obsolete
08:33:58.882 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,786": 'GetPlayerPlatformId' is obsolete
08:33:59.018 SCRIPT (W): @"Scripts/Game/ERR/ERR_SiteService.c,191": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.153 SCRIPT (W): @"Scripts/Game/Workshop/SCR_AddonManager.c,876": 'GetRefCount' is obsolete: Will be removed
08:33:59.185 SCRIPT (W): @"Scripts/Game/Campaign/SCR_PlayerProfileManagerComponent.c,142": 'PlayerData' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,159": 'GetDSSession' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,162": 'RoomID' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,197": 'GetDSSession' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,201": 'RoomID' is obsolete
08:33:59.322 SCRIPT (W): @"Scripts/Game/ERR/ERR_CasualtyGroundSupport.c,21": 'GetBoneIndex' is obsolete: Use GetAnimation().GetBoneIndex() instead
08:33:59.383 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,481": 'GetStorage' is obsolete
08:33:59.383 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,483": 'GetOnlineWritePrivilege' is obsolete
08:33:59.388 SCRIPT (W): @"Scripts/Game/Utilities/SCR_PlayerIdentityUtils.c,20": 'GetPlayerIdentityId' is obsolete
08:33:59.427 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,45": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.427 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,56": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.428 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,643": 'GetNotifyCount' is obsolete: Will be substitued by Notification Api.
08:33:59.428 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,645": 'GetNotifyItem' is obsolete: Will be substitued by Notification Api.
08:33:59.455 SCRIPT (W): @"Scripts/Game/ERR/ERR_NativeTransportProbe.c,82": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.488 SCRIPT (W): @"Scripts/Game/DataCollection/PlayerData/SCR_PlayerData.c,210": 'PlayerData' is obsolete
08:33:59.750 SCRIPT : Module: WorkbenchGame; loaded 172x files; 617x classes; used 2483K of static memory; defines: "ENF_WB,WORKBENCH,PLATFORM_WINDOWS,ENABLE_DIAG,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE"; CRC32: e963af0e
08:33:59.756 SCRIPT : Module: Game; loaded 5759x files; 11304x classes; used 33167K of static memory; defines: "ENF_WB,WORKBENCH,PLATFORM_WINDOWS,ENABLE_DIAG,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE,ENABLE_BASE_DESTRUCTION,BUDGET_OPTIMIZATION_CHECKS,SHOW_DISCLAIMER,DEBUG,RESPAWN_TIMER_COMPONENT_DEBUG,GAME_MODE_DEBUG,DEBUG_CONFIGURABLE_DIALOGS,DISABLE_WEAPON_SWITCHING,SCRIPTED_AIM_MODIFIER_DEBUG"; CRC32: 38d29813
08:33:59.794 PROFILING : Compiling Game scripts took: 2219.106800 ms
08:33:59.800 INIT : Creating game instance(ArmaReforgerScripted), version 1.8.0.13 built 2026-08-21 14:30:18 UTC.
08:33:59.840 ENGINE : Game successfully created.
08:33:59.841 PROFILING : Workbench Create Game took: 2374.873600 ms
08:33:59.851 DEFAULT : Using thumbnail cache directory: C:/users/steamuser/AppData/Local/Temp/Arma Reforger Workbench/Projects/ERR_Chat/thumbnails
08:34:00.698 INIT : INIT : Workbench Reload Game
08:34:00.700 ENGINE : Game destroyed.
08:34:00.707 GUI : Using default language (en_us)
08:34:00.707 GUI : Loading 'en_us' localization file.
08:34:00.707 INIT : INIT : Loading StringTable
08:34:00.717 PROFILING : Loading StringTable took: 9.608100 ms
08:34:00.717 INIT : Creating game instance(ArmaReforgerScripted), version 1.8.0.13 built 2026-08-21 14:30:18 UTC.
08:34:00.724 SCRIPT : Unable to register a script command due keyword duplicity: ban
08:34:00.724 SCRIPT : Unable to register a script command due keyword duplicity: kick
08:34:00.724 ENGINE : Game successfully created.
08:34:00.724 ENGINE : Game successfully initialized.
08:34:00.724 PROFILING : Workbench Reload Game took: 26.331400 ms
08:34:01.444 WORLD : WORLD : Entities load '$ERR_Core:Worlds/ERR_Everon.ent'
08:34:02.435 PROFILING : Entities load took: 991.315100 ms
08:34:02.446 WORLD : WORLD : CreateEntities
08:34:02.451 WORLD : WORLD : NotifyBeforeEntitiesCreated
08:34:02.451 PROFILING : NotifyBeforeEntitiesCreated took: 0.003600 ms
08:34:02.451 WORLD : WORLD : Wait for preloading data
08:34:02.451 PROFILING : Wait for preloading data took: 0.003200 ms
08:34:02.568 ENTITY : Create entity @"ENTITY:2" ('Eden', GenericTerrainEntity) at <0.000000 0.000000 0.000000> @"{5AD924374E8C7AF6}Prefabs/World/Game/Eden/GenericTerrain_Eden.et"
08:34:02.568 PROFILING : PROFILING : Terrain load
08:34:04.634 PROFILING : Terrain load took: 2065.424800 ms
08:34:08.606 WORLD : CreateEntities
08:34:08.606 ENTITY : Create entity @"ENTITY:610406" ('StaticModelEntity','Assets/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.xob') at <1931.796021 81.777000 5138.725098> @"{6A004A8F0571D456}Prefabs/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.et"
08:34:08.606 ENTITY : CreateComponent 'ScriptedRadioComponent'
08:34:08.606 DEFAULT (W): World doesn't contain RadioManagerEntity to support any BaseRadioComponent.
08:34:19.257 WORLD : WORLD : NotifyBeforeEntitiesInitialized
08:34:19.257 PROFILING : NotifyBeforeEntitiesInitialized took: 0.005100 ms
08:34:19.713 WORLD : WORLD : NotifyEntitiesInitialized
08:34:19.713 TERRAIN : TERRAIN : Initializing road networks...
08:34:19.716 PROFILING : Initializing road networks... took: 2.551600 ms
08:34:19.716 PROFILING : NotifyEntitiesInitialized took: 2.959900 ms
08:34:19.716 PROFILING : CreateEntities took: 17269.857300 ms
08:34:19.899 PROFILING : * WorldEditor: LoadWorld: 18461.046300 ms
08:34:21.405 TERRAIN : Loading tile map config (worlds/Eden/Eden/tileMap.conf)
08:34:21.406 TERRAIN : Loading minimap config (worlds/Eden/Eden/miniMap.conf)
08:34:21.407 TERRAIN : The default minimap texture ('worlds/Eden/EdenRasterized.edds') not found. Trying 'worlds/Eden/Eden.edds'...
08:34:21.408 TERRAIN : The default minimap texture ('worlds/Eden/Eden.edds') not found. Skipping...
08:34:21.496 SCRIPT : ERR VALIDATION: prison terrain=211.344, radio terrain=159.656, extraction terrain=65.1562
08:34:21.496 SCRIPT : ERR TERRAIN: x=6084 z=7154 y=211.531
08:34:21.496 SCRIPT : ERR TERRAIN: x=6084 z=7157 y=211.516
08:34:21.496 SCRIPT : ERR TERRAIN: x=6084 z=7160 y=211.5
08:34:21.496 SCRIPT : ERR TERRAIN: x=6084 z=7163 y=211.453
08:34:21.497 SCRIPT : ERR TERRAIN: x=6084 z=7166 y=211.406
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7154 y=211.438
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7157 y=211.438
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7160 y=211.422
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7163 y=211.391
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7166 y=211.344
08:34:21.497 SCRIPT : ERR TERRAIN: x=6090 z=7154 y=211.344
08:34:21.497 SCRIPT : ERR TERRAIN: x=6090 z=7157 y=211.344
08:34:21.497 SCRIPT : ERR TERRAIN: x=6090 z=7160 y=211.344
08:34:21.497 SCRIPT : ERR TERRAIN: x=6090 z=7163 y=211.328
08:34:21.498 SCRIPT : ERR TERRAIN: x=6090 z=7166 y=211.281
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7154 y=211.25
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7157 y=211.281
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7160 y=211.25
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7163 y=211.234
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7166 y=211.188
08:34:21.498 SCRIPT : ERR TERRAIN: x=6096 z=7154 y=211.156
08:34:21.498 SCRIPT : ERR TERRAIN: x=6096 z=7157 y=211.172
08:34:21.498 SCRIPT : ERR TERRAIN: x=6096 z=7160 y=211.156
08:34:21.498 SCRIPT : ERR TERRAIN: x=6096 z=7163 y=211.141
08:34:21.499 SCRIPT : ERR TERRAIN: x=6096 z=7166 y=211.094
08:34:21.520 SCRIPT : ERR SITE CANDIDATE: position=<6090,211.344,7160> elevationRange=0.640625
08:34:21.542 BACKEND : Attempting online Game Config instead.
08:34:24.850 INIT : INIT : Workbench Reload Game
08:34:24.852 ENGINE : Game destroyed.
08:34:24.859 GUI : Using default language (en_us)
08:34:24.859 GUI : Loading 'en_us' localization file.
08:34:24.859 INIT : INIT : Loading StringTable
08:34:24.879 PROFILING : Loading StringTable took: 19.364600 ms
08:34:24.879 INIT : Creating game instance(ArmaReforgerScripted), version 1.8.0.13 built 2026-08-21 14:30:18 UTC.
08:34:24.887 SCRIPT : Unable to register a script command due keyword duplicity: ban
08:34:24.887 SCRIPT : Unable to register a script command due keyword duplicity: kick
08:34:24.887 ENGINE : Game successfully created.
08:34:24.887 ENGINE : Game successfully initialized.
08:34:24.887 PROFILING : Workbench Reload Game took: 37.287900 ms
08:34:24.890 DEFAULT (W): LogiLED: Cannot initialize! (service not running or no compatible device detected)
08:34:24.944 PLATFORM : Save data from container 'settings' have been loaded
08:34:25.032 PLATFORM : Save data from container 'sessions' have been loaded
08:34:25.033 PLATFORM : GameProject user settings load from profile @"ReforgerGameSettings.conf"
08:34:25.033 ENGINE : Game user settings config loaded
08:34:25.130 DEFAULT : [SaveGameManager] Starting new playthrough nr.0 '' for mission '{B6C516F86302C679}Worlds/ERR_Everon.ent'.
08:34:25.138 WORLD : WORLD : Game::LoadEntities
08:34:25.138 WORLD : WORLD : Initializing world systems @"{1C60D2EDA2B468B8}Configs/Systems/BaseGameModeSystems.conf"
08:34:25.139 NETWORK : Enabled lag compensation, 29 frames with 100 FPS and 280 ms rewind limits.
08:34:25.139 WORLD : WORLD : CreateEntities
08:34:25.139 WORLD : WORLD : CreateEntities
08:34:25.139 WORLD : WORLD : NotifyBeforeEntitiesCreated
08:34:25.151 RESOURCES : Loaded mission headers from 7 addon(s)!
08:34:25.151 PROFILING : NotifyBeforeEntitiesCreated took: 11.719800 ms
08:34:25.151 WORLD : WORLD : Wait for preloading data
08:34:25.151 PROFILING : Wait for preloading data took: 0.000900 ms
08:34:29.785 WORLD : Game::LoadEntities
08:34:29.786 WORLD : CreateEntities
08:34:29.786 WORLD : CreateEntities
08:34:29.786 ENTITY : Create entity @"ENTITY:610406" ('StaticModelEntity','Assets/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.xob') at <1931.796021 81.777000 5138.725098> @"{6A004A8F0571D456}Prefabs/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.et"
08:34:29.786 ENTITY : CreateComponent 'ScriptedRadioComponent'
08:34:29.786 DEFAULT (W): World doesn't contain RadioManagerEntity to support any BaseRadioComponent.
08:34:31.174 ENTITY : Create entity @"ENTITY:842066" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1080.213013 10.776751 6018.347168>
08:34:31.174 ENTITY : CreateComponent 'Hierarchy'
08:34:31.174 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842066" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1080.213013 10.776751 6018.347168>')
08:34:31.175 ENTITY : Create entity @"ENTITY:842068" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1082.185913 10.778749 6018.331055>
08:34:31.175 ENTITY : CreateComponent 'Hierarchy'
08:34:31.175 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842068" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1082.185913 10.778749 6018.331055>')
08:34:31.175 ENTITY : Create entity @"ENTITY:842070" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1084.190918 10.790751 6018.334961>
08:34:31.175 ENTITY : CreateComponent 'Hierarchy'
08:34:31.175 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842070" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1084.190918 10.790751 6018.334961>')
08:34:31.180 ENTITY : Create entity @"ENTITY:842333" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4425.594727 9.981750 11029.402344>
08:34:31.180 ENTITY : CreateComponent 'Hierarchy'
08:34:31.180 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842333" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4425.594727 9.981750 11029.402344>')
08:34:31.180 ENTITY : Create entity @"ENTITY:842335" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4426.584473 9.983749 11031.109375>
08:34:31.180 ENTITY : CreateComponent 'Hierarchy'
08:34:31.180 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842335" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4426.584473 9.983749 11031.109375>')
08:34:31.180 ENTITY : Create entity @"ENTITY:842337" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4427.572266 9.995750 11032.853516>
08:34:31.180 ENTITY : CreateComponent 'Hierarchy'
08:34:31.180 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842337" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4427.572266 9.995750 11032.853516>')
08:34:31.185 ENTITY : Create entity @"ENTITY:842591" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10009.946289 10.470250 1551.986084>
08:34:31.185 ENTITY : CreateComponent 'Hierarchy'
08:34:31.185 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842591" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10009.946289 10.470250 1551.986084>')
08:34:31.185 ENTITY : Create entity @"ENTITY:842593" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10009.430664 10.472250 1550.081421>
08:34:31.185 ENTITY : CreateComponent 'Hierarchy'
08:34:31.185 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842593" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10009.430664 10.472250 1550.081421>')
08:34:31.186 ENTITY : Create entity @"ENTITY:842595" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10008.926758 10.484250 1548.140869>
08:34:31.186 ENTITY : CreateComponent 'Hierarchy'
08:34:31.186 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842595" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10008.926758 10.484250 1548.140869>')
08:34:36.513 WORLD : WORLD : NotifyBeforeEntitiesInitialized
08:34:36.513 PROFILING : NotifyBeforeEntitiesInitialized took: 0.059000 ms
08:34:38.450 WORLD : InitEntities 'world'
08:34:38.450 ENTITY : Init entity @"ENTITY:2305843009213693953" ('Rereintroduced', ERR_GameMode) at <1076.468018 51.000999 1325.246948> @"{978E045E53EF36C8}Prefabs/ERR/GameMode.et"
08:34:38.450 SCRIPT (W): SCR_PerceivedFactionManagerComponent trying to set fall back faction 'CIV' but this faction could not be found so it is null instead.
08:34:38.474 WORLD : InitEntities 'world'
08:34:38.474 ENTITY : Init entity @"ENTITY:2305843009213693953" ('Rereintroduced', ERR_GameMode) at <1076.468018 51.000999 1325.246948> @"{978E045E53EF36C8}Prefabs/ERR/GameMode.et"
08:34:38.474 SCRIPT : ERR SMOKE: scripted integration test enabled; gameplay acceptance remains separate
08:34:38.475 WORLD : WORLD : NotifyEntitiesInitialized
08:34:38.475 TERRAIN : TERRAIN : Initializing road networks...
08:34:38.477 PROFILING : Initializing road networks... took: 2.500100 ms
08:34:38.477 DEFAULT : DEFAULT : WorldVolumesCollection
08:34:38.533 PROFILING : WorldVolumesCollection took: 55.687900 ms
08:34:38.533 INIT : INIT : SoundWorldInit
08:34:38.546 PROFILING : SoundWorldInit took: 12.824400 ms
08:34:38.546 PROFILING : NotifyEntitiesInitialized took: 71.249000 ms
08:34:38.546 PROFILING : CreateEntities took: 13406.715800 ms
08:34:38.546 PROFILING : CreateEntities took: 13406.905500 ms
08:34:38.547 WORLD : WORLD : Wait for preloading data around camera
08:34:38.547 PROFILING : Wait for preloading data around camera took: 0.001500 ms
08:34:38.547 WORLD : WORLD : EOnActivate
08:34:38.580 PROFILING : EOnActivate took: 32.713400 ms
08:34:38.580 PROFILING : Game::LoadEntities took: 13441.853900 ms
08:34:38.903 DEFAULT : Entered offline game state.
08:34:39.006 NETWORK : Player connected: connectionID=2147483646
08:34:39.007 NETWORK : ### Connecting player: connectionID=2147483646, Name=
08:34:39.007 NETWORK : ### Creating player: PlayerId=1, Name=jakub
08:34:39.012 ENTITY : SpawnEntityPrefab @"{225E51284CC95CFA}Prefabs/Characters/Core/DefaultPlayerControllerMP.et"
08:34:39.012 ENTITY : Create entity @"ENTITY:4611686018427388381" ('SCR_PlayerController') at <0.000000 0.000000 0.000000>
08:34:39.012 ENTITY : EntityPrefabUse @"{225E51284CC95CFA}Prefabs/Characters/Core/DefaultPlayerControllerMP.et"
08:34:39.013 SCRIPT (W): Notification data in 'SCR_NotificationsLogDisplay' has duplicate notification info key: 'EDITOR_PERCEIVED_FACTION_PUNISHMENT_KILLING_SET'. There should only be one of each key!
08:34:39.013 SCRIPT (W): Notification data in 'SCR_NotificationsLogDisplay' has duplicate notification info key: 'EDITOR_PERCEIVED_FACTION_TYPE_DISABLED'. There should only be one of each key!
08:34:39.015 SCRIPT (W): Can't open config file ""
08:34:39.022 WORLD : InitEntities 'world'
08:34:39.022 ENTITY : Init entity @"ENTITY:4611686018427388381" ('SCR_PlayerController') at <0.000000 0.000000 0.000000> @"{225E51284CC95CFA}Prefabs/Characters/Core/DefaultPlayerControllerMP.et"
08:34:39.022 GUI : WidgetManager: CrateWidgets @"{3C9DCDD76AB83157}UI/layouts/HUD/HUDLayouts/HUDManager_Root.layout"
08:34:39.022 SCRIPT (W): Slot_WeaponInfo Has no Content!
08:34:39.022 SCRIPT (W): Slot_Chat Has no Content!
08:34:39.023 SCRIPT (W): Slot_VON Has no Content!
08:34:39.023 SCRIPT (W): Slot_AvailableActions Has no Content!
08:34:39.023 SCRIPT (W): Slot_Vehicle Has no Content!
08:34:39.023 SCRIPT (W): Slot_GameVersion Has no Content!
08:34:39.023 SCRIPT (W): Slot_Notifications Has no Content!
08:34:39.023 SCRIPT (W): Slot_Hints Has no Content!
08:34:39.035 ENTITY : SpawnEntityPrefab @"{59EF8ECAE1DCD417}Prefabs/Editor/Modes/EditorModeEdit.et"
08:34:39.035 ENTITY : Create entity @"ENTITY:4611686018427388384" ('SCR_EditorModeEntity') at <0.000000 0.000000 0.000000>
08:34:39.035 ENTITY : EntityPrefabUse @"{59EF8ECAE1DCD417}Prefabs/Editor/Modes/EditorModeEdit.et"
08:34:39.036 SCRIPT (W): SCR_EntityCatalogManagerComponent.GetFilteredEditorPrefabsOfAllFactions: Detected that {259EE7B78C51B624}UAZ469.et is present in at least two different faction entity catalogs! Since this may cause issues, such as dupliacted entries in build mode, one of them will be discarded! This is only supported for items. Other things require creation of faction specific variants.
08:34:39.036 SCRIPT (W): SCR_EntityCatalogManagerComponent.GetFilteredEditorPrefabsOfAllFactions: Detected that {DF5CCB7C0FF049F4}Mi8MT_unarmed_transport.et is present in at least two different faction entity catalogs! Since this may cause issues, such as dupliacted entries in build mode, one of them will be discarded! This is only supported for items. Other things require creation of faction specific variants.
08:34:39.038 NETWORK : ### Updating player: PlayerId=1, Name=jakub, rplIdentity=0xFFFFFFFE, IdentityId=00000000-0000-0000-0000-000000000000
08:34:39.039 SCRIPT (W): Ban Settings could not be loaded from BE Storage: Relying on default config
08:34:39.039 NETWORK : Players connecting: 0
08:34:39.039 NETWORK : Players connected: 1 / 1
08:34:39.068 DEFAULT : Using autosave directory: C:/users/steamuser/AppData/Local/Temp/Arma Reforger Workbench/Projects/ERR_Chat/autosaves
08:34:39.069 PROFILING : Workbench startup took: 46854.562300 ms
08:34:39.093 WORLD : Frame start
08:34:39.093 SCRIPT : ScenarioFramework: Available tasks are empty, no new tasks will be generated.
08:34:39.107 WORLD : UpdateEntities
08:34:39.107 WORLD : Frame
08:34:39.107 SCRIPT : SCR_BaseGameMode::OnGameStateChanged = GAME
08:34:39.281 WORLD : UpdateEntities
08:34:39.281 WORLD : PostFrame
08:34:39.281 GUI : WidgetManager: CrateWidgets @"{D89BBA18F99053D6}UI/layouts/HUD/Chat/ChatHud.layout"
08:34:39.281 SCRIPT (W): EditBoxFilterComponent used on invalid widget type.
08:34:39.326 RESOURCES : GetResourceObject @"{20A6917D2114E29A}UI/layouts/HUD/Hint/HintInfoDisplay.layout"
08:34:39.326 GUI : Layout load @"{20A6917D2114E29A}UI/layouts/HUD/Hint/HintInfoDisplay.layout"
08:34:39.326 GUI : Widget prefab @"{EA1CC57D868E94F9}UI/layouts/HUD/Hint/Hint.layout"
08:34:39.326 GUI (W): Overridden prefab member (GUID: '{661AB14E0F471C66}' type: ButtonWidgetClass) no longer exists in prefab
08:34:39.470 RENDER : RENDER : ObjectsHeightMap::Build
08:34:39.471 RENDER : RENDER : MeshOccupancyGridManager::GenerateAllForWorld
08:34:39.631 PROFILING : MeshOccupancyGridManager::GenerateAllForWorld took: 160.071300 ms
08:34:39.638 PROFILING : ObjectsHeightMap::Build took: 167.372900 ms
08:34:40.811 SCRIPT : Rereintroduced [sites]: cache clearance position=<6086,211.538,7160> clear=1
08:34:40.836 SCRIPT : Rereintroduced [sites]: authored everon-prison-1 at <6090,211.444,7160>
08:34:40.837 SCRIPT : Rereintroduced [sites]: cache clearance position=<6150,203.288,7050> clear=1
08:34:40.868 SCRIPT : Rereintroduced [sites]: authored everon-supply-1 at <6150,203.288,7050>
08:34:40.870 SCRIPT : Rereintroduced [sites]: authored everon-radio-1 at <6500,159.756,7200>
08:34:40.931 SCRIPT : Rereintroduced [sites]: authored everon-extraction-1 at <7000,65.2562,7500>
08:34:40.931 SCRIPT : Rereintroduced [sites]: cache clearance position=<5960,220.256,7220> clear=1
08:34:40.939 SCRIPT : Rereintroduced [sites]: transport parking=<5960,220.256,7212> radius=4 terrainRange=0.8125 obstructed=0 clear=1
08:34:40.992 SCRIPT : Rereintroduced [sites]: authored everon-supply-2 at <5960,220.256,7220>
08:34:40.993 SCRIPT : Rereintroduced [sites]: cache clearance position=<6340,175.788,7400> clear=1
08:34:40.995 SCRIPT : Rereintroduced [sites]: authored everon-medical-1 at <6340,175.788,7400>
08:34:40.995 SCRIPT : Rereintroduced [sites]: cache clearance position=<6740,140.6,7300> clear=1
08:34:40.999 SCRIPT : Rereintroduced [sites]: cache clearance position=<6740,140.913,7296> clear=1
08:34:41.001 SCRIPT : Rereintroduced [sites]: cache clearance position=<6736,140.975,7300> clear=1
08:34:41.001 SCRIPT : Rereintroduced [sites]: cache clearance position=<6744,140.288,7300> clear=1
08:34:41.002 SCRIPT : Rereintroduced [sites]: authored everon-outpost-1 at <6740,140.6,7300>
08:34:41.002 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=0 origin=<7012,63.725,7500> up=1
08:34:41.002 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0 angularSpeed=0
08:34:41.003 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=0 engine=0 origin=<0,0,0> up=1 entityDifference=10267.5
08:34:41.003 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012,64.0216,7502.25>
08:34:41.003 SCRIPT : ERR GEAR TERRAIN: bottom=<7012,63.7216,7502.25> terrainY=63.2926 tireTerrainGap=0.428944
08:34:41.003 SCRIPT : ERR GEAR SUPPORT: center=<7012,64.0216,7502.25> radius=0.3 bottom=<7012,63.7216,7502.25> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:34:41.003 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.72,64.4897,7497.97>
08:34:41.004 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.72,64.0397,7497.97> terrainY=64.1655 tireTerrainGap=-0.125717
08:34:41.004 SCRIPT : ERR GEAR SUPPORT: center=<7009.72,64.4897,7497.97> radius=0.45 bottom=<7009.72,64.0397,7497.97> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:34:41.004 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.28,64.4898,7497.97>
08:34:41.004 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.28,64.0398,7497.97> terrainY=63.8096 tireTerrainGap=0.230156
08:34:41.004 SCRIPT : ERR GEAR SUPPORT: center=<7014.28,64.4898,7497.97> radius=0.45 bottom=<7014.28,64.0398,7497.97> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:34:41.004 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.767 WORLD : UpdateEntities
08:34:41.768 WORLD : AfterPostSimulate
08:34:41.768 DEFAULT (W): Collider UCS_FG_DriveShaft_01 not found
08:34:41.843 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:41.844 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:41.844 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:41.844 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:42.094 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.08,63.5298,7499.7> up=0.99566
08:34:42.094 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.314761 angularSpeed=0.054178
08:34:42.094 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:42.095 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.06,63.6151,7501.98>
08:34:42.095 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.06,63.3151,7501.98> terrainY=63.3158 tireTerrainGap=-0.000720978
08:34:42.095 SCRIPT : ERR GEAR SUPPORT: center=<7012.06,63.6151,7501.98> radius=0.3 bottom=<7012.06,63.3151,7501.98> fraction=0.451541 normal=<-0,0.990257,0.139255> self=0 dynamic=0 supported=1 gap=-0.000659943
08:34:42.095 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.88,64.6035,7497.71>
08:34:42.095 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.88,64.1535,7497.71> terrainY=64.156 tireTerrainGap=-0.00251007
08:34:42.096 SCRIPT : ERR GEAR SUPPORT: center=<7009.88,64.6035,7497.71> radius=0.45 bottom=<7009.88,64.1535,7497.71> fraction=0.443634 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=-0.00239563
08:34:42.096 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.42,64.2636,7497.75>
08:34:42.096 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.42,63.8136,7497.75> terrainY=63.8176 tireTerrainGap=-0.00397873
08:34:42.096 SCRIPT : ERR GEAR SUPPORT: center=<7014.42,64.2636,7497.75> radius=0.45 bottom=<7014.42,63.8136,7497.75> fraction=0.436389 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00399399
08:34:42.096 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:42.347 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:42.347 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:42.348 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:42.348 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:42.849 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:42.850 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:42.850 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:43.099 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.09,63.5333,7499.72> up=0.994184
08:34:43.100 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.0956389 angularSpeed=0.0274173
08:34:43.100 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:43.100 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.06,63.6188,7501.99>
08:34:43.100 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.06,63.3188,7501.99> terrainY=63.3138 tireTerrainGap=0.00501251
08:34:43.100 SCRIPT : ERR GEAR SUPPORT: center=<7012.06,63.6188,7501.99> radius=0.3 bottom=<7012.06,63.3188,7501.99> fraction=0.477311 normal=<-0,0.990257,0.139255> self=0 dynamic=0 supported=1 gap=0.0050087
08:34:43.101 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.92,64.6035,7497.72>
08:34:43.101 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.92,64.1535,7497.72> terrainY=64.1496 tireTerrainGap=0.00389862
08:34:43.101 SCRIPT : ERR GEAR SUPPORT: center=<7009.92,64.6035,7497.72> radius=0.45 bottom=<7009.92,64.1535,7497.72> fraction=0.472503 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00395203
08:34:43.101 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.46,64.2654,7497.79>
08:34:43.101 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.46,63.8154,7497.79> terrainY=63.8152 tireTerrainGap=0.000133514
08:34:43.101 SCRIPT : ERR GEAR SUPPORT: center=<7014.46,64.2654,7497.79> radius=0.45 bottom=<7014.46,63.8154,7497.79> fraction=0.455 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=9.91821e-05
08:34:43.102 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:43.352 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:43.353 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:43.353 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:43.353 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:43.607 SCRIPT : Rereintroduced [extraction placement]: native supported aircraft stable for one second, fuel present, exactly one initial wake
08:34:43.858 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:43.858 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:43.859 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:43.859 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:44.180 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.11,63.5324,7499.74> up=0.993868
08:34:44.181 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.0420608 angularSpeed=0.0613614
08:34:44.181 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:44.181 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.07,63.6135,7502.01>
08:34:44.181 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.07,63.3135,7502.01> terrainY=63.3116 tireTerrainGap=0.00194168
08:34:44.181 SCRIPT : ERR GEAR SUPPORT: center=<7012.07,63.6135,7502.01> radius=0.3 bottom=<7012.07,63.3135,7502.01> fraction=0.463272 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00191879
08:34:44.182 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.96,64.5949,7497.72>
08:34:44.182 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.96,64.1449,7497.72> terrainY=64.1435 tireTerrainGap=0.0014267
08:34:44.182 SCRIPT : ERR GEAR SUPPORT: center=<7009.96,64.5949,7497.72> radius=0.45 bottom=<7009.96,64.1449,7497.72> fraction=0.461582 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00154877
08:34:44.182 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.5,64.26,7497.83>
08:34:44.182 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.5,63.81,7497.83> terrainY=63.8127 tireTerrainGap=-0.00266647
08:34:44.183 SCRIPT : ERR GEAR SUPPORT: center=<7014.5,64.26,7497.83> radius=0.45 bottom=<7014.5,63.81,7497.83> fraction=0.442222 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00271225
08:34:44.183 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:44.183 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:44.184 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:44.184 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:44.184 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:44.683 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:44.683 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:44.684 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:44.684 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:45.190 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.12,63.5283,7499.74> up=0.993815
08:34:45.190 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=0 speed=0 angularSpeed=0
08:34:45.191 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:45.191 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.07,63.6126,7502.01>
08:34:45.191 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.07,63.3126,7502.01> terrainY=63.3113 tireTerrainGap=0.00128174
08:34:45.191 SCRIPT : ERR GEAR SUPPORT: center=<7012.07,63.6126,7502.01> radius=0.3 bottom=<7012.07,63.3126,7502.01> fraction=0.46034 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00127411
08:34:45.192 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5947,7497.72>
08:34:45.192 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1447,7497.72> terrainY=64.1421 tireTerrainGap=0.00263214
08:34:45.192 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5947,7497.72> radius=0.45 bottom=<7009.97,64.1447,7497.72> fraction=0.466891 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00271606
08:34:45.192 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.2603,7497.84>
08:34:45.193 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.8103,7497.84> terrainY=63.8121 tireTerrainGap=-0.00181198
08:34:45.193 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.2603,7497.84> radius=0.45 bottom=<7014.51,63.8103,7497.84> fraction=0.446111 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00185394
08:34:45.193 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:45.193 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:45.194 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:45.194 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:45.194 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:45.696 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:45.697 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:45.697 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:45.697 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:46.198 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.12,63.5283,7499.74> up=0.993815
08:34:46.199 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=0 speed=0 angularSpeed=0
08:34:46.199 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:46.199 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.07,63.6126,7502.01>
08:34:46.199 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.07,63.3126,7502.01> terrainY=63.3113 tireTerrainGap=0.00128174
08:34:46.199 SCRIPT : ERR GEAR SUPPORT: center=<7012.07,63.6126,7502.01> radius=0.3 bottom=<7012.07,63.3126,7502.01> fraction=0.46034 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00127411
08:34:46.200 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5947,7497.72>
08:34:46.200 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1447,7497.72> terrainY=64.1421 tireTerrainGap=0.00263214
08:34:46.200 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5947,7497.72> radius=0.45 bottom=<7009.97,64.1447,7497.72> fraction=0.466891 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00271606
08:34:46.200 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.2603,7497.84>
08:34:46.200 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.8103,7497.84> terrainY=63.8121 tireTerrainGap=-0.00181198
08:34:46.201 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.2603,7497.84> radius=0.45 bottom=<7014.51,63.8103,7497.84> fraction=0.446111 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00185394
08:34:46.201 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:46.201 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:46.202 SCRIPT : Rereintroduced [sites]: 7 sites and 117 physical stock items ready
08:34:46.212 SCRIPT : Rereintroduced [environment]: date=authored weather=authored
08:34:46.213 SCRIPT : Rereintroduced [time]: started at 14:00 with 1x progression
08:34:46.213 SCRIPT : Rereintroduced [mission]: phase 0 -> 1
08:34:46.358 SCRIPT : INFO: Faction: player jakub (playerID = 1 | UUID = 00000000-0000-0000-0000-000000000000) has joined faction #AR-Faction_US (US)
08:34:46.398 SCRIPT : Rereintroduced [spawn]: player 1 at <6088.5,211.491,7158.5>
08:34:46.631 SCRIPT : ERR SMOKE PASS: new identity may enter prison
08:34:46.631 SCRIPT : ERR SMOKE PASS: spawn consumes identity life
08:34:46.632 SCRIPT : ERR SMOKE PASS: disconnect retains living actor and clears connection
08:34:46.632 SCRIPT : ERR SMOKE PASS: reconnected identity retains spent life
08:34:46.632 SCRIPT : ERR SMOKE PASS: duplicate active identity rejected
08:34:46.632 SCRIPT : ERR SMOKE PASS: recycled connection receives independent life and extraction admission policy
08:34:46.632 SCRIPT : ERR SMOKE PASS: base contracts catalog resolves hostile vanilla factions and successful preparation
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts physical prisoner matches injected faction and resource
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts physical guard squad comes from injected catalog
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts same-side factions rejected
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts unknown world faction rejected
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts missing prisoner resource rejected
08:34:46.634 SCRIPT : ERR SMOKE PASS: base contracts isolated catalog restored without mutating live configuration
08:34:46.634 SCRIPT : ERR SMOKE PASS: base contracts unauthorized settings request rejected
08:34:46.634 SCRIPT : ERR SMOKE PASS: base contracts partially numeric input rejected without mutation
08:34:46.634 SCRIPT : ERR SMOKE PASS: base contracts out-of-range duration rejected without mutation
08:34:46.637 SCRIPT : ERR SMOKE PASS: base contracts normalized base command saves validated duration
08:34:46.637 SCRIPT : ERR SMOKE PASS: base contracts base command reads saved duration
08:34:46.637 SCRIPT : ERR SMOKE PASS: base contracts base settings listing available
08:34:46.637 SCRIPT : ERR SMOKE PASS: base contracts base mission status available before companions
08:34:46.639 SCRIPT : ERR SMOKE PASS: base contracts test setting restored
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: hq interval show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: hq squads show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: hq radius show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: intel carrying show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: intel reveal show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion journal is behind Core admin authorization
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion HQ status uses the shared command service
08:34:47.139 SCRIPT : ERR MORTAR FIXTURE: step=0 startup=0 source=M0 observedEvents=0 ready=1 failure=
08:34:52.182 SCRIPT : ERR MORTAR FIXTURE: step=0 startup=0 source=M0 observedEvents=0 ready=1 failure=
08:34:57.235 SCRIPT : ERR MORTAR FIXTURE: step=0 startup=0 source=M0 observedEvents=0 ready=1 failure=
08:34:57.746 SCRIPT : ERR SMOKE PASS: mortar firing untasked original gun and complete four-person crew start without shots
08:34:57.746 SCRIPT : ERR SMOKE PASS: mortar firing initial physical crew member is conscious and unique
08:34:57.747 SCRIPT : ERR SMOKE PASS: mortar firing initial physical crew member is conscious and unique
08:34:57.747 SCRIPT : ERR SMOKE PASS: mortar firing initial physical crew member is conscious and unique
08:34:57.747 SCRIPT : ERR SMOKE PASS: mortar firing initial physical crew member is conscious and unique
08:34:57.747 SCRIPT : ERR SMOKE PASS: mortar firing dedicated actual manpack supplies the radio route
08:34:57.748 SCRIPT : ERR SMOKE PASS: mortar firing exactly 27 distinct physical initial HE shells
08:34:57.764 SCRIPT : ERR MORTAR FIXTURE IMPACT: position=<5200,80.1937,6400> batteryDistance=1000; no characters/vehicles in 400m square; production settlement/friendly exclusions passed
08:34:57.764 SCRIPT : ERR SMOKE PASS: mortar firing bounded candidate survey finds an unoccupied production-safe impact area
08:34:57.764 SCRIPT : ERR SMOKE PASS: mortar firing fixture-owned inert report identity exists; no enemy perception is claimed
08:34:57.765 SCRIPT : ERR SMOKE PASS: mortar firing synthetic observation enters actual existing radio uplink once
08:35:02.301 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:07.341 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:12.390 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:17.439 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:22.503 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:27.540 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:32.598 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:37.627 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:38.871 WORLD : UpdateEntities
08:35:38.871 WORLD : Frame
08:35:38.872 SCRIPT : ERR MORTAR FIXTURE PROJECTILE: event=1 entity=Projectile<0x000000019F269600> @"ENTITY:4611686018427390926" ('Projectile','Assets/Weapons/Ammo/Shells/82mm_Mortar_2B14/Shell_82mm_HE_O832DU.xob') at <5999.590820 204.000366 6999.681641> @"{98EC9C526AFBA282}Prefabs/Weapons/Ammo/Ammo_Shell_82mm_HE_O832DU.et" origin=<5999.59,204,6999.68> order=1 source=M1 aimAge=1909.73 flight=24.2333; impact is not measured
08:35:39.144 SCRIPT : ERR SMOKE PASS: mortar firing one physical projectile follows real uplink/downlink, native activity and fresh aim
08:35:39.145 SCRIPT : ERR SMOKE PASS: mortar firing one fired projectile consumes one of 27 original inventory shells
08:35:39.145 SCRIPT : ERR SMOKE PASS: mortar firing explicit support Stop closes native order and route idempotently
08:35:42.668 SCRIPT : ERR MORTAR FIXTURE: step=2 startup=1 source=M1 observedEvents=1 ready=0 failure=
08:35:47.713 SCRIPT : ERR MORTAR FIXTURE: step=2 startup=1 source=M1 observedEvents=1 ready=0 failure=
08:35:51.256 SCRIPT : ERR SMOKE PASS: mortar firing stopped service issues no duplicate order, projectile or replenishment over 12 seconds
08:35:51.256 SCRIPT : ERR SMOKE PASS: mortar firing original group and gun retain four crew
08:35:51.256 SCRIPT : ERR SMOKE PASS: mortar firing final conscious crew entity belongs to original physical roster
08:35:51.256 SCRIPT : ERR SMOKE PASS: mortar firing final conscious crew entity belongs to original physical roster
08:35:51.257 SCRIPT : ERR SMOKE PASS: mortar firing final conscious crew entity belongs to original physical roster
08:35:51.257 SCRIPT : ERR SMOKE PASS: mortar firing final conscious crew entity belongs to original physical roster
08:35:51.257 SCRIPT : Rereintroduced [mission]: phase 1 -> 6
08:35:51.257 SCRIPT : ERR SMOKE PASS: native mortar first shot and stop complete before explicit reset
08:35:51.257 SCRIPT : ERR SMOKE COMPLETE: native HQ radio to first mortar projectile and explicit stop; fixture reset requested
08:35:51.365 SCRIPT : SCR_BaseGameMode::OnGameStateChanged = POSTGAME
08:35:51.367 GUI : WidgetManager: CrateWidgets @"{144919871D65F121}UI/layouts/HUD/GameOver/EndScreen/EndScreen.layout"
08:35:51.367 SCRIPT (W): Slot_Chat Has no Content!
08:35:51.367 SCRIPT (W): Slot_VON Has no Content!
08:35:51.368 SCRIPT (W): Slot_GameVersion Has no Content!
08:35:51.368 SCRIPT (W): Slot_Notifications Has no Content!
08:35:53.422 SCRIPT (W): SCR_ScriptedWidgetComponent.GetComponent: widget not found: SCR_InputButtonComponent Back
08:35:53.423 SCRIPT : -- Stack trace --
08:35:53.423 SCRIPT : GetComponent() Scripts/Game/UI/Components/WidgetLibrary/SCR_ScriptedWidgetComponent.c : 43
08:35:53.423 SCRIPT : GetInputButtonComponent() Scripts/Game/UI/Components/WidgetLibrary/SCR_InputButton/SCR_InputButtonComponent.c : 1214
08:35:53.423 SCRIPT : OnMenuOpen() Scripts/Game/UI/GameOverScreen/SCR_GameOverScreenInput.c : 15
08:35:53.423 SCRIPT : OpenGameOverScreen() Scripts/Game/GameOverScreen/SCR_GameOverScreenManagerComponent.c : 447
08:35:53.423 SCRIPT : ShowGameOverScreen() Scripts/Game/GameOverScreen/SCR_GameOverScreenManagerComponent.c : 177
08:35:53.423 SCRIPT : OnUpdate() Scripts/Game/game.c : 885
08:35:53.423 SCRIPT : -----------------
08:35:53.423 SCRIPT (W): SCR_ScriptedWidgetComponent.GetComponent: widget not found: SCR_InputButtonComponent ChatButton
08:35:53.424 SCRIPT : -- Stack trace --
08:35:53.424 SCRIPT : GetComponent() Scripts/Game/UI/Components/WidgetLibrary/SCR_ScriptedWidgetComponent.c : 43
08:35:53.424 SCRIPT : GetInputButtonComponent() Scripts/Game/UI/Components/WidgetLibrary/SCR_InputButton/SCR_InputButtonComponent.c : 1214
08:35:53.424 SCRIPT : OnMenuOpen() Scripts/Game/UI/GameOverScreen/SCR_GameOverScreenInput.c : 21
08:35:53.424 SCRIPT : OpenGameOverScreen() Scripts/Game/GameOverScreen/SCR_GameOverScreenManagerComponent.c : 447
08:35:53.424 SCRIPT : ShowGameOverScreen() Scripts/Game/GameOverScreen/SCR_GameOverScreenManagerComponent.c : 177
08:35:53.424 SCRIPT : OnUpdate() Scripts/Game/game.c : 885
08:35:53.424 SCRIPT : -----------------
08:35:53.426 GUI : WidgetManager: CrateWidgets @"{144919871D65F121}UI/layouts/HUD/GameOver/EndScreen/EndScreen.layout"
08:35:53.426 SCRIPT (W): Slot_Chat Has no Content!
08:35:53.426 SCRIPT (W): Slot_VON Has no Content!
08:35:53.427 SCRIPT (W): Slot_GameVersion Has no Content!
08:35:53.427 SCRIPT (W): Slot_Notifications Has no Content!
@@ -0,0 +1,118 @@
---------------------------------------------
Log Z:\tmp\erri-workbench-profile\logs\logs_2026-09-19_08-33-52\error.log started at 2026-09-19 08:33:53 (2026-09-19 06:33:53 UTC)
08:33:53.984 INIT : Workbench startup
08:33:53.984 INIT : Workbench Init Engine
08:33:53.984 RESOURCES : ResourceDB: full scan
08:33:53.984 RESOURCES : processing files...
08:33:53.984 RESOURCES (W): resource not registered: @"$profile:rereintroduced.json". Setting null GUID
08:33:53.984 RESOURCES (W): resource not registered: @"$logs:launch-source-sha256.json". Setting null GUID
08:33:53.984 RESOURCES (W): resource not registered: @"$logs:launch-source.json". Setting null GUID
08:33:58.882 INIT : Workbench Create Game
08:33:58.882 SCRIPT : Compiling Game scripts
08:33:58.882 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,785": 'GetPlayerPlatformKind' is obsolete
08:33:58.882 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,786": 'GetPlayerPlatformId' is obsolete
08:33:59.018 SCRIPT (W): @"Scripts/Game/ERR/ERR_SiteService.c,191": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.153 SCRIPT (W): @"Scripts/Game/Workshop/SCR_AddonManager.c,876": 'GetRefCount' is obsolete: Will be removed
08:33:59.185 SCRIPT (W): @"Scripts/Game/Campaign/SCR_PlayerProfileManagerComponent.c,142": 'PlayerData' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,159": 'GetDSSession' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,162": 'RoomID' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,197": 'GetDSSession' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,201": 'RoomID' is obsolete
08:33:59.322 SCRIPT (W): @"Scripts/Game/ERR/ERR_CasualtyGroundSupport.c,21": 'GetBoneIndex' is obsolete: Use GetAnimation().GetBoneIndex() instead
08:33:59.383 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,481": 'GetStorage' is obsolete
08:33:59.383 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,483": 'GetOnlineWritePrivilege' is obsolete
08:33:59.388 SCRIPT (W): @"Scripts/Game/Utilities/SCR_PlayerIdentityUtils.c,20": 'GetPlayerIdentityId' is obsolete
08:33:59.427 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,45": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.427 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,56": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.428 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,643": 'GetNotifyCount' is obsolete: Will be substitued by Notification Api.
08:33:59.428 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,645": 'GetNotifyItem' is obsolete: Will be substitued by Notification Api.
08:33:59.455 SCRIPT (W): @"Scripts/Game/ERR/ERR_NativeTransportProbe.c,82": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.488 SCRIPT (W): @"Scripts/Game/DataCollection/PlayerData/SCR_PlayerData.c,210": 'PlayerData' is obsolete
08:34:08.606 WORLD : CreateEntities
08:34:08.606 ENTITY : Create entity @"ENTITY:610406" ('StaticModelEntity','Assets/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.xob') at <1931.796021 81.777000 5138.725098> @"{6A004A8F0571D456}Prefabs/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.et"
08:34:08.606 ENTITY : CreateComponent 'ScriptedRadioComponent'
08:34:08.606 DEFAULT (W): World doesn't contain RadioManagerEntity to support any BaseRadioComponent.
08:34:24.890 DEFAULT (W): LogiLED: Cannot initialize! (service not running or no compatible device detected)
08:34:29.785 WORLD : Game::LoadEntities
08:34:29.786 WORLD : CreateEntities
08:34:29.786 WORLD : CreateEntities
08:34:29.786 ENTITY : Create entity @"ENTITY:610406" ('StaticModelEntity','Assets/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.xob') at <1931.796021 81.777000 5138.725098> @"{6A004A8F0571D456}Prefabs/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.et"
08:34:29.786 ENTITY : CreateComponent 'ScriptedRadioComponent'
08:34:29.786 DEFAULT (W): World doesn't contain RadioManagerEntity to support any BaseRadioComponent.
08:34:31.174 ENTITY : Create entity @"ENTITY:842066" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1080.213013 10.776751 6018.347168>
08:34:31.174 ENTITY : CreateComponent 'Hierarchy'
08:34:31.174 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842066" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1080.213013 10.776751 6018.347168>')
08:34:31.175 ENTITY : Create entity @"ENTITY:842068" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1082.185913 10.778749 6018.331055>
08:34:31.175 ENTITY : CreateComponent 'Hierarchy'
08:34:31.175 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842068" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1082.185913 10.778749 6018.331055>')
08:34:31.175 ENTITY : Create entity @"ENTITY:842070" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1084.190918 10.790751 6018.334961>
08:34:31.175 ENTITY : CreateComponent 'Hierarchy'
08:34:31.175 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842070" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <1084.190918 10.790751 6018.334961>')
08:34:31.180 ENTITY : Create entity @"ENTITY:842333" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4425.594727 9.981750 11029.402344>
08:34:31.180 ENTITY : CreateComponent 'Hierarchy'
08:34:31.180 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842333" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4425.594727 9.981750 11029.402344>')
08:34:31.180 ENTITY : Create entity @"ENTITY:842335" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4426.584473 9.983749 11031.109375>
08:34:31.180 ENTITY : CreateComponent 'Hierarchy'
08:34:31.180 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842335" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4426.584473 9.983749 11031.109375>')
08:34:31.180 ENTITY : Create entity @"ENTITY:842337" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4427.572266 9.995750 11032.853516>
08:34:31.180 ENTITY : CreateComponent 'Hierarchy'
08:34:31.180 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842337" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <4427.572266 9.995750 11032.853516>')
08:34:31.185 ENTITY : Create entity @"ENTITY:842591" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10009.946289 10.470250 1551.986084>
08:34:31.185 ENTITY : CreateComponent 'Hierarchy'
08:34:31.185 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842591" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10009.946289 10.470250 1551.986084>')
08:34:31.185 ENTITY : Create entity @"ENTITY:842593" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10009.430664 10.472250 1550.081421>
08:34:31.185 ENTITY : CreateComponent 'Hierarchy'
08:34:31.185 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842593" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10009.430664 10.472250 1550.081421>')
08:34:31.186 ENTITY : Create entity @"ENTITY:842595" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10008.926758 10.484250 1548.140869>
08:34:31.186 ENTITY : CreateComponent 'Hierarchy'
08:34:31.186 ENTITY (W): Invalid PivotID 'socket_light_04' in Hierarchy component ('@"ENTITY:842595" ('GameEntity','Assets/Structures/BuildingsParts/Lights/LampTower_01.xob') at <10008.926758 10.484250 1548.140869>')
08:34:38.450 WORLD : InitEntities 'world'
08:34:38.450 ENTITY : Init entity @"ENTITY:2305843009213693953" ('Rereintroduced', ERR_GameMode) at <1076.468018 51.000999 1325.246948> @"{978E045E53EF36C8}Prefabs/ERR/GameMode.et"
08:34:38.450 SCRIPT (W): SCR_PerceivedFactionManagerComponent trying to set fall back faction 'CIV' but this faction could not be found so it is null instead.
08:34:39.012 ENTITY : SpawnEntityPrefab @"{225E51284CC95CFA}Prefabs/Characters/Core/DefaultPlayerControllerMP.et"
08:34:39.012 ENTITY : Create entity @"ENTITY:4611686018427388381" ('SCR_PlayerController') at <0.000000 0.000000 0.000000>
08:34:39.012 ENTITY : EntityPrefabUse @"{225E51284CC95CFA}Prefabs/Characters/Core/DefaultPlayerControllerMP.et"
08:34:39.013 SCRIPT (W): Notification data in 'SCR_NotificationsLogDisplay' has duplicate notification info key: 'EDITOR_PERCEIVED_FACTION_PUNISHMENT_KILLING_SET'. There should only be one of each key!
08:34:39.013 SCRIPT (W): Notification data in 'SCR_NotificationsLogDisplay' has duplicate notification info key: 'EDITOR_PERCEIVED_FACTION_TYPE_DISABLED'. There should only be one of each key!
08:34:39.015 SCRIPT (W): Can't open config file ""
08:34:39.022 WORLD : InitEntities 'world'
08:34:39.022 ENTITY : Init entity @"ENTITY:4611686018427388381" ('SCR_PlayerController') at <0.000000 0.000000 0.000000> @"{225E51284CC95CFA}Prefabs/Characters/Core/DefaultPlayerControllerMP.et"
08:34:39.022 GUI : WidgetManager: CrateWidgets @"{3C9DCDD76AB83157}UI/layouts/HUD/HUDLayouts/HUDManager_Root.layout"
08:34:39.022 SCRIPT (W): Slot_WeaponInfo Has no Content!
08:34:39.022 SCRIPT (W): Slot_Chat Has no Content!
08:34:39.023 SCRIPT (W): Slot_VON Has no Content!
08:34:39.023 SCRIPT (W): Slot_AvailableActions Has no Content!
08:34:39.023 SCRIPT (W): Slot_Vehicle Has no Content!
08:34:39.023 SCRIPT (W): Slot_GameVersion Has no Content!
08:34:39.023 SCRIPT (W): Slot_Notifications Has no Content!
08:34:39.023 SCRIPT (W): Slot_Hints Has no Content!
08:34:39.035 ENTITY : SpawnEntityPrefab @"{59EF8ECAE1DCD417}Prefabs/Editor/Modes/EditorModeEdit.et"
08:34:39.035 ENTITY : Create entity @"ENTITY:4611686018427388384" ('SCR_EditorModeEntity') at <0.000000 0.000000 0.000000>
08:34:39.035 ENTITY : EntityPrefabUse @"{59EF8ECAE1DCD417}Prefabs/Editor/Modes/EditorModeEdit.et"
08:34:39.036 SCRIPT (W): SCR_EntityCatalogManagerComponent.GetFilteredEditorPrefabsOfAllFactions: Detected that {259EE7B78C51B624}UAZ469.et is present in at least two different faction entity catalogs! Since this may cause issues, such as dupliacted entries in build mode, one of them will be discarded! This is only supported for items. Other things require creation of faction specific variants.
08:34:39.036 SCRIPT (W): SCR_EntityCatalogManagerComponent.GetFilteredEditorPrefabsOfAllFactions: Detected that {DF5CCB7C0FF049F4}Mi8MT_unarmed_transport.et is present in at least two different faction entity catalogs! Since this may cause issues, such as dupliacted entries in build mode, one of them will be discarded! This is only supported for items. Other things require creation of faction specific variants.
08:34:39.039 SCRIPT (W): Ban Settings could not be loaded from BE Storage: Relying on default config
08:34:39.281 WORLD : UpdateEntities
08:34:39.281 WORLD : PostFrame
08:34:39.281 GUI : WidgetManager: CrateWidgets @"{D89BBA18F99053D6}UI/layouts/HUD/Chat/ChatHud.layout"
08:34:39.281 SCRIPT (W): EditBoxFilterComponent used on invalid widget type.
08:34:39.326 RESOURCES : GetResourceObject @"{20A6917D2114E29A}UI/layouts/HUD/Hint/HintInfoDisplay.layout"
08:34:39.326 GUI : Layout load @"{20A6917D2114E29A}UI/layouts/HUD/Hint/HintInfoDisplay.layout"
08:34:39.326 GUI : Widget prefab @"{EA1CC57D868E94F9}UI/layouts/HUD/Hint/Hint.layout"
08:34:39.326 GUI (W): Overridden prefab member (GUID: '{661AB14E0F471C66}' type: ButtonWidgetClass) no longer exists in prefab
08:34:41.767 WORLD : UpdateEntities
08:34:41.768 WORLD : AfterPostSimulate
08:34:41.768 DEFAULT (W): Collider UCS_FG_DriveShaft_01 not found
08:35:51.367 GUI : WidgetManager: CrateWidgets @"{144919871D65F121}UI/layouts/HUD/GameOver/EndScreen/EndScreen.layout"
08:35:51.367 SCRIPT (W): Slot_Chat Has no Content!
08:35:51.367 SCRIPT (W): Slot_VON Has no Content!
08:35:51.368 SCRIPT (W): Slot_GameVersion Has no Content!
08:35:51.368 SCRIPT (W): Slot_Notifications Has no Content!
08:35:53.422 SCRIPT (W): SCR_ScriptedWidgetComponent.GetComponent: widget not found: SCR_InputButtonComponent Back
08:35:53.423 SCRIPT (W): SCR_ScriptedWidgetComponent.GetComponent: widget not found: SCR_InputButtonComponent ChatButton
08:35:53.426 GUI : WidgetManager: CrateWidgets @"{144919871D65F121}UI/layouts/HUD/GameOver/EndScreen/EndScreen.layout"
08:35:53.426 SCRIPT (W): Slot_Chat Has no Content!
08:35:53.426 SCRIPT (W): Slot_VON Has no Content!
08:35:53.427 SCRIPT (W): Slot_GameVersion Has no Content!
08:35:53.427 SCRIPT (W): Slot_Notifications Has no Content!
@@ -0,0 +1,150 @@
[gamescope] [Info] console: gamescope version 3.16.28 (gcc 16.2.1)
No CAP_SYS_NICE, falling back to regular-priority compute and threads.
Performance will be affected.
[gamescope] [Info] scriptmgr: Loading scripts from: '/usr/share/gamescope/scripts'
[gamescope] [Info] scriptmgr: Loading scripts from: '/usr/share/gamescope/scripts/00-gamescope'
[gamescope] [Info] scriptmgr: Loading scripts from: '/usr/share/gamescope/scripts/00-gamescope/common'
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/common/inspect.lua' (id: 0)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/common/modegen.lua' (id: 1)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/common/util.lua' (id: 2)
[gamescope] [Info] scriptmgr: Loading scripts from: '/usr/share/gamescope/scripts/00-gamescope/displays'
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/displays/asus.rogally.lcd.lua' (id: 3)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/displays/deckhd.steamdeck.deckhd-lcd.lua' (id: 4)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/displays/gpd.win4.lcd.lua' (id: 5)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/displays/lenovo.legiongo.lcd.lua' (id: 6)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/displays/lenovo.legiongos.lcd.lua' (id: 7)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/displays/onexplayer.f1.oled.lua' (id: 8)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/displays/valve.steamdeck.lcd.lua' (id: 9)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/displays/valve.steamdeck.oled.lua' (id: 10)
[gamescope] [Info] scriptmgr: Running script file '/usr/share/gamescope/scripts/00-gamescope/displays/zotac.zone.oled.lua' (id: 11)
[gamescope] [Info] scriptmgr: Loading scripts from: '/etc/gamescope/scripts'
[gamescope] [Warn] scriptmgr: Directory '/etc/gamescope/scripts' does not exist
[gamescope] [Info] scriptmgr: Loading scripts from: '/home/jakub/.config/gamescope/scripts'
[gamescope] [Warn] scriptmgr: Directory '/home/jakub/.config/gamescope/scripts' does not exist
[gamescope] [Info] vulkan: selecting physical device 'AMD Radeon RX 6950 XT (RADV NAVI21)': queue family 1 (general queue family 0)
[gamescope] [Info] vulkan: physical device supports DRM format modifiers
[gamescope] [Info] wlserver: [backend/headless/backend.c:60] Creating headless backend
[gamescope] [Info] vulkan: supported DRM formats for sampling usage:
[gamescope] [Info] vulkan: AR24 (0x34325241)
[gamescope] [Info] vulkan: XR24 (0x34325258)
[gamescope] [Info] vulkan: AB24 (0x34324241)
[gamescope] [Info] vulkan: XB24 (0x34324258)
[gamescope] [Info] vulkan: RG16 (0x36314752)
[gamescope] [Info] vulkan: NV12 (0x3231564E)
[gamescope] [Info] vulkan: AB4H (0x48344241)
[gamescope] [Info] vulkan: XB4H (0x48344258)
[gamescope] [Info] vulkan: AB48 (0x38344241)
[gamescope] [Info] vulkan: XB48 (0x38344258)
[gamescope] [Info] vulkan: AB30 (0x30334241)
[gamescope] [Info] vulkan: XB30 (0x30334258)
[gamescope] [Info] vulkan: AR30 (0x30335241)
[gamescope] [Info] vulkan: XR30 (0x30335258)
[gamescope] [Info] wlserver: Using explicit sync when available
[gamescope] [Info] wlserver: Running compositor on wayland display 'gamescope-0'
[gamescope] [Info] wlserver: [backend/headless/backend.c:17] Starting headless backend
[gamescope] [Info] wlserver: Successfully initialized libei for input emulation!
[gamescope] [Error] wlserver: [xwayland/sockets.c:47] Failed to bind socket @/tmp/.X11-unix/X0: Address already in use
[gamescope] [Info] wlserver: [xwayland/server.c:108] Starting Xwayland on :2
The XKEYBOARD keymap compiler (xkbcomp) reports:
> Warning: Multiple symbols for level 1/group 1 on key <FK23>
> Using F23, ignoring XF86TouchpadOff
> Warning: Symbol map for key <FK23> redefined
> Using last definition for conflicting fields
> Warning: Symbol map for key <FK24> redefined
> Using last definition for conflicting fields
> Warning: Could not resolve keysym XF86ElectronicPrivacyScreenOn
> Warning: Could not resolve keysym XF86ElectronicPrivacyScreenOff
> Warning: Could not resolve keysym XF86ActionOnSelection
> Warning: Could not resolve keysym XF86ContextualInsert
> Warning: Could not resolve keysym XF86ContextualQuery
Errors from xkbcomp are not fatal to the X server
[gamescope] [Info] pipewire: stream state changed: connecting
[gamescope] [Info] pipewire: stream state changed: paused
[gamescope] [Info] pipewire: stream available on node ID: 178
[gamescope] [Info] vblank: Using timerfd.
fsync: up and running.
[Gamescope WSI] No application info given.
[Gamescope WSI] Executable name: explorer.exe
ATTENTION: default value of option vk_wsi_force_swapchain_to_current_extent overridden by environment.
[Gamescope WSI] Application info:
pApplicationName: xalia.exe
applicationVersion: 0
pEngineName: DXVK
engineVersion: 12587008
apiVersion: 4206592
[Gamescope WSI] Executable name: xalia.exe
ATTENTION: default value of option vk_wsi_force_swapchain_to_current_extent overridden by environment.
[Gamescope WSI] No application info given.
[Gamescope WSI] Application info:
pApplicationName: ArmaReforgerWorkbenchSteamDiag.exe
applicationVersion: 1
pEngineName: DXVK
engineVersion: 12587008
apiVersion: 4206592
[Gamescope WSI] Executable name: ArmaReforgerWorkbenchSteamDiag.exe
ATTENTION: default value of option vk_wsi_force_swapchain_to_current_extent overridden by environment.
[Gamescope WSI] No application info given.
The XKEYBOARD keymap compiler (xkbcomp) reports:
> Warning: Unsupported maximum keycode 709, clipping.
> X11 cannot support keycodes above 255.
> Warning: Virtual modifier Hyper multiply defined
> Using 0, ignoring 0
> Warning: Virtual modifier ScrollLock multiply defined
> Using 0, ignoring 0
Errors from xkbcomp are not fatal to the X server
ATTENTION: default value of option vk_wsi_force_swapchain_to_current_extent overridden by environment.
[Gamescope WSI] Application info:
pApplicationName: ArmaReforgerWorkbenchSteamDiag.exe
applicationVersion: 0
pEngineName: DXVK
engineVersion: 12587008
apiVersion: 4206592
ATTENTION: default value of option vk_wsi_force_swapchain_to_current_extent overridden by environment.
[Gamescope WSI] Application info:
pApplicationName: ArmaReforgerWorkbenchSteamDiag.exe
applicationVersion: 0
pEngineName: vkd3d
engineVersion: 12587008
apiVersion: 4206592
[Gamescope WSI] Forcing on VK_EXT_swapchain_maintenance1.
ATTENTION: default value of option vk_wsi_force_swapchain_to_current_extent overridden by environment.
[Gamescope WSI] No application info given.
ATTENTION: default value of option vk_wsi_force_swapchain_to_current_extent overridden by environment.
[Gamescope WSI] Application info:
pApplicationName: ArmaReforgerWorkbenchSteamDiag.exe
applicationVersion: 0
pEngineName: vkd3d
engineVersion: 12587008
apiVersion: 4206592
[Gamescope WSI] Forcing on VK_EXT_swapchain_maintenance1.
[Gamescope WSI] Creating Gamescope surface: xid: 0x1c001a4
[Gamescope WSI] Atom of T was wrong type. Expected XCB_ATOM_CARDINAL.
[Gamescope WSI] Made gamescope surface for xid: 0x1c001a4
[Gamescope WSI] Surface state:
steam app id: 1874910
window xid: 0x1c001a4
wayland surface res id: 5
layer client flags: 0x4
server hdr output enabled: false
hdr formats exposed to client: false
[Gamescope WSI] Creating Gamescope surface: xid: 0x1c003a4
[Gamescope WSI] Atom of T was wrong type. Expected XCB_ATOM_CARDINAL.
[Gamescope WSI] Made gamescope surface for xid: 0x1c003a4
[Gamescope WSI] Surface state:
steam app id: 1874910
window xid: 0x1c003a4
wayland surface res id: 10
layer client flags: 0x4
server hdr output enabled: false
hdr formats exposed to client: false
[Gamescope WSI] Creating swapchain for xid: 0x1c003a4 - oldSwapchain: (nil) - provided minImageCount: 3 - minImageCount: 3 - format: VK_FORMAT_B8G8R8A8_UNORM - colorspace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - flip: false
[Gamescope WSI] Created swapchain for xid: 0x1c003a4 swapchain: 0x5555651afbb0 - imageCount: 4
[Gamescope WSI] Destroying swapchain: 0x5555651afbb0
[Gamescope WSI] Destroyed swapchain: 0x5555651afbb0
[Gamescope WSI] Creating swapchain for xid: 0x1c003a4 - oldSwapchain: (nil) - provided minImageCount: 3 - minImageCount: 3 - format: VK_FORMAT_B8G8R8A8_UNORM - colorspace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - flip: false
[Gamescope WSI] Created swapchain for xid: 0x1c003a4 swapchain: 0x5555651afbb0 - imageCount: 4
[Gamescope WSI] Destroying swapchain: 0x5555651afbb0
[Gamescope WSI] Destroyed swapchain: 0x5555651afbb0
[Gamescope WSI] Creating swapchain for xid: 0x1c003a4 - oldSwapchain: (nil) - provided minImageCount: 3 - minImageCount: 3 - format: VK_FORMAT_B8G8R8A8_UNORM - colorspace: VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - flip: false
[Gamescope WSI] Created swapchain for xid: 0x1c003a4 swapchain: 0x55556513c740 - imageCount: 4
[gamescope] [Info] launch: Primary child shut down!
@@ -0,0 +1,164 @@
{
"addons/ai/Prefabs/ERR/MortarCrew.et": "05d3e7353ff9fe5523218a1487b31b7b742b0be8adbcb060c7099978cf008bce",
"addons/ai/Prefabs/ERR/MortarCrew.et.meta": "fdfd4fcd21a67c3d698fa4aadc4e5c76e665cebf4be86013bc389e493fab63cc",
"addons/ai/Scripts/Game/ERR/ERR_HQ.c": "ceafd6740ed277748744ce56ac0f0bb3a8521fcc060dafb2cdb99896aedf405a",
"addons/ai/Scripts/Game/ERR/ERR_HQJournal.c": "b3e402cfe92d415f37f666045afb062e6e11670ba03a0ca6f2d9fd4fc3520ac1",
"addons/ai/Scripts/Game/ERR/ERR_HQNetwork.c": "92ff2caca52e94c2cc9642dfc8509ce6e9349b257012bade8650bace9231128c",
"addons/ai/Scripts/Game/ERR/ERR_HQObservation.c": "36c978ec5f052213ac1236e1398d85063efbfd7ef60fe04f1fc11447fefe1d68",
"addons/ai/Scripts/Game/ERR/ERR_HQReport.c": "c4d16ccb571db4d9444c0a8d2be7318845d25ff90238b6d304e96a9ea19f1a08",
"addons/ai/Scripts/Game/ERR/ERR_HelicopterAvailability.c": "60eaef2f6d4b2fd44861c5a4434ef97e732e40a5ff7401e2da451ed2dd9c2762",
"addons/ai/Scripts/Game/ERR/ERR_MortarAimSolution.c": "59f8052c2038072deb90623aad4bd750088499aae1d2754c72a770bf836a800a",
"addons/ai/Scripts/Game/ERR/ERR_MortarBattery.c": "e4589e5af55701f8c1f7f33e0a49e45f34b073bfddbdc87e009bea69af683828",
"addons/ai/Scripts/Game/ERR/ERR_MortarFiring.c": "672ce8527494bd9d3155b93702ac9812f194f2d5f93c8a8c46c5f690bdd3eb93",
"addons/ai/Scripts/Game/ERR/ERR_MortarPrediction.c": "470dd196ed64800c697d24c09d1344bacd2502587fac76af4ee0edae2563092d",
"addons/ai/Scripts/Game/ERR/ERR_MortarReadiness.c": "1a7282d9bd53dcd115d53c9b460ca62d3218931a74635cc516eac1a13b7d9347",
"addons/ai/Scripts/Game/ERR/ERR_MortarSalvo.c": "697c01f479df6c505a41d984a29c02002e3052114dafa2ec6252ae55e2979a2b",
"addons/ai/Scripts/Game/ERR/ERR_MortarSupplyTransfer.c": "34f7eaa01dc68e97aae8c1177b7f8fd6c15d5a41c6dc86de377f00b3613a8e77",
"addons/ai/Scripts/Game/ERR/ERR_MortarSystem.c": "acbc8a1d6a5c76278c447b666ae7362740953422a9ca287361ad6286b6944c59",
"addons/ai/Scripts/Game/ERR/ERR_NativeMortarFiringProbe.c": "d66e57ada46678eb0a6dfa6ff818b656f6132c4eed28881abafafa1e44f8cd2c",
"addons/ai/Scripts/Game/ERR/ERR_NativeMortarTransferProbe.c": "399c21940ef10777b46fdb3e905430ce43404ce1de2f4a6bb62f9c61c1a0689c",
"addons/ai/Scripts/Game/ERR/ERR_NativePatrolHQProbe.c": "4c04aa3e1b6b000747da8e2a919a6501107880fd041134c019f516665bb6f758",
"addons/ai/Scripts/Game/ERR/ERR_SettlementSafety.c": "e5c0ebc95521a9a33a3f7d9cca6c551dda862a08b7af20b017877aba9584795b",
"addons/ai/Scripts/Game/ERR/ERR_SupportScenario.c": "71757018ec9716c4dc24f62a292a214919d3fd5daed3c16e03e56abd208e9f03",
"addons/ai/addon.gproj": "5f559db8f526700db11e6ae763f5245f19b7006fc68c56e4c09fb6f940bdf2a1",
"addons/chat/Missions/ERR_Everon.conf": "76f3ac0d21b585654beac7ddd68e3c8cbdd66dbfe909b17b04838fa813a7c29b",
"addons/chat/Missions/ERR_Everon.conf.meta": "0a23c98bf83873536c65fa17d38dea33a1d7b9e4ab210f90633ff688abcc551f",
"addons/chat/Scripts/Game/ERR/ERR_AdminCommands.c": "d7b4ed95fc32767911936cb0fcc60763233f2c31afd34a6a0fa998b39cec9f5c",
"addons/chat/Scripts/Game/ERR/ERR_NativeMortarProbe.c": "ddb892141500c192c0787b011d57dd8c07dd8c9a3ca5fdc407f6c271897bde0a",
"addons/chat/Scripts/Game/ERR/ERR_NativeRadioProbe.c": "84524163c63402755b4f834f74dfe6d8e5c397dc26031f532593c6f79f5a93b1",
"addons/chat/Scripts/Game/ERR/ERR_NativeSmoke.c": "95186a6c1553b38c6a214e897f845ef1799d8acca0cc896d8df73de680050888",
"addons/chat/Scripts/Game/ERRChat/ERR_OrdinaryScenarioLaunchChat.c": "dda715c9691d366e35fa2ad5e390dee1971651f137a5a9f9aeb23dcbe53ec87e",
"addons/chat/Scripts/WorkbenchGame/ERR/ERR_ValidateWorldPlugin.c": "81c92d408ce88cc9f98d6053f1d0c863427693ba748f00df9f1bf8079015ef94",
"addons/chat/addon.gproj": "ea1587e0174cf795334d306c71d99b06797fc891427cd57b6cab6e21cf0e4e0e",
"addons/core/Configs/ERR/EveronSites.conf": "ade92cc8d2b14a84ac378bbbb52608b351dca65d359dd7a315d64a145fa4b46f",
"addons/core/Configs/ERR/EveronSites.conf.meta": "d5fe68025ef4e7c1e16082cf5873b7c7172eacbfaef4ab29b7e0e3c98f8dca56",
"addons/core/Configs/ERR/Factions/MissionVehicles.conf": "5f74f4a7089c7e7b54ad62463159ce8f0bab25a6b85268dc3872ea6001e048fb",
"addons/core/Configs/ERR/Factions/MissionVehicles.conf.meta": "00c368b6271d3440cc8bf627b03a384d247635723923fc5ad2104b8b4007b035",
"addons/core/Configs/ERR/Factions/US.conf": "4c3da063abb6e3ee39a6e4e0c5a9ffd5eae9d209d58470ea18b45dba5528db1b",
"addons/core/Configs/ERR/Factions/US.conf.meta": "a05469aef028e9e17eba545e81e2af2887b59f0fef17dac51a23c7b8155e381b",
"addons/core/Configs/ERR/Factions/USSR.conf": "407ea27f80a64c5184c089d43cdd0bdabfc5974c84f1d2a245081fdf2afa3f30",
"addons/core/Configs/ERR/Factions/USSR.conf.meta": "057397d97096346791b51b7b13fbe18af218bcf78e9984d9c01b49a2403de611",
"addons/core/Configs/ERR/GameOverScreens.conf": "45231061911a1462d45fb6db0fecc2b0793f17b5ae71017174954ff4fbd20236",
"addons/core/Configs/ERR/GameOverScreens.conf.meta": "eb654b745c0b97b41c991694569ef4877a3c2315e0826f9556337cd68690843e",
"addons/core/Configs/ERR/VanillaFactions.conf": "db890b61b48ee15484041fd2245a862d9fa9e7ba21b1229c281ff37c448a35b1",
"addons/core/Configs/ERR/VanillaFactions.conf.meta": "ac77725c0c21974991ef47a466b88122e939de8b46fd23e68889e7674cbb2bfd",
"addons/core/Missions/ERR_Everon_Base.conf": "1e6a0e9a756d15495201f71121626890f01efe6b00154c561672d4ec157960bd",
"addons/core/Missions/ERR_Everon_Base.conf.meta": "9b16267c644d815bcf98a3a3aaff30b93d7224fb24d3a2bac66730a28011f317",
"addons/core/Prefabs/ERR/Extraction.et": "1aa286ef253c5410f09fa641e4be91a7be8ec834487a7fbb74cfb45cab60ee1e",
"addons/core/Prefabs/ERR/Extraction.et.meta": "c2a838633001e2e3a202d39cb33aa744ebcd996017ad032359069641b5d13853",
"addons/core/Prefabs/ERR/FactionManager.et": "425f916b890019c537f6b2f72b1af9e7be54b0a476320da969e1f313a7ac5ea5",
"addons/core/Prefabs/ERR/FactionManager.et.meta": "9bf53d5e4bcbe60dd1a4ece1409fc23c349055c860708620f5f6e9716290a97d",
"addons/core/Prefabs/ERR/FieldCover.et": "20f8095e69dbfe3db74ff19078e528ea75405362b335e03560ccd61f8df2e7f3",
"addons/core/Prefabs/ERR/FieldCover.et.meta": "83461ffa76244e1d69f20b053a9741ccdf7d127009182bd540a7e5ba6150c3d9",
"addons/core/Prefabs/ERR/GameMode.et": "385c97a5b8067091d92aa60c2d4fcf02002cf606b95523866ead65c96b8c0029",
"addons/core/Prefabs/ERR/GameMode.et.meta": "106769cd34525c9d440057072836cb7401a6752148c40edd7fe61c03bd58328c",
"addons/core/Prefabs/ERR/ObjectiveDocument.et": "2e72270bf186654af12d2c3ff9bf940690b03fb17fca44f873c1fde5d11384c0",
"addons/core/Prefabs/ERR/ObjectiveDocument.et.meta": "eaba9903be147b98a1106e2273e2270773df73b9b22f2cd4e20136a8e281382e",
"addons/core/Prefabs/ERR/Patrol.et": "c5685a8bc311cc5563fb3334beec9408d3d7a1069152fddeeb7df4f1b7f9e6ce",
"addons/core/Prefabs/ERR/Patrol.et.meta": "7c5da568fa2fcf0709ee2959253cb068d7c7ed7c2467af3b247a7e70efd96b69",
"addons/core/Prefabs/ERR/Prison.et": "1503db1441d8cd7a4f0b45c27ba9623b9fa39f0f81016e180bd2aa1379e1f42a",
"addons/core/Prefabs/ERR/Prison.et.meta": "2e426ef3de68f4107907854b51e818bc11d84649a01c538e3f18dd9ebec766bb",
"addons/core/Prefabs/ERR/PrisonDoor.et": "fc66be9d36f1f01084de59f1b0a1e8817f9e46547ead33d4fafaac0107446c40",
"addons/core/Prefabs/ERR/PrisonDoor.et.meta": "b8f3db52bf186426026668fbb9d633c3cbd4d438ab301fba880398f6a0e781c2",
"addons/core/Prefabs/ERR/PrisonWall.et": "8009d19365ae72a4749d7ad4fa04662575b06c65c6bf06507d380d57258b5eed",
"addons/core/Prefabs/ERR/PrisonWall.et.meta": "0294bc5dbb56f90f8153d62459bb0a6ad91d76a479812bbec9c7db182fdb58d6",
"addons/core/Prefabs/ERR/Prisoner.et": "198b5badabb12f218f86df7eb4dc268fd830769dc3de7eef6362cfaee4d6fc8d",
"addons/core/Prefabs/ERR/Prisoner.et.meta": "974278ba49fafeed70b619a0067bbc70ae4d534be441c812ce2bef4a5fb3c022",
"addons/core/Prefabs/ERR/Radio.et": "b4b5cfe125b39019855816c9a1c508ca4d65d435b5546fdaa6c1fa3c8c9b1165",
"addons/core/Prefabs/ERR/Radio.et.meta": "bc91137b68ba550217914fb8892bb44d7e1920e4a1086f3e506623832a44212f",
"addons/core/Prefabs/ERR/SpectatorCamera.et": "b5b87d5b7b707f3745741aebe7c923067c8a74f8fbb2a4711834bab03bb5a812",
"addons/core/Prefabs/ERR/SpectatorCamera.et.meta": "2a16558f93915e31908a674509e9c89976470f78a84a1174a64b94b68b8f77ad",
"addons/core/Prefabs/ERR/SupplyCache.et": "bccf7afbaae97cfcdd78dd6dbbf4be5b2c045d348f50fe4581962e556c0044d7",
"addons/core/Prefabs/ERR/SupplyCache.et.meta": "2f5de3a4aab1e9d0e35521f48dc57b95bd6e449c383dec4f1c258e10295904cb",
"addons/core/Prefabs/ERR/SupplySite.et": "dc5decce5cabf39b6116e8794ec3960cb1e35761854fdbe69740da118787ded4",
"addons/core/Prefabs/ERR/SupplySite.et.meta": "b41944b12eb3528ff7a3ac94258b18c66ef161aa6a38894aee300a1ac4798630",
"addons/core/Scripts/Game/ERR/ERR_Actions.c": "adf93245e6d78c59b9839599d157a0d2b2b93ea93b3d1ae52e2904dd6c288266",
"addons/core/Scripts/Game/ERR/ERR_Actors.c": "b3c5aabb05f7cf35167bc09b5db51a4ffd89a46658805d6eedbfb80eee30273d",
"addons/core/Scripts/Game/ERR/ERR_AdminService.c": "9985747d5ddaeb91bf27937836a6c369f8dcb353263b77a49212ec28c10ba4eb",
"addons/core/Scripts/Game/ERR/ERR_CasualtyGroundSupport.c": "26f0c7ebe8563bb022f7c383674e7d8997b0cc35c7ea321d39d74f2493c1ed9d",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingGameMode.c": "f4cf19440583ac24346831a2d5f1d7f734c031e46dc266c499972329dd0533cf",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingOwner.c": "6346a05ddda030f7d9b6f026f977d5f018ee16002fa519e8c49dcd700c323dc7",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingService.c": "df787bc40099512656e622c6c511d18caea2ff7a88d2c113e0d6940a551ad566",
"addons/core/Scripts/Game/ERR/ERR_DiscoveryMap.c": "80fda5976c3d7a74ee3a481a0d5f365d5e59553046ebe84d0c84117829a32aaf",
"addons/core/Scripts/Game/ERR/ERR_DiscoveryService.c": "65cc0c23da131f986c3c90a8e4d294522e1d0681bec709b618daecb6e0d393c0",
"addons/core/Scripts/Game/ERR/ERR_DocumentComponent.c": "17bb76b80ebd3357e46d553c44674f602c7bd6901c92aec53ac8214194aa4ff2",
"addons/core/Scripts/Game/ERR/ERR_EnvironmentService.c": "867e9f47adfb7a9819a8b58498688ff86127282cb89cf2529ae81f73e529e1c5",
"addons/core/Scripts/Game/ERR/ERR_EscapeGameOverScreenInfo.c": "b1e1afb7795cb77c0bad94c85abf705b26b9dc2a9400905d80eafd56bdd009d3",
"addons/core/Scripts/Game/ERR/ERR_ExtractionPlacement.c": "c30222ca25cc0e91dec4077e6b82b37a9edafcf2cbebd0be5b6bd8656b53adfe",
"addons/core/Scripts/Game/ERR/ERR_ExtractionService.c": "91357099b4e0401196b67d48963be54be30e56bdba57cdac67dc20b8ebb883e9",
"addons/core/Scripts/Game/ERR/ERR_FactionCatalog.c": "a5a8c53acf21259e14f59cb919535910f30dabff5a9179c664bc6a7a4d744d6e",
"addons/core/Scripts/Game/ERR/ERR_GameMode.c": "043ac9ab7f3163f3285038ed008be782030714607d8e59e25593cfe95dd023b2",
"addons/core/Scripts/Game/ERR/ERR_InitialGuardRules.c": "8c9d6b1dc4c2af96284e34f487eebb5a221091016ef108006dec60b4e3836558",
"addons/core/Scripts/Game/ERR/ERR_Inventory.c": "b63e679d5b650b63a7a91dfc3f42a62f4be58b0338f6df3313e66d29a93bebf6",
"addons/core/Scripts/Game/ERR/ERR_LoadCasualtyAction.c": "5d868fb065a1a0fea7d5abfc81d1d8be96823815535f2ffd0dc4ff60d8eae794",
"addons/core/Scripts/Game/ERR/ERR_LocalAdmission.c": "b0e824c6880cbf9b1f368dc7ada9907bde78b22b948d419b6c861323f32258be",
"addons/core/Scripts/Game/ERR/ERR_Location.c": "d2035f56ded35743312ec6ca91a67f8623a466c91255e1893c570edf0954ff24",
"addons/core/Scripts/Game/ERR/ERR_MissionRules.c": "f7abc38ad8fdc375ce7fa63a65f0bade027d22b37e09de5e3f94ba8c3c63cc41",
"addons/core/Scripts/Game/ERR/ERR_NativeAdminSettingsProbe.c": "6a4df33a2b0e6b6aeed944c6895961e658d4f0db9aed9b8433a43a451fa35cae",
"addons/core/Scripts/Game/ERR/ERR_NativeBaseSmoke.c": "84e0a2d73bc12160cd0a95138085eb7647fa26b2326f790a95cb53748009fdd3",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyGroundProbe.c": "41f40db3735f8aa535c0061458d9892dcfe972222b8a17238e67b65633c46bc3",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyLoadProbe.c": "94c533deea654ec546df3f1ebb7cd213e6cd79b1125d99bab5303ef8e87b018b",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyRemoveProbe.c": "4cfc06f6d43b709b63caae714155ffc562502e884f49a9825623c6f46972ad36",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyServiceProbe.c": "02a9d70d1f4ba20326df199ba41489cfbae12b7bb0aab441361421cee38ad9ea",
"addons/core/Scripts/Game/ERR/ERR_NativeContractsProbe.c": "d1556df885171cf967e96eef5d8981a2e9ee4e3938b7d32fdd0426f647bbabc0",
"addons/core/Scripts/Game/ERR/ERR_NativeDefinitionProbe.c": "c07048341396443ddf5307e340e2087254d65f0bddf8f7d93e6b6bd7f03ca360",
"addons/core/Scripts/Game/ERR/ERR_NativeEnvironmentProbe.c": "8b1d110717aa5f07bfb8fe633847eab519109e3a8a4100970a487be05c053418",
"addons/core/Scripts/Game/ERR/ERR_NativeEnvironmentRestartProbe.c": "7a836a206381b8e8de24c92baf141beb30575723675dd6948d738169ed26b507",
"addons/core/Scripts/Game/ERR/ERR_NativeExtractionProbe.c": "4b09385f73206de004f4f3c38a6192fd658a0d2012482dc5a84dff1599ceb972",
"addons/core/Scripts/Game/ERR/ERR_NativeFactionCatalogProbe.c": "ee11486cf77da9070506ccc0cfd6e94240c5387c8be455bf864934a8fef65f78",
"addons/core/Scripts/Game/ERR/ERR_NativeGuardCancelProbe.c": "bfa1c65cb039e19c3d1891e4a3fd33469e974c97cc7f42128efc31a8f587d514",
"addons/core/Scripts/Game/ERR/ERR_NativeLifecycleProbe.c": "b613a5dbe81c2032fd02d31070ae5631166d14d0b02cdbec3b63b782f0bbc115",
"addons/core/Scripts/Game/ERR/ERR_NativeMedicalProbe.c": "43fa51ffbcf9dd0cd8e905a1135bcf0756651da3af34677f3c92e7d264ed70b6",
"addons/core/Scripts/Game/ERR/ERR_NativeObjectiveLossProbe.c": "6b80fd317a8c6e8583bd4337870838a86251e3b8a681d0aa07e8b52e22abfc48",
"addons/core/Scripts/Game/ERR/ERR_NativeObjectiveProbe.c": "71fbd2479a70048f83d8b262ad1452f427be2c0afc8b071ef13bff477b9dc29b",
"addons/core/Scripts/Game/ERR/ERR_NativePatrolProbe.c": "02bd9fdf5454db7dd4c82240efe0d947bf8d6488ace42809c3aef6505cb6266d",
"addons/core/Scripts/Game/ERR/ERR_NativePrisonerProbe.c": "e2d1ffe5d269add55124601ff0d1dc032a398c7d51010736e6f0e4cbeb38ae86",
"addons/core/Scripts/Game/ERR/ERR_NativeRadioDefenceProbe.c": "cad54f0b43cefd72df74697dfc7e93725ff0acac6d311e963ce4f817428c272c",
"addons/core/Scripts/Game/ERR/ERR_NativeRecoveryProbe.c": "4de6868cd3e76afb80cf0ae5dac1e35d2c417838f640c2f18aa3343217eea2f2",
"addons/core/Scripts/Game/ERR/ERR_NativeResultProbe.c": "b9a117eef2d5f65fbd792041a2b3e59e38e201bda8e0df8c503e1a1242cfc415",
"addons/core/Scripts/Game/ERR/ERR_NativeSiteSurvey.c": "ac0203753ade0cdff6d483132797a80e4520f14546c3f9dea288281cd4cd9c4f",
"addons/core/Scripts/Game/ERR/ERR_NativeStationTeardownDiagnostic.c": "a363c2383e66311415fd29124f26f3b0c6cb866648d86673afac29fca22a994a",
"addons/core/Scripts/Game/ERR/ERR_NativeTimeProbe.c": "c93d049785971e51246fcc07cf24804270a752a655505f2c38e48c80df5255ae",
"addons/core/Scripts/Game/ERR/ERR_NativeTransportProbe.c": "63ec0c5ce698114daa6314b2a6e3c3e98e76094117c477f9d0d072260686d193",
"addons/core/Scripts/Game/ERR/ERR_NativeTransportSurvey.c": "3e94493bf54d15be2bceb106ad18873e14e6755af09c05f07db7fb26fb7adff5",
"addons/core/Scripts/Game/ERR/ERR_ObjectiveDetails.c": "628ebd166dcb5544c2d18dce489619984887ee18296cf2446fc6d894f89dd5bf",
"addons/core/Scripts/Game/ERR/ERR_ObjectiveText.c": "815fa44350798229784efffe0d4ec16d3382dd62df149215e49d527cc2961553",
"addons/core/Scripts/Game/ERR/ERR_Objectives.c": "88d95a52fcba103483ea751571e1afeae0e6fc82115ed50d6fc195424726960f",
"addons/core/Scripts/Game/ERR/ERR_Observer.c": "b719e723369ab4f403950c85226e1336eb48e3c127e84530ac1c695eb86bd0f9",
"addons/core/Scripts/Game/ERR/ERR_OrdinaryScenarioLaunch.c": "e2803ff9198e6213bfcbaefad64a35ae3ffe06846c410cf6da6de7653adbf28d",
"addons/core/Scripts/Game/ERR/ERR_PlayerAdminCommands.c": "a084d7dc097dfcde3d6cd9c2e326b9e2f8f2a519f77b30c4f56ab7a1429aa721",
"addons/core/Scripts/Game/ERR/ERR_PlayerEscapeResult.c": "3124ab4d2d6d471409a47aba0af528790734df53243c03fe0cdac3e407047c14",
"addons/core/Scripts/Game/ERR/ERR_PlayerGuide.c": "2c9c365b88651f8b12618443638bf52c04e497221592bd483c33447e30468f36",
"addons/core/Scripts/Game/ERR/ERR_PlayerRoster.c": "c038dac0f749bd29ebc35a4e952904b41a34417ba738904d5efcd1833a263e0b",
"addons/core/Scripts/Game/ERR/ERR_RadioDefenceService.c": "5d347cf1a3b021074d560aad8db774828b797e685b63ddff3d28f55781e33ea8",
"addons/core/Scripts/Game/ERR/ERR_RadioFeedback.c": "545262e65e9b3645d9e514a0521e442fe08f0c2e4e7c83ba638c5105d09818db",
"addons/core/Scripts/Game/ERR/ERR_RecoveryService.c": "ba9ffb93679012c20a665636ef6b201cbe7d8d14fdf53e8cd3eb12ac7248943f",
"addons/core/Scripts/Game/ERR/ERR_Resources.c": "d0169aac6fd0c38928c47a9002ded0fd8ba558ea3314a600e792d307ac1ca3ee",
"addons/core/Scripts/Game/ERR/ERR_ScenarioComponent.c": "abba03af68323d5715ba1e2497fc66f3c706e6a6a983c3a386228abdfddeec89",
"addons/core/Scripts/Game/ERR/ERR_Settings.c": "b9390548936b386e0211d487c1b76b65410fdd2e339cd8ecd9585ef4f4ffed31",
"addons/core/Scripts/Game/ERR/ERR_SiteDefinition.c": "b422feeaca90084ea2bee5cde94dc9c6fcae542749b55d95f7226f922a6a68ac",
"addons/core/Scripts/Game/ERR/ERR_SiteDiscoveryRules.c": "50f7b3ff4f32bde37ce5ae2be7f598fc4dd8cc08f45914f6e3260d31c84baef2",
"addons/core/Scripts/Game/ERR/ERR_SiteService.c": "6bc9a0b5aed326822807f05e17459d0fc2da10b709e8168972b4e40fd09f87cb",
"addons/core/Scripts/Game/ERR/ERR_SpawnFinalization.c": "2e295b0f225208c5414728ba83333e5e0ab6eef3a708ce39eb1dfce5400c94c9",
"addons/core/Scripts/Game/ERR/ERR_SpawnLogic.c": "bbbf35110259cacdac63779604ce22149d1a2198ec4c4cf43f7f3bf57e3241e8",
"addons/core/Scripts/Game/ERR/ERR_SpawnPlacement.c": "55323dcb330c23d49dc8fa3fde86a3ae3958c0b6563d6c3cd0960da88333f93d",
"addons/core/Scripts/Game/ERR/ERR_Supplies.c": "752e8a56b0b8cde33cf532032cb0a203553017b686faac2e19bee06f7a9c0713",
"addons/core/Scripts/Game/ERR/ERR_TimeService.c": "d9f481b7da01e08d2c982a948c18ba6bde76889d7cc9d26d510708f4ba479453",
"addons/core/Scripts/GameLib/ERR/ERR_DiagnosticNoSplash.c": "0ea1b402f8927b6d68bf6f7e5caa2967f7e3a39147634faab147796b791933b5",
"addons/core/Scripts/WorkbenchGame/ERR/ERR_ValidateBaseWorldPlugin.c": "7f44aa64ea7b4f8b3640a37a4b781c43bf6adb80e4a3a702d9491131698056f6",
"addons/core/Worlds/ERR_Everon.ent": "22324bc7eb0d80dec8a1f3bd61a9df9201b72f749f4e751766b0c9d0b7d46b87",
"addons/core/Worlds/ERR_Everon.ent.meta": "19d1903ca72baa326b4724a6791d0da1104a1e53f3f31dc1ca41a856efd68e83",
"addons/core/Worlds/ERR_Everon_Layers/default.layer": "17105538007199bfc419aa04a64debaf2da0a7b77a1dc3ba983e92bf747c862e",
"addons/core/addon.gproj": "231274e6b62302f32c65f9ff31de2ce8a9e51e1c8d12c87deeec82ae1f40de46",
"addons/intel/Scripts/Game/ERR/ERR_IntelService.c": "482839434b94e7f8c345d5fd96490aeebb765f3dd0c1bb25fceea2f435c0e722",
"addons/intel/addon.gproj": "d0ced242cefb220a5cccd6779d61fda9bc55581701b9f78bcf13c09d92ddbcbe",
"addons/map/Materials/ERRM_MapRenderTarget.emat": "9877c5b175c5f30dd80bea36c711b21ab38219aa7075adf9ae79932e1d4c76bc",
"addons/map/Materials/ERRM_MapRenderTarget.emat.meta": "5ee1a705f8011a44020ca2691f5ccc17d44bf596fef9a36e98d1f267eb58fab0",
"addons/map/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et": "30dee8e9eab459ea32a7d835a9fb89d43df47708057cab829f067b25a24cd581",
"addons/map/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et.meta": "59093e9072c50d99c86da7609c87541016da5bcf92b98d99db4c524e1c8e0e8d",
"addons/map/Scripts/Game/ERR/ERR_ScenarioMap.c": "75fa1d742129ef7f33c005cd48f56db7f49ee7bde3c5428532b0b501b032b0a3",
"addons/map/Scripts/Game/ERRMap/ERRM_SharedMapComponent.c": "fc1a0c7df4fc96da446d7542a45a10fbec1eda1e543ba2f0581cb772277a47c5",
"addons/map/UI/layouts/ERRMap/SharedMapRenderTarget.layout": "49a2da4181b94d42174f58c7f9b6bf2207116c99427d61ff1c212092ac7db4d2",
"addons/map/UI/layouts/ERRMap/SharedMapRenderTarget.layout.meta": "5c846445cc089e2e08899ba703059d4adb805ff30ab5a16409a3cd59718cbd54",
"addons/map/addon.gproj": "1b371e5e01ea9fa46e76570fecb8aaa3a9298e34cba7ccca8a6bdb5ca86eb46a"
}
@@ -0,0 +1,45 @@
{
"schema_version": 1,
"launch_id": "fd2f772d-e946-4722-b0e0-9000847a6a67",
"captured_unix": 1789799630.6427813,
"source_root": "/home/jakub/devel/escapistsrereintroduced",
"command": [
"gamescope",
"--backend",
"headless",
"-W",
"1280",
"-H",
"720",
"-w",
"1280",
"-h",
"720",
"-r",
"30",
"--",
"/home/jakub/.local/share/Steam/steamapps/common/Proton - Experimental/proton",
"run",
"/home/jakub/.local/share/Steam/steamapps/common/Arma Reforger Tools/Workbench/ArmaReforgerWorkbenchSteamDiag.exe",
"-gproj",
"Z:/home/jakub/devel/escapistsrereintroduced/addons/chat/addon.gproj",
"-addonsDir",
"Z:/home/jakub/devel/escapistsrereintroduced/addons",
"-profile",
"Z:/tmp/erri-workbench-profile",
"-logconsole",
"-wbModule=WorldEditor",
"-load",
"Worlds/ERR_Everon.ent",
"-plugin=ERR_ValidateWorldPlugin",
"-errPlay",
"1",
"-errSmoke",
"1",
"-errSmokeOutcome",
"mortar-fire",
"-noThrow",
"-disableCrashReporter"
],
"manifest_sha256": "765c0e51c7be74ab4caf116f40960328d1e31fcc8c433ef8bfbb39035abb77b4"
}
@@ -0,0 +1,9 @@
{
"log": "docs/evidence/2026-09-19-mortar-first-shot/console.log.txt",
"smoke_completions": 1,
"assertions_passed": 48,
"script_or_runtime_failures": [],
"engine_errors": [],
"missing_end_screen": [],
"scope": "scripted local Workbench integration only; no multiplayer, piloting or FPS claim"
}
@@ -0,0 +1,66 @@
#1 t=6.5s M0 REGISTER group 1 [session=1789799678-1]
#2 t=6.5s M0 MORTAR DEPLOY site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; authored gun and four-person crew; finite ammunition initialization pending [session=1789799678-1]
#3 t=7.5s M0 MORTAR SITE STATUS site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; claimed=1 startup=0 operational=1 crew agents=1 fighting=1 inventory HE=0 radio connected=0 cooldown remaining=0s [session=1789799678-1]
#4 t=7.5s M0 MORTAR ORDER STATUS site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; open=0 route pending=0 native action=-1 shell committed=0 order shots=0 total shots=0 age=7.48225s last failure= [session=1789799678-1]
#5 t=8.6s M0 REGISTER group 2 [session=1789799678-1]
#6 t=8.6s M0 REGISTER group 3 [session=1789799678-1]
#7 t=8.6s M0 REGISTER group 4 [session=1789799678-1]
#8 t=8.6s M0 REGISTER group 5 [session=1789799678-1]
#9 t=8.6s M0 REGISTER group 6 [session=1789799678-1]
#10 t=8.6s M0 REGISTER group 7 [session=1789799678-1]
#11 t=12.5s M0 MORTAR SITE STATUS site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; claimed=1 startup=0 operational=1 crew agents=4 fighting=4 inventory HE=0 radio connected=1 cooldown remaining=0s [session=1789799678-1]
#12 t=12.5s M0 MORTAR ORDER STATUS site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; open=0 route pending=0 native action=-1 shell committed=0 order shots=0 total shots=0 age=12.5255s last failure= [session=1789799678-1]
#13 t=17.6s M0 MORTAR SITE STATUS site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; claimed=1 startup=0 operational=1 crew agents=4 fighting=4 inventory HE=27 radio connected=1 cooldown remaining=0s [session=1789799678-1]
#14 t=17.6s M0 MORTAR ORDER STATUS site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; open=0 route pending=0 native action=-1 shell committed=0 order shots=0 total shots=0 age=17.5787s last failure= [session=1789799678-1]
#15 t=17.8s M0 MORTAR CREW READY site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; four original physical members, one manpack, 27 confirmed HE; new shell requests=27; allocation permanently closed [session=1789799678-1]
#16 t=18.1s M1 FIXTURE REPORT EXPLICIT SYNTHETIC OBSERVATION: X=5200 Z=6400: at least 1 spotted nearby; on foot; 0 km/h, azimuth 0 degrees (stationary); seen weapons: fixture observation; vector X/Z=[0,0] m/s (0s ago) [session=1789799678-1]
#17 t=18.8s M1 TRANSMIT unit 1 -> HQ (long-range) [session=1789799678-1]
#18 t=20.8s M1 RECEIVE HQ received from unit 1 [session=1789799678-1]
#19 t=22.6s M0 MORTAR SITE STATUS site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; claimed=1 startup=1 operational=1 crew agents=4 fighting=4 inventory HE=27 radio connected=1 cooldown remaining=0s [session=1789799678-1]
#20 t=22.6s M0 MORTAR ORDER STATUS site=1 order=0 radio=M0 source=M0 position=<6000,202.788,7000>; open=0 route pending=0 native action=-1 shell committed=0 order shots=0 total shots=0 age=22.644s last failure= [session=1789799678-1]
#21 t=22.8s M5 TRANSMIT HQ -> unit 6 (long-range) [session=1789799678-1]
#22 t=22.8s M4 TRANSMIT HQ -> unit 4 (long-range) [session=1789799678-1]
#23 t=22.8s M3 TRANSMIT HQ -> unit 3 (long-range) [session=1789799678-1]
#24 t=22.8s M2 TRANSMIT HQ -> unit 2 (long-range) [session=1789799678-1]
#25 t=24.8s M5 RECEIVE unit 6 received from HQ [session=1789799678-1]
#26 t=24.8s M5 ORDER DELIVERED group 6 from report M1: X=5200 Z=6400: at least 1 spotted nearby; on foot; 0 km/h, azimuth 0 degrees (stationary); seen weapons: fixture observation; vector X/Z=[0,0] m/s (7s ago) [session=1789799678-1]
#27 t=24.8s M4 RECEIVE unit 4 received from HQ [session=1789799678-1]
#28 t=24.8s M4 ORDER DELIVERED group 4 from report M1: X=5200 Z=6400: at least 1 spotted nearby; on foot; 0 km/h, azimuth 0 degrees (stationary); seen weapons: fixture observation; vector X/Z=[0,0] m/s (7s ago) [session=1789799678-1]
#29 t=24.8s M3 RECEIVE unit 3 received from HQ [session=1789799678-1]
#30 t=24.8s M3 ORDER DELIVERED group 3 from report M1: X=5200 Z=6400: at least 1 spotted nearby; on foot; 0 km/h, azimuth 0 degrees (stationary); seen weapons: fixture observation; vector X/Z=[0,0] m/s (7s ago) [session=1789799678-1]
#31 t=24.8s M2 RECEIVE unit 2 received from HQ [session=1789799678-1]
#32 t=24.8s M2 ORDER DELIVERED group 2 from report M1: X=5200 Z=6400: at least 1 spotted nearby; on foot; 0 km/h, azimuth 0 degrees (stationary); seen weapons: fixture observation; vector X/Z=[0,0] m/s (7s ago) [session=1789799678-1]
#33 t=26.8s M6 ORDER QUEUED MORTAR ORDER from report M1; X=5200 Z=6400: at least 1 spotted nearby; on foot; 0 km/h, azimuth 0 degrees (stationary); seen weapons: fixture observation; vector X/Z=[0,0] m/s (9s ago) [session=1789799678-1]
#34 t=26.8s M0 MORTAR COMMAND site=1 order=1 radio=M0 source=M1 position=<6000,202.788,7000>; requested rounds=8 HE radius=40m; X=5200 Z=6400: at least 1 spotted nearby; on foot; 0 km/h, azimuth 0 degrees (stationary); seen weapons: fixture observation; vector X/Z=[0,0] m/s (9s ago) [session=1789799678-1]
#35 t=27.7s M6 MORTAR SITE STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; claimed=1 startup=1 operational=1 crew agents=4 fighting=4 inventory HE=27 radio connected=1 cooldown remaining=0s [session=1789799678-1]
#36 t=27.7s M6 MORTAR ORDER STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; open=1 route pending=1 native action=-1 shell committed=0 order shots=0 total shots=0 age=0.8689s last failure= [session=1789799678-1]
#37 t=27.8s M6 TRANSMIT HQ -> unit 1 (long-range) [session=1789799678-1]
#38 t=29.8s M6 RECEIVE unit 1 received from HQ [session=1789799678-1]
#39 t=29.8s M6 MORTAR AIM site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; native activity created; latest source=M1 observed=X=5200 Z=6400: at least 1 spotted nearby; on foot; 0 km/h, azimuth 0 degrees (stationary); seen weapons: fixture observation; vector X/Z=[0,0] m/s (12s ago) [session=1789799678-1]
#40 t=30.8s M6 MORTAR ACTIVITY site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; reason=native state=1; age=1.00274s aim age=30.8386s committed=0 shots=0; previous= repeated polls omitted=0 [session=1789799678-1]
#41 t=32.7s M6 MORTAR SITE STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; claimed=1 startup=1 operational=1 crew agents=4 fighting=4 inventory HE=27 radio connected=1 cooldown remaining=27.1018s [session=1789799678-1]
#42 t=32.7s M6 MORTAR ORDER STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; open=1 route pending=0 native action=1 shell committed=0 order shots=0 total shots=0 age=2.89819s last failure= [session=1789799678-1]
#43 t=32.9s M6 MORTAR AIM START site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; reason=solving moving intercept; latest source=M1; X=5200 Z=6400: at least 1 spotted nearby; on foot; 0 km/h, azimuth 0 degrees (stationary); seen weapons: fixture observation; vector X/Z=[0,0] m/s (15s ago); previous= repeated polls omitted=0 [session=1789799678-1]
#44 t=32.9s M6 MORTAR AIM SOLUTION site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; reason=ready; predicted impact=<5207.07,78.6842,6387.75> flight=24.2333s charge index=2 aim target=<5207.07,2689.01,6387.75> latest source=M1; previous= repeated polls omitted=0 [session=1789799678-1]
#45 t=37.8s M6 MORTAR SITE STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; claimed=1 startup=1 operational=1 crew agents=4 fighting=4 inventory HE=27 radio connected=1 cooldown remaining=22.0531s [session=1789799678-1]
#46 t=37.8s M6 MORTAR ORDER STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; open=1 route pending=0 native action=1 shell committed=0 order shots=0 total shots=0 age=7.94694s last failure= [session=1789799678-1]
#47 t=42.8s M6 MORTAR SITE STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; claimed=1 startup=1 operational=1 crew agents=4 fighting=4 inventory HE=27 radio connected=1 cooldown remaining=16.9899s [session=1789799678-1]
#48 t=42.8s M6 MORTAR ORDER STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; open=1 route pending=0 native action=1 shell committed=0 order shots=0 total shots=0 age=13.0101s last failure= [session=1789799678-1]
#49 t=47.9s M6 MORTAR SITE STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; claimed=1 startup=1 operational=1 crew agents=4 fighting=4 inventory HE=27 radio connected=1 cooldown remaining=11.9519s [session=1789799678-1]
#50 t=47.9s M6 MORTAR ORDER STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; open=1 route pending=0 native action=1 shell committed=0 order shots=0 total shots=0 age=18.0481s last failure= [session=1789799678-1]
#51 t=52.9s M6 MORTAR SITE STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; claimed=1 startup=1 operational=1 crew agents=4 fighting=4 inventory HE=27 radio connected=1 cooldown remaining=6.89482s [session=1789799678-1]
#52 t=52.9s M6 MORTAR ORDER STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; open=1 route pending=0 native action=1 shell committed=0 order shots=0 total shots=0 age=23.1052s last failure= [session=1789799678-1]
#53 t=57.3s M6 MORTAR AIM REVALIDATED site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; reason=same native command; fresh ballistic solve matched original; source=M1 observed age=39.2116s; previous= repeated polls omitted=0 [session=1789799678-1]
#54 t=57.3s M6 MORTAR SHOOT NODE site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; reason=native result=2; authorization passed; node result does not confirm a physical shot; previous= repeated polls omitted=0 [session=1789799678-1]
#55 t=58s M6 MORTAR SITE STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; claimed=1 startup=1 operational=1 crew agents=4 fighting=4 inventory HE=27 radio connected=1 cooldown remaining=1.86609s [session=1789799678-1]
#56 t=58s M6 MORTAR ORDER STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; open=1 route pending=0 native action=1 shell committed=0 order shots=0 total shots=0 age=28.1339s last failure= [session=1789799678-1]
#57 t=58.2s M6 MORTAR SHELL COMMIT site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; final safety passed; gunner=SCR_ChimeraCharacter<0x00000001BBD4D770> @"ENTITY:4611686018427390717" ('SCR_ChimeraCharacter','Assets/Characters/Basebody/Basebody_Male_01.xob') at <5999.121094 202.731979 7000.143555> @"{86E565387A634103}Prefabs/Characters/Campaign/Final/OPFOR/USSR_Army/Regular/Campaign_USSR_Player_MortarCrew.et" predicted impact=<5207.07,78.6842,6387.75> flight=24.2333s; invoking native transfer, awaiting projectile event [session=1789799678-1]
#58 t=59.2s M6 MORTAR FIRED site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; physical projectile=Projectile<0x000000019F269600> @"ENTITY:4611686018427390926" ('Projectile','Assets/Weapons/Ammo/Shells/82mm_Mortar_2B14/Shell_82mm_HE_O832DU.xob') at <5999.590820 204.000366 6999.681641> @"{98EC9C526AFBA282}Prefabs/Weapons/Ammo/Ammo_Shell_82mm_HE_O832DU.et" origin=<5999.59,204,6999.68> order shots=1 total shots=1 predicted impact=<5207.07,78.6842,6387.75> predicted flight=24.2333s gunner=SCR_ChimeraCharacter<0x00000001BBD4D770> @"ENTITY:4611686018427390717" ('SCR_ChimeraCharacter','Assets/Characters/Basebody/Basebody_Male_01.xob') at <5999.121094 202.734802 7000.143555> @"{86E565387A634103}Prefabs/Characters/Campaign/Final/OPFOR/USSR_Army/Regular/Campaign_USSR_Player_MortarCrew.et" (impact not observed) [session=1789799678-1]
#59 t=59.5s M6 MORTAR REPEATS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; phase=ACTIVITY reason=native state=1 repeated polls omitted=28 [session=1789799678-1]
#60 t=59.5s M6 MORTAR ORDER END site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; reason=HQ stopped observed shots=1 shell committed=0 elapsed=29.6502s last failure= [session=1789799678-1]
#61 t=63s M6 MORTAR SITE STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; claimed=1 startup=1 operational=0 crew agents=4 fighting=4 inventory HE=26 radio connected=1 cooldown remaining=0s [session=1789799678-1]
#62 t=63s M6 MORTAR ORDER STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; open=0 route pending=0 native action=-1 shell committed=0 order shots=1 total shots=1 age=33.1751s last failure= [session=1789799678-1]
#63 t=63s M6 MORTAR SITE BLOCK site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; reason=battery stopped; spawn failure=; previous= repeated polls omitted=0 [session=1789799678-1]
#64 t=68.1s M6 MORTAR SITE STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; claimed=1 startup=1 operational=0 crew agents=4 fighting=4 inventory HE=26 radio connected=1 cooldown remaining=0s [session=1789799678-1]
#65 t=68.1s M6 MORTAR ORDER STATUS site=1 order=1 radio=M6 source=M1 position=<6000,202.788,7000>; open=0 route pending=0 native action=-1 shell committed=0 order shots=1 total shots=1 age=38.2199s last failure= [session=1789799678-1]
#66 t=71.6s M0 STOP HQ stopped; tactical orders released [session=1789799678-1]
@@ -0,0 +1,19 @@
{
"stopped_unix": 1789799758.8077834,
"console_sha256": "c7ddf6da7e620085c8617aa24788769f61b6117dd7b9b70969de09034e15f32f",
"end_source_sha256": "765c0e51c7be74ab4caf116f40960328d1e31fcc8c433ef8bfbb39035abb77b4",
"source_unchanged_after_run": true,
"source_provenance": "launch_snapshot",
"launch_id": "fd2f772d-e946-4722-b0e0-9000847a6a67",
"launch_source_manifest": "launch-source-sha256.json",
"launch_source_metadata": "launch-source.json",
"launch_source_sha256": "765c0e51c7be74ab4caf116f40960328d1e31fcc8c433ef8bfbb39035abb77b4",
"started_unix": 1789799630.6428425,
"result": "smoke-completed",
"session": "/tmp/erri-workbench-profile/logs/logs_2026-09-19_08-33-52",
"rounds_required": 1,
"project": "chat",
"display": "headless Gamescope 1280x720/30Hz",
"dedicated_server": false,
"audio": "silent sink and per-test-stream mute"
}
@@ -0,0 +1,315 @@
---------------------------------------------
Log Z:\tmp\erri-workbench-profile\logs\logs_2026-09-19_08-33-52\script.log started at 2026-09-19 08:33:55 (2026-09-19 06:33:55 UTC)
08:33:55.242 SCRIPT : SCRIPT : Initializing scripts
08:33:55.242 SCRIPT : SCRIPT : ScriptProjectManager init
08:33:57.504 SCRIPT : SCRIPT : Compiling GameLib scripts
08:33:57.574 SCRIPT : Module: Workbench; loaded 18x files; 36x classes; used 125K of static memory; defines: "ENF_WB,WORKBENCH,PLATFORM_WINDOWS,ENABLE_DIAG,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE"; CRC32: 90ce0460
08:33:57.574 SCRIPT : Module: GameLib; loaded 466x files; 648x classes; used 828K of static memory; defines: "ENF_WB,WORKBENCH,PLATFORM_WINDOWS,ENABLE_DIAG,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE"; CRC32: d66caacb
08:33:57.575 SCRIPT : SCRIPT : Compiling Game scripts
08:33:58.882 SCRIPT : Compiling Game scripts
08:33:58.882 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,785": 'GetPlayerPlatformKind' is obsolete
08:33:58.882 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,786": 'GetPlayerPlatformId' is obsolete
08:33:59.018 SCRIPT (W): @"Scripts/Game/ERR/ERR_SiteService.c,191": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.153 SCRIPT (W): @"Scripts/Game/Workshop/SCR_AddonManager.c,876": 'GetRefCount' is obsolete: Will be removed
08:33:59.185 SCRIPT (W): @"Scripts/Game/Campaign/SCR_PlayerProfileManagerComponent.c,142": 'PlayerData' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,159": 'GetDSSession' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,162": 'RoomID' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,197": 'GetDSSession' is obsolete
08:33:59.285 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,201": 'RoomID' is obsolete
08:33:59.322 SCRIPT (W): @"Scripts/Game/ERR/ERR_CasualtyGroundSupport.c,21": 'GetBoneIndex' is obsolete: Use GetAnimation().GetBoneIndex() instead
08:33:59.383 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,481": 'GetStorage' is obsolete
08:33:59.383 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,483": 'GetOnlineWritePrivilege' is obsolete
08:33:59.388 SCRIPT (W): @"Scripts/Game/Utilities/SCR_PlayerIdentityUtils.c,20": 'GetPlayerIdentityId' is obsolete
08:33:59.427 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,45": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.427 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,56": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.428 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,643": 'GetNotifyCount' is obsolete: Will be substitued by Notification Api.
08:33:59.428 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,645": 'GetNotifyItem' is obsolete: Will be substitued by Notification Api.
08:33:59.455 SCRIPT (W): @"Scripts/Game/ERR/ERR_NativeTransportProbe.c,82": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:33:59.488 SCRIPT (W): @"Scripts/Game/DataCollection/PlayerData/SCR_PlayerData.c,210": 'PlayerData' is obsolete
08:33:59.750 SCRIPT : Module: WorkbenchGame; loaded 172x files; 617x classes; used 2483K of static memory; defines: "ENF_WB,WORKBENCH,PLATFORM_WINDOWS,ENABLE_DIAG,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE"; CRC32: e963af0e
08:33:59.756 SCRIPT : Module: Game; loaded 5759x files; 11304x classes; used 33167K of static memory; defines: "ENF_WB,WORKBENCH,PLATFORM_WINDOWS,ENABLE_DIAG,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE,ENABLE_BASE_DESTRUCTION,BUDGET_OPTIMIZATION_CHECKS,SHOW_DISCLAIMER,DEBUG,RESPAWN_TIMER_COMPONENT_DEBUG,GAME_MODE_DEBUG,DEBUG_CONFIGURABLE_DIALOGS,DISABLE_WEAPON_SWITCHING,SCRIPTED_AIM_MODIFIER_DEBUG"; CRC32: 38d29813
08:34:00.724 SCRIPT : Unable to register a script command due keyword duplicity: ban
08:34:00.724 SCRIPT : Unable to register a script command due keyword duplicity: kick
08:34:21.496 SCRIPT : ERR VALIDATION: prison terrain=211.344, radio terrain=159.656, extraction terrain=65.1562
08:34:21.496 SCRIPT : ERR TERRAIN: x=6084 z=7154 y=211.531
08:34:21.496 SCRIPT : ERR TERRAIN: x=6084 z=7157 y=211.516
08:34:21.496 SCRIPT : ERR TERRAIN: x=6084 z=7160 y=211.5
08:34:21.497 SCRIPT : ERR TERRAIN: x=6084 z=7163 y=211.453
08:34:21.497 SCRIPT : ERR TERRAIN: x=6084 z=7166 y=211.406
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7154 y=211.438
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7157 y=211.438
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7160 y=211.422
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7163 y=211.391
08:34:21.497 SCRIPT : ERR TERRAIN: x=6087 z=7166 y=211.344
08:34:21.497 SCRIPT : ERR TERRAIN: x=6090 z=7154 y=211.344
08:34:21.497 SCRIPT : ERR TERRAIN: x=6090 z=7157 y=211.344
08:34:21.497 SCRIPT : ERR TERRAIN: x=6090 z=7160 y=211.344
08:34:21.497 SCRIPT : ERR TERRAIN: x=6090 z=7163 y=211.328
08:34:21.498 SCRIPT : ERR TERRAIN: x=6090 z=7166 y=211.281
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7154 y=211.25
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7157 y=211.281
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7160 y=211.25
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7163 y=211.234
08:34:21.498 SCRIPT : ERR TERRAIN: x=6093 z=7166 y=211.188
08:34:21.498 SCRIPT : ERR TERRAIN: x=6096 z=7154 y=211.156
08:34:21.498 SCRIPT : ERR TERRAIN: x=6096 z=7157 y=211.172
08:34:21.498 SCRIPT : ERR TERRAIN: x=6096 z=7160 y=211.156
08:34:21.499 SCRIPT : ERR TERRAIN: x=6096 z=7163 y=211.141
08:34:21.499 SCRIPT : ERR TERRAIN: x=6096 z=7166 y=211.094
08:34:21.520 SCRIPT : ERR SITE CANDIDATE: position=<6090,211.344,7160> elevationRange=0.640625
08:34:24.887 SCRIPT : Unable to register a script command due keyword duplicity: ban
08:34:24.887 SCRIPT : Unable to register a script command due keyword duplicity: kick
08:34:38.450 SCRIPT (W): SCR_PerceivedFactionManagerComponent trying to set fall back faction 'CIV' but this faction could not be found so it is null instead.
08:34:38.474 SCRIPT : ERR SMOKE: scripted integration test enabled; gameplay acceptance remains separate
08:34:39.013 SCRIPT (W): Notification data in 'SCR_NotificationsLogDisplay' has duplicate notification info key: 'EDITOR_PERCEIVED_FACTION_PUNISHMENT_KILLING_SET'. There should only be one of each key!
08:34:39.013 SCRIPT (W): Notification data in 'SCR_NotificationsLogDisplay' has duplicate notification info key: 'EDITOR_PERCEIVED_FACTION_TYPE_DISABLED'. There should only be one of each key!
08:34:39.015 SCRIPT (W): Can't open config file ""
08:34:39.022 SCRIPT (W): Slot_WeaponInfo Has no Content!
08:34:39.022 SCRIPT (W): Slot_Chat Has no Content!
08:34:39.023 SCRIPT (W): Slot_VON Has no Content!
08:34:39.023 SCRIPT (W): Slot_AvailableActions Has no Content!
08:34:39.023 SCRIPT (W): Slot_Vehicle Has no Content!
08:34:39.023 SCRIPT (W): Slot_GameVersion Has no Content!
08:34:39.023 SCRIPT (W): Slot_Notifications Has no Content!
08:34:39.023 SCRIPT (W): Slot_Hints Has no Content!
08:34:39.036 SCRIPT (W): SCR_EntityCatalogManagerComponent.GetFilteredEditorPrefabsOfAllFactions: Detected that {259EE7B78C51B624}UAZ469.et is present in at least two different faction entity catalogs! Since this may cause issues, such as dupliacted entries in build mode, one of them will be discarded! This is only supported for items. Other things require creation of faction specific variants.
08:34:39.036 SCRIPT (W): SCR_EntityCatalogManagerComponent.GetFilteredEditorPrefabsOfAllFactions: Detected that {DF5CCB7C0FF049F4}Mi8MT_unarmed_transport.et is present in at least two different faction entity catalogs! Since this may cause issues, such as dupliacted entries in build mode, one of them will be discarded! This is only supported for items. Other things require creation of faction specific variants.
08:34:39.039 SCRIPT (W): Ban Settings could not be loaded from BE Storage: Relying on default config
08:34:39.093 SCRIPT : ScenarioFramework: Available tasks are empty, no new tasks will be generated.
08:34:39.107 SCRIPT : SCR_BaseGameMode::OnGameStateChanged = GAME
08:34:39.281 SCRIPT (W): EditBoxFilterComponent used on invalid widget type.
08:34:40.811 SCRIPT : Rereintroduced [sites]: cache clearance position=<6086,211.538,7160> clear=1
08:34:40.836 SCRIPT : Rereintroduced [sites]: authored everon-prison-1 at <6090,211.444,7160>
08:34:40.837 SCRIPT : Rereintroduced [sites]: cache clearance position=<6150,203.288,7050> clear=1
08:34:40.868 SCRIPT : Rereintroduced [sites]: authored everon-supply-1 at <6150,203.288,7050>
08:34:40.870 SCRIPT : Rereintroduced [sites]: authored everon-radio-1 at <6500,159.756,7200>
08:34:40.931 SCRIPT : Rereintroduced [sites]: authored everon-extraction-1 at <7000,65.2562,7500>
08:34:40.931 SCRIPT : Rereintroduced [sites]: cache clearance position=<5960,220.256,7220> clear=1
08:34:40.939 SCRIPT : Rereintroduced [sites]: transport parking=<5960,220.256,7212> radius=4 terrainRange=0.8125 obstructed=0 clear=1
08:34:40.992 SCRIPT : Rereintroduced [sites]: authored everon-supply-2 at <5960,220.256,7220>
08:34:40.993 SCRIPT : Rereintroduced [sites]: cache clearance position=<6340,175.788,7400> clear=1
08:34:40.995 SCRIPT : Rereintroduced [sites]: authored everon-medical-1 at <6340,175.788,7400>
08:34:40.995 SCRIPT : Rereintroduced [sites]: cache clearance position=<6740,140.6,7300> clear=1
08:34:40.999 SCRIPT : Rereintroduced [sites]: cache clearance position=<6740,140.913,7296> clear=1
08:34:41.001 SCRIPT : Rereintroduced [sites]: cache clearance position=<6736,140.975,7300> clear=1
08:34:41.001 SCRIPT : Rereintroduced [sites]: cache clearance position=<6744,140.288,7300> clear=1
08:34:41.002 SCRIPT : Rereintroduced [sites]: authored everon-outpost-1 at <6740,140.6,7300>
08:34:41.002 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=0 origin=<7012,63.725,7500> up=1
08:34:41.002 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0 angularSpeed=0
08:34:41.003 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=0 engine=0 origin=<0,0,0> up=1 entityDifference=10267.5
08:34:41.003 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012,64.0216,7502.25>
08:34:41.003 SCRIPT : ERR GEAR TERRAIN: bottom=<7012,63.7216,7502.25> terrainY=63.2926 tireTerrainGap=0.428944
08:34:41.003 SCRIPT : ERR GEAR SUPPORT: center=<7012,64.0216,7502.25> radius=0.3 bottom=<7012,63.7216,7502.25> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:34:41.003 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.72,64.4897,7497.97>
08:34:41.004 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.72,64.0397,7497.97> terrainY=64.1655 tireTerrainGap=-0.125717
08:34:41.004 SCRIPT : ERR GEAR SUPPORT: center=<7009.72,64.4897,7497.97> radius=0.45 bottom=<7009.72,64.0397,7497.97> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:34:41.004 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.28,64.4898,7497.97>
08:34:41.004 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.28,64.0398,7497.97> terrainY=63.8096 tireTerrainGap=0.230156
08:34:41.004 SCRIPT : ERR GEAR SUPPORT: center=<7014.28,64.4898,7497.97> radius=0.45 bottom=<7014.28,64.0398,7497.97> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:34:41.004 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.005 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:34:41.843 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:41.844 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:41.844 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:41.844 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:42.094 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.08,63.5298,7499.7> up=0.99566
08:34:42.094 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.314761 angularSpeed=0.054178
08:34:42.094 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:42.095 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.06,63.6151,7501.98>
08:34:42.095 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.06,63.3151,7501.98> terrainY=63.3158 tireTerrainGap=-0.000720978
08:34:42.095 SCRIPT : ERR GEAR SUPPORT: center=<7012.06,63.6151,7501.98> radius=0.3 bottom=<7012.06,63.3151,7501.98> fraction=0.451541 normal=<-0,0.990257,0.139255> self=0 dynamic=0 supported=1 gap=-0.000659943
08:34:42.095 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.88,64.6035,7497.71>
08:34:42.095 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.88,64.1535,7497.71> terrainY=64.156 tireTerrainGap=-0.00251007
08:34:42.096 SCRIPT : ERR GEAR SUPPORT: center=<7009.88,64.6035,7497.71> radius=0.45 bottom=<7009.88,64.1535,7497.71> fraction=0.443634 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=-0.00239563
08:34:42.096 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.42,64.2636,7497.75>
08:34:42.096 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.42,63.8136,7497.75> terrainY=63.8176 tireTerrainGap=-0.00397873
08:34:42.096 SCRIPT : ERR GEAR SUPPORT: center=<7014.42,64.2636,7497.75> radius=0.45 bottom=<7014.42,63.8136,7497.75> fraction=0.436389 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00399399
08:34:42.096 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:42.347 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:42.347 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:42.348 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:42.348 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:34:42.849 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:42.850 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:42.850 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:43.100 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.09,63.5333,7499.72> up=0.994184
08:34:43.100 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.0956389 angularSpeed=0.0274173
08:34:43.100 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:43.100 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.06,63.6188,7501.99>
08:34:43.100 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.06,63.3188,7501.99> terrainY=63.3138 tireTerrainGap=0.00501251
08:34:43.100 SCRIPT : ERR GEAR SUPPORT: center=<7012.06,63.6188,7501.99> radius=0.3 bottom=<7012.06,63.3188,7501.99> fraction=0.477311 normal=<-0,0.990257,0.139255> self=0 dynamic=0 supported=1 gap=0.0050087
08:34:43.101 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.92,64.6035,7497.72>
08:34:43.101 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.92,64.1535,7497.72> terrainY=64.1496 tireTerrainGap=0.00389862
08:34:43.101 SCRIPT : ERR GEAR SUPPORT: center=<7009.92,64.6035,7497.72> radius=0.45 bottom=<7009.92,64.1535,7497.72> fraction=0.472503 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00395203
08:34:43.101 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.46,64.2654,7497.79>
08:34:43.101 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.46,63.8154,7497.79> terrainY=63.8152 tireTerrainGap=0.000133514
08:34:43.101 SCRIPT : ERR GEAR SUPPORT: center=<7014.46,64.2654,7497.79> radius=0.45 bottom=<7014.46,63.8154,7497.79> fraction=0.455 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=9.91821e-05
08:34:43.102 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:43.352 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:43.353 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:43.353 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:34:43.353 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:43.607 SCRIPT : Rereintroduced [extraction placement]: native supported aircraft stable for one second, fuel present, exactly one initial wake
08:34:43.858 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:43.858 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:43.859 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:43.859 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=3 conscious=3 nativeComplete=0
08:34:44.180 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.11,63.5324,7499.74> up=0.993868
08:34:44.181 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.0420608 angularSpeed=0.0613614
08:34:44.181 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:44.181 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.07,63.6135,7502.01>
08:34:44.181 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.07,63.3135,7502.01> terrainY=63.3116 tireTerrainGap=0.00194168
08:34:44.181 SCRIPT : ERR GEAR SUPPORT: center=<7012.07,63.6135,7502.01> radius=0.3 bottom=<7012.07,63.3135,7502.01> fraction=0.463272 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00191879
08:34:44.182 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.96,64.5949,7497.72>
08:34:44.182 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.96,64.1449,7497.72> terrainY=64.1435 tireTerrainGap=0.0014267
08:34:44.182 SCRIPT : ERR GEAR SUPPORT: center=<7009.96,64.5949,7497.72> radius=0.45 bottom=<7009.96,64.1449,7497.72> fraction=0.461582 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00154877
08:34:44.182 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.5,64.26,7497.83>
08:34:44.182 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.5,63.81,7497.83> terrainY=63.8127 tireTerrainGap=-0.00266647
08:34:44.183 SCRIPT : ERR GEAR SUPPORT: center=<7014.5,64.26,7497.83> radius=0.45 bottom=<7014.5,63.81,7497.83> fraction=0.442222 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00271225
08:34:44.183 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:44.183 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:44.184 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:44.184 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:44.184 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:44.683 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:44.683 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:44.684 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:44.684 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:34:45.190 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.12,63.5283,7499.74> up=0.993815
08:34:45.190 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=0 speed=0 angularSpeed=0
08:34:45.191 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:45.191 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.07,63.6126,7502.01>
08:34:45.191 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.07,63.3126,7502.01> terrainY=63.3113 tireTerrainGap=0.00128174
08:34:45.191 SCRIPT : ERR GEAR SUPPORT: center=<7012.07,63.6126,7502.01> radius=0.3 bottom=<7012.07,63.3126,7502.01> fraction=0.46034 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00127411
08:34:45.192 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5947,7497.72>
08:34:45.192 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1447,7497.72> terrainY=64.1421 tireTerrainGap=0.00263214
08:34:45.192 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5947,7497.72> radius=0.45 bottom=<7009.97,64.1447,7497.72> fraction=0.466891 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00271606
08:34:45.192 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.2603,7497.84>
08:34:45.193 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.8103,7497.84> terrainY=63.8121 tireTerrainGap=-0.00181198
08:34:45.193 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.2603,7497.84> radius=0.45 bottom=<7014.51,63.8103,7497.84> fraction=0.446111 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00185394
08:34:45.193 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:45.193 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:45.194 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:45.194 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:45.194 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:34:45.696 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:45.697 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:45.697 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:45.697 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:46.198 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.12,63.5283,7499.74> up=0.993815
08:34:46.199 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=0 speed=0 angularSpeed=0
08:34:46.199 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:34:46.199 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.07,63.6126,7502.01>
08:34:46.199 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.07,63.3126,7502.01> terrainY=63.3113 tireTerrainGap=0.00128174
08:34:46.199 SCRIPT : ERR GEAR SUPPORT: center=<7012.07,63.6126,7502.01> radius=0.3 bottom=<7012.07,63.3126,7502.01> fraction=0.46034 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00127411
08:34:46.200 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5947,7497.72>
08:34:46.200 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1447,7497.72> terrainY=64.1421 tireTerrainGap=0.00263214
08:34:46.200 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5947,7497.72> radius=0.45 bottom=<7009.97,64.1447,7497.72> fraction=0.466891 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00271606
08:34:46.200 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.2603,7497.84>
08:34:46.200 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.8103,7497.84> terrainY=63.8121 tireTerrainGap=-0.00181198
08:34:46.201 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.2603,7497.84> radius=0.45 bottom=<7014.51,63.8103,7497.84> fraction=0.446111 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00185394
08:34:46.201 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:34:46.201 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:34:46.202 SCRIPT : Rereintroduced [sites]: 7 sites and 117 physical stock items ready
08:34:46.212 SCRIPT : Rereintroduced [environment]: date=authored weather=authored
08:34:46.213 SCRIPT : Rereintroduced [time]: started at 14:00 with 1x progression
08:34:46.213 SCRIPT : Rereintroduced [mission]: phase 0 -> 1
08:34:46.358 SCRIPT : INFO: Faction: player jakub (playerID = 1 | UUID = 00000000-0000-0000-0000-000000000000) has joined faction #AR-Faction_US (US)
08:34:46.398 SCRIPT : Rereintroduced [spawn]: player 1 at <6088.5,211.491,7158.5>
08:34:46.631 SCRIPT : ERR SMOKE PASS: new identity may enter prison
08:34:46.631 SCRIPT : ERR SMOKE PASS: spawn consumes identity life
08:34:46.632 SCRIPT : ERR SMOKE PASS: disconnect retains living actor and clears connection
08:34:46.632 SCRIPT : ERR SMOKE PASS: reconnected identity retains spent life
08:34:46.632 SCRIPT : ERR SMOKE PASS: duplicate active identity rejected
08:34:46.632 SCRIPT : ERR SMOKE PASS: recycled connection receives independent life and extraction admission policy
08:34:46.632 SCRIPT : ERR SMOKE PASS: base contracts catalog resolves hostile vanilla factions and successful preparation
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts physical prisoner matches injected faction and resource
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts physical guard squad comes from injected catalog
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts same-side factions rejected
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts unknown world faction rejected
08:34:46.633 SCRIPT : ERR SMOKE PASS: base contracts missing prisoner resource rejected
08:34:46.634 SCRIPT : ERR SMOKE PASS: base contracts isolated catalog restored without mutating live configuration
08:34:46.634 SCRIPT : ERR SMOKE PASS: base contracts unauthorized settings request rejected
08:34:46.634 SCRIPT : ERR SMOKE PASS: base contracts partially numeric input rejected without mutation
08:34:46.634 SCRIPT : ERR SMOKE PASS: base contracts out-of-range duration rejected without mutation
08:34:46.637 SCRIPT : ERR SMOKE PASS: base contracts normalized base command saves validated duration
08:34:46.637 SCRIPT : ERR SMOKE PASS: base contracts base command reads saved duration
08:34:46.637 SCRIPT : ERR SMOKE PASS: base contracts base settings listing available
08:34:46.637 SCRIPT : ERR SMOKE PASS: base contracts base mission status available before companions
08:34:46.639 SCRIPT : ERR SMOKE PASS: base contracts test setting restored
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: hq interval show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: hq squads show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: hq radius show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: intel carrying show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion command retained: intel reveal show
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion journal is behind Core admin authorization
08:34:46.640 SCRIPT : ERR SMOKE PASS: companion HQ status uses the shared command service
08:34:47.139 SCRIPT : ERR MORTAR FIXTURE: step=0 startup=0 source=M0 observedEvents=0 ready=1 failure=
08:34:52.182 SCRIPT : ERR MORTAR FIXTURE: step=0 startup=0 source=M0 observedEvents=0 ready=1 failure=
08:34:57.235 SCRIPT : ERR MORTAR FIXTURE: step=0 startup=0 source=M0 observedEvents=0 ready=1 failure=
08:34:57.746 SCRIPT : ERR SMOKE PASS: mortar firing untasked original gun and complete four-person crew start without shots
08:34:57.746 SCRIPT : ERR SMOKE PASS: mortar firing initial physical crew member is conscious and unique
08:34:57.747 SCRIPT : ERR SMOKE PASS: mortar firing initial physical crew member is conscious and unique
08:34:57.747 SCRIPT : ERR SMOKE PASS: mortar firing initial physical crew member is conscious and unique
08:34:57.747 SCRIPT : ERR SMOKE PASS: mortar firing initial physical crew member is conscious and unique
08:34:57.747 SCRIPT : ERR SMOKE PASS: mortar firing dedicated actual manpack supplies the radio route
08:34:57.748 SCRIPT : ERR SMOKE PASS: mortar firing exactly 27 distinct physical initial HE shells
08:34:57.764 SCRIPT : ERR MORTAR FIXTURE IMPACT: position=<5200,80.1937,6400> batteryDistance=1000; no characters/vehicles in 400m square; production settlement/friendly exclusions passed
08:34:57.764 SCRIPT : ERR SMOKE PASS: mortar firing bounded candidate survey finds an unoccupied production-safe impact area
08:34:57.764 SCRIPT : ERR SMOKE PASS: mortar firing fixture-owned inert report identity exists; no enemy perception is claimed
08:34:57.765 SCRIPT : ERR SMOKE PASS: mortar firing synthetic observation enters actual existing radio uplink once
08:35:02.301 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:07.341 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:12.390 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:17.439 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:22.503 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:27.540 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:32.598 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:37.627 SCRIPT : ERR MORTAR FIXTURE: step=1 startup=1 source=M1 observedEvents=0 ready=1 failure=
08:35:38.872 SCRIPT : ERR MORTAR FIXTURE PROJECTILE: event=1 entity=Projectile<0x000000019F269600> @"ENTITY:4611686018427390926" ('Projectile','Assets/Weapons/Ammo/Shells/82mm_Mortar_2B14/Shell_82mm_HE_O832DU.xob') at <5999.590820 204.000366 6999.681641> @"{98EC9C526AFBA282}Prefabs/Weapons/Ammo/Ammo_Shell_82mm_HE_O832DU.et" origin=<5999.59,204,6999.68> order=1 source=M1 aimAge=1909.73 flight=24.2333; impact is not measured
08:35:39.144 SCRIPT : ERR SMOKE PASS: mortar firing one physical projectile follows real uplink/downlink, native activity and fresh aim
08:35:39.145 SCRIPT : ERR SMOKE PASS: mortar firing one fired projectile consumes one of 27 original inventory shells
08:35:39.145 SCRIPT : ERR SMOKE PASS: mortar firing explicit support Stop closes native order and route idempotently
08:35:42.668 SCRIPT : ERR MORTAR FIXTURE: step=2 startup=1 source=M1 observedEvents=1 ready=0 failure=
08:35:47.713 SCRIPT : ERR MORTAR FIXTURE: step=2 startup=1 source=M1 observedEvents=1 ready=0 failure=
08:35:51.256 SCRIPT : ERR SMOKE PASS: mortar firing stopped service issues no duplicate order, projectile or replenishment over 12 seconds
08:35:51.256 SCRIPT : ERR SMOKE PASS: mortar firing original group and gun retain four crew
08:35:51.256 SCRIPT : ERR SMOKE PASS: mortar firing final conscious crew entity belongs to original physical roster
08:35:51.256 SCRIPT : ERR SMOKE PASS: mortar firing final conscious crew entity belongs to original physical roster
08:35:51.257 SCRIPT : ERR SMOKE PASS: mortar firing final conscious crew entity belongs to original physical roster
08:35:51.257 SCRIPT : ERR SMOKE PASS: mortar firing final conscious crew entity belongs to original physical roster
08:35:51.257 SCRIPT : Rereintroduced [mission]: phase 1 -> 6
08:35:51.257 SCRIPT : ERR SMOKE PASS: native mortar first shot and stop complete before explicit reset
08:35:51.257 SCRIPT : ERR SMOKE COMPLETE: native HQ radio to first mortar projectile and explicit stop; fixture reset requested
08:35:51.365 SCRIPT : SCR_BaseGameMode::OnGameStateChanged = POSTGAME
08:35:51.367 SCRIPT (W): Slot_Chat Has no Content!
08:35:51.367 SCRIPT (W): Slot_VON Has no Content!
08:35:51.368 SCRIPT (W): Slot_GameVersion Has no Content!
08:35:51.368 SCRIPT (W): Slot_Notifications Has no Content!
08:35:53.422 SCRIPT (W): SCR_ScriptedWidgetComponent.GetComponent: widget not found: SCR_InputButtonComponent Back
08:35:53.423 SCRIPT : -- Stack trace --
08:35:53.423 SCRIPT : GetComponent() Scripts/Game/UI/Components/WidgetLibrary/SCR_ScriptedWidgetComponent.c : 43
08:35:53.423 SCRIPT : GetInputButtonComponent() Scripts/Game/UI/Components/WidgetLibrary/SCR_InputButton/SCR_InputButtonComponent.c : 1214
08:35:53.423 SCRIPT : OnMenuOpen() Scripts/Game/UI/GameOverScreen/SCR_GameOverScreenInput.c : 15
08:35:53.423 SCRIPT : OpenGameOverScreen() Scripts/Game/GameOverScreen/SCR_GameOverScreenManagerComponent.c : 447
08:35:53.423 SCRIPT : ShowGameOverScreen() Scripts/Game/GameOverScreen/SCR_GameOverScreenManagerComponent.c : 177
08:35:53.423 SCRIPT : OnUpdate() Scripts/Game/game.c : 885
08:35:53.423 SCRIPT : -----------------
08:35:53.423 SCRIPT (W): SCR_ScriptedWidgetComponent.GetComponent: widget not found: SCR_InputButtonComponent ChatButton
08:35:53.424 SCRIPT : -- Stack trace --
08:35:53.424 SCRIPT : GetComponent() Scripts/Game/UI/Components/WidgetLibrary/SCR_ScriptedWidgetComponent.c : 43
08:35:53.424 SCRIPT : GetInputButtonComponent() Scripts/Game/UI/Components/WidgetLibrary/SCR_InputButton/SCR_InputButtonComponent.c : 1214
08:35:53.424 SCRIPT : OnMenuOpen() Scripts/Game/UI/GameOverScreen/SCR_GameOverScreenInput.c : 21
08:35:53.424 SCRIPT : OpenGameOverScreen() Scripts/Game/GameOverScreen/SCR_GameOverScreenManagerComponent.c : 447
08:35:53.424 SCRIPT : ShowGameOverScreen() Scripts/Game/GameOverScreen/SCR_GameOverScreenManagerComponent.c : 177
08:35:53.424 SCRIPT : OnUpdate() Scripts/Game/game.c : 885
08:35:53.424 SCRIPT : -----------------
08:35:53.426 SCRIPT (W): Slot_Chat Has no Content!
08:35:53.426 SCRIPT (W): Slot_VON Has no Content!
08:35:53.427 SCRIPT (W): Slot_GameVersion Has no Content!
08:35:53.427 SCRIPT (W): Slot_Notifications Has no Content!
@@ -0,0 +1,4 @@
{
"schema_version": 1,
"kind": "launch_snapshot"
}
@@ -0,0 +1,164 @@
{
"addons/ai/Prefabs/ERR/MortarCrew.et": "05d3e7353ff9fe5523218a1487b31b7b742b0be8adbcb060c7099978cf008bce",
"addons/ai/Prefabs/ERR/MortarCrew.et.meta": "fdfd4fcd21a67c3d698fa4aadc4e5c76e665cebf4be86013bc389e493fab63cc",
"addons/ai/Scripts/Game/ERR/ERR_HQ.c": "ceafd6740ed277748744ce56ac0f0bb3a8521fcc060dafb2cdb99896aedf405a",
"addons/ai/Scripts/Game/ERR/ERR_HQJournal.c": "b3e402cfe92d415f37f666045afb062e6e11670ba03a0ca6f2d9fd4fc3520ac1",
"addons/ai/Scripts/Game/ERR/ERR_HQNetwork.c": "92ff2caca52e94c2cc9642dfc8509ce6e9349b257012bade8650bace9231128c",
"addons/ai/Scripts/Game/ERR/ERR_HQObservation.c": "36c978ec5f052213ac1236e1398d85063efbfd7ef60fe04f1fc11447fefe1d68",
"addons/ai/Scripts/Game/ERR/ERR_HQReport.c": "c4d16ccb571db4d9444c0a8d2be7318845d25ff90238b6d304e96a9ea19f1a08",
"addons/ai/Scripts/Game/ERR/ERR_HelicopterAvailability.c": "60eaef2f6d4b2fd44861c5a4434ef97e732e40a5ff7401e2da451ed2dd9c2762",
"addons/ai/Scripts/Game/ERR/ERR_MortarAimSolution.c": "59f8052c2038072deb90623aad4bd750088499aae1d2754c72a770bf836a800a",
"addons/ai/Scripts/Game/ERR/ERR_MortarBattery.c": "e4589e5af55701f8c1f7f33e0a49e45f34b073bfddbdc87e009bea69af683828",
"addons/ai/Scripts/Game/ERR/ERR_MortarFiring.c": "672ce8527494bd9d3155b93702ac9812f194f2d5f93c8a8c46c5f690bdd3eb93",
"addons/ai/Scripts/Game/ERR/ERR_MortarPrediction.c": "470dd196ed64800c697d24c09d1344bacd2502587fac76af4ee0edae2563092d",
"addons/ai/Scripts/Game/ERR/ERR_MortarReadiness.c": "1a7282d9bd53dcd115d53c9b460ca62d3218931a74635cc516eac1a13b7d9347",
"addons/ai/Scripts/Game/ERR/ERR_MortarSalvo.c": "697c01f479df6c505a41d984a29c02002e3052114dafa2ec6252ae55e2979a2b",
"addons/ai/Scripts/Game/ERR/ERR_MortarSupplyTransfer.c": "34f7eaa01dc68e97aae8c1177b7f8fd6c15d5a41c6dc86de377f00b3613a8e77",
"addons/ai/Scripts/Game/ERR/ERR_MortarSystem.c": "acbc8a1d6a5c76278c447b666ae7362740953422a9ca287361ad6286b6944c59",
"addons/ai/Scripts/Game/ERR/ERR_NativeMortarFiringProbe.c": "d66e57ada46678eb0a6dfa6ff818b656f6132c4eed28881abafafa1e44f8cd2c",
"addons/ai/Scripts/Game/ERR/ERR_NativeMortarTransferProbe.c": "399c21940ef10777b46fdb3e905430ce43404ce1de2f4a6bb62f9c61c1a0689c",
"addons/ai/Scripts/Game/ERR/ERR_NativePatrolHQProbe.c": "4c04aa3e1b6b000747da8e2a919a6501107880fd041134c019f516665bb6f758",
"addons/ai/Scripts/Game/ERR/ERR_SettlementSafety.c": "e5c0ebc95521a9a33a3f7d9cca6c551dda862a08b7af20b017877aba9584795b",
"addons/ai/Scripts/Game/ERR/ERR_SupportScenario.c": "71757018ec9716c4dc24f62a292a214919d3fd5daed3c16e03e56abd208e9f03",
"addons/ai/addon.gproj": "5f559db8f526700db11e6ae763f5245f19b7006fc68c56e4c09fb6f940bdf2a1",
"addons/chat/Missions/ERR_Everon.conf": "76f3ac0d21b585654beac7ddd68e3c8cbdd66dbfe909b17b04838fa813a7c29b",
"addons/chat/Missions/ERR_Everon.conf.meta": "0a23c98bf83873536c65fa17d38dea33a1d7b9e4ab210f90633ff688abcc551f",
"addons/chat/Scripts/Game/ERR/ERR_AdminCommands.c": "d7b4ed95fc32767911936cb0fcc60763233f2c31afd34a6a0fa998b39cec9f5c",
"addons/chat/Scripts/Game/ERR/ERR_NativeMortarProbe.c": "ddb892141500c192c0787b011d57dd8c07dd8c9a3ca5fdc407f6c271897bde0a",
"addons/chat/Scripts/Game/ERR/ERR_NativeRadioProbe.c": "84524163c63402755b4f834f74dfe6d8e5c397dc26031f532593c6f79f5a93b1",
"addons/chat/Scripts/Game/ERR/ERR_NativeSmoke.c": "95186a6c1553b38c6a214e897f845ef1799d8acca0cc896d8df73de680050888",
"addons/chat/Scripts/Game/ERRChat/ERR_OrdinaryScenarioLaunchChat.c": "dda715c9691d366e35fa2ad5e390dee1971651f137a5a9f9aeb23dcbe53ec87e",
"addons/chat/Scripts/WorkbenchGame/ERR/ERR_ValidateWorldPlugin.c": "81c92d408ce88cc9f98d6053f1d0c863427693ba748f00df9f1bf8079015ef94",
"addons/chat/addon.gproj": "ea1587e0174cf795334d306c71d99b06797fc891427cd57b6cab6e21cf0e4e0e",
"addons/core/Configs/ERR/EveronSites.conf": "ade92cc8d2b14a84ac378bbbb52608b351dca65d359dd7a315d64a145fa4b46f",
"addons/core/Configs/ERR/EveronSites.conf.meta": "d5fe68025ef4e7c1e16082cf5873b7c7172eacbfaef4ab29b7e0e3c98f8dca56",
"addons/core/Configs/ERR/Factions/MissionVehicles.conf": "5f74f4a7089c7e7b54ad62463159ce8f0bab25a6b85268dc3872ea6001e048fb",
"addons/core/Configs/ERR/Factions/MissionVehicles.conf.meta": "00c368b6271d3440cc8bf627b03a384d247635723923fc5ad2104b8b4007b035",
"addons/core/Configs/ERR/Factions/US.conf": "4c3da063abb6e3ee39a6e4e0c5a9ffd5eae9d209d58470ea18b45dba5528db1b",
"addons/core/Configs/ERR/Factions/US.conf.meta": "a05469aef028e9e17eba545e81e2af2887b59f0fef17dac51a23c7b8155e381b",
"addons/core/Configs/ERR/Factions/USSR.conf": "407ea27f80a64c5184c089d43cdd0bdabfc5974c84f1d2a245081fdf2afa3f30",
"addons/core/Configs/ERR/Factions/USSR.conf.meta": "057397d97096346791b51b7b13fbe18af218bcf78e9984d9c01b49a2403de611",
"addons/core/Configs/ERR/GameOverScreens.conf": "45231061911a1462d45fb6db0fecc2b0793f17b5ae71017174954ff4fbd20236",
"addons/core/Configs/ERR/GameOverScreens.conf.meta": "eb654b745c0b97b41c991694569ef4877a3c2315e0826f9556337cd68690843e",
"addons/core/Configs/ERR/VanillaFactions.conf": "db890b61b48ee15484041fd2245a862d9fa9e7ba21b1229c281ff37c448a35b1",
"addons/core/Configs/ERR/VanillaFactions.conf.meta": "ac77725c0c21974991ef47a466b88122e939de8b46fd23e68889e7674cbb2bfd",
"addons/core/Missions/ERR_Everon_Base.conf": "1e6a0e9a756d15495201f71121626890f01efe6b00154c561672d4ec157960bd",
"addons/core/Missions/ERR_Everon_Base.conf.meta": "9b16267c644d815bcf98a3a3aaff30b93d7224fb24d3a2bac66730a28011f317",
"addons/core/Prefabs/ERR/Extraction.et": "1aa286ef253c5410f09fa641e4be91a7be8ec834487a7fbb74cfb45cab60ee1e",
"addons/core/Prefabs/ERR/Extraction.et.meta": "c2a838633001e2e3a202d39cb33aa744ebcd996017ad032359069641b5d13853",
"addons/core/Prefabs/ERR/FactionManager.et": "425f916b890019c537f6b2f72b1af9e7be54b0a476320da969e1f313a7ac5ea5",
"addons/core/Prefabs/ERR/FactionManager.et.meta": "9bf53d5e4bcbe60dd1a4ece1409fc23c349055c860708620f5f6e9716290a97d",
"addons/core/Prefabs/ERR/FieldCover.et": "20f8095e69dbfe3db74ff19078e528ea75405362b335e03560ccd61f8df2e7f3",
"addons/core/Prefabs/ERR/FieldCover.et.meta": "83461ffa76244e1d69f20b053a9741ccdf7d127009182bd540a7e5ba6150c3d9",
"addons/core/Prefabs/ERR/GameMode.et": "385c97a5b8067091d92aa60c2d4fcf02002cf606b95523866ead65c96b8c0029",
"addons/core/Prefabs/ERR/GameMode.et.meta": "106769cd34525c9d440057072836cb7401a6752148c40edd7fe61c03bd58328c",
"addons/core/Prefabs/ERR/ObjectiveDocument.et": "2e72270bf186654af12d2c3ff9bf940690b03fb17fca44f873c1fde5d11384c0",
"addons/core/Prefabs/ERR/ObjectiveDocument.et.meta": "eaba9903be147b98a1106e2273e2270773df73b9b22f2cd4e20136a8e281382e",
"addons/core/Prefabs/ERR/Patrol.et": "c5685a8bc311cc5563fb3334beec9408d3d7a1069152fddeeb7df4f1b7f9e6ce",
"addons/core/Prefabs/ERR/Patrol.et.meta": "7c5da568fa2fcf0709ee2959253cb068d7c7ed7c2467af3b247a7e70efd96b69",
"addons/core/Prefabs/ERR/Prison.et": "1503db1441d8cd7a4f0b45c27ba9623b9fa39f0f81016e180bd2aa1379e1f42a",
"addons/core/Prefabs/ERR/Prison.et.meta": "2e426ef3de68f4107907854b51e818bc11d84649a01c538e3f18dd9ebec766bb",
"addons/core/Prefabs/ERR/PrisonDoor.et": "fc66be9d36f1f01084de59f1b0a1e8817f9e46547ead33d4fafaac0107446c40",
"addons/core/Prefabs/ERR/PrisonDoor.et.meta": "b8f3db52bf186426026668fbb9d633c3cbd4d438ab301fba880398f6a0e781c2",
"addons/core/Prefabs/ERR/PrisonWall.et": "8009d19365ae72a4749d7ad4fa04662575b06c65c6bf06507d380d57258b5eed",
"addons/core/Prefabs/ERR/PrisonWall.et.meta": "0294bc5dbb56f90f8153d62459bb0a6ad91d76a479812bbec9c7db182fdb58d6",
"addons/core/Prefabs/ERR/Prisoner.et": "198b5badabb12f218f86df7eb4dc268fd830769dc3de7eef6362cfaee4d6fc8d",
"addons/core/Prefabs/ERR/Prisoner.et.meta": "974278ba49fafeed70b619a0067bbc70ae4d534be441c812ce2bef4a5fb3c022",
"addons/core/Prefabs/ERR/Radio.et": "b4b5cfe125b39019855816c9a1c508ca4d65d435b5546fdaa6c1fa3c8c9b1165",
"addons/core/Prefabs/ERR/Radio.et.meta": "bc91137b68ba550217914fb8892bb44d7e1920e4a1086f3e506623832a44212f",
"addons/core/Prefabs/ERR/SpectatorCamera.et": "b5b87d5b7b707f3745741aebe7c923067c8a74f8fbb2a4711834bab03bb5a812",
"addons/core/Prefabs/ERR/SpectatorCamera.et.meta": "2a16558f93915e31908a674509e9c89976470f78a84a1174a64b94b68b8f77ad",
"addons/core/Prefabs/ERR/SupplyCache.et": "bccf7afbaae97cfcdd78dd6dbbf4be5b2c045d348f50fe4581962e556c0044d7",
"addons/core/Prefabs/ERR/SupplyCache.et.meta": "2f5de3a4aab1e9d0e35521f48dc57b95bd6e449c383dec4f1c258e10295904cb",
"addons/core/Prefabs/ERR/SupplySite.et": "dc5decce5cabf39b6116e8794ec3960cb1e35761854fdbe69740da118787ded4",
"addons/core/Prefabs/ERR/SupplySite.et.meta": "b41944b12eb3528ff7a3ac94258b18c66ef161aa6a38894aee300a1ac4798630",
"addons/core/Scripts/Game/ERR/ERR_Actions.c": "adf93245e6d78c59b9839599d157a0d2b2b93ea93b3d1ae52e2904dd6c288266",
"addons/core/Scripts/Game/ERR/ERR_Actors.c": "b3c5aabb05f7cf35167bc09b5db51a4ffd89a46658805d6eedbfb80eee30273d",
"addons/core/Scripts/Game/ERR/ERR_AdminService.c": "9985747d5ddaeb91bf27937836a6c369f8dcb353263b77a49212ec28c10ba4eb",
"addons/core/Scripts/Game/ERR/ERR_CasualtyGroundSupport.c": "26f0c7ebe8563bb022f7c383674e7d8997b0cc35c7ea321d39d74f2493c1ed9d",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingGameMode.c": "f4cf19440583ac24346831a2d5f1d7f734c031e46dc266c499972329dd0533cf",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingOwner.c": "6346a05ddda030f7d9b6f026f977d5f018ee16002fa519e8c49dcd700c323dc7",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingService.c": "df787bc40099512656e622c6c511d18caea2ff7a88d2c113e0d6940a551ad566",
"addons/core/Scripts/Game/ERR/ERR_DiscoveryMap.c": "80fda5976c3d7a74ee3a481a0d5f365d5e59553046ebe84d0c84117829a32aaf",
"addons/core/Scripts/Game/ERR/ERR_DiscoveryService.c": "65cc0c23da131f986c3c90a8e4d294522e1d0681bec709b618daecb6e0d393c0",
"addons/core/Scripts/Game/ERR/ERR_DocumentComponent.c": "17bb76b80ebd3357e46d553c44674f602c7bd6901c92aec53ac8214194aa4ff2",
"addons/core/Scripts/Game/ERR/ERR_EnvironmentService.c": "867e9f47adfb7a9819a8b58498688ff86127282cb89cf2529ae81f73e529e1c5",
"addons/core/Scripts/Game/ERR/ERR_EscapeGameOverScreenInfo.c": "b1e1afb7795cb77c0bad94c85abf705b26b9dc2a9400905d80eafd56bdd009d3",
"addons/core/Scripts/Game/ERR/ERR_ExtractionPlacement.c": "c30222ca25cc0e91dec4077e6b82b37a9edafcf2cbebd0be5b6bd8656b53adfe",
"addons/core/Scripts/Game/ERR/ERR_ExtractionService.c": "91357099b4e0401196b67d48963be54be30e56bdba57cdac67dc20b8ebb883e9",
"addons/core/Scripts/Game/ERR/ERR_FactionCatalog.c": "a5a8c53acf21259e14f59cb919535910f30dabff5a9179c664bc6a7a4d744d6e",
"addons/core/Scripts/Game/ERR/ERR_GameMode.c": "043ac9ab7f3163f3285038ed008be782030714607d8e59e25593cfe95dd023b2",
"addons/core/Scripts/Game/ERR/ERR_InitialGuardRules.c": "8c9d6b1dc4c2af96284e34f487eebb5a221091016ef108006dec60b4e3836558",
"addons/core/Scripts/Game/ERR/ERR_Inventory.c": "b63e679d5b650b63a7a91dfc3f42a62f4be58b0338f6df3313e66d29a93bebf6",
"addons/core/Scripts/Game/ERR/ERR_LoadCasualtyAction.c": "5d868fb065a1a0fea7d5abfc81d1d8be96823815535f2ffd0dc4ff60d8eae794",
"addons/core/Scripts/Game/ERR/ERR_LocalAdmission.c": "b0e824c6880cbf9b1f368dc7ada9907bde78b22b948d419b6c861323f32258be",
"addons/core/Scripts/Game/ERR/ERR_Location.c": "d2035f56ded35743312ec6ca91a67f8623a466c91255e1893c570edf0954ff24",
"addons/core/Scripts/Game/ERR/ERR_MissionRules.c": "f7abc38ad8fdc375ce7fa63a65f0bade027d22b37e09de5e3f94ba8c3c63cc41",
"addons/core/Scripts/Game/ERR/ERR_NativeAdminSettingsProbe.c": "6a4df33a2b0e6b6aeed944c6895961e658d4f0db9aed9b8433a43a451fa35cae",
"addons/core/Scripts/Game/ERR/ERR_NativeBaseSmoke.c": "84e0a2d73bc12160cd0a95138085eb7647fa26b2326f790a95cb53748009fdd3",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyGroundProbe.c": "41f40db3735f8aa535c0061458d9892dcfe972222b8a17238e67b65633c46bc3",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyLoadProbe.c": "94c533deea654ec546df3f1ebb7cd213e6cd79b1125d99bab5303ef8e87b018b",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyRemoveProbe.c": "4cfc06f6d43b709b63caae714155ffc562502e884f49a9825623c6f46972ad36",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyServiceProbe.c": "02a9d70d1f4ba20326df199ba41489cfbae12b7bb0aab441361421cee38ad9ea",
"addons/core/Scripts/Game/ERR/ERR_NativeContractsProbe.c": "d1556df885171cf967e96eef5d8981a2e9ee4e3938b7d32fdd0426f647bbabc0",
"addons/core/Scripts/Game/ERR/ERR_NativeDefinitionProbe.c": "c07048341396443ddf5307e340e2087254d65f0bddf8f7d93e6b6bd7f03ca360",
"addons/core/Scripts/Game/ERR/ERR_NativeEnvironmentProbe.c": "8b1d110717aa5f07bfb8fe633847eab519109e3a8a4100970a487be05c053418",
"addons/core/Scripts/Game/ERR/ERR_NativeEnvironmentRestartProbe.c": "7a836a206381b8e8de24c92baf141beb30575723675dd6948d738169ed26b507",
"addons/core/Scripts/Game/ERR/ERR_NativeExtractionProbe.c": "4b09385f73206de004f4f3c38a6192fd658a0d2012482dc5a84dff1599ceb972",
"addons/core/Scripts/Game/ERR/ERR_NativeFactionCatalogProbe.c": "ee11486cf77da9070506ccc0cfd6e94240c5387c8be455bf864934a8fef65f78",
"addons/core/Scripts/Game/ERR/ERR_NativeGuardCancelProbe.c": "bfa1c65cb039e19c3d1891e4a3fd33469e974c97cc7f42128efc31a8f587d514",
"addons/core/Scripts/Game/ERR/ERR_NativeLifecycleProbe.c": "b613a5dbe81c2032fd02d31070ae5631166d14d0b02cdbec3b63b782f0bbc115",
"addons/core/Scripts/Game/ERR/ERR_NativeMedicalProbe.c": "43fa51ffbcf9dd0cd8e905a1135bcf0756651da3af34677f3c92e7d264ed70b6",
"addons/core/Scripts/Game/ERR/ERR_NativeObjectiveLossProbe.c": "6b80fd317a8c6e8583bd4337870838a86251e3b8a681d0aa07e8b52e22abfc48",
"addons/core/Scripts/Game/ERR/ERR_NativeObjectiveProbe.c": "71fbd2479a70048f83d8b262ad1452f427be2c0afc8b071ef13bff477b9dc29b",
"addons/core/Scripts/Game/ERR/ERR_NativePatrolProbe.c": "02bd9fdf5454db7dd4c82240efe0d947bf8d6488ace42809c3aef6505cb6266d",
"addons/core/Scripts/Game/ERR/ERR_NativePrisonerProbe.c": "e2d1ffe5d269add55124601ff0d1dc032a398c7d51010736e6f0e4cbeb38ae86",
"addons/core/Scripts/Game/ERR/ERR_NativeRadioDefenceProbe.c": "cad54f0b43cefd72df74697dfc7e93725ff0acac6d311e963ce4f817428c272c",
"addons/core/Scripts/Game/ERR/ERR_NativeRecoveryProbe.c": "4de6868cd3e76afb80cf0ae5dac1e35d2c417838f640c2f18aa3343217eea2f2",
"addons/core/Scripts/Game/ERR/ERR_NativeResultProbe.c": "b9a117eef2d5f65fbd792041a2b3e59e38e201bda8e0df8c503e1a1242cfc415",
"addons/core/Scripts/Game/ERR/ERR_NativeSiteSurvey.c": "ac0203753ade0cdff6d483132797a80e4520f14546c3f9dea288281cd4cd9c4f",
"addons/core/Scripts/Game/ERR/ERR_NativeStationTeardownDiagnostic.c": "a363c2383e66311415fd29124f26f3b0c6cb866648d86673afac29fca22a994a",
"addons/core/Scripts/Game/ERR/ERR_NativeTimeProbe.c": "c93d049785971e51246fcc07cf24804270a752a655505f2c38e48c80df5255ae",
"addons/core/Scripts/Game/ERR/ERR_NativeTransportProbe.c": "63ec0c5ce698114daa6314b2a6e3c3e98e76094117c477f9d0d072260686d193",
"addons/core/Scripts/Game/ERR/ERR_NativeTransportSurvey.c": "3e94493bf54d15be2bceb106ad18873e14e6755af09c05f07db7fb26fb7adff5",
"addons/core/Scripts/Game/ERR/ERR_ObjectiveDetails.c": "628ebd166dcb5544c2d18dce489619984887ee18296cf2446fc6d894f89dd5bf",
"addons/core/Scripts/Game/ERR/ERR_ObjectiveText.c": "815fa44350798229784efffe0d4ec16d3382dd62df149215e49d527cc2961553",
"addons/core/Scripts/Game/ERR/ERR_Objectives.c": "88d95a52fcba103483ea751571e1afeae0e6fc82115ed50d6fc195424726960f",
"addons/core/Scripts/Game/ERR/ERR_Observer.c": "b719e723369ab4f403950c85226e1336eb48e3c127e84530ac1c695eb86bd0f9",
"addons/core/Scripts/Game/ERR/ERR_OrdinaryScenarioLaunch.c": "e2803ff9198e6213bfcbaefad64a35ae3ffe06846c410cf6da6de7653adbf28d",
"addons/core/Scripts/Game/ERR/ERR_PlayerAdminCommands.c": "a084d7dc097dfcde3d6cd9c2e326b9e2f8f2a519f77b30c4f56ab7a1429aa721",
"addons/core/Scripts/Game/ERR/ERR_PlayerEscapeResult.c": "3124ab4d2d6d471409a47aba0af528790734df53243c03fe0cdac3e407047c14",
"addons/core/Scripts/Game/ERR/ERR_PlayerGuide.c": "2c9c365b88651f8b12618443638bf52c04e497221592bd483c33447e30468f36",
"addons/core/Scripts/Game/ERR/ERR_PlayerRoster.c": "c038dac0f749bd29ebc35a4e952904b41a34417ba738904d5efcd1833a263e0b",
"addons/core/Scripts/Game/ERR/ERR_RadioDefenceService.c": "5d347cf1a3b021074d560aad8db774828b797e685b63ddff3d28f55781e33ea8",
"addons/core/Scripts/Game/ERR/ERR_RadioFeedback.c": "545262e65e9b3645d9e514a0521e442fe08f0c2e4e7c83ba638c5105d09818db",
"addons/core/Scripts/Game/ERR/ERR_RecoveryService.c": "ba9ffb93679012c20a665636ef6b201cbe7d8d14fdf53e8cd3eb12ac7248943f",
"addons/core/Scripts/Game/ERR/ERR_Resources.c": "d0169aac6fd0c38928c47a9002ded0fd8ba558ea3314a600e792d307ac1ca3ee",
"addons/core/Scripts/Game/ERR/ERR_ScenarioComponent.c": "abba03af68323d5715ba1e2497fc66f3c706e6a6a983c3a386228abdfddeec89",
"addons/core/Scripts/Game/ERR/ERR_Settings.c": "b9390548936b386e0211d487c1b76b65410fdd2e339cd8ecd9585ef4f4ffed31",
"addons/core/Scripts/Game/ERR/ERR_SiteDefinition.c": "b422feeaca90084ea2bee5cde94dc9c6fcae542749b55d95f7226f922a6a68ac",
"addons/core/Scripts/Game/ERR/ERR_SiteDiscoveryRules.c": "50f7b3ff4f32bde37ce5ae2be7f598fc4dd8cc08f45914f6e3260d31c84baef2",
"addons/core/Scripts/Game/ERR/ERR_SiteService.c": "6bc9a0b5aed326822807f05e17459d0fc2da10b709e8168972b4e40fd09f87cb",
"addons/core/Scripts/Game/ERR/ERR_SpawnFinalization.c": "2e295b0f225208c5414728ba83333e5e0ab6eef3a708ce39eb1dfce5400c94c9",
"addons/core/Scripts/Game/ERR/ERR_SpawnLogic.c": "bbbf35110259cacdac63779604ce22149d1a2198ec4c4cf43f7f3bf57e3241e8",
"addons/core/Scripts/Game/ERR/ERR_SpawnPlacement.c": "55323dcb330c23d49dc8fa3fde86a3ae3958c0b6563d6c3cd0960da88333f93d",
"addons/core/Scripts/Game/ERR/ERR_Supplies.c": "752e8a56b0b8cde33cf532032cb0a203553017b686faac2e19bee06f7a9c0713",
"addons/core/Scripts/Game/ERR/ERR_TimeService.c": "d9f481b7da01e08d2c982a948c18ba6bde76889d7cc9d26d510708f4ba479453",
"addons/core/Scripts/GameLib/ERR/ERR_DiagnosticNoSplash.c": "0ea1b402f8927b6d68bf6f7e5caa2967f7e3a39147634faab147796b791933b5",
"addons/core/Scripts/WorkbenchGame/ERR/ERR_ValidateBaseWorldPlugin.c": "7f44aa64ea7b4f8b3640a37a4b781c43bf6adb80e4a3a702d9491131698056f6",
"addons/core/Worlds/ERR_Everon.ent": "22324bc7eb0d80dec8a1f3bd61a9df9201b72f749f4e751766b0c9d0b7d46b87",
"addons/core/Worlds/ERR_Everon.ent.meta": "19d1903ca72baa326b4724a6791d0da1104a1e53f3f31dc1ca41a856efd68e83",
"addons/core/Worlds/ERR_Everon_Layers/default.layer": "17105538007199bfc419aa04a64debaf2da0a7b77a1dc3ba983e92bf747c862e",
"addons/core/addon.gproj": "231274e6b62302f32c65f9ff31de2ce8a9e51e1c8d12c87deeec82ae1f40de46",
"addons/intel/Scripts/Game/ERR/ERR_IntelService.c": "482839434b94e7f8c345d5fd96490aeebb765f3dd0c1bb25fceea2f435c0e722",
"addons/intel/addon.gproj": "d0ced242cefb220a5cccd6779d61fda9bc55581701b9f78bcf13c09d92ddbcbe",
"addons/map/Materials/ERRM_MapRenderTarget.emat": "9877c5b175c5f30dd80bea36c711b21ab38219aa7075adf9ae79932e1d4c76bc",
"addons/map/Materials/ERRM_MapRenderTarget.emat.meta": "5ee1a705f8011a44020ca2691f5ccc17d44bf596fef9a36e98d1f267eb58fab0",
"addons/map/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et": "30dee8e9eab459ea32a7d835a9fb89d43df47708057cab829f067b25a24cd581",
"addons/map/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et.meta": "59093e9072c50d99c86da7609c87541016da5bcf92b98d99db4c524e1c8e0e8d",
"addons/map/Scripts/Game/ERR/ERR_ScenarioMap.c": "75fa1d742129ef7f33c005cd48f56db7f49ee7bde3c5428532b0b501b032b0a3",
"addons/map/Scripts/Game/ERRMap/ERRM_SharedMapComponent.c": "fc1a0c7df4fc96da446d7542a45a10fbec1eda1e543ba2f0581cb772277a47c5",
"addons/map/UI/layouts/ERRMap/SharedMapRenderTarget.layout": "49a2da4181b94d42174f58c7f9b6bf2207116c99427d61ff1c212092ac7db4d2",
"addons/map/UI/layouts/ERRMap/SharedMapRenderTarget.layout.meta": "5c846445cc089e2e08899ba703059d4adb805ff30ab5a16409a3cd59718cbd54",
"addons/map/addon.gproj": "1b371e5e01ea9fa46e76570fecb8aaa3a9298e34cba7ccca8a6bdb5ca86eb46a"
}
@@ -0,0 +1,15 @@
{
"cleanup-verification.json": "54e31b30fa5f8102a42d020b6a687799a063dd320ae5b0b30ae1efe64964b553",
"command.json": "20ab83f7e1ec457f3e4b7fad7f89c54c6ae7b649c63f142a552697b55c7bfcad",
"isolation-preflight.json": "bbf1e635e862532fbdd7d6210610b3906f4f1caad7c9ba08e67ecf84324dba7a",
"profile/logs/logs_2026-09-19_08-32-13/console.log": "44a061e2fa092e5a513a51341a54d6254b1d64d2909e0463071c4e348b3f15a0",
"profile/logs/logs_2026-09-19_08-32-13/error.log": "242f30914808638ddab976738b475e4e0c277c9e27a4b2bda46484f438049d0b",
"profile/logs/logs_2026-09-19_08-32-13/script.log": "81f3191e38f6a9932a77d05a22b746777d355938369b65d6cd17be450493b923",
"profile/profile/.save/settings/ReforgerEngineSettings.conf": "a36a9bbca20b2019099052c86f48fb00db7ec01ff7409cc81b6d102789ed50a9",
"profile/profile/.save/settings/ReforgerGameSettings.conf": "1656680640c178239490ffbf9b3ddae04d3ac0993cd84471c0d27b28b76abf13",
"result.json": "d4ca570adf8da3a0dc302f5f163e7f2278ba8f97826ed62154bd2f674c7881af",
"review.json": "5de14885c7e8a62cedd38c03a01ef0d566a1507de0439d42a6da721fd1123741",
"source-manifest-after.json": "d66a6a1a256aec91b752acb153dd1fac94d0950419e3a10ccecb74d50a914a15",
"source-manifest.json": "d66a6a1a256aec91b752acb153dd1fac94d0950419e3a10ccecb74d50a914a15",
"stdout.log": "acb9c1a7d09e057f988c139d97100ca9ac93c2475e83107aced4de869096e865"
}
@@ -0,0 +1,4 @@
{
"ownedSupervisorAbsent": true,
"remainingNativeServerExecutables": []
}
@@ -0,0 +1,111 @@
{
"command": [
"bwrap",
"--unshare-net",
"--unshare-pid",
"--unshare-ipc",
"--unshare-uts",
"--die-with-parent",
"--cap-drop",
"ALL",
"--clearenv",
"--ro-bind",
"/",
"/",
"--tmpfs",
"/home",
"--tmpfs",
"/tmp",
"--tmpfs",
"/run",
"--proc",
"/proc",
"--dev",
"/dev",
"--ro-bind",
"/tmp/erri-dedicated-runtime/server",
"/tmp/runtime",
"--bind",
"/tmp/erri-dedicated-native-build/attempt-02-header/source",
"/tmp/source",
"--bind",
"/tmp/erri-dedicated-native-build/attempt-02-header",
"/tmp/work",
"--setenv",
"HOME",
"/tmp/work/home",
"--setenv",
"TMPDIR",
"/tmp/work/tmp",
"--setenv",
"XDG_CONFIG_HOME",
"/tmp/work/home/.config",
"--setenv",
"XDG_DATA_HOME",
"/tmp/work/home/.local/share",
"--setenv",
"XDG_CACHE_HOME",
"/tmp/work/home/.cache",
"--setenv",
"PATH",
"/usr/bin:/bin",
"--setenv",
"LANG",
"C.UTF-8",
"--chdir",
"/tmp/runtime",
"/usr/bin/python3",
"-c",
"import json,os,socket,sys\nstate={\"netns\":os.readlink(\"/proc/self/ns/net\"),\"interfaces\":socket.if_nameindex(),\"routes\":open(\"/proc/net/route\").read(),\"ipv6Routes\":open(\"/proc/net/ipv6_route\").read()}\nprint(\"ERR ISOLATION \"+json.dumps(state),flush=True)\nassert state[\"netns\"] != sys.argv[1], \"network namespace was not isolated\"\nassert [name for _,name in state[\"interfaces\"]] == [\"lo\"], \"non-loopback interface present\"\nassert len(state[\"routes\"].splitlines()) == 1, \"IPv4 route present\"\nassert all(line.split()[-1] == \"lo\" for line in state[\"ipv6Routes\"].splitlines()), \"non-loopback IPv6 route present\"\nif len(sys.argv)>2: os.execv(sys.argv[2],sys.argv[2:])\n",
"net:[4026531833]",
"/tmp/runtime/ArmaReforgerServer",
"-addonsDir",
"/tmp/source/addons",
"-addons",
"2528466DE220D91C",
"-profile",
"/tmp/work/profile",
"-noBackend",
"-noSound",
"-noSplash",
"-noThrow",
"-bindIP",
"127.0.0.1",
"-bindPort",
"2001",
"-maxFPS",
"30",
"-logStats",
"5000",
"-server",
"{AD62322D5213C440}Missions/ERR_Everon_Base.conf"
],
"engine": [
"/tmp/runtime/ArmaReforgerServer",
"-addonsDir",
"/tmp/source/addons",
"-addons",
"2528466DE220D91C",
"-profile",
"/tmp/work/profile",
"-noBackend",
"-noSound",
"-noSplash",
"-noThrow",
"-bindIP",
"127.0.0.1",
"-bindPort",
"2001",
"-maxFPS",
"30",
"-logStats",
"5000",
"-server",
"{AD62322D5213C440}Missions/ERR_Everon_Base.conf"
],
"seconds": 90,
"binarySHA256": "91fdf333ec49c266d309be358aabab4244a93a2f9cfa11853a600e026104001f",
"serverLaunched": false,
"realPlayers": 0,
"multiplayerProven": false
}
@@ -0,0 +1,65 @@
{
"command": [
"bwrap",
"--unshare-net",
"--unshare-pid",
"--unshare-ipc",
"--unshare-uts",
"--die-with-parent",
"--cap-drop",
"ALL",
"--clearenv",
"--ro-bind",
"/",
"/",
"--tmpfs",
"/home",
"--tmpfs",
"/tmp",
"--tmpfs",
"/run",
"--proc",
"/proc",
"--dev",
"/dev",
"--ro-bind",
"/tmp/erri-dedicated-runtime/server",
"/tmp/runtime",
"--bind",
"/tmp/erri-dedicated-native-build/attempt-02-header/source",
"/tmp/source",
"--bind",
"/tmp/erri-dedicated-native-build/attempt-02-header",
"/tmp/work",
"--setenv",
"HOME",
"/tmp/work/home",
"--setenv",
"TMPDIR",
"/tmp/work/tmp",
"--setenv",
"XDG_CONFIG_HOME",
"/tmp/work/home/.config",
"--setenv",
"XDG_DATA_HOME",
"/tmp/work/home/.local/share",
"--setenv",
"XDG_CACHE_HOME",
"/tmp/work/home/.cache",
"--setenv",
"PATH",
"/usr/bin:/bin",
"--setenv",
"LANG",
"C.UTF-8",
"--chdir",
"/tmp/runtime",
"/usr/bin/python3",
"-c",
"import json,os,socket,sys\nstate={\"netns\":os.readlink(\"/proc/self/ns/net\"),\"interfaces\":socket.if_nameindex(),\"routes\":open(\"/proc/net/route\").read(),\"ipv6Routes\":open(\"/proc/net/ipv6_route\").read()}\nprint(\"ERR ISOLATION \"+json.dumps(state),flush=True)\nassert state[\"netns\"] != sys.argv[1], \"network namespace was not isolated\"\nassert [name for _,name in state[\"interfaces\"]] == [\"lo\"], \"non-loopback interface present\"\nassert len(state[\"routes\"].splitlines()) == 1, \"IPv4 route present\"\nassert all(line.split()[-1] == \"lo\" for line in state[\"ipv6Routes\"].splitlines()), \"non-loopback IPv6 route present\"\nif len(sys.argv)>2: os.execv(sys.argv[2],sys.argv[2:])\n",
"net:[4026531833]"
],
"exit": 0,
"stdout": "ERR ISOLATION {\"netns\": \"net:[4026534801]\", \"interfaces\": [[1, \"lo\"]], \"routes\": \"Iface\\tDestination\\tGateway \\tFlags\\tRefCnt\\tUse\\tMetric\\tMask\\t\\tMTU\\tWindow\\tIRTT \\n\", \"ipv6Routes\": \"00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 00000000 00200200 lo\\n00000000000000000000000000000001 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000002 00000000 80200001 lo\\n00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 00000000 00200200 lo\\n\"}\n",
"stderr": ""
}
@@ -0,0 +1,346 @@
---------------------------------------------
Log /tmp/work/profile/logs/logs_2026-09-19_08-32-13/console.log started at 2026-09-19 08:32:13 (2026-09-19 06:32:13 UTC)
08:32:13.285 ENGINE : FileSystem: Adding relative directory '/tmp/work/profile/logs/logs_2026-09-19_08-32-13' to filesystem under name logs
08:32:13.285 ENGINE : FileSystem: Adding relative directory '/tmp/work/profile/profile' to filesystem under name profile
08:32:13.285 ENGINE : FileSystem: Current working directory: '/tmp/runtime/'
08:32:13.287 ENGINE : Initializing engine, version 192142
08:32:13.287 ENGINE : CLI Params: -addonsDir /tmp/source/addons -addons 2528466DE220D91C -profile /tmp/work/profile -noBackend -noSound -noSplash -noThrow -bindIP 127.0.0.1 -bindPort 2001 -maxFPS 30 -logStats 5000 -server {AD62322D5213C440}Missions/ERR_Everon_Base.conf
08:32:13.288 ENGINE : Addon dirs:
08:32:13.289 ENGINE : dir: '/tmp/source/addons'
08:32:13.289 ENGINE : dir: './addons'
08:32:13.289 ENGINE : dir: '/tmp/work/profile/addons'
08:32:13.289 ENGINE : Available addons:
08:32:13.289 ENGINE : gproj: '/tmp/source/addons/core/addon.gproj' guid: '2528466DE220D91C'
08:32:13.289 ENGINE : gproj: '/tmp/source/addons/ai/addon.gproj' guid: '5192138CB9D5B911'
08:32:13.289 ENGINE : gproj: '/tmp/source/addons/intel/addon.gproj' guid: 'D31039C7C53E348A'
08:32:13.289 ENGINE : gproj: '/tmp/source/addons/chat/addon.gproj' guid: 'FA804F411BDDF2C6'
08:32:13.289 ENGINE : gproj: '/tmp/source/addons/map/addon.gproj' guid: '9AAEE9041D79809E'
08:32:13.289 ENGINE : gproj: './addons/data/ArmaReforger.gproj' guid: '58D0FB3206B6F859' (packed)
08:32:13.289 ENGINE : gproj: './addons/core/core.gproj' guid: '5614BBCCBB55ED1C' (packed)
08:32:13.289 ENGINE : FileSystem: Adding relative directory '/tmp/source/addons/core' to filesystem under name ERR_Core
08:32:13.366 ENGINE : FileSystem: Adding package './addons/data/' (pak count: 6) to filesystem under name ArmaReforger
08:32:13.366 ENGINE : FileSystem: Adding package './addons/core/' (pak count: 1) to filesystem under name core
08:32:13.366 ENGINE : CPU vendor : AuthenticAMD
08:32:13.366 ENGINE : CPU type : 2
08:32:13.366 ENGINE : CPU name : AMD Ryzen 7 3800XT 8-Core Processor
08:32:13.366 ENGINE : CPU cache info : Unknown cache
08:32:13.366 ENGINE : CPU count logical : 16
08:32:13.366 ENGINE : CPU count physical : 8
08:32:13.366 ENGINE : CPU features : mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 popcnt aesni pclmulqdq osxsave avx sha avx2
08:32:13.366 RESOURCES : ResourceDB: loading cache (id=0 name=ERR_Core path=/tmp/source/addons/core/resourceDatabase.rdb)
08:32:13.366 RESOURCES : ResourceDB: loading cache (id=1 name=ArmaReforger path=./addons/data/resourceDatabase.rdb)
08:32:13.483 RESOURCES : ResourceDB: loading cache (id=2 name=core path=./addons/core/resourceDatabase.rdb)
08:32:13.484 RESOURCES : ResourceDB: loading cache (id=3 name=profile path=/tmp/work/profile/profile/resourceDatabase.rdb)
08:32:13.484 RESOURCES : ResourceDB: loading cache (id=4 name=logs path=/tmp/work/profile/logs/logs_2026-09-19_08-32-13/resourceDatabase.rdb)
08:32:13.632 ENGINE : GameProject load
08:32:13.632 ENGINE : Loaded addons:
08:32:13.632 ENGINE : gproj: './addons/core/core.gproj' guid: '5614BBCCBB55ED1C'
08:32:13.632 ENGINE : gproj: './addons/data/ArmaReforger.gproj' guid: '58D0FB3206B6F859'
08:32:13.632 ENGINE : gproj: '/tmp/source/addons/core/addon.gproj' guid: '2528466DE220D91C'
08:32:13.633 ENGINE : Loading custom engine user config '$profile:.save/settings/ReforgerEngineSettings.conf'
08:32:13.633 ENGINE : No Enfusion settings file loaded. Continuing with defaults
08:32:13.633 RENDER : Basic screen setup:
08:32:13.633 RENDER : Back buffer width x height: 0x0
08:32:13.633 RENDER : Back buffer format : TEXFMT_UNKNOWN (0)
08:32:13.633 RENDER : MSAA : none
08:32:13.633 RENDER : GPU_DUMMY (0xFFFF) (Enfusion dummy render) with 1 GPU detected, VRAM 128MB (fast 128MB), shared 128MB, driver version Unknown version
08:32:13.633 RENDER : Detected output devices:
08:32:13.633 RENDER : * 1 device/s connected to Dummy:
08:32:13.633 RENDER : Dummy output (Dummy device for our dummy render.), 1920x1080 (offset 0x0), 60Hz
08:32:13.633 RENDER : Concurrent frames limit 2
08:32:13.633 ENGINE : Job system settings: coreCount=16, shortJobContextCount=16, shortJobThreadCount=15, longJobThreadCount=7
08:32:13.645 PROFILING : Settings changed took: 0.028000 ms
08:32:13.647 ENGINE : Initializing inputs.
08:32:13.654 NETWORK : Initializing networking.
08:32:13.654 NETWORK : Using new GameRplScheduler.
08:32:13.655 SCRIPT : SCRIPT : Initializing scripts
08:32:13.655 SCRIPT : SCRIPT : ScriptProjectManager init
08:32:13.655 PROFILING : ScriptProjectManager init took: 0.008000 ms
08:32:13.672 PROFILING : Initializing scripts took: 16.979000 ms
08:32:13.672 BACKEND : Backend Services are disabled.
08:32:13.672 ENGINE : Enfusion engine successfully created.
08:32:13.674 GUI : Using default language (en_us)
08:32:13.674 GUI : Loading 'en_us' localization file.
08:32:13.674 INIT : INIT : Loading StringTable
08:32:13.698 PROFILING : Loading StringTable took: 23.889000 ms
08:32:13.698 SCRIPT : SCRIPT : Compiling GameLib scripts
08:32:13.727 SCRIPT : Module: GameLib; loaded 466x files; 608x classes; used 654K of static memory; defines: "PLATFORM_LINUX,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE"; CRC32: d66caacb
08:32:13.727 PROFILING : Compiling GameLib scripts took: 29.382000 ms
08:32:13.727 SCRIPT : SCRIPT : Compiling Game scripts
08:32:14.505 SCRIPT : Compiling Game scripts
08:32:14.505 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,785": 'GetPlayerPlatformKind' is obsolete
08:32:14.505 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,786": 'GetPlayerPlatformId' is obsolete
08:32:14.728 SCRIPT (W): @"Scripts/Game/ERR/ERR_SiteService.c,191": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:32:14.739 SCRIPT (W): @"Scripts/Game/Workshop/SCR_AddonManager.c,876": 'GetRefCount' is obsolete: Will be removed
08:32:14.765 SCRIPT (W): @"Scripts/Game/Campaign/SCR_PlayerProfileManagerComponent.c,142": 'PlayerData' is obsolete
08:32:14.856 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,159": 'GetDSSession' is obsolete
08:32:14.856 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,162": 'RoomID' is obsolete
08:32:14.857 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,197": 'GetDSSession' is obsolete
08:32:14.857 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,201": 'RoomID' is obsolete
08:32:14.885 SCRIPT (W): @"Scripts/Game/ERR/ERR_CasualtyGroundSupport.c,21": 'GetBoneIndex' is obsolete: Use GetAnimation().GetBoneIndex() instead
08:32:14.929 SCRIPT (W): @"Scripts/Game/ERR/ERR_SpawnLogic.c,64": 'GetPlayerIdentityId' is obsolete
08:32:14.941 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,481": 'GetStorage' is obsolete
08:32:14.941 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,483": 'GetOnlineWritePrivilege' is obsolete
08:32:14.943 SCRIPT (W): @"Scripts/Game/Utilities/SCR_PlayerIdentityUtils.c,20": 'GetPlayerIdentityId' is obsolete
08:32:14.978 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,45": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:32:14.978 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,56": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:32:14.979 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,643": 'GetNotifyCount' is obsolete: Will be substitued by Notification Api.
08:32:14.979 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,645": 'GetNotifyItem' is obsolete: Will be substitued by Notification Api.
08:32:15.036 SCRIPT (W): @"Scripts/Game/DataCollection/PlayerData/SCR_PlayerData.c,210": 'PlayerData' is obsolete
08:32:15.140 SCRIPT : Module: Game; loaded 5732x files; 11115x classes; used 25833K of static memory; defines: "PLATFORM_LINUX,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE,ENABLE_BASE_DESTRUCTION,BUDGET_OPTIMIZATION_CHECKS,DEBUG,RESPAWN_TIMER_COMPONENT_DEBUG,DEBUG_CONFIGURABLE_DIALOGS,DISABLE_WEAPON_SWITCHING,SCRIPTED_AIM_MODIFIER_DEBUG"; CRC32: 2ef250fb
08:32:15.155 PROFILING : Compiling Game scripts took: 1428.098000 ms
08:32:15.155 INIT : Creating game instance(ArmaReforgerScripted), version 1.8.0.13 built 2026-08-21 14:30:18 UTC.
08:32:15.175 ENGINE : Game successfully created.
08:32:15.259 PLATFORM : Save data from container 'settings' have been loaded
08:32:15.358 PLATFORM : Save data from container 'sessions' have been loaded
08:32:15.358 PLATFORM : System language differs from the saved one - using new language {new: 'en_us'; old: ''}
08:32:15.358 PLATFORM : Save data transaction to 'settings' started.
08:32:15.359 NETWORK : Starting local multiplayer server using command line args.
08:32:15.458 DEFAULT : [SaveGameManager] Starting new playthrough nr.0 '' for mission '{AD62322D5213C440}Missions/ERR_Everon_Base.conf'.
08:32:15.458 WORLD : WORLD : Entities load '$ERR_Core:Worlds/ERR_Everon.ent'
08:32:16.058 WORLD : Entities load '$ERR_Core:Worlds/ERR_Everon.ent'
08:32:16.058 WORLD : Subscene load @"{853E92315D1D9EFE}worlds/Eden/Eden.ent"
08:32:16.058 RESOURCES : GetResourceObject @"{C8FAB83670BCF7C3}Prefabs/Structures/Cultural/Calvaries/CalvaryLarge_01.et"
08:32:16.058 WORLD : Entity prefab load @"{C8FAB83670BCF7C3}Prefabs/Structures/Cultural/Calvaries/CalvaryLarge_01.et"
08:32:16.058 RESOURCES (E): Wrong GUID/name for resource @"{45ECF6B1797D3CD9}system/wbdata/PreviewWindow/TransparentMat.emat" in property "AssignedMaterial"
08:32:16.206 PROFILING : Entities load took: 748.131000 ms
08:32:16.207 WORLD : WORLD : Game::LoadEntities
08:32:16.207 WORLD : WORLD : Initializing world systems @"{C50579A2EC48E8EF}Configs/Systems/MissionSystems.conf"
08:32:16.208 NETWORK : Enabled lag compensation, 29 frames with 100 FPS and 280 ms rewind limits.
08:32:16.208 WORLD : WORLD : CreateEntities
08:32:16.208 WORLD : WORLD : CreateEntities
08:32:16.208 WORLD : WORLD : NotifyBeforeEntitiesCreated
08:32:16.209 RESOURCES : Loaded mission headers from 7 addon(s)!
08:32:16.209 PROFILING : NotifyBeforeEntitiesCreated took: 0.922000 ms
08:32:16.209 WORLD : WORLD : Wait for preloading data
08:32:19.448 WORLD : Game::LoadEntities
08:32:19.448 WORLD : CreateEntities
08:32:19.448 WORLD : CreateEntities
08:32:19.448 WORLD : Wait for preloading data
08:32:19.448 RESOURCES : GetResourceObject @"{58E62C5D17281925}Prefabs/Particles/Blasts/Blast_small_Invisible_Trigger.et"
08:32:19.448 WORLD : Entity prefab load @"{58E62C5D17281925}Prefabs/Particles/Blasts/Blast_small_Invisible_Trigger.et"
08:32:19.448 RESOURCES (E): Wrong GUID/name for resource @"{FF35BE9795BA3797}system/wbdata/Gizmo3D/sphere.xob" in property "Object"
08:32:19.514 PROFILING : Wait for preloading data took: 3304.813000 ms
08:32:19.577 ENTITY : Create entity @"ENTITY:2" ('Eden', GenericTerrainEntity) at <0.000000 0.000000 0.000000> @"{5AD924374E8C7AF6}Prefabs/World/Game/Eden/GenericTerrain_Eden.et"
08:32:19.577 PROFILING : PROFILING : Terrain load
08:32:20.724 PROFILING : Terrain load took: 1147.054000 ms
08:32:23.175 ENTITY : Create entity @"ENTITY:610406" ('StaticModelEntity','Assets/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.xob') at <1931.796021 81.777000 5138.725098> @"{6A004A8F0571D456}Prefabs/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.et"
08:32:23.175 ENTITY : CreateComponent 'ScriptedRadioComponent'
08:32:23.175 DEFAULT (W): World doesn't contain RadioManagerEntity to support any BaseRadioComponent.
08:32:25.294 ENTITY : Create entity @"ENTITY:1104061" ('StaticModelEntity') at <8831.291016 95.934265 2673.487061>
08:32:25.294 ENTITY : EntityPrefabUse @"{C8FAB83670BCF7C3}Prefabs/Structures/Cultural/Calvaries/CalvaryLarge_01.et"
08:32:25.294 RESOURCES : CreateComponentData @"{904345715F67BBAC}Assets/Structures/Cultural/Calvaries/CalvaryLarge_01/CalvaryLarge_01.xob"
08:32:25.294 MATERIAL : Material load @"{45ECF6B1797D3CD9}system/wbdata/PreviewWindow/TransparentMat.emat"
08:32:25.294 MATERIAL (E): Material file not found
08:32:25.294 MATERIAL (E): Cannot load material @"system/wbdata/PreviewWindow/TransparentMat.emat", creating default one (class MatPBRBasic)
08:32:27.847 WORLD : WORLD : NotifyBeforeEntitiesInitialized
08:32:27.847 PROFILING : NotifyBeforeEntitiesInitialized took: 0.028000 ms
08:32:27.847 WORLD : InitEntities 'world'
08:32:27.847 ENTITY : Init entity @"ENTITY:3" ('SCR_MapEntity1', SCR_MapEntity) at <6400.000000 0.000000 6400.000000> @"{E1B88C66BF6CA1F9}Prefabs/World/Game/Eden/MapEntity_Everon.et"
08:32:27.847 SCRIPT (W): SCR_MapEntity: Cannot get the size from terrain. Using default.
08:32:28.358 ENTITY : Init entity @"ENTITY:2305843009213693953" ('Rereintroduced', ERR_GameMode) at <1076.468018 51.000999 1325.246948> @"{978E045E53EF36C8}Prefabs/ERR/GameMode.et"
08:32:28.358 SCRIPT (W): SCR_PerceivedFactionManagerComponent trying to set fall back faction 'CIV' but this faction could not be found so it is null instead.
08:32:28.359 WORLD : WORLD : NotifyEntitiesInitialized
08:32:28.359 TERRAIN : TERRAIN : Initializing road networks...
08:32:28.360 PROFILING : Initializing road networks... took: 1.812000 ms
08:32:28.360 DEFAULT : DEFAULT : WorldVolumesCollection
08:32:28.415 PROFILING : WorldVolumesCollection took: 54.141000 ms
08:32:28.415 INIT : INIT : SoundWorldInit
08:32:28.422 PROFILING : SoundWorldInit took: 7.362000 ms
08:32:28.422 PROFILING : NotifyEntitiesInitialized took: 63.416000 ms
08:32:28.422 PROFILING : CreateEntities took: 12213.648000 ms
08:32:28.422 PROFILING : CreateEntities took: 12213.656000 ms
08:32:28.422 WORLD : WORLD : EOnActivate
08:32:28.451 PROFILING : EOnActivate took: 28.588000 ms
08:32:28.451 PROFILING : Game::LoadEntities took: 12243.502000 ms
08:32:28.539 NETWORK : Starting RPL server, listening on address 0.0.0.0:2001, fastValidation=false
08:32:29.005 DEFAULT : Entered online game state.
08:32:29.005 PROFILING : Settings changed took: 0.411000 ms
08:32:29.015 WORLD : Frame start
08:32:29.015 SCRIPT : ScenarioFramework: Available tasks are empty, no new tasks will be generated.
08:32:29.023 WORLD : UpdateEntities
08:32:29.023 WORLD : Frame
08:32:29.023 SCRIPT : SCR_BaseGameMode::OnGameStateChanged = GAME
08:32:30.376 SCRIPT : Rereintroduced [sites]: cache clearance position=<6086,211.538,7160> clear=1
08:32:30.379 SCRIPT : Rereintroduced [sites]: authored everon-prison-1 at <6090,211.444,7160>
08:32:30.379 SCRIPT : Rereintroduced [sites]: cache clearance position=<6150,203.288,7050> clear=1
08:32:30.382 SCRIPT : Rereintroduced [sites]: authored everon-supply-1 at <6150,203.288,7050>
08:32:30.383 SCRIPT : Rereintroduced [sites]: authored everon-radio-1 at <6500,159.756,7200>
08:32:30.401 SCRIPT : Rereintroduced [sites]: authored everon-extraction-1 at <7000,65.2562,7500>
08:32:30.401 SCRIPT : Rereintroduced [sites]: cache clearance position=<5960,220.256,7220> clear=1
08:32:30.402 SCRIPT : Rereintroduced [sites]: transport parking=<5960,220.256,7212> radius=4 terrainRange=0.8125 obstructed=0 clear=1
08:32:30.418 SCRIPT : Rereintroduced [sites]: authored everon-supply-2 at <5960,220.256,7220>
08:32:30.419 SCRIPT : Rereintroduced [sites]: cache clearance position=<6340,175.788,7400> clear=1
08:32:30.419 SCRIPT : Rereintroduced [sites]: authored everon-medical-1 at <6340,175.788,7400>
08:32:30.420 SCRIPT : Rereintroduced [sites]: cache clearance position=<6740,140.6,7300> clear=1
08:32:30.421 SCRIPT : Rereintroduced [sites]: cache clearance position=<6740,140.913,7296> clear=1
08:32:30.421 SCRIPT : Rereintroduced [sites]: cache clearance position=<6736,140.975,7300> clear=1
08:32:30.421 SCRIPT : Rereintroduced [sites]: cache clearance position=<6744,140.288,7300> clear=1
08:32:30.422 SCRIPT : Rereintroduced [sites]: authored everon-outpost-1 at <6740,140.6,7300>
08:32:30.422 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=0 origin=<7012,63.725,7500> up=1
08:32:30.422 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0 angularSpeed=0
08:32:30.422 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=0 engine=0 origin=<0,0,0> up=1 entityDifference=10267.5
08:32:30.422 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012,64.0216,7502.25>
08:32:30.422 SCRIPT : ERR GEAR TERRAIN: bottom=<7012,63.7216,7502.25> terrainY=63.2926 tireTerrainGap=0.428944
08:32:30.422 SCRIPT : ERR GEAR SUPPORT: center=<7012,64.0216,7502.25> radius=0.3 bottom=<7012,63.7216,7502.25> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:32:30.422 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.72,64.4897,7497.97>
08:32:30.422 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.72,64.0397,7497.97> terrainY=64.1655 tireTerrainGap=-0.125717
08:32:30.422 SCRIPT : ERR GEAR SUPPORT: center=<7009.72,64.4897,7497.97> radius=0.45 bottom=<7009.72,64.0397,7497.97> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:32:30.422 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.28,64.4898,7497.97>
08:32:30.422 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.28,64.0398,7497.97> terrainY=63.8096 tireTerrainGap=0.230156
08:32:30.422 SCRIPT : ERR GEAR SUPPORT: center=<7014.28,64.4898,7497.97> radius=0.45 bottom=<7014.28,64.0398,7497.97> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:31.175 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.175 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.175 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.175 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.442 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.07,63.5457,7499.69> up=0.995704
08:32:31.442 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.345002 angularSpeed=0.059733
08:32:31.442 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:31.442 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.04,63.6117,7501.97>
08:32:31.442 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.04,63.3117,7501.97> terrainY=63.3164 tireTerrainGap=-0.00473785
08:32:31.442 SCRIPT : ERR GEAR SUPPORT: center=<7012.04,63.6117,7501.97> radius=0.3 bottom=<7012.04,63.3117,7501.97> fraction=0.433053 normal=<-0,0.990257,0.139255> self=0 dynamic=0 supported=1 gap=-0.00472641
08:32:31.442 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.88,64.5942,7497.69>
08:32:31.442 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.88,64.1442,7497.69> terrainY=64.1567 tireTerrainGap=-0.0125656
08:32:31.442 SCRIPT : ERR GEAR SUPPORT: center=<7009.88,64.5942,7497.69> radius=0.45 bottom=<7009.88,64.1442,7497.69> fraction=0.397644 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=-0.0125198
08:32:31.442 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.42,64.2597,7497.75>
08:32:31.442 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.42,63.8097,7497.75> terrainY=63.8177 tireTerrainGap=-0.00805283
08:32:31.442 SCRIPT : ERR GEAR SUPPORT: center=<7014.42,64.2597,7497.75> radius=0.45 bottom=<7014.42,63.8097,7497.75> fraction=0.417778 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00808716
08:32:31.442 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:31.709 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:31.709 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:31.709 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.709 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:32.242 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:32.242 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:32.242 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:32.508 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.09,63.5355,7499.71> up=0.994317
08:32:32.508 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.102028 angularSpeed=0.0585238
08:32:32.508 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:32.508 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.05,63.6213,7501.99>
08:32:32.508 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.05,63.3213,7501.99> terrainY=63.3145 tireTerrainGap=0.00682831
08:32:32.508 SCRIPT : ERR GEAR SUPPORT: center=<7012.05,63.6213,7501.99> radius=0.3 bottom=<7012.05,63.3213,7501.99> fraction=0.485987 normal=<-0,0.990257,0.139255> self=0 dynamic=0 supported=1 gap=0.00691605
08:32:32.508 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.93,64.6035,7497.7>
08:32:32.508 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.93,64.1535,7497.7> terrainY=64.1488 tireTerrainGap=0.00473022
08:32:32.508 SCRIPT : ERR GEAR SUPPORT: center=<7009.93,64.6035,7497.7> radius=0.45 bottom=<7009.93,64.1535,7497.7> fraction=0.476164 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00476074
08:32:32.508 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.47,64.2666,7497.79>
08:32:32.508 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.47,63.8166,7497.79> terrainY=63.8149 tireTerrainGap=0.00174332
08:32:32.508 SCRIPT : ERR GEAR SUPPORT: center=<7014.47,64.2666,7497.79> radius=0.45 bottom=<7014.47,63.8166,7497.79> fraction=0.4625 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=0.00175095
08:32:32.508 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:32.508 SCRIPT : Rereintroduced [extraction placement]: native supported aircraft stable for one second, fuel present, exactly one initial wake
08:32:32.775 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:32.775 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:32.775 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:32.775 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.309 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.309 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.309 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.576 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.12,63.531,7499.75> up=0.994244
08:32:33.576 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.0510799 angularSpeed=0.0476384
08:32:33.576 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:33.576 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.07,63.6153,7502.02>
08:32:33.576 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.07,63.3153,7502.02> terrainY=63.3111 tireTerrainGap=0.00417709
08:32:33.576 SCRIPT : ERR GEAR SUPPORT: center=<7012.07,63.6153,7502.02> radius=0.3 bottom=<7012.07,63.3153,7502.02> fraction=0.473567 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00418472
08:32:33.576 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5924,7497.72>
08:32:33.576 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1424,7497.72> terrainY=64.1428 tireTerrainGap=-0.00038147
08:32:33.576 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5924,7497.72> radius=0.45 bottom=<7009.97,64.1424,7497.72> fraction=0.453169 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=-0.000297546
08:32:33.576 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.258,7497.83>
08:32:33.576 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.808,7497.83> terrainY=63.8124 tireTerrainGap=-0.00437546
08:32:33.576 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.258,7497.83> radius=0.45 bottom=<7014.51,63.808,7497.83> fraction=0.434444 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00442123
08:32:33.576 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:33.842 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:33.842 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.842 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:33.842 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:34.010 WORLD : UpdateEntities
08:32:34.010 WORLD : Frame
08:32:34.010 DEFAULT : FPS: 29.8, frame time (avg: 33.6 ms, min: 3.3 ms, max: 89.1 ms, mean: 33.3 ms, median: 33.3 ms), Mem: 996027 kB, Player: 0, AI: 29, AIChar: 22, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 698, Static: 57591, Disabled: 30 | New: 0, Del: 0, Bump: 16)
08:32:34.376 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:34.376 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:34.376 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:34.376 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:34.642 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.13,63.5286,7499.76> up=0.994199
08:32:34.642 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=0 speed=0 angularSpeed=0
08:32:34.642 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:34.642 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.08,63.6119,7502.03>
08:32:34.642 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.08,63.3119,7502.03> terrainY=63.3102 tireTerrainGap=0.00168228
08:32:34.642 SCRIPT : ERR GEAR SUPPORT: center=<7012.08,63.6119,7502.03> radius=0.3 bottom=<7012.08,63.3119,7502.03> fraction=0.462159 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00167465
08:32:34.642 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5928,7497.74>
08:32:34.642 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1428,7497.74> terrainY=64.1412 tireTerrainGap=0.00151825
08:32:34.642 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5928,7497.74> radius=0.45 bottom=<7009.97,64.1428,7497.74> fraction=0.461582 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00154877
08:32:34.642 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.2594,7497.84>
08:32:34.642 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.8094,7497.84> terrainY=63.8118 tireTerrainGap=-0.0024147
08:32:34.642 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.2594,7497.84> radius=0.45 bottom=<7014.51,63.8094,7497.84> fraction=0.443333 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00246811
08:32:34.642 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:34.909 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:34.909 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:34.909 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:34.909 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:35.442 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:35.442 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.442 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.442 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.708 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.13,63.5286,7499.76> up=0.994199
08:32:35.708 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=0 speed=0 angularSpeed=0
08:32:35.708 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:35.708 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.08,63.6119,7502.03>
08:32:35.709 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.08,63.3119,7502.03> terrainY=63.3102 tireTerrainGap=0.00168228
08:32:35.709 SCRIPT : ERR GEAR SUPPORT: center=<7012.08,63.6119,7502.03> radius=0.3 bottom=<7012.08,63.3119,7502.03> fraction=0.462159 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00167465
08:32:35.709 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5928,7497.74>
08:32:35.709 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1428,7497.74> terrainY=64.1412 tireTerrainGap=0.00151825
08:32:35.709 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5928,7497.74> radius=0.45 bottom=<7009.97,64.1428,7497.74> fraction=0.461582 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00154877
08:32:35.709 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.2594,7497.84>
08:32:35.709 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.8094,7497.84> terrainY=63.8118 tireTerrainGap=-0.0024147
08:32:35.709 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.2594,7497.84> radius=0.45 bottom=<7014.51,63.8094,7497.84> fraction=0.443333 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00246811
08:32:35.709 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:35.976 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.976 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.976 SCRIPT : Rereintroduced [sites]: 7 sites and 117 physical stock items ready
08:32:35.976 SCRIPT : Rereintroduced [environment]: date=authored weather=authored
08:32:35.977 SCRIPT : Rereintroduced [time]: started at 14:00 with 1x progression
08:32:35.977 SCRIPT : Rereintroduced [mission]: phase 0 -> 1
08:32:39.010 WORLD : UpdateEntities
08:32:39.010 WORLD : Frame
08:32:39.010 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 6.5 ms, max: 65.6 ms, mean: 33.3 ms, median: 33.3 ms), Mem: 1001182 kB, Player: 0, AI: 46, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 790, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:32:44.043 WORLD : UpdateEntities
08:32:44.043 WORLD : Frame
08:32:44.043 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 29.2 ms, max: 38.2 ms, mean: 33.3 ms, median: 33.5 ms), Mem: 1001296 kB, Player: 0, AI: 46, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 790, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:32:49.043 WORLD : UpdateEntities
08:32:49.043 WORLD : Frame
08:32:49.043 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 32.3 ms, max: 34.3 ms, mean: 33.3 ms, median: 33.4 ms), Mem: 1001371 kB, Player: 0, AI: 46, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 790, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:32:54.043 WORLD : UpdateEntities
08:32:54.043 WORLD : Frame
08:32:54.043 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 30.6 ms, max: 35.6 ms, mean: 33.3 ms, median: 33.3 ms), Mem: 1001500 kB, Player: 0, AI: 46, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 790, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:32:59.043 WORLD : UpdateEntities
08:32:59.043 WORLD : Frame
08:32:59.043 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 32.4 ms, max: 34.5 ms, mean: 33.3 ms, median: 33.4 ms), Mem: 1001492 kB, Player: 0, AI: 46, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 790, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:33:04.076 WORLD : UpdateEntities
08:33:04.076 WORLD : Frame
08:33:04.076 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 32.0 ms, max: 34.9 ms, mean: 33.3 ms, median: 33.3 ms), Mem: 1001452 kB, Player: 0, AI: 46, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 790, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:33:09.076 WORLD : UpdateEntities
08:33:09.076 WORLD : Frame
08:33:09.076 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 32.1 ms, max: 34.4 ms, mean: 33.3 ms, median: 33.5 ms), Mem: 1001493 kB, Player: 0, AI: 46, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 790, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:33:14.076 WORLD : UpdateEntities
08:33:14.076 WORLD : Frame
08:33:14.076 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 32.0 ms, max: 34.5 ms, mean: 33.3 ms, median: 33.4 ms), Mem: 1001501 kB, Player: 0, AI: 46, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 790, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:33:19.109 WORLD : UpdateEntities
08:33:19.109 WORLD : Frame
08:33:19.109 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 32.3 ms, max: 34.4 ms, mean: 33.3 ms, median: 33.4 ms), Mem: 1001522 kB, Player: 0, AI: 47, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 791, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:33:24.109 WORLD : UpdateEntities
08:33:24.109 WORLD : Frame
08:33:24.109 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 31.6 ms, max: 35.2 ms, mean: 33.3 ms, median: 33.4 ms), Mem: 1001558 kB, Player: 0, AI: 47, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 791, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:33:29.143 WORLD : UpdateEntities
08:33:29.143 WORLD : Frame
08:33:29.143 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 31.8 ms, max: 34.8 ms, mean: 33.3 ms, median: 33.5 ms), Mem: 1001460 kB, Player: 0, AI: 47, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 791, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:33:34.176 WORLD : UpdateEntities
08:33:34.176 WORLD : Frame
08:33:34.176 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 32.4 ms, max: 34.3 ms, mean: 33.3 ms, median: 33.4 ms), Mem: 1001558 kB, Player: 0, AI: 47, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 791, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
08:33:39.176 WORLD : UpdateEntities
08:33:39.176 WORLD : Frame
08:33:39.176 DEFAULT : FPS: 30.0, frame time (avg: 33.3 ms, min: 32.3 ms, max: 34.5 ms, mean: 33.3 ms, median: 33.5 ms), Mem: 1001527 kB, Player: 0, AI: 47, AIChar: 36, Veh: 0 (2), Proj (S: 0, M: 0, G: 0 | 0), Streaming(Dynam: 791, Static: 57591, Disabled: 31 | New: 0, Del: 0, Bump: 16)
@@ -0,0 +1,49 @@
---------------------------------------------
Log /tmp/work/profile/logs/logs_2026-09-19_08-32-13/error.log started at 2026-09-19 08:32:14 (2026-09-19 06:32:14 UTC)
08:32:14.505 SCRIPT : Compiling Game scripts
08:32:14.505 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,785": 'GetPlayerPlatformKind' is obsolete
08:32:14.505 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,786": 'GetPlayerPlatformId' is obsolete
08:32:14.728 SCRIPT (W): @"Scripts/Game/ERR/ERR_SiteService.c,191": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:32:14.739 SCRIPT (W): @"Scripts/Game/Workshop/SCR_AddonManager.c,876": 'GetRefCount' is obsolete: Will be removed
08:32:14.765 SCRIPT (W): @"Scripts/Game/Campaign/SCR_PlayerProfileManagerComponent.c,142": 'PlayerData' is obsolete
08:32:14.856 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,159": 'GetDSSession' is obsolete
08:32:14.856 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,162": 'RoomID' is obsolete
08:32:14.857 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,197": 'GetDSSession' is obsolete
08:32:14.857 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,201": 'RoomID' is obsolete
08:32:14.885 SCRIPT (W): @"Scripts/Game/ERR/ERR_CasualtyGroundSupport.c,21": 'GetBoneIndex' is obsolete: Use GetAnimation().GetBoneIndex() instead
08:32:14.929 SCRIPT (W): @"Scripts/Game/ERR/ERR_SpawnLogic.c,64": 'GetPlayerIdentityId' is obsolete
08:32:14.941 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,481": 'GetStorage' is obsolete
08:32:14.941 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,483": 'GetOnlineWritePrivilege' is obsolete
08:32:14.943 SCRIPT (W): @"Scripts/Game/Utilities/SCR_PlayerIdentityUtils.c,20": 'GetPlayerIdentityId' is obsolete
08:32:14.978 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,45": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:32:14.978 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,56": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:32:14.979 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,643": 'GetNotifyCount' is obsolete: Will be substitued by Notification Api.
08:32:14.979 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,645": 'GetNotifyItem' is obsolete: Will be substitued by Notification Api.
08:32:15.036 SCRIPT (W): @"Scripts/Game/DataCollection/PlayerData/SCR_PlayerData.c,210": 'PlayerData' is obsolete
08:32:16.058 WORLD : Entities load '$ERR_Core:Worlds/ERR_Everon.ent'
08:32:16.058 WORLD : Subscene load @"{853E92315D1D9EFE}worlds/Eden/Eden.ent"
08:32:16.058 RESOURCES : GetResourceObject @"{C8FAB83670BCF7C3}Prefabs/Structures/Cultural/Calvaries/CalvaryLarge_01.et"
08:32:16.058 WORLD : Entity prefab load @"{C8FAB83670BCF7C3}Prefabs/Structures/Cultural/Calvaries/CalvaryLarge_01.et"
08:32:16.058 RESOURCES (E): Wrong GUID/name for resource @"{45ECF6B1797D3CD9}system/wbdata/PreviewWindow/TransparentMat.emat" in property "AssignedMaterial"
08:32:19.448 WORLD : Game::LoadEntities
08:32:19.448 WORLD : CreateEntities
08:32:19.448 WORLD : CreateEntities
08:32:19.448 WORLD : Wait for preloading data
08:32:19.448 RESOURCES : GetResourceObject @"{58E62C5D17281925}Prefabs/Particles/Blasts/Blast_small_Invisible_Trigger.et"
08:32:19.448 WORLD : Entity prefab load @"{58E62C5D17281925}Prefabs/Particles/Blasts/Blast_small_Invisible_Trigger.et"
08:32:19.448 RESOURCES (E): Wrong GUID/name for resource @"{FF35BE9795BA3797}system/wbdata/Gizmo3D/sphere.xob" in property "Object"
08:32:23.175 ENTITY : Create entity @"ENTITY:610406" ('StaticModelEntity','Assets/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.xob') at <1931.796021 81.777000 5138.725098> @"{6A004A8F0571D456}Prefabs/Structures/Infrastructure/Towers/TransmitterTower_01/TransmitterTower_01_small.et"
08:32:23.175 ENTITY : CreateComponent 'ScriptedRadioComponent'
08:32:23.175 DEFAULT (W): World doesn't contain RadioManagerEntity to support any BaseRadioComponent.
08:32:25.294 ENTITY : Create entity @"ENTITY:1104061" ('StaticModelEntity') at <8831.291016 95.934265 2673.487061>
08:32:25.294 ENTITY : EntityPrefabUse @"{C8FAB83670BCF7C3}Prefabs/Structures/Cultural/Calvaries/CalvaryLarge_01.et"
08:32:25.294 RESOURCES : CreateComponentData @"{904345715F67BBAC}Assets/Structures/Cultural/Calvaries/CalvaryLarge_01/CalvaryLarge_01.xob"
08:32:25.294 MATERIAL : Material load @"{45ECF6B1797D3CD9}system/wbdata/PreviewWindow/TransparentMat.emat"
08:32:25.294 MATERIAL (E): Material file not found
08:32:25.294 MATERIAL (E): Cannot load material @"system/wbdata/PreviewWindow/TransparentMat.emat", creating default one (class MatPBRBasic)
08:32:27.847 WORLD : InitEntities 'world'
08:32:27.847 ENTITY : Init entity @"ENTITY:3" ('SCR_MapEntity1', SCR_MapEntity) at <6400.000000 0.000000 6400.000000> @"{E1B88C66BF6CA1F9}Prefabs/World/Game/Eden/MapEntity_Everon.et"
08:32:27.847 SCRIPT (W): SCR_MapEntity: Cannot get the size from terrain. Using default.
08:32:28.358 ENTITY : Init entity @"ENTITY:2305843009213693953" ('Rereintroduced', ERR_GameMode) at <1076.468018 51.000999 1325.246948> @"{978E045E53EF36C8}Prefabs/ERR/GameMode.et"
08:32:28.358 SCRIPT (W): SCR_PerceivedFactionManagerComponent trying to set fall back faction 'CIV' but this faction could not be found so it is null instead.
@@ -0,0 +1,173 @@
---------------------------------------------
Log /tmp/work/profile/logs/logs_2026-09-19_08-32-13/script.log started at 2026-09-19 08:32:13 (2026-09-19 06:32:13 UTC)
08:32:13.655 SCRIPT : SCRIPT : Initializing scripts
08:32:13.655 SCRIPT : SCRIPT : ScriptProjectManager init
08:32:13.698 SCRIPT : SCRIPT : Compiling GameLib scripts
08:32:13.727 SCRIPT : Module: GameLib; loaded 466x files; 608x classes; used 654K of static memory; defines: "PLATFORM_LINUX,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE"; CRC32: d66caacb
08:32:13.727 SCRIPT : SCRIPT : Compiling Game scripts
08:32:14.505 SCRIPT : Compiling Game scripts
08:32:14.505 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,785": 'GetPlayerPlatformKind' is obsolete
08:32:14.505 SCRIPT (W): @"Scripts/Game/Editor/Components/EditableEntity/SCR_EditableEntityComponent.c,786": 'GetPlayerPlatformId' is obsolete
08:32:14.728 SCRIPT (W): @"Scripts/Game/ERR/ERR_SiteService.c,191": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:32:14.739 SCRIPT (W): @"Scripts/Game/Workshop/SCR_AddonManager.c,876": 'GetRefCount' is obsolete: Will be removed
08:32:14.765 SCRIPT (W): @"Scripts/Game/Campaign/SCR_PlayerProfileManagerComponent.c,142": 'PlayerData' is obsolete
08:32:14.856 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,159": 'GetDSSession' is obsolete
08:32:14.856 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,162": 'RoomID' is obsolete
08:32:14.857 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,197": 'GetDSSession' is obsolete
08:32:14.857 SCRIPT (W): @"Scripts/Game/UI/Backend/CareerBackend.c,201": 'RoomID' is obsolete
08:32:14.885 SCRIPT (W): @"Scripts/Game/ERR/ERR_CasualtyGroundSupport.c,21": 'GetBoneIndex' is obsolete: Use GetAnimation().GetBoneIndex() instead
08:32:14.929 SCRIPT (W): @"Scripts/Game/ERR/ERR_SpawnLogic.c,64": 'GetPlayerIdentityId' is obsolete
08:32:14.941 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,481": 'GetStorage' is obsolete
08:32:14.941 SCRIPT (W): @"Scripts/Game/DataCollection/SCR_DataCollectorComponent.c,483": 'GetOnlineWritePrivilege' is obsolete
08:32:14.943 SCRIPT (W): @"Scripts/Game/Utilities/SCR_PlayerIdentityUtils.c,20": 'GetPlayerIdentityId' is obsolete
08:32:14.978 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,45": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:32:14.978 SCRIPT (W): @"Scripts/Game/ERR/ERR_ExtractionService.c,56": 'GetCompartmentType' is obsolete: Use GetType() on the compartment instance directly.
08:32:14.979 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,643": 'GetNotifyCount' is obsolete: Will be substitued by Notification Api.
08:32:14.979 SCRIPT (W): @"Scripts/Game/UI/Menu/MainMenuUI.c,645": 'GetNotifyItem' is obsolete: Will be substitued by Notification Api.
08:32:15.036 SCRIPT (W): @"Scripts/Game/DataCollection/PlayerData/SCR_PlayerData.c,210": 'PlayerData' is obsolete
08:32:15.140 SCRIPT : Module: Game; loaded 5732x files; 11115x classes; used 25833K of static memory; defines: "PLATFORM_LINUX,ENF_ENABLE_VHC_OVERRIDE,ENF_ENABLE_RPLCOMPONENT_IN_GAMECODE,ENABLE_BASE_DESTRUCTION,BUDGET_OPTIMIZATION_CHECKS,DEBUG,RESPAWN_TIMER_COMPONENT_DEBUG,DEBUG_CONFIGURABLE_DIALOGS,DISABLE_WEAPON_SWITCHING,SCRIPTED_AIM_MODIFIER_DEBUG"; CRC32: 2ef250fb
08:32:27.847 SCRIPT (W): SCR_MapEntity: Cannot get the size from terrain. Using default.
08:32:28.358 SCRIPT (W): SCR_PerceivedFactionManagerComponent trying to set fall back faction 'CIV' but this faction could not be found so it is null instead.
08:32:29.015 SCRIPT : ScenarioFramework: Available tasks are empty, no new tasks will be generated.
08:32:29.023 SCRIPT : SCR_BaseGameMode::OnGameStateChanged = GAME
08:32:30.376 SCRIPT : Rereintroduced [sites]: cache clearance position=<6086,211.538,7160> clear=1
08:32:30.379 SCRIPT : Rereintroduced [sites]: authored everon-prison-1 at <6090,211.444,7160>
08:32:30.379 SCRIPT : Rereintroduced [sites]: cache clearance position=<6150,203.288,7050> clear=1
08:32:30.382 SCRIPT : Rereintroduced [sites]: authored everon-supply-1 at <6150,203.288,7050>
08:32:30.383 SCRIPT : Rereintroduced [sites]: authored everon-radio-1 at <6500,159.756,7200>
08:32:30.401 SCRIPT : Rereintroduced [sites]: authored everon-extraction-1 at <7000,65.2562,7500>
08:32:30.401 SCRIPT : Rereintroduced [sites]: cache clearance position=<5960,220.256,7220> clear=1
08:32:30.402 SCRIPT : Rereintroduced [sites]: transport parking=<5960,220.256,7212> radius=4 terrainRange=0.8125 obstructed=0 clear=1
08:32:30.418 SCRIPT : Rereintroduced [sites]: authored everon-supply-2 at <5960,220.256,7220>
08:32:30.419 SCRIPT : Rereintroduced [sites]: cache clearance position=<6340,175.788,7400> clear=1
08:32:30.419 SCRIPT : Rereintroduced [sites]: authored everon-medical-1 at <6340,175.788,7400>
08:32:30.420 SCRIPT : Rereintroduced [sites]: cache clearance position=<6740,140.6,7300> clear=1
08:32:30.421 SCRIPT : Rereintroduced [sites]: cache clearance position=<6740,140.913,7296> clear=1
08:32:30.421 SCRIPT : Rereintroduced [sites]: cache clearance position=<6736,140.975,7300> clear=1
08:32:30.421 SCRIPT : Rereintroduced [sites]: cache clearance position=<6744,140.288,7300> clear=1
08:32:30.422 SCRIPT : Rereintroduced [sites]: authored everon-outpost-1 at <6740,140.6,7300>
08:32:30.422 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=0 origin=<7012,63.725,7500> up=1
08:32:30.422 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0 angularSpeed=0
08:32:30.422 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=0 engine=0 origin=<0,0,0> up=1 entityDifference=10267.5
08:32:30.422 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012,64.0216,7502.25>
08:32:30.422 SCRIPT : ERR GEAR TERRAIN: bottom=<7012,63.7216,7502.25> terrainY=63.2926 tireTerrainGap=0.428944
08:32:30.422 SCRIPT : ERR GEAR SUPPORT: center=<7012,64.0216,7502.25> radius=0.3 bottom=<7012,63.7216,7502.25> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:32:30.422 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.72,64.4897,7497.97>
08:32:30.422 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.72,64.0397,7497.97> terrainY=64.1655 tireTerrainGap=-0.125717
08:32:30.422 SCRIPT : ERR GEAR SUPPORT: center=<7009.72,64.4897,7497.97> radius=0.45 bottom=<7009.72,64.0397,7497.97> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:32:30.422 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.28,64.4898,7497.97>
08:32:30.422 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.28,64.0398,7497.97> terrainY=63.8096 tireTerrainGap=0.230156
08:32:30.422 SCRIPT : ERR GEAR SUPPORT: center=<7014.28,64.4898,7497.97> radius=0.45 bottom=<7014.28,64.0398,7497.97> fraction=1 normal=<0,0,0> self=0 dynamic=0 supported=0 gap=0.119999
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:30.422 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=0 conscious=0 nativeComplete=0
08:32:31.175 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.175 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.175 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.175 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.442 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.07,63.5457,7499.69> up=0.995704
08:32:31.442 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.345002 angularSpeed=0.059733
08:32:31.442 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:31.442 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.04,63.6117,7501.97>
08:32:31.442 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.04,63.3117,7501.97> terrainY=63.3164 tireTerrainGap=-0.00473785
08:32:31.442 SCRIPT : ERR GEAR SUPPORT: center=<7012.04,63.6117,7501.97> radius=0.3 bottom=<7012.04,63.3117,7501.97> fraction=0.433053 normal=<-0,0.990257,0.139255> self=0 dynamic=0 supported=1 gap=-0.00472641
08:32:31.442 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.88,64.5942,7497.69>
08:32:31.442 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.88,64.1442,7497.69> terrainY=64.1567 tireTerrainGap=-0.0125656
08:32:31.442 SCRIPT : ERR GEAR SUPPORT: center=<7009.88,64.5942,7497.69> radius=0.45 bottom=<7009.88,64.1442,7497.69> fraction=0.397644 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=-0.0125198
08:32:31.442 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.42,64.2597,7497.75>
08:32:31.442 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.42,63.8097,7497.75> terrainY=63.8177 tireTerrainGap=-0.00805283
08:32:31.442 SCRIPT : ERR GEAR SUPPORT: center=<7014.42,64.2597,7497.75> radius=0.45 bottom=<7014.42,63.8097,7497.75> fraction=0.417778 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00808716
08:32:31.442 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:31.709 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:31.709 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:31.709 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:31.709 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=1 conscious=1 nativeComplete=0
08:32:32.242 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:32.242 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:32.242 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:32.508 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.09,63.5355,7499.71> up=0.994317
08:32:32.508 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.102028 angularSpeed=0.0585238
08:32:32.508 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:32.508 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.05,63.6213,7501.99>
08:32:32.508 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.05,63.3213,7501.99> terrainY=63.3145 tireTerrainGap=0.00682831
08:32:32.508 SCRIPT : ERR GEAR SUPPORT: center=<7012.05,63.6213,7501.99> radius=0.3 bottom=<7012.05,63.3213,7501.99> fraction=0.485987 normal=<-0,0.990257,0.139255> self=0 dynamic=0 supported=1 gap=0.00691605
08:32:32.508 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.93,64.6035,7497.7>
08:32:32.508 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.93,64.1535,7497.7> terrainY=64.1488 tireTerrainGap=0.00473022
08:32:32.508 SCRIPT : ERR GEAR SUPPORT: center=<7009.93,64.6035,7497.7> radius=0.45 bottom=<7009.93,64.1535,7497.7> fraction=0.476164 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00476074
08:32:32.508 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.47,64.2666,7497.79>
08:32:32.508 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.47,63.8166,7497.79> terrainY=63.8149 tireTerrainGap=0.00174332
08:32:32.508 SCRIPT : ERR GEAR SUPPORT: center=<7014.47,64.2666,7497.79> radius=0.45 bottom=<7014.47,63.8166,7497.79> fraction=0.4625 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=0.00175095
08:32:32.508 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:32.508 SCRIPT : Rereintroduced [extraction placement]: native supported aircraft stable for one second, fuel present, exactly one initial wake
08:32:32.775 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:32.775 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:32.775 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=2 conscious=2 nativeComplete=0
08:32:32.775 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.309 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.309 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.309 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.576 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.12,63.531,7499.75> up=0.994244
08:32:33.576 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=1 speed=0.0510799 angularSpeed=0.0476384
08:32:33.576 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:33.576 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.07,63.6153,7502.02>
08:32:33.576 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.07,63.3153,7502.02> terrainY=63.3111 tireTerrainGap=0.00417709
08:32:33.576 SCRIPT : ERR GEAR SUPPORT: center=<7012.07,63.6153,7502.02> radius=0.3 bottom=<7012.07,63.3153,7502.02> fraction=0.473567 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00418472
08:32:33.576 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5924,7497.72>
08:32:33.576 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1424,7497.72> terrainY=64.1428 tireTerrainGap=-0.00038147
08:32:33.576 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5924,7497.72> radius=0.45 bottom=<7009.97,64.1424,7497.72> fraction=0.453169 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=-0.000297546
08:32:33.576 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.258,7497.83>
08:32:33.576 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.808,7497.83> terrainY=63.8124 tireTerrainGap=-0.00437546
08:32:33.576 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.258,7497.83> radius=0.45 bottom=<7014.51,63.808,7497.83> fraction=0.434444 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00442123
08:32:33.576 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:33.842 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:33.842 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=3 conscious=3 nativeComplete=0
08:32:33.842 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:33.842 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:34.376 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:34.376 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:34.376 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:34.376 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=4 conscious=4 nativeComplete=0
08:32:34.642 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.13,63.5286,7499.76> up=0.994199
08:32:34.642 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=0 speed=0 angularSpeed=0
08:32:34.642 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:34.642 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.08,63.6119,7502.03>
08:32:34.642 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.08,63.3119,7502.03> terrainY=63.3102 tireTerrainGap=0.00168228
08:32:34.642 SCRIPT : ERR GEAR SUPPORT: center=<7012.08,63.6119,7502.03> radius=0.3 bottom=<7012.08,63.3119,7502.03> fraction=0.462159 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00167465
08:32:34.642 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5928,7497.74>
08:32:34.642 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1428,7497.74> terrainY=64.1412 tireTerrainGap=0.00151825
08:32:34.642 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5928,7497.74> radius=0.45 bottom=<7009.97,64.1428,7497.74> fraction=0.461582 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00154877
08:32:34.642 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.2594,7497.84>
08:32:34.642 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.8094,7497.84> terrainY=63.8118 tireTerrainGap=-0.0024147
08:32:34.642 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.2594,7497.84> radius=0.45 bottom=<7014.51,63.8094,7497.84> fraction=0.443333 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00246811
08:32:34.642 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:34.909 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:34.909 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:34.909 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:34.909 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:35.442 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=5 conscious=5 nativeComplete=0
08:32:35.442 SCRIPT : Rereintroduced [guards]: initial site=everon-extraction-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.442 SCRIPT : Rereintroduced [guards]: initial site=everon-supply-2 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.442 SCRIPT : Rereintroduced [guards]: initial site=everon-outpost-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.708 SCRIPT : ERR EXTRACTION PLACEMENT: wakes=1 alive=1 ready=1 origin=<7012.13,63.5286,7499.76> up=0.994199
08:32:35.708 SCRIPT : ERR EXTRACTION PHYSICS: dynamic=1 awake=0 speed=0 angularSpeed=0
08:32:35.708 SCRIPT : ERR EXTRACTION NATIVE: valid=1 contact=1 engine=0 origin=<0,0,0> up=1 entityDifference=10267.4
08:32:35.708 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_F node=-1704401612 center=<7012.08,63.6119,7502.03>
08:32:35.709 SCRIPT : ERR GEAR TERRAIN: bottom=<7012.08,63.3119,7502.03> terrainY=63.3102 tireTerrainGap=0.00168228
08:32:35.709 SCRIPT : ERR GEAR SUPPORT: center=<7012.08,63.6119,7502.03> radius=0.3 bottom=<7012.08,63.3119,7502.03> fraction=0.462159 normal=<0,0.996962,0.0778877> self=0 dynamic=0 supported=1 gap=0.00167465
08:32:35.709 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bL node=-410678372 center=<7009.97,64.5928,7497.74>
08:32:35.709 SCRIPT : ERR GEAR TERRAIN: bottom=<7009.97,64.1428,7497.74> terrainY=64.1412 tireTerrainGap=0.00151825
08:32:35.709 SCRIPT : ERR GEAR SUPPORT: center=<7009.97,64.5928,7497.74> radius=0.45 bottom=<7009.97,64.1428,7497.74> fraction=0.461582 normal=<0.139105,0.989191,0.0463683> self=0 dynamic=0 supported=1 gap=0.00154877
08:32:35.709 SCRIPT : ERR GEAR PIVOT: bone=v_wheel_bR node=-410678366 center=<7014.51,64.2594,7497.84>
08:32:35.709 SCRIPT : ERR GEAR TERRAIN: bottom=<7014.51,63.8094,7497.84> terrainY=63.8118 tireTerrainGap=-0.0024147
08:32:35.709 SCRIPT : ERR GEAR SUPPORT: center=<7014.51,64.2594,7497.84> radius=0.45 bottom=<7014.51,63.8094,7497.84> fraction=0.443333 normal=<0.015606,0.998782,0.0468179> self=0 dynamic=0 supported=1 gap=-0.00246811
08:32:35.709 SCRIPT : ERR EXTRACTION FUEL: manager=1 hasFuel=1
08:32:35.976 SCRIPT : Rereintroduced [guards]: initial site=everon-prison-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.976 SCRIPT : Rereintroduced [guards]: initial site=everon-radio-1 requested=6 physical=6 conscious=6 nativeComplete=1
08:32:35.976 SCRIPT : Rereintroduced [sites]: 7 sites and 117 physical stock items ready
08:32:35.976 SCRIPT : Rereintroduced [environment]: date=authored weather=authored
08:32:35.977 SCRIPT : Rereintroduced [time]: started at 14:00 with 1x progression
08:32:35.977 SCRIPT : Rereintroduced [mission]: phase 0 -> 1
@@ -0,0 +1,96 @@
EngineUserSettings {
GameProjectUserSettings GameProjectUserSettings {
}
GraphicsQualitySettings GraphicsQualitySettings {
}
GrassMaterialSettings GrassMaterialSettings {
}
InputDeviceUserSettings InputDeviceUserSettings {
GamepadProfile InputProfileGamepad "{6A66680D49B27FD4}" {
LeftThumbHorizontal InputProfileKey "{6A66680D49B27FD3}" {
Transition CurveCubicSplineFloat "{6A66680D49B27FD2}" {
}
}
LeftThumbVertical InputProfileKey "{6A66680D49B27FD1}" {
Transition CurveCubicSplineFloat "{6A66680D49B3A9D2}" {
}
}
RightThumbHorizontal InputProfileKey "{6A66680D49B3A9D3}" {
Transition CurveCubicSplineFloat "{6A66680D49B3DB15}" {
}
}
RightThumbVertical InputProfileKey "{6A66680D49B3274B}" {
Transition CurveCubicSplineFloat "{6A66680D49ACB6DD}" {
}
}
LeftTrigger InputProfileKey "{6A66680D49AC34C2}" {
Transition CurveCubicSplineFloat "{6A66680D49AC2D4F}" {
}
}
RightTrigger InputProfileKey "{6A66680D49AC2DB0}" {
Transition CurveCubicSplineFloat "{6A66680D49AC696F}" {
}
}
}
JoystickProfile InputProfileJoystick "{6A66680D49AD8C01}" {
Axis00 InputProfileKey "{6A66680D49ADDFE7}" {
Transition CurveCubicSplineFloat "{6A66680D49ADDFE6}" {
}
}
Axis01 InputProfileKey "{6A66680D49AD0E94}" {
Transition CurveCubicSplineFloat "{6A66680D49AD6C11}" {
}
}
Axis02 InputProfileKey "{6A66680D49AEB567}" {
Transition CurveCubicSplineFloat "{6A66680D49AE8459}" {
}
}
Axis03 InputProfileKey "{6A66680D49AED11D}" {
Transition CurveCubicSplineFloat "{6A66680D49AE15EA}" {
}
}
Axis04 InputProfileKey "{6A66680D49AE15E9}" {
Transition CurveCubicSplineFloat "{6A66680D49AE4DC2}" {
}
}
Axis05 InputProfileKey "{6A66680D49AF9DFD}" {
Transition CurveCubicSplineFloat "{6A66680D49AFC7C3}" {
}
}
Axis06 InputProfileKey "{6A66680D49AF1B25}" {
Transition CurveCubicSplineFloat "{6A66680D49AF6CCB}" {
}
}
Axis07 InputProfileKey "{6A66680D49AF4E2B}" {
Transition CurveCubicSplineFloat "{6A66680D49A8B72B}" {
}
}
Axis08 InputProfileKey "{6A66680D49A8AB2F}" {
Transition CurveCubicSplineFloat "{6A66680D49A8AB2E}" {
}
}
Axis09 InputProfileKey "{6A66680D49A88A2C}" {
Transition CurveCubicSplineFloat "{6A66680D49A80A0F}" {
}
}
}
}
MaterialSystemUserSettings MaterialSystemUserSettings {
}
PostprocessUserSettings PostprocessUserSettings {
}
ResourceManagerUserSettings ResourceManagerUserSettings {
}
TerrainGenMaterialSettings TerrainGenMaterialSettings {
}
UserInterfaceSettings UserInterfaceSettings {
LanguageCode "en_us"
SystemLanguageCode "en_us"
}
VideoUserSettings VideoUserSettings {
WindowPosX -640
WindowPosY -360
}
WaterPoolMaterialSettings WaterPoolMaterialSettings {
}
}
@@ -0,0 +1,116 @@
{
"command": [
"bwrap",
"--unshare-net",
"--unshare-pid",
"--unshare-ipc",
"--unshare-uts",
"--die-with-parent",
"--cap-drop",
"ALL",
"--clearenv",
"--ro-bind",
"/",
"/",
"--tmpfs",
"/home",
"--tmpfs",
"/tmp",
"--tmpfs",
"/run",
"--proc",
"/proc",
"--dev",
"/dev",
"--ro-bind",
"/tmp/erri-dedicated-runtime/server",
"/tmp/runtime",
"--bind",
"/tmp/erri-dedicated-native-build/attempt-02-header/source",
"/tmp/source",
"--bind",
"/tmp/erri-dedicated-native-build/attempt-02-header",
"/tmp/work",
"--setenv",
"HOME",
"/tmp/work/home",
"--setenv",
"TMPDIR",
"/tmp/work/tmp",
"--setenv",
"XDG_CONFIG_HOME",
"/tmp/work/home/.config",
"--setenv",
"XDG_DATA_HOME",
"/tmp/work/home/.local/share",
"--setenv",
"XDG_CACHE_HOME",
"/tmp/work/home/.cache",
"--setenv",
"PATH",
"/usr/bin:/bin",
"--setenv",
"LANG",
"C.UTF-8",
"--chdir",
"/tmp/runtime",
"/usr/bin/python3",
"-c",
"import json,os,socket,sys\nstate={\"netns\":os.readlink(\"/proc/self/ns/net\"),\"interfaces\":socket.if_nameindex(),\"routes\":open(\"/proc/net/route\").read(),\"ipv6Routes\":open(\"/proc/net/ipv6_route\").read()}\nprint(\"ERR ISOLATION \"+json.dumps(state),flush=True)\nassert state[\"netns\"] != sys.argv[1], \"network namespace was not isolated\"\nassert [name for _,name in state[\"interfaces\"]] == [\"lo\"], \"non-loopback interface present\"\nassert len(state[\"routes\"].splitlines()) == 1, \"IPv4 route present\"\nassert all(line.split()[-1] == \"lo\" for line in state[\"ipv6Routes\"].splitlines()), \"non-loopback IPv6 route present\"\nif len(sys.argv)>2: os.execv(sys.argv[2],sys.argv[2:])\n",
"net:[4026531833]",
"/tmp/runtime/ArmaReforgerServer",
"-addonsDir",
"/tmp/source/addons",
"-addons",
"2528466DE220D91C",
"-profile",
"/tmp/work/profile",
"-noBackend",
"-noSound",
"-noSplash",
"-noThrow",
"-bindIP",
"127.0.0.1",
"-bindPort",
"2001",
"-maxFPS",
"30",
"-logStats",
"5000",
"-server",
"{AD62322D5213C440}Missions/ERR_Everon_Base.conf"
],
"engine": [
"/tmp/runtime/ArmaReforgerServer",
"-addonsDir",
"/tmp/source/addons",
"-addons",
"2528466DE220D91C",
"-profile",
"/tmp/work/profile",
"-noBackend",
"-noSound",
"-noSplash",
"-noThrow",
"-bindIP",
"127.0.0.1",
"-bindPort",
"2001",
"-maxFPS",
"30",
"-logStats",
"5000",
"-server",
"{AD62322D5213C440}Missions/ERR_Everon_Base.conf"
],
"seconds": 90,
"binarySHA256": "91fdf333ec49c266d309be358aabab4244a93a2f9cfa11853a600e026104001f",
"serverLaunched": true,
"realPlayers": 0,
"multiplayerProven": false,
"supervisorPid": 2151422,
"startedUTC": "2026-09-19T06:32:13Z",
"timeout": true,
"exit": -15,
"finishedUTC": "2026-09-19T06:33:43Z"
}
@@ -0,0 +1,23 @@
{
"scriptErrors": [],
"nativeErrors": [
"08:32:16.058 RESOURCES (E): Wrong GUID/name for resource @\"{45ECF6B1797D3CD9}system/wbdata/PreviewWindow/TransparentMat.emat\" in property \"AssignedMaterial\"",
"08:32:19.448 RESOURCES (E): Wrong GUID/name for resource @\"{FF35BE9795BA3797}system/wbdata/Gizmo3D/sphere.xob\" in property \"Object\"",
"08:32:25.294 MATERIAL (E): Material file not found",
"08:32:25.294 MATERIAL (E): Cannot load material @\"system/wbdata/PreviewWindow/TransparentMat.emat\", creating default one (class MatPBRBasic)"
],
"evidence": [
"08:32:13.672 BACKEND : Backend Services are disabled.",
"08:32:15.175 ENGINE : Game successfully created.",
"08:32:15.458 DEFAULT : [SaveGameManager] Starting new playthrough nr.0 '' for mission '{AD62322D5213C440}Missions/ERR_Everon_Base.conf'.",
"08:32:16.207 WORLD : WORLD : Initializing world systems @\"{C50579A2EC48E8EF}Configs/Systems/MissionSystems.conf\"",
"08:32:28.539 NETWORK : Starting RPL server, listening on address 0.0.0.0:2001, fastValidation=false",
"08:32:35.977 SCRIPT : Rereintroduced [mission]: phase 0 -> 1"
],
"limits": [
"No real players or authentication; no multiplayer/performance acceptance",
"90-second supervisor termination, not graceful mission teardown",
"Native installed-asset resource errors preserved; no all-clean claim",
"No direct RplSession.Mode script instrumentation in this unchanged-source run"
]
}
@@ -0,0 +1,279 @@
{
".gitattributes": "86cd7c797b8cac2699f5959add72303d5474f34fb0d141c36e6d8d095f7bc718",
".gitignore": "1647a8de89a13712bdb3678396c3d09b268e90e99b17bd56a1462eef7efd00d1",
"README.md": "557ecb725cb83911cba20c285624bc2f7cd527932407f87844f824e12821524d",
"addons/ai/Prefabs/ERR/MortarCrew.et": "05d3e7353ff9fe5523218a1487b31b7b742b0be8adbcb060c7099978cf008bce",
"addons/ai/Prefabs/ERR/MortarCrew.et.meta": "fdfd4fcd21a67c3d698fa4aadc4e5c76e665cebf4be86013bc389e493fab63cc",
"addons/ai/Scripts/Game/ERR/ERR_HQ.c": "ceafd6740ed277748744ce56ac0f0bb3a8521fcc060dafb2cdb99896aedf405a",
"addons/ai/Scripts/Game/ERR/ERR_HQJournal.c": "b3e402cfe92d415f37f666045afb062e6e11670ba03a0ca6f2d9fd4fc3520ac1",
"addons/ai/Scripts/Game/ERR/ERR_HQNetwork.c": "92ff2caca52e94c2cc9642dfc8509ce6e9349b257012bade8650bace9231128c",
"addons/ai/Scripts/Game/ERR/ERR_HQObservation.c": "36c978ec5f052213ac1236e1398d85063efbfd7ef60fe04f1fc11447fefe1d68",
"addons/ai/Scripts/Game/ERR/ERR_HQReport.c": "c4d16ccb571db4d9444c0a8d2be7318845d25ff90238b6d304e96a9ea19f1a08",
"addons/ai/Scripts/Game/ERR/ERR_HelicopterAvailability.c": "60eaef2f6d4b2fd44861c5a4434ef97e732e40a5ff7401e2da451ed2dd9c2762",
"addons/ai/Scripts/Game/ERR/ERR_MortarBattery.c": "20a5b1975c2b185afd1b9b476f19730bae24064fab4d0e6538fc44bc49818b21",
"addons/ai/Scripts/Game/ERR/ERR_MortarFiring.c": "b843484cd73340a6f865f06ce16b5405b26b9d460a89e8598234c6f27332890b",
"addons/ai/Scripts/Game/ERR/ERR_MortarPrediction.c": "470dd196ed64800c697d24c09d1344bacd2502587fac76af4ee0edae2563092d",
"addons/ai/Scripts/Game/ERR/ERR_MortarReadiness.c": "1a7282d9bd53dcd115d53c9b460ca62d3218931a74635cc516eac1a13b7d9347",
"addons/ai/Scripts/Game/ERR/ERR_MortarSalvo.c": "697c01f479df6c505a41d984a29c02002e3052114dafa2ec6252ae55e2979a2b",
"addons/ai/Scripts/Game/ERR/ERR_MortarSupplyTransfer.c": "34f7eaa01dc68e97aae8c1177b7f8fd6c15d5a41c6dc86de377f00b3613a8e77",
"addons/ai/Scripts/Game/ERR/ERR_MortarSystem.c": "60b05d729ee961196b3e3d27bb7942d7aacdf1e42a38f7d63ec2499eea3ed2eb",
"addons/ai/Scripts/Game/ERR/ERR_NativeMortarFiringProbe.c": "d66e57ada46678eb0a6dfa6ff818b656f6132c4eed28881abafafa1e44f8cd2c",
"addons/ai/Scripts/Game/ERR/ERR_NativePatrolHQProbe.c": "4c04aa3e1b6b000747da8e2a919a6501107880fd041134c019f516665bb6f758",
"addons/ai/Scripts/Game/ERR/ERR_SettlementSafety.c": "e5c0ebc95521a9a33a3f7d9cca6c551dda862a08b7af20b017877aba9584795b",
"addons/ai/Scripts/Game/ERR/ERR_SupportScenario.c": "71757018ec9716c4dc24f62a292a214919d3fd5daed3c16e03e56abd208e9f03",
"addons/ai/addon.gproj": "5f559db8f526700db11e6ae763f5245f19b7006fc68c56e4c09fb6f940bdf2a1",
"addons/ai/resourceDatabase.rdb": "129c2d601531447ffd1864982af3f9fec03ed64db23623d44e29115c0c1998c2",
"addons/chat/Missions/ERR_Everon.conf": "76f3ac0d21b585654beac7ddd68e3c8cbdd66dbfe909b17b04838fa813a7c29b",
"addons/chat/Missions/ERR_Everon.conf.meta": "0a23c98bf83873536c65fa17d38dea33a1d7b9e4ab210f90633ff688abcc551f",
"addons/chat/Scripts/Game/ERR/ERR_AdminCommands.c": "d7b4ed95fc32767911936cb0fcc60763233f2c31afd34a6a0fa998b39cec9f5c",
"addons/chat/Scripts/Game/ERR/ERR_NativeMortarProbe.c": "ddb892141500c192c0787b011d57dd8c07dd8c9a3ca5fdc407f6c271897bde0a",
"addons/chat/Scripts/Game/ERR/ERR_NativeRadioProbe.c": "84524163c63402755b4f834f74dfe6d8e5c397dc26031f532593c6f79f5a93b1",
"addons/chat/Scripts/Game/ERR/ERR_NativeSmoke.c": "0fe7825e6c2feea1bac766a5d8c904124f577aea3ff07d21b1d440c89d3a47b7",
"addons/chat/Scripts/Game/ERRChat/ERR_OrdinaryScenarioLaunchChat.c": "dda715c9691d366e35fa2ad5e390dee1971651f137a5a9f9aeb23dcbe53ec87e",
"addons/chat/Scripts/WorkbenchGame/ERR/ERR_ValidateWorldPlugin.c": "81c92d408ce88cc9f98d6053f1d0c863427693ba748f00df9f1bf8079015ef94",
"addons/chat/addon.gproj": "ea1587e0174cf795334d306c71d99b06797fc891427cd57b6cab6e21cf0e4e0e",
"addons/chat/resourceDatabase.rdb": "d9a737a8d09f9fced6b1e7fe108e477c0fc9877ad044f3c5be0aaa7c60b0056e",
"addons/core/Configs/ERR/EveronSites.conf": "ade92cc8d2b14a84ac378bbbb52608b351dca65d359dd7a315d64a145fa4b46f",
"addons/core/Configs/ERR/EveronSites.conf.meta": "d5fe68025ef4e7c1e16082cf5873b7c7172eacbfaef4ab29b7e0e3c98f8dca56",
"addons/core/Configs/ERR/Factions/MissionVehicles.conf": "5f74f4a7089c7e7b54ad62463159ce8f0bab25a6b85268dc3872ea6001e048fb",
"addons/core/Configs/ERR/Factions/MissionVehicles.conf.meta": "00c368b6271d3440cc8bf627b03a384d247635723923fc5ad2104b8b4007b035",
"addons/core/Configs/ERR/Factions/US.conf": "4c3da063abb6e3ee39a6e4e0c5a9ffd5eae9d209d58470ea18b45dba5528db1b",
"addons/core/Configs/ERR/Factions/US.conf.meta": "a05469aef028e9e17eba545e81e2af2887b59f0fef17dac51a23c7b8155e381b",
"addons/core/Configs/ERR/Factions/USSR.conf": "407ea27f80a64c5184c089d43cdd0bdabfc5974c84f1d2a245081fdf2afa3f30",
"addons/core/Configs/ERR/Factions/USSR.conf.meta": "057397d97096346791b51b7b13fbe18af218bcf78e9984d9c01b49a2403de611",
"addons/core/Configs/ERR/GameOverScreens.conf": "45231061911a1462d45fb6db0fecc2b0793f17b5ae71017174954ff4fbd20236",
"addons/core/Configs/ERR/GameOverScreens.conf.meta": "eb654b745c0b97b41c991694569ef4877a3c2315e0826f9556337cd68690843e",
"addons/core/Configs/ERR/VanillaFactions.conf": "db890b61b48ee15484041fd2245a862d9fa9e7ba21b1229c281ff37c448a35b1",
"addons/core/Configs/ERR/VanillaFactions.conf.meta": "ac77725c0c21974991ef47a466b88122e939de8b46fd23e68889e7674cbb2bfd",
"addons/core/Missions/ERR_Everon_Base.conf": "1e6a0e9a756d15495201f71121626890f01efe6b00154c561672d4ec157960bd",
"addons/core/Missions/ERR_Everon_Base.conf.meta": "9b16267c644d815bcf98a3a3aaff30b93d7224fb24d3a2bac66730a28011f317",
"addons/core/Prefabs/ERR/Extraction.et": "1aa286ef253c5410f09fa641e4be91a7be8ec834487a7fbb74cfb45cab60ee1e",
"addons/core/Prefabs/ERR/Extraction.et.meta": "c2a838633001e2e3a202d39cb33aa744ebcd996017ad032359069641b5d13853",
"addons/core/Prefabs/ERR/FactionManager.et": "425f916b890019c537f6b2f72b1af9e7be54b0a476320da969e1f313a7ac5ea5",
"addons/core/Prefabs/ERR/FactionManager.et.meta": "9bf53d5e4bcbe60dd1a4ece1409fc23c349055c860708620f5f6e9716290a97d",
"addons/core/Prefabs/ERR/FieldCover.et": "20f8095e69dbfe3db74ff19078e528ea75405362b335e03560ccd61f8df2e7f3",
"addons/core/Prefabs/ERR/FieldCover.et.meta": "83461ffa76244e1d69f20b053a9741ccdf7d127009182bd540a7e5ba6150c3d9",
"addons/core/Prefabs/ERR/GameMode.et": "385c97a5b8067091d92aa60c2d4fcf02002cf606b95523866ead65c96b8c0029",
"addons/core/Prefabs/ERR/GameMode.et.meta": "106769cd34525c9d440057072836cb7401a6752148c40edd7fe61c03bd58328c",
"addons/core/Prefabs/ERR/ObjectiveDocument.et": "2e72270bf186654af12d2c3ff9bf940690b03fb17fca44f873c1fde5d11384c0",
"addons/core/Prefabs/ERR/ObjectiveDocument.et.meta": "eaba9903be147b98a1106e2273e2270773df73b9b22f2cd4e20136a8e281382e",
"addons/core/Prefabs/ERR/Patrol.et": "c5685a8bc311cc5563fb3334beec9408d3d7a1069152fddeeb7df4f1b7f9e6ce",
"addons/core/Prefabs/ERR/Patrol.et.meta": "7c5da568fa2fcf0709ee2959253cb068d7c7ed7c2467af3b247a7e70efd96b69",
"addons/core/Prefabs/ERR/Prison.et": "1503db1441d8cd7a4f0b45c27ba9623b9fa39f0f81016e180bd2aa1379e1f42a",
"addons/core/Prefabs/ERR/Prison.et.meta": "2e426ef3de68f4107907854b51e818bc11d84649a01c538e3f18dd9ebec766bb",
"addons/core/Prefabs/ERR/PrisonDoor.et": "fc66be9d36f1f01084de59f1b0a1e8817f9e46547ead33d4fafaac0107446c40",
"addons/core/Prefabs/ERR/PrisonDoor.et.meta": "b8f3db52bf186426026668fbb9d633c3cbd4d438ab301fba880398f6a0e781c2",
"addons/core/Prefabs/ERR/PrisonWall.et": "8009d19365ae72a4749d7ad4fa04662575b06c65c6bf06507d380d57258b5eed",
"addons/core/Prefabs/ERR/PrisonWall.et.meta": "0294bc5dbb56f90f8153d62459bb0a6ad91d76a479812bbec9c7db182fdb58d6",
"addons/core/Prefabs/ERR/Prisoner.et": "198b5badabb12f218f86df7eb4dc268fd830769dc3de7eef6362cfaee4d6fc8d",
"addons/core/Prefabs/ERR/Prisoner.et.meta": "974278ba49fafeed70b619a0067bbc70ae4d534be441c812ce2bef4a5fb3c022",
"addons/core/Prefabs/ERR/Radio.et": "b4b5cfe125b39019855816c9a1c508ca4d65d435b5546fdaa6c1fa3c8c9b1165",
"addons/core/Prefabs/ERR/Radio.et.meta": "bc91137b68ba550217914fb8892bb44d7e1920e4a1086f3e506623832a44212f",
"addons/core/Prefabs/ERR/SpectatorCamera.et": "b5b87d5b7b707f3745741aebe7c923067c8a74f8fbb2a4711834bab03bb5a812",
"addons/core/Prefabs/ERR/SpectatorCamera.et.meta": "2a16558f93915e31908a674509e9c89976470f78a84a1174a64b94b68b8f77ad",
"addons/core/Prefabs/ERR/SupplyCache.et": "bccf7afbaae97cfcdd78dd6dbbf4be5b2c045d348f50fe4581962e556c0044d7",
"addons/core/Prefabs/ERR/SupplyCache.et.meta": "2f5de3a4aab1e9d0e35521f48dc57b95bd6e449c383dec4f1c258e10295904cb",
"addons/core/Prefabs/ERR/SupplySite.et": "dc5decce5cabf39b6116e8794ec3960cb1e35761854fdbe69740da118787ded4",
"addons/core/Prefabs/ERR/SupplySite.et.meta": "b41944b12eb3528ff7a3ac94258b18c66ef161aa6a38894aee300a1ac4798630",
"addons/core/Scripts/Game/ERR/ERR_Actions.c": "adf93245e6d78c59b9839599d157a0d2b2b93ea93b3d1ae52e2904dd6c288266",
"addons/core/Scripts/Game/ERR/ERR_Actors.c": "b3c5aabb05f7cf35167bc09b5db51a4ffd89a46658805d6eedbfb80eee30273d",
"addons/core/Scripts/Game/ERR/ERR_AdminService.c": "9985747d5ddaeb91bf27937836a6c369f8dcb353263b77a49212ec28c10ba4eb",
"addons/core/Scripts/Game/ERR/ERR_CasualtyGroundSupport.c": "26f0c7ebe8563bb022f7c383674e7d8997b0cc35c7ea321d39d74f2493c1ed9d",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingGameMode.c": "f4cf19440583ac24346831a2d5f1d7f734c031e46dc266c499972329dd0533cf",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingOwner.c": "6346a05ddda030f7d9b6f026f977d5f018ee16002fa519e8c49dcd700c323dc7",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingService.c": "df787bc40099512656e622c6c511d18caea2ff7a88d2c113e0d6940a551ad566",
"addons/core/Scripts/Game/ERR/ERR_DiscoveryMap.c": "80fda5976c3d7a74ee3a481a0d5f365d5e59553046ebe84d0c84117829a32aaf",
"addons/core/Scripts/Game/ERR/ERR_DiscoveryService.c": "65cc0c23da131f986c3c90a8e4d294522e1d0681bec709b618daecb6e0d393c0",
"addons/core/Scripts/Game/ERR/ERR_DocumentComponent.c": "17bb76b80ebd3357e46d553c44674f602c7bd6901c92aec53ac8214194aa4ff2",
"addons/core/Scripts/Game/ERR/ERR_EnvironmentService.c": "867e9f47adfb7a9819a8b58498688ff86127282cb89cf2529ae81f73e529e1c5",
"addons/core/Scripts/Game/ERR/ERR_EscapeGameOverScreenInfo.c": "b1e1afb7795cb77c0bad94c85abf705b26b9dc2a9400905d80eafd56bdd009d3",
"addons/core/Scripts/Game/ERR/ERR_ExtractionPlacement.c": "c30222ca25cc0e91dec4077e6b82b37a9edafcf2cbebd0be5b6bd8656b53adfe",
"addons/core/Scripts/Game/ERR/ERR_ExtractionService.c": "91357099b4e0401196b67d48963be54be30e56bdba57cdac67dc20b8ebb883e9",
"addons/core/Scripts/Game/ERR/ERR_FactionCatalog.c": "a5a8c53acf21259e14f59cb919535910f30dabff5a9179c664bc6a7a4d744d6e",
"addons/core/Scripts/Game/ERR/ERR_GameMode.c": "043ac9ab7f3163f3285038ed008be782030714607d8e59e25593cfe95dd023b2",
"addons/core/Scripts/Game/ERR/ERR_InitialGuardRules.c": "8c9d6b1dc4c2af96284e34f487eebb5a221091016ef108006dec60b4e3836558",
"addons/core/Scripts/Game/ERR/ERR_Inventory.c": "b63e679d5b650b63a7a91dfc3f42a62f4be58b0338f6df3313e66d29a93bebf6",
"addons/core/Scripts/Game/ERR/ERR_LoadCasualtyAction.c": "5d868fb065a1a0fea7d5abfc81d1d8be96823815535f2ffd0dc4ff60d8eae794",
"addons/core/Scripts/Game/ERR/ERR_LocalAdmission.c": "b0e824c6880cbf9b1f368dc7ada9907bde78b22b948d419b6c861323f32258be",
"addons/core/Scripts/Game/ERR/ERR_Location.c": "d2035f56ded35743312ec6ca91a67f8623a466c91255e1893c570edf0954ff24",
"addons/core/Scripts/Game/ERR/ERR_MissionRules.c": "f7abc38ad8fdc375ce7fa63a65f0bade027d22b37e09de5e3f94ba8c3c63cc41",
"addons/core/Scripts/Game/ERR/ERR_NativeAdminSettingsProbe.c": "6a4df33a2b0e6b6aeed944c6895961e658d4f0db9aed9b8433a43a451fa35cae",
"addons/core/Scripts/Game/ERR/ERR_NativeBaseSmoke.c": "84e0a2d73bc12160cd0a95138085eb7647fa26b2326f790a95cb53748009fdd3",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyGroundProbe.c": "41f40db3735f8aa535c0061458d9892dcfe972222b8a17238e67b65633c46bc3",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyLoadProbe.c": "94c533deea654ec546df3f1ebb7cd213e6cd79b1125d99bab5303ef8e87b018b",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyRemoveProbe.c": "4cfc06f6d43b709b63caae714155ffc562502e884f49a9825623c6f46972ad36",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyServiceProbe.c": "02a9d70d1f4ba20326df199ba41489cfbae12b7bb0aab441361421cee38ad9ea",
"addons/core/Scripts/Game/ERR/ERR_NativeContractsProbe.c": "d1556df885171cf967e96eef5d8981a2e9ee4e3938b7d32fdd0426f647bbabc0",
"addons/core/Scripts/Game/ERR/ERR_NativeDefinitionProbe.c": "c07048341396443ddf5307e340e2087254d65f0bddf8f7d93e6b6bd7f03ca360",
"addons/core/Scripts/Game/ERR/ERR_NativeEnvironmentProbe.c": "8b1d110717aa5f07bfb8fe633847eab519109e3a8a4100970a487be05c053418",
"addons/core/Scripts/Game/ERR/ERR_NativeEnvironmentRestartProbe.c": "7a836a206381b8e8de24c92baf141beb30575723675dd6948d738169ed26b507",
"addons/core/Scripts/Game/ERR/ERR_NativeExtractionProbe.c": "4b09385f73206de004f4f3c38a6192fd658a0d2012482dc5a84dff1599ceb972",
"addons/core/Scripts/Game/ERR/ERR_NativeFactionCatalogProbe.c": "ee11486cf77da9070506ccc0cfd6e94240c5387c8be455bf864934a8fef65f78",
"addons/core/Scripts/Game/ERR/ERR_NativeGuardCancelProbe.c": "bfa1c65cb039e19c3d1891e4a3fd33469e974c97cc7f42128efc31a8f587d514",
"addons/core/Scripts/Game/ERR/ERR_NativeLifecycleProbe.c": "b613a5dbe81c2032fd02d31070ae5631166d14d0b02cdbec3b63b782f0bbc115",
"addons/core/Scripts/Game/ERR/ERR_NativeMedicalProbe.c": "43fa51ffbcf9dd0cd8e905a1135bcf0756651da3af34677f3c92e7d264ed70b6",
"addons/core/Scripts/Game/ERR/ERR_NativeObjectiveLossProbe.c": "6b80fd317a8c6e8583bd4337870838a86251e3b8a681d0aa07e8b52e22abfc48",
"addons/core/Scripts/Game/ERR/ERR_NativeObjectiveProbe.c": "71fbd2479a70048f83d8b262ad1452f427be2c0afc8b071ef13bff477b9dc29b",
"addons/core/Scripts/Game/ERR/ERR_NativePatrolProbe.c": "02bd9fdf5454db7dd4c82240efe0d947bf8d6488ace42809c3aef6505cb6266d",
"addons/core/Scripts/Game/ERR/ERR_NativePrisonerProbe.c": "e2d1ffe5d269add55124601ff0d1dc032a398c7d51010736e6f0e4cbeb38ae86",
"addons/core/Scripts/Game/ERR/ERR_NativeRadioDefenceProbe.c": "cad54f0b43cefd72df74697dfc7e93725ff0acac6d311e963ce4f817428c272c",
"addons/core/Scripts/Game/ERR/ERR_NativeRecoveryProbe.c": "4de6868cd3e76afb80cf0ae5dac1e35d2c417838f640c2f18aa3343217eea2f2",
"addons/core/Scripts/Game/ERR/ERR_NativeResultProbe.c": "b9a117eef2d5f65fbd792041a2b3e59e38e201bda8e0df8c503e1a1242cfc415",
"addons/core/Scripts/Game/ERR/ERR_NativeSiteSurvey.c": "ac0203753ade0cdff6d483132797a80e4520f14546c3f9dea288281cd4cd9c4f",
"addons/core/Scripts/Game/ERR/ERR_NativeStationTeardownDiagnostic.c": "a363c2383e66311415fd29124f26f3b0c6cb866648d86673afac29fca22a994a",
"addons/core/Scripts/Game/ERR/ERR_NativeTimeProbe.c": "c93d049785971e51246fcc07cf24804270a752a655505f2c38e48c80df5255ae",
"addons/core/Scripts/Game/ERR/ERR_NativeTransportProbe.c": "63ec0c5ce698114daa6314b2a6e3c3e98e76094117c477f9d0d072260686d193",
"addons/core/Scripts/Game/ERR/ERR_NativeTransportSurvey.c": "3e94493bf54d15be2bceb106ad18873e14e6755af09c05f07db7fb26fb7adff5",
"addons/core/Scripts/Game/ERR/ERR_ObjectiveDetails.c": "628ebd166dcb5544c2d18dce489619984887ee18296cf2446fc6d894f89dd5bf",
"addons/core/Scripts/Game/ERR/ERR_ObjectiveText.c": "815fa44350798229784efffe0d4ec16d3382dd62df149215e49d527cc2961553",
"addons/core/Scripts/Game/ERR/ERR_Objectives.c": "88d95a52fcba103483ea751571e1afeae0e6fc82115ed50d6fc195424726960f",
"addons/core/Scripts/Game/ERR/ERR_Observer.c": "b719e723369ab4f403950c85226e1336eb48e3c127e84530ac1c695eb86bd0f9",
"addons/core/Scripts/Game/ERR/ERR_OrdinaryScenarioLaunch.c": "e2803ff9198e6213bfcbaefad64a35ae3ffe06846c410cf6da6de7653adbf28d",
"addons/core/Scripts/Game/ERR/ERR_PlayerAdminCommands.c": "a084d7dc097dfcde3d6cd9c2e326b9e2f8f2a519f77b30c4f56ab7a1429aa721",
"addons/core/Scripts/Game/ERR/ERR_PlayerEscapeResult.c": "3124ab4d2d6d471409a47aba0af528790734df53243c03fe0cdac3e407047c14",
"addons/core/Scripts/Game/ERR/ERR_PlayerGuide.c": "2c9c365b88651f8b12618443638bf52c04e497221592bd483c33447e30468f36",
"addons/core/Scripts/Game/ERR/ERR_PlayerRoster.c": "c038dac0f749bd29ebc35a4e952904b41a34417ba738904d5efcd1833a263e0b",
"addons/core/Scripts/Game/ERR/ERR_RadioDefenceService.c": "5d347cf1a3b021074d560aad8db774828b797e685b63ddff3d28f55781e33ea8",
"addons/core/Scripts/Game/ERR/ERR_RadioFeedback.c": "545262e65e9b3645d9e514a0521e442fe08f0c2e4e7c83ba638c5105d09818db",
"addons/core/Scripts/Game/ERR/ERR_RecoveryService.c": "ba9ffb93679012c20a665636ef6b201cbe7d8d14fdf53e8cd3eb12ac7248943f",
"addons/core/Scripts/Game/ERR/ERR_Resources.c": "d0169aac6fd0c38928c47a9002ded0fd8ba558ea3314a600e792d307ac1ca3ee",
"addons/core/Scripts/Game/ERR/ERR_ScenarioComponent.c": "abba03af68323d5715ba1e2497fc66f3c706e6a6a983c3a386228abdfddeec89",
"addons/core/Scripts/Game/ERR/ERR_Settings.c": "b9390548936b386e0211d487c1b76b65410fdd2e339cd8ecd9585ef4f4ffed31",
"addons/core/Scripts/Game/ERR/ERR_SiteDefinition.c": "b422feeaca90084ea2bee5cde94dc9c6fcae542749b55d95f7226f922a6a68ac",
"addons/core/Scripts/Game/ERR/ERR_SiteDiscoveryRules.c": "50f7b3ff4f32bde37ce5ae2be7f598fc4dd8cc08f45914f6e3260d31c84baef2",
"addons/core/Scripts/Game/ERR/ERR_SiteService.c": "6bc9a0b5aed326822807f05e17459d0fc2da10b709e8168972b4e40fd09f87cb",
"addons/core/Scripts/Game/ERR/ERR_SpawnFinalization.c": "2e295b0f225208c5414728ba83333e5e0ab6eef3a708ce39eb1dfce5400c94c9",
"addons/core/Scripts/Game/ERR/ERR_SpawnLogic.c": "bbbf35110259cacdac63779604ce22149d1a2198ec4c4cf43f7f3bf57e3241e8",
"addons/core/Scripts/Game/ERR/ERR_SpawnPlacement.c": "55323dcb330c23d49dc8fa3fde86a3ae3958c0b6563d6c3cd0960da88333f93d",
"addons/core/Scripts/Game/ERR/ERR_Supplies.c": "752e8a56b0b8cde33cf532032cb0a203553017b686faac2e19bee06f7a9c0713",
"addons/core/Scripts/Game/ERR/ERR_TimeService.c": "d9f481b7da01e08d2c982a948c18ba6bde76889d7cc9d26d510708f4ba479453",
"addons/core/Scripts/GameLib/ERR/ERR_DiagnosticNoSplash.c": "0ea1b402f8927b6d68bf6f7e5caa2967f7e3a39147634faab147796b791933b5",
"addons/core/Scripts/WorkbenchGame/ERR/ERR_ValidateBaseWorldPlugin.c": "7f44aa64ea7b4f8b3640a37a4b781c43bf6adb80e4a3a702d9491131698056f6",
"addons/core/Worlds/ERR_Everon.ent": "22324bc7eb0d80dec8a1f3bd61a9df9201b72f749f4e751766b0c9d0b7d46b87",
"addons/core/Worlds/ERR_Everon.ent.meta": "19d1903ca72baa326b4724a6791d0da1104a1e53f3f31dc1ca41a856efd68e83",
"addons/core/Worlds/ERR_Everon_Layers/default.layer": "17105538007199bfc419aa04a64debaf2da0a7b77a1dc3ba983e92bf747c862e",
"addons/core/addon.gproj": "231274e6b62302f32c65f9ff31de2ce8a9e51e1c8d12c87deeec82ae1f40de46",
"addons/core/resourceDatabase.rdb": "5765206693e176009ad2d37e0d46141ff57fec2348ea6331ed9511433eb001cb",
"addons/intel/Scripts/Game/ERR/ERR_IntelService.c": "482839434b94e7f8c345d5fd96490aeebb765f3dd0c1bb25fceea2f435c0e722",
"addons/intel/addon.gproj": "d0ced242cefb220a5cccd6779d61fda9bc55581701b9f78bcf13c09d92ddbcbe",
"addons/intel/resourceDatabase.rdb": "062996b9102e99d19eb680bed04880b0e087d9f8789681c0f3ff8ab6772339ba",
"addons/map/Materials/ERRM_MapRenderTarget.emat": "9877c5b175c5f30dd80bea36c711b21ab38219aa7075adf9ae79932e1d4c76bc",
"addons/map/Materials/ERRM_MapRenderTarget.emat.meta": "5ee1a705f8011a44020ca2691f5ccc17d44bf596fef9a36e98d1f267eb58fab0",
"addons/map/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et": "30dee8e9eab459ea32a7d835a9fb89d43df47708057cab829f067b25a24cd581",
"addons/map/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et.meta": "59093e9072c50d99c86da7609c87541016da5bcf92b98d99db4c524e1c8e0e8d",
"addons/map/Scripts/Game/ERR/ERR_ScenarioMap.c": "75fa1d742129ef7f33c005cd48f56db7f49ee7bde3c5428532b0b501b032b0a3",
"addons/map/Scripts/Game/ERRMap/ERRM_SharedMapComponent.c": "fc1a0c7df4fc96da446d7542a45a10fbec1eda1e543ba2f0581cb772277a47c5",
"addons/map/UI/layouts/ERRMap/SharedMapRenderTarget.layout": "49a2da4181b94d42174f58c7f9b6bf2207116c99427d61ff1c212092ac7db4d2",
"addons/map/UI/layouts/ERRMap/SharedMapRenderTarget.layout.meta": "5c846445cc089e2e08899ba703059d4adb805ff30ab5a16409a3cd59718cbd54",
"addons/map/addon.gproj": "1b371e5e01ea9fa46e76570fecb8aaa3a9298e34cba7ccca8a6bdb5ca86eb46a",
"addons/map/resourceDatabase.rdb": "fe2d3eea469f3a69dcdb8567a7bb8119dcc03f940b423ad0babfc3b84e5cb0da",
"docs/acceptance.json": "283f08dc1658d214d3551d8b22f3a1d179fbb95f9d85cfbe63015adffc3b365d",
"docs/addons.json": "be6097ca5fb6ccb8c17bf4c05849e3e75225473162cdffef18a1cad13d056186",
"docs/admin-discovery-setting.md": "a140f09cd1f27635824a9fa27e88e99259fc0030ff3228dd1376e2e949edbc1c",
"docs/architecture.md": "6d7b52d5456b8fcd396421a7d8ed04be01c9111dabf38fa3e42b5db5fe4dce72",
"docs/base-gameplay-gaps.md": "8fb9ce4bf3d36507fdcd03af9681657c473bdf1f1d188380e7e4a83d47b10625",
"docs/base-replacement.md": "e99b648932b784e2993d086d6f56176fda5d853f53a4363cbf4754774cd8afec",
"docs/casualty-ground-source-sha256.json": "90ffa7d0c61e3823922ca9d4773e3d12fd5e9a1760a35c3b29fd12a53642f83a",
"docs/casualty-ground-support.md": "bf5bdf19f9dfa0fb83dfdb9a9933e5cf6a63be3918f74953759a639f85f121e4",
"docs/casualty-incapacitation.md": "2811fa294de0348fbdf8e78b0c66bc31a59dd8f1e43fe16af8da87cb7e789820",
"docs/casualty-loading.md": "9970b46ae4b9d0247e6bfad8378bba33c237f16cb49a4f53da49706291872b18",
"docs/casualty-remove-source-sha256.json": "4799a5843315fe5b5b2e933e8068a8b4bae6d924a49438eccb7f68ffc8e12be9",
"docs/configuration.md": "654657c3c6a515d101e4f43dba74a2146358a8ead56aa5444cac4aec48177bf5",
"docs/current-status.md": "b1003d1b7c0167304b694b50e31b851cdf763f986885c593a3426f369ae2dfa9",
"docs/dependency-audit.json": "d5e6cbcdc59c0a25e5748c590d6a195da9c97e8296119e07185f4c360bdfc4ae",
"docs/environment-restart-fixture.md": "1c1bd3872a67c5a59c12c1293d075d52fe0b563fcd5e9e10a1ce1850c7efcea9",
"docs/environment.md": "eff60684482ca8332e6ac4909850b6acd1048a5518ac70ae121dd16afb1a4409",
"docs/extraction.md": "215c96cbc004b3817a70ee40f30b181a72e78123e69e16a3585ed4d8d566837d",
"docs/faction-catalog-source-hashes.json": "46060bf2bfe6c39517e3140acb004f9b129c26695a7ee890b4aae571b3f0da76",
"docs/finite-mortar-operations.md": "e3d230810bd42a02afc798639ea36f08fe0dcc45d73d14457cf37e7791d499f3",
"docs/ground-transport.md": "4ef0b23e1e752b807344100948e7d0f880448158292f96309dcec5de9583a1a0",
"docs/guard-cancellation-fix.md": "41f8bd169de714df4df4a61189d47a37f9be2f1b1554edc99c29d8a1fa4aaf19",
"docs/guard-cancellation-source-hashes.json": "a1bf169c021931cdcba835d52e420df44e5dd2ef351257f0be10f63c8727afd4",
"docs/guard-source-hashes.json": "874845def1458901d61adeb090a464bbee7c7b18816406ae3780ff48fe855266",
"docs/initial-extraction-placement-source-sha256.json": "a44a32cedc54a70f635bf5840e7b29d35850a2212fcf64b1fd36ca096f10fffa",
"docs/initial-extraction-placement.md": "643b50d231dd9ceb49b81fd8f061cd114a9618fd1ad5a6f88724c0199a5a304c",
"docs/initial-guard-readiness.md": "5f2b45f3744f1f0316f198225a34e25d93eb4795bb05d6cfded8de1f1a116c18",
"docs/inventory-identity.md": "02092960cf937b175c5a190b426b84e0383104fa71f324c8b3a0ceb4fbe01164",
"docs/local-singleplayer-admission.md": "79943060c67330bd0b386733306653b59b1cb92c0924ff3bb0ffd3b582bec70a",
"docs/medical-kit-teardown-ownership.md": "2116a4062425f6fba029142ea0239264d313ec52f69ec7f88ee7b250a90814bf",
"docs/migration-provenance.json": "3f0ab1e9d1314265a7cdea3535a9e81af441c1b7a5c9c925e84aa824a1730663",
"docs/migration.md": "42514af2fbef0663d05f3353a26f3b2fcd4f7359634652d23fda53a8e7bfcd0f",
"docs/mission-faction-catalogs.md": "2ce3e49404d103a4c372ab0386de3bcf831bee87d95b1092372345a3d32ef8d2",
"docs/mission-time.md": "29d9a18c7acef0587764becbd04c2c63684644a05c7b3b2fe77defe1881ae7a0",
"docs/mortar-transactions-source-sha256.json": "dabad1cbc6eb3dd6f66b3e9ece574edcabff94adceeb2494b1adb2147608dbc0",
"docs/native-casualty-remove.md": "d55f54fba75e6cd1b9c30b489db17d58aa708afed792d1eafcf33d6d43c55e76",
"docs/native-errors.md": "f0cbc674803f5254db0c823bce2df437cad121756e19f6c658087d5d2fddb349",
"docs/native-followup-snapshot.json": "6b686ee641830edbc223cfcee4d6a198fcfa36ce8531bb16855fa9cbe9f5cbd2",
"docs/native-guard-cancellation.md": "880b545b8451a86f16ef47e0a378d081c8fecb1175bf9a8a122bf853ff9b816c",
"docs/native-initial-snapshot.json": "1ba571aa6da7c72d3db3eaaac54f5399820603ac33d7b21b87946eee3aa4eaf3",
"docs/native-medical-fixture.md": "3c915a74afbcac1dfa45f0c1e9d8d4801f33704cac9ce1b66355121805ecfbb1",
"docs/native-mortar-firing.md": "5fd4a5a4059ea6f8a3fa353b16c8f507316689daa60a883387c20114c4c16892",
"docs/objective-widget-lifecycle.md": "3ec0ee8c74b2a3117356477a16125a077dfbf010050e53280a00769b710958a0",
"docs/ordinary-diagnostic-splash.md": "6e07a87a03df81dd5c9d6c0f9602b26e08ec7fd7cf941b91f2b8007bd9d33e6a",
"docs/ordinary-game-startup.md": "6a95a55aa5fbccbe9a54fd7c695929d392f30bf2ce0c9f509304cfc4b627e14e",
"docs/ordinary-identity-diagnostics.md": "6d5017ff1bf27a276208cc42d567ab2c9f0e8936bf7dca3156c649f67eca359b",
"docs/ordinary-launch-callback-fix.md": "b74b8d0d011f25c367ea07b37e1a5ef488a2b378542ddca63ff9e981e649b874",
"docs/ordinary-splash-source-hashes.json": "b2e277e3487c2b790bce741527555bb74f6b9820b9e5626950ab709533d9fa97",
"docs/original-feature-coverage.json": "27cc7d2934abb3d307a4cfc0fb1f10ac53611bef64dcca99aa939f68c842e98a",
"docs/original-feature-coverage.md": "2807936a75db548342e4f89c01795395038270a6793aafe15c6069c82537c30a",
"docs/original-resource-inventory.json": "bc52a981c42f933134e637a027d08a0924abb19784782731590b7ef0b0e2e73f",
"docs/performance-comparison.md": "8065fae91ef0ef572b06f9aba079bd9f6ab96b25fa8c63e7a4a30b34f77765a0",
"docs/player-lifecycle.md": "903302c21da86668d6a3ff78a11d5eb2a5c36c30062f65a2039df717c195a140",
"docs/prisoner-loadout.md": "0b27f5fce4af457bea7133e461dbc37d8fa73fe126c8c3de90d723b358af389a",
"docs/radio-defence.md": "845078af4648e21781357b263916ce351e38489e4f49ebf17fb0bc75d7a859ff",
"docs/radio-document-loss.md": "44ce397e471b2fa5d8b773379f475e2c4cb93b33b936a76919e64e15251c2b9d",
"docs/radio-feedback.md": "3aaaecb318e2f737321bd08f9deb9323af153f2ae9ed196b55104c0616dd2be8",
"docs/recovery.md": "a91e170b0ea164f50db64acc1f19b78a6dce9392736f194a9192e85c68a71a88",
"docs/release-qualification.md": "7bdf42f51fe3a4c1d6187d0e6f5248ac9a68ce16873281909bd96e1cea6c406b",
"docs/runtime-testing.md": "2db2fc790785633e701e503e087a8a9de8633a11ed8f1b4f9f22972506005524",
"docs/site-authoring.md": "7a2e66e75ca3fdab43bd730f16e864c31909ab42fe060b00715caa13b8352ce7",
"docs/site-patrols.md": "5956f70a5ebea4167819a43c2a15f8b6d6460bc724b000f989d5ad5265d48d56",
"docs/validation.md": "48206348ef58afe52daf5dc8dca4aa65beaf00086aabfc995c808b5b0e8233fa",
"docs/vanilla-resources.json": "a18dbb7683641c439418091530219fd3d4de65b14e8a139577411c2a020a9903",
"tests/helicopter_availability_regression.py": "b8eabe0646467d6b55b7bc08c75121185410d3460c2c951f70737a5decbbfefe",
"tests/hq_network_regression.py": "3b077e1c527029d60432cbe2e0373c3a4a55ed4e80d6be59e639de8bc9411188",
"tests/mortar_salvo_regression.py": "6624f57ac28aabadd3ae2ba96b802910ffe739786d9aca0ad1caea68ad08eb5b",
"tests/policy_harness.py": "e861c30037b3e456f0c8ef1c02e9fe1417b601ffb15d2037974715008865e4be",
"tests/test_admin_setting_policy.py": "8d8ce49f4079d930c06bf23be410eb610e30082e3177a9f88bd6a0dfbf54189d",
"tests/test_casualty_ground_policy.py": "6b6fb5dccfef32eb46f7e5fee11d28acd3068c25837d2f1474491fd139be9316",
"tests/test_casualty_incapacitation.py": "fdeee4ae5b0e383c592ecbcd132b108ed6e92cb0e1f4767da02f95bfa33b7a4a",
"tests/test_casualty_loading_policy.py": "3a85d86dd1b19aa616fafb5d3a38f5374d5bb14d176844210150ef95df62033a",
"tests/test_casualty_remove_probe.py": "61578d8ca863d5e5be32dab2661fdd410e8441eaf1a9ae3b5123906eb3d57a68",
"tests/test_casualty_reservation_death.py": "dd5abb0ca2e7ec289f6933c406517515475d34ffeea95d732c329b42080773b7",
"tests/test_diagnostic_no_splash.py": "a9f54ced5864953c8031208d519c2dec9d604a70ad65bc738b51c6656a8aab22",
"tests/test_environment_policy.py": "4f844728d47ab3ad66c8a06f37833e0325f00bd04c0803d7dcf0eed14d8935c3",
"tests/test_environment_restart_runner.py": "05bc09bc45db70ba4a635b65b0a96aa38437ba50c98640b47ed8d0683c3a5f71",
"tests/test_extraction_placement_policy.py": "4cef86ff87338bc2e0bf66683c78050f3ba49d940d0c221a89333f4cb61a2442",
"tests/test_faction_catalog_scope.py": "c8fab92575f2621f47ed8685243338aa9ea717bb809c2ef9e8e0884af9df263b",
"tests/test_guard_cancellation_policy.py": "4a0671c62a5d875c0839d7cd9bdb0703cc28172ae6a3b483e041ec299b02efb1",
"tests/test_headless_game_runner.py": "29f045b65dbcb53f06359daa1ed7e981351517f9b08d0287da828eb1f8b4212a",
"tests/test_initial_guard_policy.py": "11354597457a240ec0427481ec0626cb952fbf06995a2955c24e81a5054edb5f",
"tests/test_inventory_enumeration_policy.py": "1a13ab9d7fdce46589a30ba005d65bada02a5a997f3fdb4dff025aec5514f802",
"tests/test_local_admission.py": "8ef122042a6c0c2258b1269e78606443546760ffdba6177c4f68f73769006e57",
"tests/test_mission_rules.py": "1561f50ea52a38227503ea3b5b2394a9303f82d9cea00268fbbe8fe83deb4b5b",
"tests/test_mortar_transactions.py": "3a17d444c1083336b52cb329fabaa1b9de7105cbe048e12b2d430600cc5bbcd1",
"tests/test_native_mortar_probe.py": "327f4c5ac1be24397c6c88c6b77d8889ae84d3b66c26caaeb400c1b2f373de5c",
"tests/test_performance_comparison.py": "5f932de9e9898acdd379f26c777a35c884269522dbf8c41991a7a25bf61c369a",
"tests/test_player_admission_policy.py": "9298c7f5f4b1da466ed044326e87f1b3ed6c7dc6fc65e8915ec08086fbc501e3",
"tests/test_prison_placement_policy.py": "269d8875e4a634bb0049acea644795ce6e58f335363d8e86ae1dae934d2ae28e",
"tests/test_radio_defence_policy.py": "9fd3c348d69c8c4e61c1135bb7e5df1b2b0ef07a2a5ad4faff1611d7b8e98097",
"tests/test_radio_feedback_policy.py": "d91c39d8291a16cfa5bb5fc5c7365a7421a7ce9f855a0b0250b76c2cb7cd1369",
"tests/test_recovery_policy.py": "e50879d0e2728f8ede3b67015d05bad5e34590dfdf315575b799adab1e23e186",
"tests/test_release_check.py": "8b6e755ed922ad129ba01c228989610a31f3a79841dc7cdddd4ddbd0e510971b",
"tests/test_settings_migration.py": "59fe9cd5f4564a6747a9a00fa422453830c6f94f6f1ba785d0592ef6feefe158",
"tests/test_site_discovery_policy.py": "79ccc06b74c05210428d602b4e22de1579523b163d5ab9ed2d52a29bed484896",
"tests/test_time_policy.py": "32c468c0a8852b7dfb873a93da80295434530131629eaca365a9c4aa9398c63a",
"tools/archive_native.py": "a302bd080275b72fbc47fa8108a98fb2689a377cbeb3cfe6e73596726bdab0bb",
"tools/check.py": "7460a22cf17fc9562fce73862c1b0791c830f2a8f25878626457618801599702",
"tools/compare_performance.py": "568acfee2525b8924f3e7a39784e8641f76d63bb3703dcce8251ab9ac9bb1854",
"tools/desktop/kwin-right-monitor.js": "8f0cf9ad290edf02e5f623cf1b0e36e2b266153ff81a022233c4cf67818b9499",
"tools/headless_game.py": "18ea1259e7f35121a7628edddecf5683ad49a1199f90f45ecdd7adbd120ca589",
"tools/headless_workbench.py": "7599cca63d7cad61201d7597ccb6776e3f8c681d1d7566b8d8261b35e3d8de69",
"tools/import_settings.py": "d9c250b52b6d29be3a80c3404f048b65a0b9b99e93b5213d5ce2be7d90a37324",
"tools/native_command.py": "4828826aa70b5ac31ab77157e658a8a3998de2829cdf782b8eee5b8c566d0385",
"tools/native_provenance.py": "d4777f1f6ffed6993f7009ee2af41b100e8e0138d60ebfdcc5404ff2128f8e2a",
"tools/native_report.py": "bb75ef5fe551f45776d441f15a49ccad4daf19abca505187f9b2d30102538658",
"tools/reference_guard.py": "545b67111927d73bf2020f291528ea6f2f687a994b3e37bf567f239c32c8cd78",
"tools/release_check.py": "65df1bff33638a583905ba5f6c583a095b9f7e38186b6f29d70b72a61525589e",
"tools/source_manifest.py": "c1a985348bad16f3b5b69ef7e545b6341eca298d8ae08111b8340b31535cc199"
}
@@ -0,0 +1,279 @@
{
".gitattributes": "86cd7c797b8cac2699f5959add72303d5474f34fb0d141c36e6d8d095f7bc718",
".gitignore": "1647a8de89a13712bdb3678396c3d09b268e90e99b17bd56a1462eef7efd00d1",
"README.md": "557ecb725cb83911cba20c285624bc2f7cd527932407f87844f824e12821524d",
"addons/ai/Prefabs/ERR/MortarCrew.et": "05d3e7353ff9fe5523218a1487b31b7b742b0be8adbcb060c7099978cf008bce",
"addons/ai/Prefabs/ERR/MortarCrew.et.meta": "fdfd4fcd21a67c3d698fa4aadc4e5c76e665cebf4be86013bc389e493fab63cc",
"addons/ai/Scripts/Game/ERR/ERR_HQ.c": "ceafd6740ed277748744ce56ac0f0bb3a8521fcc060dafb2cdb99896aedf405a",
"addons/ai/Scripts/Game/ERR/ERR_HQJournal.c": "b3e402cfe92d415f37f666045afb062e6e11670ba03a0ca6f2d9fd4fc3520ac1",
"addons/ai/Scripts/Game/ERR/ERR_HQNetwork.c": "92ff2caca52e94c2cc9642dfc8509ce6e9349b257012bade8650bace9231128c",
"addons/ai/Scripts/Game/ERR/ERR_HQObservation.c": "36c978ec5f052213ac1236e1398d85063efbfd7ef60fe04f1fc11447fefe1d68",
"addons/ai/Scripts/Game/ERR/ERR_HQReport.c": "c4d16ccb571db4d9444c0a8d2be7318845d25ff90238b6d304e96a9ea19f1a08",
"addons/ai/Scripts/Game/ERR/ERR_HelicopterAvailability.c": "60eaef2f6d4b2fd44861c5a4434ef97e732e40a5ff7401e2da451ed2dd9c2762",
"addons/ai/Scripts/Game/ERR/ERR_MortarBattery.c": "20a5b1975c2b185afd1b9b476f19730bae24064fab4d0e6538fc44bc49818b21",
"addons/ai/Scripts/Game/ERR/ERR_MortarFiring.c": "b843484cd73340a6f865f06ce16b5405b26b9d460a89e8598234c6f27332890b",
"addons/ai/Scripts/Game/ERR/ERR_MortarPrediction.c": "470dd196ed64800c697d24c09d1344bacd2502587fac76af4ee0edae2563092d",
"addons/ai/Scripts/Game/ERR/ERR_MortarReadiness.c": "1a7282d9bd53dcd115d53c9b460ca62d3218931a74635cc516eac1a13b7d9347",
"addons/ai/Scripts/Game/ERR/ERR_MortarSalvo.c": "697c01f479df6c505a41d984a29c02002e3052114dafa2ec6252ae55e2979a2b",
"addons/ai/Scripts/Game/ERR/ERR_MortarSupplyTransfer.c": "34f7eaa01dc68e97aae8c1177b7f8fd6c15d5a41c6dc86de377f00b3613a8e77",
"addons/ai/Scripts/Game/ERR/ERR_MortarSystem.c": "60b05d729ee961196b3e3d27bb7942d7aacdf1e42a38f7d63ec2499eea3ed2eb",
"addons/ai/Scripts/Game/ERR/ERR_NativeMortarFiringProbe.c": "d66e57ada46678eb0a6dfa6ff818b656f6132c4eed28881abafafa1e44f8cd2c",
"addons/ai/Scripts/Game/ERR/ERR_NativePatrolHQProbe.c": "4c04aa3e1b6b000747da8e2a919a6501107880fd041134c019f516665bb6f758",
"addons/ai/Scripts/Game/ERR/ERR_SettlementSafety.c": "e5c0ebc95521a9a33a3f7d9cca6c551dda862a08b7af20b017877aba9584795b",
"addons/ai/Scripts/Game/ERR/ERR_SupportScenario.c": "71757018ec9716c4dc24f62a292a214919d3fd5daed3c16e03e56abd208e9f03",
"addons/ai/addon.gproj": "5f559db8f526700db11e6ae763f5245f19b7006fc68c56e4c09fb6f940bdf2a1",
"addons/ai/resourceDatabase.rdb": "129c2d601531447ffd1864982af3f9fec03ed64db23623d44e29115c0c1998c2",
"addons/chat/Missions/ERR_Everon.conf": "76f3ac0d21b585654beac7ddd68e3c8cbdd66dbfe909b17b04838fa813a7c29b",
"addons/chat/Missions/ERR_Everon.conf.meta": "0a23c98bf83873536c65fa17d38dea33a1d7b9e4ab210f90633ff688abcc551f",
"addons/chat/Scripts/Game/ERR/ERR_AdminCommands.c": "d7b4ed95fc32767911936cb0fcc60763233f2c31afd34a6a0fa998b39cec9f5c",
"addons/chat/Scripts/Game/ERR/ERR_NativeMortarProbe.c": "ddb892141500c192c0787b011d57dd8c07dd8c9a3ca5fdc407f6c271897bde0a",
"addons/chat/Scripts/Game/ERR/ERR_NativeRadioProbe.c": "84524163c63402755b4f834f74dfe6d8e5c397dc26031f532593c6f79f5a93b1",
"addons/chat/Scripts/Game/ERR/ERR_NativeSmoke.c": "0fe7825e6c2feea1bac766a5d8c904124f577aea3ff07d21b1d440c89d3a47b7",
"addons/chat/Scripts/Game/ERRChat/ERR_OrdinaryScenarioLaunchChat.c": "dda715c9691d366e35fa2ad5e390dee1971651f137a5a9f9aeb23dcbe53ec87e",
"addons/chat/Scripts/WorkbenchGame/ERR/ERR_ValidateWorldPlugin.c": "81c92d408ce88cc9f98d6053f1d0c863427693ba748f00df9f1bf8079015ef94",
"addons/chat/addon.gproj": "ea1587e0174cf795334d306c71d99b06797fc891427cd57b6cab6e21cf0e4e0e",
"addons/chat/resourceDatabase.rdb": "d9a737a8d09f9fced6b1e7fe108e477c0fc9877ad044f3c5be0aaa7c60b0056e",
"addons/core/Configs/ERR/EveronSites.conf": "ade92cc8d2b14a84ac378bbbb52608b351dca65d359dd7a315d64a145fa4b46f",
"addons/core/Configs/ERR/EveronSites.conf.meta": "d5fe68025ef4e7c1e16082cf5873b7c7172eacbfaef4ab29b7e0e3c98f8dca56",
"addons/core/Configs/ERR/Factions/MissionVehicles.conf": "5f74f4a7089c7e7b54ad62463159ce8f0bab25a6b85268dc3872ea6001e048fb",
"addons/core/Configs/ERR/Factions/MissionVehicles.conf.meta": "00c368b6271d3440cc8bf627b03a384d247635723923fc5ad2104b8b4007b035",
"addons/core/Configs/ERR/Factions/US.conf": "4c3da063abb6e3ee39a6e4e0c5a9ffd5eae9d209d58470ea18b45dba5528db1b",
"addons/core/Configs/ERR/Factions/US.conf.meta": "a05469aef028e9e17eba545e81e2af2887b59f0fef17dac51a23c7b8155e381b",
"addons/core/Configs/ERR/Factions/USSR.conf": "407ea27f80a64c5184c089d43cdd0bdabfc5974c84f1d2a245081fdf2afa3f30",
"addons/core/Configs/ERR/Factions/USSR.conf.meta": "057397d97096346791b51b7b13fbe18af218bcf78e9984d9c01b49a2403de611",
"addons/core/Configs/ERR/GameOverScreens.conf": "45231061911a1462d45fb6db0fecc2b0793f17b5ae71017174954ff4fbd20236",
"addons/core/Configs/ERR/GameOverScreens.conf.meta": "eb654b745c0b97b41c991694569ef4877a3c2315e0826f9556337cd68690843e",
"addons/core/Configs/ERR/VanillaFactions.conf": "db890b61b48ee15484041fd2245a862d9fa9e7ba21b1229c281ff37c448a35b1",
"addons/core/Configs/ERR/VanillaFactions.conf.meta": "ac77725c0c21974991ef47a466b88122e939de8b46fd23e68889e7674cbb2bfd",
"addons/core/Missions/ERR_Everon_Base.conf": "1e6a0e9a756d15495201f71121626890f01efe6b00154c561672d4ec157960bd",
"addons/core/Missions/ERR_Everon_Base.conf.meta": "9b16267c644d815bcf98a3a3aaff30b93d7224fb24d3a2bac66730a28011f317",
"addons/core/Prefabs/ERR/Extraction.et": "1aa286ef253c5410f09fa641e4be91a7be8ec834487a7fbb74cfb45cab60ee1e",
"addons/core/Prefabs/ERR/Extraction.et.meta": "c2a838633001e2e3a202d39cb33aa744ebcd996017ad032359069641b5d13853",
"addons/core/Prefabs/ERR/FactionManager.et": "425f916b890019c537f6b2f72b1af9e7be54b0a476320da969e1f313a7ac5ea5",
"addons/core/Prefabs/ERR/FactionManager.et.meta": "9bf53d5e4bcbe60dd1a4ece1409fc23c349055c860708620f5f6e9716290a97d",
"addons/core/Prefabs/ERR/FieldCover.et": "20f8095e69dbfe3db74ff19078e528ea75405362b335e03560ccd61f8df2e7f3",
"addons/core/Prefabs/ERR/FieldCover.et.meta": "83461ffa76244e1d69f20b053a9741ccdf7d127009182bd540a7e5ba6150c3d9",
"addons/core/Prefabs/ERR/GameMode.et": "385c97a5b8067091d92aa60c2d4fcf02002cf606b95523866ead65c96b8c0029",
"addons/core/Prefabs/ERR/GameMode.et.meta": "106769cd34525c9d440057072836cb7401a6752148c40edd7fe61c03bd58328c",
"addons/core/Prefabs/ERR/ObjectiveDocument.et": "2e72270bf186654af12d2c3ff9bf940690b03fb17fca44f873c1fde5d11384c0",
"addons/core/Prefabs/ERR/ObjectiveDocument.et.meta": "eaba9903be147b98a1106e2273e2270773df73b9b22f2cd4e20136a8e281382e",
"addons/core/Prefabs/ERR/Patrol.et": "c5685a8bc311cc5563fb3334beec9408d3d7a1069152fddeeb7df4f1b7f9e6ce",
"addons/core/Prefabs/ERR/Patrol.et.meta": "7c5da568fa2fcf0709ee2959253cb068d7c7ed7c2467af3b247a7e70efd96b69",
"addons/core/Prefabs/ERR/Prison.et": "1503db1441d8cd7a4f0b45c27ba9623b9fa39f0f81016e180bd2aa1379e1f42a",
"addons/core/Prefabs/ERR/Prison.et.meta": "2e426ef3de68f4107907854b51e818bc11d84649a01c538e3f18dd9ebec766bb",
"addons/core/Prefabs/ERR/PrisonDoor.et": "fc66be9d36f1f01084de59f1b0a1e8817f9e46547ead33d4fafaac0107446c40",
"addons/core/Prefabs/ERR/PrisonDoor.et.meta": "b8f3db52bf186426026668fbb9d633c3cbd4d438ab301fba880398f6a0e781c2",
"addons/core/Prefabs/ERR/PrisonWall.et": "8009d19365ae72a4749d7ad4fa04662575b06c65c6bf06507d380d57258b5eed",
"addons/core/Prefabs/ERR/PrisonWall.et.meta": "0294bc5dbb56f90f8153d62459bb0a6ad91d76a479812bbec9c7db182fdb58d6",
"addons/core/Prefabs/ERR/Prisoner.et": "198b5badabb12f218f86df7eb4dc268fd830769dc3de7eef6362cfaee4d6fc8d",
"addons/core/Prefabs/ERR/Prisoner.et.meta": "974278ba49fafeed70b619a0067bbc70ae4d534be441c812ce2bef4a5fb3c022",
"addons/core/Prefabs/ERR/Radio.et": "b4b5cfe125b39019855816c9a1c508ca4d65d435b5546fdaa6c1fa3c8c9b1165",
"addons/core/Prefabs/ERR/Radio.et.meta": "bc91137b68ba550217914fb8892bb44d7e1920e4a1086f3e506623832a44212f",
"addons/core/Prefabs/ERR/SpectatorCamera.et": "b5b87d5b7b707f3745741aebe7c923067c8a74f8fbb2a4711834bab03bb5a812",
"addons/core/Prefabs/ERR/SpectatorCamera.et.meta": "2a16558f93915e31908a674509e9c89976470f78a84a1174a64b94b68b8f77ad",
"addons/core/Prefabs/ERR/SupplyCache.et": "bccf7afbaae97cfcdd78dd6dbbf4be5b2c045d348f50fe4581962e556c0044d7",
"addons/core/Prefabs/ERR/SupplyCache.et.meta": "2f5de3a4aab1e9d0e35521f48dc57b95bd6e449c383dec4f1c258e10295904cb",
"addons/core/Prefabs/ERR/SupplySite.et": "dc5decce5cabf39b6116e8794ec3960cb1e35761854fdbe69740da118787ded4",
"addons/core/Prefabs/ERR/SupplySite.et.meta": "b41944b12eb3528ff7a3ac94258b18c66ef161aa6a38894aee300a1ac4798630",
"addons/core/Scripts/Game/ERR/ERR_Actions.c": "adf93245e6d78c59b9839599d157a0d2b2b93ea93b3d1ae52e2904dd6c288266",
"addons/core/Scripts/Game/ERR/ERR_Actors.c": "b3c5aabb05f7cf35167bc09b5db51a4ffd89a46658805d6eedbfb80eee30273d",
"addons/core/Scripts/Game/ERR/ERR_AdminService.c": "9985747d5ddaeb91bf27937836a6c369f8dcb353263b77a49212ec28c10ba4eb",
"addons/core/Scripts/Game/ERR/ERR_CasualtyGroundSupport.c": "26f0c7ebe8563bb022f7c383674e7d8997b0cc35c7ea321d39d74f2493c1ed9d",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingGameMode.c": "f4cf19440583ac24346831a2d5f1d7f734c031e46dc266c499972329dd0533cf",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingOwner.c": "6346a05ddda030f7d9b6f026f977d5f018ee16002fa519e8c49dcd700c323dc7",
"addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingService.c": "df787bc40099512656e622c6c511d18caea2ff7a88d2c113e0d6940a551ad566",
"addons/core/Scripts/Game/ERR/ERR_DiscoveryMap.c": "80fda5976c3d7a74ee3a481a0d5f365d5e59553046ebe84d0c84117829a32aaf",
"addons/core/Scripts/Game/ERR/ERR_DiscoveryService.c": "65cc0c23da131f986c3c90a8e4d294522e1d0681bec709b618daecb6e0d393c0",
"addons/core/Scripts/Game/ERR/ERR_DocumentComponent.c": "17bb76b80ebd3357e46d553c44674f602c7bd6901c92aec53ac8214194aa4ff2",
"addons/core/Scripts/Game/ERR/ERR_EnvironmentService.c": "867e9f47adfb7a9819a8b58498688ff86127282cb89cf2529ae81f73e529e1c5",
"addons/core/Scripts/Game/ERR/ERR_EscapeGameOverScreenInfo.c": "b1e1afb7795cb77c0bad94c85abf705b26b9dc2a9400905d80eafd56bdd009d3",
"addons/core/Scripts/Game/ERR/ERR_ExtractionPlacement.c": "c30222ca25cc0e91dec4077e6b82b37a9edafcf2cbebd0be5b6bd8656b53adfe",
"addons/core/Scripts/Game/ERR/ERR_ExtractionService.c": "91357099b4e0401196b67d48963be54be30e56bdba57cdac67dc20b8ebb883e9",
"addons/core/Scripts/Game/ERR/ERR_FactionCatalog.c": "a5a8c53acf21259e14f59cb919535910f30dabff5a9179c664bc6a7a4d744d6e",
"addons/core/Scripts/Game/ERR/ERR_GameMode.c": "043ac9ab7f3163f3285038ed008be782030714607d8e59e25593cfe95dd023b2",
"addons/core/Scripts/Game/ERR/ERR_InitialGuardRules.c": "8c9d6b1dc4c2af96284e34f487eebb5a221091016ef108006dec60b4e3836558",
"addons/core/Scripts/Game/ERR/ERR_Inventory.c": "b63e679d5b650b63a7a91dfc3f42a62f4be58b0338f6df3313e66d29a93bebf6",
"addons/core/Scripts/Game/ERR/ERR_LoadCasualtyAction.c": "5d868fb065a1a0fea7d5abfc81d1d8be96823815535f2ffd0dc4ff60d8eae794",
"addons/core/Scripts/Game/ERR/ERR_LocalAdmission.c": "b0e824c6880cbf9b1f368dc7ada9907bde78b22b948d419b6c861323f32258be",
"addons/core/Scripts/Game/ERR/ERR_Location.c": "d2035f56ded35743312ec6ca91a67f8623a466c91255e1893c570edf0954ff24",
"addons/core/Scripts/Game/ERR/ERR_MissionRules.c": "f7abc38ad8fdc375ce7fa63a65f0bade027d22b37e09de5e3f94ba8c3c63cc41",
"addons/core/Scripts/Game/ERR/ERR_NativeAdminSettingsProbe.c": "6a4df33a2b0e6b6aeed944c6895961e658d4f0db9aed9b8433a43a451fa35cae",
"addons/core/Scripts/Game/ERR/ERR_NativeBaseSmoke.c": "84e0a2d73bc12160cd0a95138085eb7647fa26b2326f790a95cb53748009fdd3",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyGroundProbe.c": "41f40db3735f8aa535c0061458d9892dcfe972222b8a17238e67b65633c46bc3",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyLoadProbe.c": "94c533deea654ec546df3f1ebb7cd213e6cd79b1125d99bab5303ef8e87b018b",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyRemoveProbe.c": "4cfc06f6d43b709b63caae714155ffc562502e884f49a9825623c6f46972ad36",
"addons/core/Scripts/Game/ERR/ERR_NativeCasualtyServiceProbe.c": "02a9d70d1f4ba20326df199ba41489cfbae12b7bb0aab441361421cee38ad9ea",
"addons/core/Scripts/Game/ERR/ERR_NativeContractsProbe.c": "d1556df885171cf967e96eef5d8981a2e9ee4e3938b7d32fdd0426f647bbabc0",
"addons/core/Scripts/Game/ERR/ERR_NativeDefinitionProbe.c": "c07048341396443ddf5307e340e2087254d65f0bddf8f7d93e6b6bd7f03ca360",
"addons/core/Scripts/Game/ERR/ERR_NativeEnvironmentProbe.c": "8b1d110717aa5f07bfb8fe633847eab519109e3a8a4100970a487be05c053418",
"addons/core/Scripts/Game/ERR/ERR_NativeEnvironmentRestartProbe.c": "7a836a206381b8e8de24c92baf141beb30575723675dd6948d738169ed26b507",
"addons/core/Scripts/Game/ERR/ERR_NativeExtractionProbe.c": "4b09385f73206de004f4f3c38a6192fd658a0d2012482dc5a84dff1599ceb972",
"addons/core/Scripts/Game/ERR/ERR_NativeFactionCatalogProbe.c": "ee11486cf77da9070506ccc0cfd6e94240c5387c8be455bf864934a8fef65f78",
"addons/core/Scripts/Game/ERR/ERR_NativeGuardCancelProbe.c": "bfa1c65cb039e19c3d1891e4a3fd33469e974c97cc7f42128efc31a8f587d514",
"addons/core/Scripts/Game/ERR/ERR_NativeLifecycleProbe.c": "b613a5dbe81c2032fd02d31070ae5631166d14d0b02cdbec3b63b782f0bbc115",
"addons/core/Scripts/Game/ERR/ERR_NativeMedicalProbe.c": "43fa51ffbcf9dd0cd8e905a1135bcf0756651da3af34677f3c92e7d264ed70b6",
"addons/core/Scripts/Game/ERR/ERR_NativeObjectiveLossProbe.c": "6b80fd317a8c6e8583bd4337870838a86251e3b8a681d0aa07e8b52e22abfc48",
"addons/core/Scripts/Game/ERR/ERR_NativeObjectiveProbe.c": "71fbd2479a70048f83d8b262ad1452f427be2c0afc8b071ef13bff477b9dc29b",
"addons/core/Scripts/Game/ERR/ERR_NativePatrolProbe.c": "02bd9fdf5454db7dd4c82240efe0d947bf8d6488ace42809c3aef6505cb6266d",
"addons/core/Scripts/Game/ERR/ERR_NativePrisonerProbe.c": "e2d1ffe5d269add55124601ff0d1dc032a398c7d51010736e6f0e4cbeb38ae86",
"addons/core/Scripts/Game/ERR/ERR_NativeRadioDefenceProbe.c": "cad54f0b43cefd72df74697dfc7e93725ff0acac6d311e963ce4f817428c272c",
"addons/core/Scripts/Game/ERR/ERR_NativeRecoveryProbe.c": "4de6868cd3e76afb80cf0ae5dac1e35d2c417838f640c2f18aa3343217eea2f2",
"addons/core/Scripts/Game/ERR/ERR_NativeResultProbe.c": "b9a117eef2d5f65fbd792041a2b3e59e38e201bda8e0df8c503e1a1242cfc415",
"addons/core/Scripts/Game/ERR/ERR_NativeSiteSurvey.c": "ac0203753ade0cdff6d483132797a80e4520f14546c3f9dea288281cd4cd9c4f",
"addons/core/Scripts/Game/ERR/ERR_NativeStationTeardownDiagnostic.c": "a363c2383e66311415fd29124f26f3b0c6cb866648d86673afac29fca22a994a",
"addons/core/Scripts/Game/ERR/ERR_NativeTimeProbe.c": "c93d049785971e51246fcc07cf24804270a752a655505f2c38e48c80df5255ae",
"addons/core/Scripts/Game/ERR/ERR_NativeTransportProbe.c": "63ec0c5ce698114daa6314b2a6e3c3e98e76094117c477f9d0d072260686d193",
"addons/core/Scripts/Game/ERR/ERR_NativeTransportSurvey.c": "3e94493bf54d15be2bceb106ad18873e14e6755af09c05f07db7fb26fb7adff5",
"addons/core/Scripts/Game/ERR/ERR_ObjectiveDetails.c": "628ebd166dcb5544c2d18dce489619984887ee18296cf2446fc6d894f89dd5bf",
"addons/core/Scripts/Game/ERR/ERR_ObjectiveText.c": "815fa44350798229784efffe0d4ec16d3382dd62df149215e49d527cc2961553",
"addons/core/Scripts/Game/ERR/ERR_Objectives.c": "88d95a52fcba103483ea751571e1afeae0e6fc82115ed50d6fc195424726960f",
"addons/core/Scripts/Game/ERR/ERR_Observer.c": "b719e723369ab4f403950c85226e1336eb48e3c127e84530ac1c695eb86bd0f9",
"addons/core/Scripts/Game/ERR/ERR_OrdinaryScenarioLaunch.c": "e2803ff9198e6213bfcbaefad64a35ae3ffe06846c410cf6da6de7653adbf28d",
"addons/core/Scripts/Game/ERR/ERR_PlayerAdminCommands.c": "a084d7dc097dfcde3d6cd9c2e326b9e2f8f2a519f77b30c4f56ab7a1429aa721",
"addons/core/Scripts/Game/ERR/ERR_PlayerEscapeResult.c": "3124ab4d2d6d471409a47aba0af528790734df53243c03fe0cdac3e407047c14",
"addons/core/Scripts/Game/ERR/ERR_PlayerGuide.c": "2c9c365b88651f8b12618443638bf52c04e497221592bd483c33447e30468f36",
"addons/core/Scripts/Game/ERR/ERR_PlayerRoster.c": "c038dac0f749bd29ebc35a4e952904b41a34417ba738904d5efcd1833a263e0b",
"addons/core/Scripts/Game/ERR/ERR_RadioDefenceService.c": "5d347cf1a3b021074d560aad8db774828b797e685b63ddff3d28f55781e33ea8",
"addons/core/Scripts/Game/ERR/ERR_RadioFeedback.c": "545262e65e9b3645d9e514a0521e442fe08f0c2e4e7c83ba638c5105d09818db",
"addons/core/Scripts/Game/ERR/ERR_RecoveryService.c": "ba9ffb93679012c20a665636ef6b201cbe7d8d14fdf53e8cd3eb12ac7248943f",
"addons/core/Scripts/Game/ERR/ERR_Resources.c": "d0169aac6fd0c38928c47a9002ded0fd8ba558ea3314a600e792d307ac1ca3ee",
"addons/core/Scripts/Game/ERR/ERR_ScenarioComponent.c": "abba03af68323d5715ba1e2497fc66f3c706e6a6a983c3a386228abdfddeec89",
"addons/core/Scripts/Game/ERR/ERR_Settings.c": "b9390548936b386e0211d487c1b76b65410fdd2e339cd8ecd9585ef4f4ffed31",
"addons/core/Scripts/Game/ERR/ERR_SiteDefinition.c": "b422feeaca90084ea2bee5cde94dc9c6fcae542749b55d95f7226f922a6a68ac",
"addons/core/Scripts/Game/ERR/ERR_SiteDiscoveryRules.c": "50f7b3ff4f32bde37ce5ae2be7f598fc4dd8cc08f45914f6e3260d31c84baef2",
"addons/core/Scripts/Game/ERR/ERR_SiteService.c": "6bc9a0b5aed326822807f05e17459d0fc2da10b709e8168972b4e40fd09f87cb",
"addons/core/Scripts/Game/ERR/ERR_SpawnFinalization.c": "2e295b0f225208c5414728ba83333e5e0ab6eef3a708ce39eb1dfce5400c94c9",
"addons/core/Scripts/Game/ERR/ERR_SpawnLogic.c": "bbbf35110259cacdac63779604ce22149d1a2198ec4c4cf43f7f3bf57e3241e8",
"addons/core/Scripts/Game/ERR/ERR_SpawnPlacement.c": "55323dcb330c23d49dc8fa3fde86a3ae3958c0b6563d6c3cd0960da88333f93d",
"addons/core/Scripts/Game/ERR/ERR_Supplies.c": "752e8a56b0b8cde33cf532032cb0a203553017b686faac2e19bee06f7a9c0713",
"addons/core/Scripts/Game/ERR/ERR_TimeService.c": "d9f481b7da01e08d2c982a948c18ba6bde76889d7cc9d26d510708f4ba479453",
"addons/core/Scripts/GameLib/ERR/ERR_DiagnosticNoSplash.c": "0ea1b402f8927b6d68bf6f7e5caa2967f7e3a39147634faab147796b791933b5",
"addons/core/Scripts/WorkbenchGame/ERR/ERR_ValidateBaseWorldPlugin.c": "7f44aa64ea7b4f8b3640a37a4b781c43bf6adb80e4a3a702d9491131698056f6",
"addons/core/Worlds/ERR_Everon.ent": "22324bc7eb0d80dec8a1f3bd61a9df9201b72f749f4e751766b0c9d0b7d46b87",
"addons/core/Worlds/ERR_Everon.ent.meta": "19d1903ca72baa326b4724a6791d0da1104a1e53f3f31dc1ca41a856efd68e83",
"addons/core/Worlds/ERR_Everon_Layers/default.layer": "17105538007199bfc419aa04a64debaf2da0a7b77a1dc3ba983e92bf747c862e",
"addons/core/addon.gproj": "231274e6b62302f32c65f9ff31de2ce8a9e51e1c8d12c87deeec82ae1f40de46",
"addons/core/resourceDatabase.rdb": "5765206693e176009ad2d37e0d46141ff57fec2348ea6331ed9511433eb001cb",
"addons/intel/Scripts/Game/ERR/ERR_IntelService.c": "482839434b94e7f8c345d5fd96490aeebb765f3dd0c1bb25fceea2f435c0e722",
"addons/intel/addon.gproj": "d0ced242cefb220a5cccd6779d61fda9bc55581701b9f78bcf13c09d92ddbcbe",
"addons/intel/resourceDatabase.rdb": "062996b9102e99d19eb680bed04880b0e087d9f8789681c0f3ff8ab6772339ba",
"addons/map/Materials/ERRM_MapRenderTarget.emat": "9877c5b175c5f30dd80bea36c711b21ab38219aa7075adf9ae79932e1d4c76bc",
"addons/map/Materials/ERRM_MapRenderTarget.emat.meta": "5ee1a705f8011a44020ca2691f5ccc17d44bf596fef9a36e98d1f267eb58fab0",
"addons/map/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et": "30dee8e9eab459ea32a7d835a9fb89d43df47708057cab829f067b25a24cd581",
"addons/map/Prefabs/Items/Equipment/ERRM_SharedFieldMap.et.meta": "59093e9072c50d99c86da7609c87541016da5bcf92b98d99db4c524e1c8e0e8d",
"addons/map/Scripts/Game/ERR/ERR_ScenarioMap.c": "75fa1d742129ef7f33c005cd48f56db7f49ee7bde3c5428532b0b501b032b0a3",
"addons/map/Scripts/Game/ERRMap/ERRM_SharedMapComponent.c": "fc1a0c7df4fc96da446d7542a45a10fbec1eda1e543ba2f0581cb772277a47c5",
"addons/map/UI/layouts/ERRMap/SharedMapRenderTarget.layout": "49a2da4181b94d42174f58c7f9b6bf2207116c99427d61ff1c212092ac7db4d2",
"addons/map/UI/layouts/ERRMap/SharedMapRenderTarget.layout.meta": "5c846445cc089e2e08899ba703059d4adb805ff30ab5a16409a3cd59718cbd54",
"addons/map/addon.gproj": "1b371e5e01ea9fa46e76570fecb8aaa3a9298e34cba7ccca8a6bdb5ca86eb46a",
"addons/map/resourceDatabase.rdb": "fe2d3eea469f3a69dcdb8567a7bb8119dcc03f940b423ad0babfc3b84e5cb0da",
"docs/acceptance.json": "283f08dc1658d214d3551d8b22f3a1d179fbb95f9d85cfbe63015adffc3b365d",
"docs/addons.json": "be6097ca5fb6ccb8c17bf4c05849e3e75225473162cdffef18a1cad13d056186",
"docs/admin-discovery-setting.md": "a140f09cd1f27635824a9fa27e88e99259fc0030ff3228dd1376e2e949edbc1c",
"docs/architecture.md": "6d7b52d5456b8fcd396421a7d8ed04be01c9111dabf38fa3e42b5db5fe4dce72",
"docs/base-gameplay-gaps.md": "8fb9ce4bf3d36507fdcd03af9681657c473bdf1f1d188380e7e4a83d47b10625",
"docs/base-replacement.md": "e99b648932b784e2993d086d6f56176fda5d853f53a4363cbf4754774cd8afec",
"docs/casualty-ground-source-sha256.json": "90ffa7d0c61e3823922ca9d4773e3d12fd5e9a1760a35c3b29fd12a53642f83a",
"docs/casualty-ground-support.md": "bf5bdf19f9dfa0fb83dfdb9a9933e5cf6a63be3918f74953759a639f85f121e4",
"docs/casualty-incapacitation.md": "2811fa294de0348fbdf8e78b0c66bc31a59dd8f1e43fe16af8da87cb7e789820",
"docs/casualty-loading.md": "9970b46ae4b9d0247e6bfad8378bba33c237f16cb49a4f53da49706291872b18",
"docs/casualty-remove-source-sha256.json": "4799a5843315fe5b5b2e933e8068a8b4bae6d924a49438eccb7f68ffc8e12be9",
"docs/configuration.md": "654657c3c6a515d101e4f43dba74a2146358a8ead56aa5444cac4aec48177bf5",
"docs/current-status.md": "b1003d1b7c0167304b694b50e31b851cdf763f986885c593a3426f369ae2dfa9",
"docs/dependency-audit.json": "d5e6cbcdc59c0a25e5748c590d6a195da9c97e8296119e07185f4c360bdfc4ae",
"docs/environment-restart-fixture.md": "1c1bd3872a67c5a59c12c1293d075d52fe0b563fcd5e9e10a1ce1850c7efcea9",
"docs/environment.md": "eff60684482ca8332e6ac4909850b6acd1048a5518ac70ae121dd16afb1a4409",
"docs/extraction.md": "215c96cbc004b3817a70ee40f30b181a72e78123e69e16a3585ed4d8d566837d",
"docs/faction-catalog-source-hashes.json": "46060bf2bfe6c39517e3140acb004f9b129c26695a7ee890b4aae571b3f0da76",
"docs/finite-mortar-operations.md": "e3d230810bd42a02afc798639ea36f08fe0dcc45d73d14457cf37e7791d499f3",
"docs/ground-transport.md": "4ef0b23e1e752b807344100948e7d0f880448158292f96309dcec5de9583a1a0",
"docs/guard-cancellation-fix.md": "41f8bd169de714df4df4a61189d47a37f9be2f1b1554edc99c29d8a1fa4aaf19",
"docs/guard-cancellation-source-hashes.json": "a1bf169c021931cdcba835d52e420df44e5dd2ef351257f0be10f63c8727afd4",
"docs/guard-source-hashes.json": "874845def1458901d61adeb090a464bbee7c7b18816406ae3780ff48fe855266",
"docs/initial-extraction-placement-source-sha256.json": "a44a32cedc54a70f635bf5840e7b29d35850a2212fcf64b1fd36ca096f10fffa",
"docs/initial-extraction-placement.md": "643b50d231dd9ceb49b81fd8f061cd114a9618fd1ad5a6f88724c0199a5a304c",
"docs/initial-guard-readiness.md": "5f2b45f3744f1f0316f198225a34e25d93eb4795bb05d6cfded8de1f1a116c18",
"docs/inventory-identity.md": "02092960cf937b175c5a190b426b84e0383104fa71f324c8b3a0ceb4fbe01164",
"docs/local-singleplayer-admission.md": "79943060c67330bd0b386733306653b59b1cb92c0924ff3bb0ffd3b582bec70a",
"docs/medical-kit-teardown-ownership.md": "2116a4062425f6fba029142ea0239264d313ec52f69ec7f88ee7b250a90814bf",
"docs/migration-provenance.json": "3f0ab1e9d1314265a7cdea3535a9e81af441c1b7a5c9c925e84aa824a1730663",
"docs/migration.md": "42514af2fbef0663d05f3353a26f3b2fcd4f7359634652d23fda53a8e7bfcd0f",
"docs/mission-faction-catalogs.md": "2ce3e49404d103a4c372ab0386de3bcf831bee87d95b1092372345a3d32ef8d2",
"docs/mission-time.md": "29d9a18c7acef0587764becbd04c2c63684644a05c7b3b2fe77defe1881ae7a0",
"docs/mortar-transactions-source-sha256.json": "dabad1cbc6eb3dd6f66b3e9ece574edcabff94adceeb2494b1adb2147608dbc0",
"docs/native-casualty-remove.md": "d55f54fba75e6cd1b9c30b489db17d58aa708afed792d1eafcf33d6d43c55e76",
"docs/native-errors.md": "f0cbc674803f5254db0c823bce2df437cad121756e19f6c658087d5d2fddb349",
"docs/native-followup-snapshot.json": "6b686ee641830edbc223cfcee4d6a198fcfa36ce8531bb16855fa9cbe9f5cbd2",
"docs/native-guard-cancellation.md": "880b545b8451a86f16ef47e0a378d081c8fecb1175bf9a8a122bf853ff9b816c",
"docs/native-initial-snapshot.json": "1ba571aa6da7c72d3db3eaaac54f5399820603ac33d7b21b87946eee3aa4eaf3",
"docs/native-medical-fixture.md": "3c915a74afbcac1dfa45f0c1e9d8d4801f33704cac9ce1b66355121805ecfbb1",
"docs/native-mortar-firing.md": "5fd4a5a4059ea6f8a3fa353b16c8f507316689daa60a883387c20114c4c16892",
"docs/objective-widget-lifecycle.md": "3ec0ee8c74b2a3117356477a16125a077dfbf010050e53280a00769b710958a0",
"docs/ordinary-diagnostic-splash.md": "6e07a87a03df81dd5c9d6c0f9602b26e08ec7fd7cf941b91f2b8007bd9d33e6a",
"docs/ordinary-game-startup.md": "6a95a55aa5fbccbe9a54fd7c695929d392f30bf2ce0c9f509304cfc4b627e14e",
"docs/ordinary-identity-diagnostics.md": "6d5017ff1bf27a276208cc42d567ab2c9f0e8936bf7dca3156c649f67eca359b",
"docs/ordinary-launch-callback-fix.md": "b74b8d0d011f25c367ea07b37e1a5ef488a2b378542ddca63ff9e981e649b874",
"docs/ordinary-splash-source-hashes.json": "b2e277e3487c2b790bce741527555bb74f6b9820b9e5626950ab709533d9fa97",
"docs/original-feature-coverage.json": "27cc7d2934abb3d307a4cfc0fb1f10ac53611bef64dcca99aa939f68c842e98a",
"docs/original-feature-coverage.md": "2807936a75db548342e4f89c01795395038270a6793aafe15c6069c82537c30a",
"docs/original-resource-inventory.json": "bc52a981c42f933134e637a027d08a0924abb19784782731590b7ef0b0e2e73f",
"docs/performance-comparison.md": "8065fae91ef0ef572b06f9aba079bd9f6ab96b25fa8c63e7a4a30b34f77765a0",
"docs/player-lifecycle.md": "903302c21da86668d6a3ff78a11d5eb2a5c36c30062f65a2039df717c195a140",
"docs/prisoner-loadout.md": "0b27f5fce4af457bea7133e461dbc37d8fa73fe126c8c3de90d723b358af389a",
"docs/radio-defence.md": "845078af4648e21781357b263916ce351e38489e4f49ebf17fb0bc75d7a859ff",
"docs/radio-document-loss.md": "44ce397e471b2fa5d8b773379f475e2c4cb93b33b936a76919e64e15251c2b9d",
"docs/radio-feedback.md": "3aaaecb318e2f737321bd08f9deb9323af153f2ae9ed196b55104c0616dd2be8",
"docs/recovery.md": "a91e170b0ea164f50db64acc1f19b78a6dce9392736f194a9192e85c68a71a88",
"docs/release-qualification.md": "7bdf42f51fe3a4c1d6187d0e6f5248ac9a68ce16873281909bd96e1cea6c406b",
"docs/runtime-testing.md": "2db2fc790785633e701e503e087a8a9de8633a11ed8f1b4f9f22972506005524",
"docs/site-authoring.md": "7a2e66e75ca3fdab43bd730f16e864c31909ab42fe060b00715caa13b8352ce7",
"docs/site-patrols.md": "5956f70a5ebea4167819a43c2a15f8b6d6460bc724b000f989d5ad5265d48d56",
"docs/validation.md": "48206348ef58afe52daf5dc8dca4aa65beaf00086aabfc995c808b5b0e8233fa",
"docs/vanilla-resources.json": "a18dbb7683641c439418091530219fd3d4de65b14e8a139577411c2a020a9903",
"tests/helicopter_availability_regression.py": "b8eabe0646467d6b55b7bc08c75121185410d3460c2c951f70737a5decbbfefe",
"tests/hq_network_regression.py": "3b077e1c527029d60432cbe2e0373c3a4a55ed4e80d6be59e639de8bc9411188",
"tests/mortar_salvo_regression.py": "6624f57ac28aabadd3ae2ba96b802910ffe739786d9aca0ad1caea68ad08eb5b",
"tests/policy_harness.py": "e861c30037b3e456f0c8ef1c02e9fe1417b601ffb15d2037974715008865e4be",
"tests/test_admin_setting_policy.py": "8d8ce49f4079d930c06bf23be410eb610e30082e3177a9f88bd6a0dfbf54189d",
"tests/test_casualty_ground_policy.py": "6b6fb5dccfef32eb46f7e5fee11d28acd3068c25837d2f1474491fd139be9316",
"tests/test_casualty_incapacitation.py": "fdeee4ae5b0e383c592ecbcd132b108ed6e92cb0e1f4767da02f95bfa33b7a4a",
"tests/test_casualty_loading_policy.py": "3a85d86dd1b19aa616fafb5d3a38f5374d5bb14d176844210150ef95df62033a",
"tests/test_casualty_remove_probe.py": "61578d8ca863d5e5be32dab2661fdd410e8441eaf1a9ae3b5123906eb3d57a68",
"tests/test_casualty_reservation_death.py": "dd5abb0ca2e7ec289f6933c406517515475d34ffeea95d732c329b42080773b7",
"tests/test_diagnostic_no_splash.py": "a9f54ced5864953c8031208d519c2dec9d604a70ad65bc738b51c6656a8aab22",
"tests/test_environment_policy.py": "4f844728d47ab3ad66c8a06f37833e0325f00bd04c0803d7dcf0eed14d8935c3",
"tests/test_environment_restart_runner.py": "05bc09bc45db70ba4a635b65b0a96aa38437ba50c98640b47ed8d0683c3a5f71",
"tests/test_extraction_placement_policy.py": "4cef86ff87338bc2e0bf66683c78050f3ba49d940d0c221a89333f4cb61a2442",
"tests/test_faction_catalog_scope.py": "c8fab92575f2621f47ed8685243338aa9ea717bb809c2ef9e8e0884af9df263b",
"tests/test_guard_cancellation_policy.py": "4a0671c62a5d875c0839d7cd9bdb0703cc28172ae6a3b483e041ec299b02efb1",
"tests/test_headless_game_runner.py": "29f045b65dbcb53f06359daa1ed7e981351517f9b08d0287da828eb1f8b4212a",
"tests/test_initial_guard_policy.py": "11354597457a240ec0427481ec0626cb952fbf06995a2955c24e81a5054edb5f",
"tests/test_inventory_enumeration_policy.py": "1a13ab9d7fdce46589a30ba005d65bada02a5a997f3fdb4dff025aec5514f802",
"tests/test_local_admission.py": "8ef122042a6c0c2258b1269e78606443546760ffdba6177c4f68f73769006e57",
"tests/test_mission_rules.py": "1561f50ea52a38227503ea3b5b2394a9303f82d9cea00268fbbe8fe83deb4b5b",
"tests/test_mortar_transactions.py": "3a17d444c1083336b52cb329fabaa1b9de7105cbe048e12b2d430600cc5bbcd1",
"tests/test_native_mortar_probe.py": "327f4c5ac1be24397c6c88c6b77d8889ae84d3b66c26caaeb400c1b2f373de5c",
"tests/test_performance_comparison.py": "5f932de9e9898acdd379f26c777a35c884269522dbf8c41991a7a25bf61c369a",
"tests/test_player_admission_policy.py": "9298c7f5f4b1da466ed044326e87f1b3ed6c7dc6fc65e8915ec08086fbc501e3",
"tests/test_prison_placement_policy.py": "269d8875e4a634bb0049acea644795ce6e58f335363d8e86ae1dae934d2ae28e",
"tests/test_radio_defence_policy.py": "9fd3c348d69c8c4e61c1135bb7e5df1b2b0ef07a2a5ad4faff1611d7b8e98097",
"tests/test_radio_feedback_policy.py": "d91c39d8291a16cfa5bb5fc5c7365a7421a7ce9f855a0b0250b76c2cb7cd1369",
"tests/test_recovery_policy.py": "e50879d0e2728f8ede3b67015d05bad5e34590dfdf315575b799adab1e23e186",
"tests/test_release_check.py": "8b6e755ed922ad129ba01c228989610a31f3a79841dc7cdddd4ddbd0e510971b",
"tests/test_settings_migration.py": "59fe9cd5f4564a6747a9a00fa422453830c6f94f6f1ba785d0592ef6feefe158",
"tests/test_site_discovery_policy.py": "79ccc06b74c05210428d602b4e22de1579523b163d5ab9ed2d52a29bed484896",
"tests/test_time_policy.py": "32c468c0a8852b7dfb873a93da80295434530131629eaca365a9c4aa9398c63a",
"tools/archive_native.py": "a302bd080275b72fbc47fa8108a98fb2689a377cbeb3cfe6e73596726bdab0bb",
"tools/check.py": "7460a22cf17fc9562fce73862c1b0791c830f2a8f25878626457618801599702",
"tools/compare_performance.py": "568acfee2525b8924f3e7a39784e8641f76d63bb3703dcce8251ab9ac9bb1854",
"tools/desktop/kwin-right-monitor.js": "8f0cf9ad290edf02e5f623cf1b0e36e2b266153ff81a022233c4cf67818b9499",
"tools/headless_game.py": "18ea1259e7f35121a7628edddecf5683ad49a1199f90f45ecdd7adbd120ca589",
"tools/headless_workbench.py": "7599cca63d7cad61201d7597ccb6776e3f8c681d1d7566b8d8261b35e3d8de69",
"tools/import_settings.py": "d9c250b52b6d29be3a80c3404f048b65a0b9b99e93b5213d5ce2be7d90a37324",
"tools/native_command.py": "4828826aa70b5ac31ab77157e658a8a3998de2829cdf782b8eee5b8c566d0385",
"tools/native_provenance.py": "d4777f1f6ffed6993f7009ee2af41b100e8e0138d60ebfdcc5404ff2128f8e2a",
"tools/native_report.py": "bb75ef5fe551f45776d441f15a49ccad4daf19abca505187f9b2d30102538658",
"tools/reference_guard.py": "545b67111927d73bf2020f291528ea6f2f687a994b3e37bf567f239c32c8cd78",
"tools/release_check.py": "65df1bff33638a583905ba5f6c583a095b9f7e38186b6f29d70b72a61525589e",
"tools/source_manifest.py": "c1a985348bad16f3b5b69ef7e545b6341eca298d8ae08111b8340b31535cc199"
}
@@ -0,0 +1,2 @@
# Preserve native evidence bytes, including engine CRLF line endings.
docs/evidence/** -text -whitespace
@@ -0,0 +1,7 @@
resourceDatabase.rdb*
*.pak
*.log
__pycache__/
.build/
.local/
profiles/
@@ -0,0 +1,32 @@
# Escapists Rereintroduced
An independently authored replacement for the abandoned Escapists base mission, initially targeting vanilla Everon and up to twelve players. This is a separate repository and **not a completed or release-ready replacement**. The base rewrite is the primary deliverable; companion migration supports it.
The current base supplies prison spawning, two independent scavenging/clue routes, finite medical and outpost stock, an optional ground vehicle, physical radio documents, named discovery markers, native objectives, a separate radio-defence service, capacity-checked helicopter extraction, identity-based partial results, early helicopter-loss defeat, saved mission time/speed, defeat/restart, identity-based lives and local spectator following. Authored site definitions and an injected vanilla faction/asset catalog own the initial physical population. Core provides administration and startup diagnostics; the optional AI, Intel, Chat and Map addons extend its interfaces. HQ coordinates enemy responses through physical radios and available forces.
See [current development status](docs/current-status.md) for verified checkpoints and the prioritized remaining work. Ordinary-game startup and ground-to-helicopter casualty loading have retained native failures; manual gameplay, real multiplayer, complete physical HQ support, measured FPS improvement and release qualification remain unfinished. The [original responsibility inventory](docs/original-feature-coverage.md) is a scope map, not proof that every original behavior has been replaced.
## Projects and scenarios
Five Workbench projects live in `addons/core`, `addons/ai`, `addons/intel`, `addons/chat` and `addons/map`:
- Open `addons/core/addon.gproj` for the independent base scenario, `{AD62322D5213C440}Missions/ERR_Everon_Base.conf`.
- Open `addons/chat/addon.gproj` for full companion integration, `{C1E20667DCE324ED}Missions/ERR_Everon.conf`.
Both use the newly authored Everon child world. The only external addon dependency is vanilla Arma Reforger. All required successor resources are inside this repository. Vanilla assets are referenced, not redistributed; original restricted Escapists code, compositions, UI and audio are not included.
See [player lifecycle](docs/player-lifecycle.md), [manual gameplay gaps](docs/base-gameplay-gaps.md), [release qualification](docs/release-qualification.md), [performance comparison tooling](docs/performance-comparison.md), [configuration and commands](docs/configuration.md), [site authoring](docs/site-authoring.md), [architecture](docs/architecture.md) and [migration priorities](docs/base-replacement.md).
## Validation
Run source/resource isolation and production-policy regressions with Python 3 and a C++17 compiler:
```sh
python3 tools/check.py
```
For bounded hidden, muted local native tests, see [runtime testing](docs/runtime-testing.md). Recorded Workbench checkpoints include Core-only and companion-loaded escape/restart, finite stock and document-loss recovery, twelve physical prisoner/seat fixtures, real medical treatment, local result/objective widgets, patrol movement and HQ preemption/resumption. Clean environment/restart evidence exists after narrowing the vanilla vehicle catalogs; it does not qualify subsequent source changes.
These scripted local fixtures manipulate positions and selected native states. They do not establish ordinary-game startup, manual escape/piloting, real remote reconnects, twelve connected players or improved FPS. [Current status](docs/current-status.md) separates those gaps from demonstrated development behavior. [Validation evidence](docs/validation.md) preserves exact source checkpoints and failed iterations; `docs/acceptance.json` keeps unverified release requirements pending.
No release package has been published.
@@ -0,0 +1,8 @@
SCR_AIGroup : "{8DE0C0830FE0C33D}Prefabs/Groups/OPFOR/Group_USSR_Base.et" {
m_aUnitPrefabSlots {
"{86E565387A634103}Prefabs/Characters/Campaign/Final/OPFOR/USSR_Army/Regular/Campaign_USSR_Player_MortarCrew.et"
"{86E565387A634103}Prefabs/Characters/Campaign/Final/OPFOR/USSR_Army/Regular/Campaign_USSR_Player_MortarCrew.et"
"{86E565387A634103}Prefabs/Characters/Campaign/Final/OPFOR/USSR_Army/Regular/Campaign_USSR_Player_MortarCrew.et"
"{612F43A4D5AE765F}Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_RTO.et"
}
}
@@ -0,0 +1,7 @@
MetaFileClass {
Name "{B84C05941C4C81B8}Prefabs/ERR/MortarCrew.et"
Configurations {
EntityTemplateResourceClass PC {}
EntityTemplateResourceClass HEADLESS {}
}
}
@@ -0,0 +1,339 @@
class ERR_HQUnit
{
int Id;
SCR_AIGroup Group;
SCR_AIGroupUtilityComponent Utility;
IEntity Radio;
float NextReport;
ref ERR_HQRoute Uplink;
ref ERR_HQReport PendingReport;
ref ERR_HQRoute Downlink;
ref ERR_HQReport PendingOrder;
ref ERR_HQReport Assignment;
AIWaypoint Waypoint;
bool ReservedForSupport;
bool Eligible(ERR_GameMode mode)
{
if (ReservedForSupport || !Group || !Utility || Group.GetPlayerCount(true) > 0 || Group.IsSlave() || Group.GetFaction() != mode.EnemyFaction()) return false;
array<AIAgent> agents = {};
Group.GetAgents(agents);
bool survivor;
foreach (AIAgent agent : agents)
{
if (!agent || !ERR_Actors.CanFight(agent.GetControlledEntity())) continue;
survivor = true;
if (CompartmentAccessComponent.GetVehicleIn(agent.GetControlledEntity())) return false;
}
return survivor;
}
void Release()
{
if (Waypoint)
{
if (Group) Group.RemoveWaypoint(Waypoint);
SCR_EntityHelper.DeleteEntityAndChildren(Waypoint);
}
Waypoint = null;
Assignment = null;
PendingOrder = null;
Downlink = null;
}
}
class ERR_HQ : ERR_CommandService
{
protected ERR_GameMode m_Mode;
protected ref ERR_MortarSystem m_Mortars;
protected ref array<ref ERR_HQUnit> m_Units = {};
protected ref array<ref ERR_HQReport> m_Contacts = {};
protected ref ERR_HQNetwork m_Network = new ERR_HQNetwork();
protected ref ERR_HQJournal m_Journal = new ERR_HQJournal();
protected int m_NextId;
protected float m_NextNetwork;
protected float m_NextAssignment;
void ERR_HQ(ERR_GameMode mode) { m_Mode = mode; m_Mortars = new ERR_MortarSystem(this); }
static ERR_HQ Get()
{
ERR_GameMode mode = ERR_GameMode.Get();
if (!mode) return null;
return ERR_HQ.Cast(mode.Command());
}
static bool MissionActive()
{
ERR_GameMode mode = ERR_GameMode.Get();
return mode && mode.Active();
}
static void Event(string kind, string message, int messageId = 0)
{
ERR_HQ hq = Get();
if (hq) hq.Journal().Write(kind, message, messageId);
}
ERR_MortarSystem Mortars() { return m_Mortars; }
bool PrepareSupport() { return m_Mortars.Prepare(); }
void ReserveGroup(SCR_AIGroup group)
{
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.Group != group) continue;
unit.Release();
unit.ReservedForSupport = true;
}
}
void PhysicalForces(out array<IEntity> entities)
{
entities.Clear();
foreach (ERR_HQUnit unit : m_Units)
{
if (!unit.Group) continue;
array<AIAgent> agents = {};
unit.Group.GetAgents(agents);
foreach (AIAgent agent : agents)
{
if (!agent || !agent.GetControlledEntity()) continue;
IEntity actor = agent.GetControlledEntity();
if (!entities.Contains(actor)) entities.Insert(actor);
IEntity vehicle = CompartmentAccessComponent.GetVehicleIn(actor);
if (vehicle && !entities.Contains(vehicle)) entities.Insert(vehicle);
}
}
m_Mortars.AppendGuns(entities);
}
bool MortarConnected(SCR_AIGroup group)
{
foreach (ERR_HQUnit unit : m_Units)
if (unit.Group == group && unit.Radio) return m_Network.Route(unit.Radio) != null;
return false;
}
ERR_HQRoute Downlink(SCR_AIGroup group, string kind, string detail, int sourceId)
{
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.Group != group || !unit.Radio) continue;
ERR_HQRoute route = m_Network.Route(unit.Radio, true);
if (!route) return null;
route.MessageId = m_Journal.Message();
route.Payload = string.Format("%1 from report M%2; %3", kind, sourceId, detail);
m_Journal.Write("ORDER QUEUED", route.Payload, route.MessageId);
return route;
}
return null;
}
void SupportContacts(out array<ref ERR_HQReport> contacts, float now)
{
contacts.Clear();
foreach (ERR_HQReport contact : m_Contacts)
if (ERR_MortarPrediction.Fresh(contact, now)) contacts.Insert(contact.Snapshot());
}
ERR_HQJournal Journal() { return m_Journal; }
string Status()
{
return string.Format("HQ: %1 groups, %2 delivered contacts, %3 assignments", m_Units.Count(), m_Contacts.Count(), Assigned()) + "; " + m_Mortars.Status();
}
override void RegisterGroup(SCR_AIGroup group)
{
if (!Replication.IsServer() || !group || m_Units.Count() >= 128) return;
foreach (ERR_HQUnit known : m_Units) if (known.Group == group) return;
SCR_AIGroupUtilityComponent utility = SCR_AIGroupUtilityComponent.Cast(group.FindComponent(SCR_AIGroupUtilityComponent));
if (!utility || group.GetFaction() != m_Mode.EnemyFaction()) return;
ERR_HQUnit unit = new ERR_HQUnit();
unit.Id = ++m_NextId;
unit.Group = group;
unit.Utility = utility;
int phase = unit.Id % 5;
unit.NextReport = GetGame().GetWorld().GetWorldTime() + phase * 1000;
m_Units.Insert(unit);
m_Journal.Write("REGISTER", string.Format("group %1", unit.Id));
}
override void UnregisterGroup(SCR_AIGroup group)
{
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.Group != group) continue;
unit.Release();
unit.Group = null;
unit.Utility = null;
}
}
protected int Assigned()
{
int total;
foreach (ERR_HQUnit unit : m_Units) if (unit.Assignment || unit.PendingOrder) total++;
return total;
}
protected void IndexRadios()
{
m_Network.Clear();
foreach (ERR_HQUnit unit : m_Units)
{
unit.Radio = null;
if (!unit.Group || unit.Group.GetPlayerCount(true) > 0 || unit.Group.GetFaction() != m_Mode.EnemyFaction()) continue;
array<AIAgent> agents = {};
unit.Group.GetAgents(agents);
int best;
foreach (AIAgent agent : agents)
{
if (!agent) continue;
IEntity actor = agent.GetControlledEntity();
int capability = ERR_HQRadio.Capability(actor);
if (capability <= 0) continue;
m_Network.Add(actor, unit.Group, unit.Id, capability);
if (capability > best) { unit.Radio = actor; best = capability; }
}
}
m_Network.Build();
}
protected void Observe(ERR_HQUnit unit, float now)
{
if (!unit.Utility || !unit.Radio || unit.Uplink || now < unit.NextReport) return;
unit.NextReport = now + m_Mode.Settings().Get("reportIntervalSeconds") * 1000;
array<ref ERR_HQVisualContact> samples = {};
ERR_HQObservation.Gather(unit.Utility, now, samples);
if (samples.IsEmpty()) return;
ERR_HQVisualContact seen = samples[0];
ERR_HQRoute route = m_Network.Route(unit.Radio);
if (!route) return;
ERR_HQReport report = new ERR_HQReport();
report.MessageId = m_Journal.Message();
report.Target = seen.Entity;
report.Source = unit.Group;
report.Position = seen.Position;
report.ObservedAt = seen.ObservedAt;
ERR_HQObservation.Describe(report, samples, now);
route.MessageId = report.MessageId;
route.Payload = report.Description(now);
unit.PendingReport = report;
unit.Uplink = route;
m_Journal.Write("REPORT", route.Payload, report.MessageId);
}
protected void Accept(ERR_HQReport report, float now)
{
if (!report || !ERR_MissionRules.ContactFresh(report.ObservedAt, now)) return;
for (int i = 0; i < m_Contacts.Count(); i++)
{
ERR_HQReport previous = m_Contacts[i];
if (previous.Target != report.Target) continue;
if (previous.ObservedAt >= report.ObservedAt) return;
float seconds = (report.ObservedAt - previous.ObservedAt) / 1000;
if (seconds > 0 && seconds < 30 && vector.DistanceXZ(previous.Position, report.Position) < 500)
{
report.Velocity = (report.Position - previous.Position) / seconds;
report.HasVelocity = report.Velocity.Length() <= 100;
}
m_Contacts[i] = report.Snapshot();
return;
}
if (m_Contacts.Count() >= 64) m_Contacts.Remove(0);
m_Contacts.Insert(report.Snapshot());
}
protected void DeliverOrder(ERR_HQUnit unit, float now)
{
ERR_HQReport order = unit.PendingOrder;
if (!order || !ERR_MissionRules.ContactFresh(order.ObservedAt, now) || !unit.Eligible(m_Mode)) { unit.Release(); return; }
SCR_AIGroupPerception perception = unit.Utility.m_Perception;
if (perception && !perception.m_aTargets.IsEmpty()) { unit.Release(); return; }
int deliveryId;
if (unit.Downlink) deliveryId = unit.Downlink.MessageId;
unit.Release();
vector position = order.Position;
if (order.HasVelocity) position = ERR_HQReport.Predict(position, order.Velocity, (now - order.ObservedAt) / 1000);
AIWaypoint waypoint = AIWaypoint.Cast(ERR_Actors.Spawn(ERR_Resources.SearchWaypoint(), ERR_Actors.Ground(position)));
if (!waypoint) { m_Journal.Write("ORDER FAILED", "waypoint spawn failed", order.MessageId); return; }
unit.Waypoint = waypoint;
unit.Assignment = order;
unit.Group.AddWaypointAt(waypoint, 0);
m_Journal.Write("ORDER DELIVERED", string.Format("group %1 from report M%2: %3", unit.Id, order.MessageId, order.Description(now)), deliveryId);
}
protected void Assign(float now)
{
int limit = m_Mode.Settings().Get("supportSquadLimit");
int radius = m_Mode.Settings().Get("responseRadiusMetres");
int assigned = Assigned();
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.Assignment && (!ERR_MissionRules.ContactFresh(unit.Assignment.ObservedAt, now) || !unit.Eligible(m_Mode) || assigned > limit))
{
unit.Release(); assigned--;
}
if (unit.PendingOrder && (!ERR_MissionRules.ContactFresh(unit.PendingOrder.ObservedAt, now) || !unit.Eligible(m_Mode) || assigned > limit))
{
unit.Release(); assigned--;
}
}
foreach (ERR_HQReport report : m_Contacts)
{
if (!ERR_MissionRules.ContactFresh(report.ObservedAt, now)) continue;
foreach (ERR_HQUnit unit : m_Units)
{
if (assigned >= limit) return;
if (unit.Assignment || unit.PendingOrder || !unit.Eligible(m_Mode) || !unit.Radio) continue;
if (vector.DistanceXZ(unit.Group.GetOrigin(), report.Position) > radius) continue;
SCR_AIGroupPerception perception = unit.Utility.m_Perception;
if (perception && !perception.m_aTargets.IsEmpty()) continue;
ERR_HQRoute route = m_Network.Route(unit.Radio, true);
if (!route) continue;
unit.PendingOrder = report.Snapshot();
unit.Downlink = route;
route.MessageId = m_Journal.Message();
route.Payload = "order from report M" + report.MessageId.ToString();
assigned++;
}
}
}
override void Tick(float now)
{
if (!Replication.IsServer()) return;
if (now >= m_NextNetwork) { IndexRadios(); m_NextNetwork = now + 5000; }
for (int i = m_Contacts.Count() - 1; i >= 0; i--)
if (!ERR_MissionRules.ContactFresh(m_Contacts[i].ObservedAt, now)) m_Contacts.Remove(i);
for (int i = m_Units.Count() - 1; i >= 0; i--)
{
ERR_HQUnit unit = m_Units[i];
if (unit.Uplink)
{
int delivered = unit.Uplink.Advance(now, m_Journal);
if (delivered == 1) Accept(unit.PendingReport, now);
if (delivered != 0) { unit.Uplink = null; unit.PendingReport = null; }
}
if (unit.Downlink)
{
int delivered = unit.Downlink.Advance(now, m_Journal);
if (delivered == 1) DeliverOrder(unit, now);
else if (delivered < 0) unit.Release();
}
if (!unit.Group && !unit.Uplink) { unit.Release(); m_Units.Remove(i); continue; }
Observe(unit, now);
}
if (now >= m_NextAssignment) { Assign(now); m_NextAssignment = now + 5000; }
m_Mortars.Tick(now);
m_Journal.Flush();
}
override void Stop()
{
m_Mortars.Stop();
foreach (ERR_HQUnit unit : m_Units) unit.Release();
m_Units.Clear();
m_Contacts.Clear();
m_Network.Clear();
m_Journal.Write("STOP", "HQ stopped; tactical orders released");
m_Journal.Flush();
}
}
modded class ERR_GameMode
{
protected override ERR_CommandService CreateCommandService() { return new ERR_HQ(this); }
}
@@ -0,0 +1,101 @@
// Server-owned audit stream. The file contains every event; chat reads a bounded
// recent-history window with explicit gap notices for clients that fall behind.
class ERR_HQJournal
{
protected ref array<string> m_Recent = {};
protected ref array<string> m_Pending = {};
protected int m_Sequence;
protected int m_Message;
protected static int s_Part;
protected static int s_Session;
protected string m_Session;
void ERR_HQJournal()
{
s_Session++;
m_Session = string.Format("%1-%2", System.GetUnixTime(), s_Session);
}
protected float m_RetryAt;
protected int m_Lost;
string Path()
{
if (s_Part == 0)
return "$logs:rereintroduced-hq.log";
return "$logs:rereintroduced-hq-" + s_Part.ToString() + ".log";
}
int Message()
{
return ++m_Message;
}
int Sequence()
{
return m_Sequence;
}
void Write(string kind, string message, int messageId = 0)
{
if (!Replication.IsServer())
return;
float seconds = GetGame().GetWorld().GetWorldTime() / 1000;
string line = string.Format("#%1 t=%2s M%3 %4 %5", ++m_Sequence, Math.Round(seconds * 10) / 10.0, messageId, kind, message) + " [session=" + m_Session + "]";
if (m_Recent.Count() >= 300)
m_Recent.Remove(0);
m_Recent.Insert(line);
if (m_Pending.Count() < 4096)
m_Pending.Insert(line);
else
m_Lost++;
}
void Read(int after, out array<string> lines, out int cursor, int limit = 8)
{
lines.Clear();
cursor = Math.Clamp(after, 0, m_Sequence);
int first = m_Sequence - m_Recent.Count();
if (cursor < first)
{
lines.Insert(string.Format("HQ log: %1 older entries are outside chat history; see %2", first - cursor, Path()));
cursor = first;
}
int characters;
for (int i = cursor - first; i < m_Recent.Count() && lines.Count() < Math.Clamp(limit, 1, 40); i++)
{
// Bound each menu RPC without skipping unread records. Chat still
// requests eight; the live menu can drain a busy journal faster.
if (characters + m_Recent[i].Length() > 16000 && !lines.IsEmpty())
break;
lines.Insert(m_Recent[i]);
characters += m_Recent[i].Length();
cursor++;
}
}
void Flush()
{
if (m_Pending.IsEmpty() || !Replication.IsServer())
return;
float now = GetGame().GetWorld().GetWorldTime();
if (now < m_RetryAt)
return;
FileHandle file = FileIO.OpenFile(Path(), FileMode.APPEND);
if (!file)
{
m_RetryAt = now + 30000;
PrintFormat("Escapists AI [HQ log]: cannot open %1; retry in 30s, chat history remains available", Path(), level: LogLevel.ERROR);
return;
}
foreach (string line : m_Pending)
file.WriteLine(line);
if (m_Lost > 0)
file.WriteLine(string.Format("HQ log: %1 entries lost while file was unavailable and buffer full", m_Lost));
bool rotate = file.GetLength() >= 5242880;
file.Close();
m_Pending.Clear();
m_Lost = 0;
if (rotate)
s_Part++;
}
}
@@ -0,0 +1,241 @@
// Radio propagation is simulated using actual living carriers and inventory.
// A manpack is the HQ uplink; short-range hops are limited to 500 m and three
// retransmissions. No virtual relay is fabricated when the network is broken.
class ERR_HQRadioNode
{
IEntity Carrier;
SCR_AIGroup Group;
int UnitId;
int Capability;
protected float m_CheckedAt = -1;
protected int m_LiveCapability;
bool Valid(bool manpack = false)
{
ERR_GameMode factions = ERR_GameMode.Get();
if (!Carrier || !Group || Group.GetPlayerCount(true) > 0 || !factions || Group.GetFaction() != factions.EnemyFaction() || ERR_Actors.Group(Carrier) != Group)
return false;
int required = 1;
if (manpack)
required = 2;
float now = GetGame().GetWorld().GetWorldTime();
if (m_CheckedAt < 0 || now < m_CheckedAt || now - m_CheckedAt >= 1000)
{
m_CheckedAt = now;
m_LiveCapability = ERR_HQRadio.Capability(Carrier);
}
return m_LiveCapability >= required;
}
string Label()
{
return "unit " + UnitId.ToString();
}
}
class ERR_HQRoute
{
ref array<ref ERR_HQRadioNode> Nodes = {};
bool Downlink;
int Cursor;
bool Sending;
float Due;
vector SentFrom;
float StartedAt = -1;
int MessageId;
string Payload;
bool Failed;
// -1 failed, 0 travelling, 1 delivered. Each hop really gates delivery.
int Advance(float now, ERR_HQJournal journal)
{
if (Failed)
return -1;
if (StartedAt < 0)
{
StartedAt = now;
if (Downlink)
Cursor = -1; // first leg is HQ to the manpack
}
if (now - StartedAt > 30000)
return Fail(journal, "route timed out");
int target = Cursor + 1;
if (Sending)
{
if (now < Due)
return 0;
if (target < Nodes.Count())
{
if (!Nodes[target].Valid(Downlink && target == 0))
return Fail(journal, "receiving carrier lost radio, died or changed ownership");
if (Cursor >= 0 && vector.DistanceXZ(SentFrom, Nodes[target].Carrier.GetOrigin()) > 500)
return Fail(journal, "receiver moved beyond the 500m link");
journal.Write("RECEIVE", Nodes[target].Label() + " received from " + SenderLabel(), MessageId);
}
else
journal.Write("RECEIVE", "HQ received from " + SenderLabel(), MessageId);
Cursor++;
Sending = false;
if ((!Downlink && Cursor >= Nodes.Count()) || (Downlink && Cursor == Nodes.Count() - 1))
return 1;
target = Cursor + 1;
}
if (Nodes.IsEmpty())
return Fail(journal, "no physical radio route");
if (Cursor >= 0 && !Nodes[Cursor].Valid(!Downlink && Cursor == Nodes.Count() - 1))
return Fail(journal, "transmitting carrier lost radio, died or changed ownership");
string recipient = "HQ";
string link = "long-range";
if (target < Nodes.Count())
{
if (!Nodes[target].Valid(Downlink && target == 0))
return Fail(journal, "next relay unavailable");
recipient = Nodes[target].Label();
if (Cursor >= 0)
{
SentFrom = Nodes[Cursor].Carrier.GetOrigin();
float distance = vector.DistanceXZ(SentFrom, Nodes[target].Carrier.GetOrigin());
if (distance > 500)
return Fail(journal, "next relay beyond 500m");
link = Math.Round(distance).ToString() + "m short-range";
}
}
journal.Write("TRANSMIT", SenderLabel() + " -> " + recipient + " (" + link + ")", MessageId);
Sending = true;
Due = now + 2000;
return 0;
}
protected string SenderLabel()
{
if (Cursor < 0)
return "HQ";
return Nodes[Cursor].Label();
}
protected int Fail(ERR_HQJournal journal, string reason)
{
Failed = true;
journal.Write("LOST", reason + "; " + Payload, MessageId);
return -1;
}
}
class ERR_HQNetwork
{
protected ref array<ref ERR_HQRadioNode> m_Nodes = {};
protected ref array<int> m_Parents = {};
protected ref array<int> m_Depths = {};
protected ref map<IEntity, int> m_Indices = new map<IEntity, int>();
protected ref map<string, ref array<int>> m_Cells = new map<string, ref array<int>>();
bool Overflow;
void Clear()
{
m_Nodes.Clear();
m_Parents.Clear();
m_Depths.Clear();
m_Indices.Clear();
m_Cells.Clear();
Overflow = false;
}
protected string Cell(int x, int z)
{
return string.Format("%1:%2", x, z);
}
void Add(IEntity carrier, SCR_AIGroup group, int unitId, int capability)
{
if (m_Indices.Contains(carrier))
return;
if (m_Nodes.Count() >= 2048)
{
Overflow = true;
return;
}
ERR_HQRadioNode node = new ERR_HQRadioNode();
node.Carrier = carrier;
node.Group = group;
node.UnitId = unitId;
node.Capability = capability;
int index = m_Nodes.Count();
m_Nodes.Insert(node);
m_Indices.Insert(carrier, index);
m_Parents.Insert(-2);
m_Depths.Insert(99);
vector position = carrier.GetOrigin();
string key = Cell(Math.Floor(position[0] / 500), Math.Floor(position[2] / 500));
array<int> cell = m_Cells.Get(key);
if (!cell)
{
cell = {};
m_Cells.Insert(key, cell);
}
cell.Insert(index);
}
void Build()
{
array<int> queue = {};
int checks;
for (int root = 0; root < m_Nodes.Count(); root++)
{
if (m_Nodes[root].Capability == 2)
{
m_Parents[root] = -1;
m_Depths[root] = 0;
queue.Insert(root);
}
}
for (int head = 0; head < queue.Count(); head++)
{
int from = queue[head];
if (m_Depths[from] >= 3)
continue;
vector position = m_Nodes[from].Carrier.GetOrigin();
int x = Math.Floor(position[0] / 500);
int z = Math.Floor(position[2] / 500);
for (int dx = -1; dx <= 1; dx++)
{
for (int dz = -1; dz <= 1; dz++)
{
array<int> neighbors = m_Cells.Get(Cell(x + dx, z + dz));
if (!neighbors)
continue;
foreach (int candidate : neighbors)
{
if (++checks > 100000)
{
Overflow = true;
return;
}
if (m_Parents[candidate] != -2 || vector.DistanceXZ(position, m_Nodes[candidate].Carrier.GetOrigin()) > 500)
continue;
m_Parents[candidate] = from;
m_Depths[candidate] = m_Depths[from] + 1;
queue.Insert(candidate);
}
}
}
}
}
ERR_HQRoute Route(IEntity caller, bool downlink = false)
{
int index;
if (!m_Indices.Find(caller, index) || m_Parents[index] == -2)
return null;
ERR_HQRoute route = new ERR_HQRoute();
route.Downlink = downlink;
while (index >= 0)
{
if (downlink)
route.Nodes.InsertAt(m_Nodes[index], 0);
else
route.Nodes.Insert(m_Nodes[index]);
index = m_Parents[index];
}
return route;
}
}
@@ -0,0 +1,199 @@
// These samples exist only at intake. HQ never revisits their entity loadouts.
class ERR_HQVisualContact
{
IEntity Entity;
vector Position;
float ObservedAt;
bool Escapist;
string Travel = "unknown";
string Weapon = "unknown";
}
class ERR_HQObservation
{
// Require current native line of sight before reading visible equipment.
static bool IsClearSighting(float age, float traceFraction, float exposure)
{
return age >= 0 && age <= 0.5 && traceFraction >= 1 && exposure > 0;
}
static bool CanIdentifyWeapon(float distance, float exposure)
{
return distance >= 0 && distance <= 150 && exposure >= 0.5;
}
static string WeaponCategory(EWeaponType type)
{
switch (type)
{
case EWeaponType.WT_HANDGUN: return "pistol";
case EWeaponType.WT_RIFLE: return "rifle";
case EWeaponType.WT_SNIPERRIFLE: return "sniper rifle";
case EWeaponType.WT_MACHINEGUN: return "machine gun";
case EWeaponType.WT_ROCKETLAUNCHER: return "rocket launcher";
case EWeaponType.WT_GRENADELAUNCHER: return "grenade launcher";
case EWeaponType.WT_FRAGGRENADE: return "grenade";
case EWeaponType.WT_SMOKEGRENADE: return "smoke grenade";
}
return "unidentified weapon";
}
static ERR_HQVisualContact Capture(BaseTarget target, float now)
{
if (!target || target.GetTargetCategory() != ETargetCategory.ENEMY || !IsClearSighting(target.GetTimeSinceSeen(), target.GetTraceFraction(), target.GetExposure()))
return null;
DamageManagerComponent damage = target.GetDamageManagerComponent();
if (damage && damage.IsDestroyed())
return null;
IEntity entity = target.GetTargetEntity();
if (!entity)
return null;
ERR_HQVisualContact seen = new ERR_HQVisualContact();
seen.Entity = entity;
seen.Position = target.GetLastSeenPosition();
seen.ObservedAt = now - target.GetTimeSinceSeen() * 1000;
SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(entity);
if (character)
{
if (GetGame().GetPlayerManager())
seen.Escapist = GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(entity) > 0;
seen.Travel = "on foot";
if (CompartmentAccessComponent.GetVehicleIn(entity))
seen.Travel = "in vehicle";
// Read only the drawn weapon; never enumerate weapons or inventory.
if (CanIdentifyWeapon(target.GetDistance(), target.GetExposure()))
{
CharacterControllerComponent controller = CharacterControllerComponent.Cast(entity.FindComponent(CharacterControllerComponent));
if (controller)
{
IEntity heldItem = controller.GetCurrentItemInHands();
BaseWeaponComponent weapon;
if (heldItem)
weapon = BaseWeaponComponent.Cast(heldItem.FindComponent(BaseWeaponComponent));
seen.Weapon = "none drawn";
if (weapon)
seen.Weapon = WeaponCategory(weapon.GetWeaponType());
}
}
}
else if (Vehicle.Cast(entity))
{
seen.Travel = "vehicle";
if (target.GetUnitType() == EAIUnitType.UnitType_Aircraft)
seen.Travel = "aircraft";
}
return seen;
}
static void Gather(SCR_AIGroupUtilityComponent utility, float now, out array<ref ERR_HQVisualContact> samples)
{
samples.Clear();
if (!utility)
return;
array<BaseTarget> visible = {};
utility.ERR_HQGetVisualTargets(visible);
foreach (BaseTarget target : visible)
{
ERR_HQVisualContact seen = Capture(target, now);
if (!seen)
continue;
ERR_HQVisualContact existing;
foreach (ERR_HQVisualContact sample : samples)
{
if (sample.Entity == seen.Entity)
{
existing = sample;
break;
}
}
if (!existing)
{
if (samples.Count() < 64)
samples.Insert(seen);
}
else if (seen.ObservedAt > existing.ObservedAt || (seen.ObservedAt == existing.ObservedAt && existing.Weapon == "unknown" && seen.Weapon != "unknown"))
{
existing.Position = seen.Position;
existing.ObservedAt = seen.ObservedAt;
existing.Travel = seen.Travel;
existing.Weapon = seen.Weapon;
}
}
}
static void Describe(ERR_HQReport report, array<ref ERR_HQVisualContact> samples, float now)
{
// New observations must not silently inherit old equipment/travel details.
report.SeenEscapists = -1;
report.TravelMode = "unknown";
report.SeenWeapons = "unknown";
report.DetailsObservedAt = -1;
if (report.Distress)
return;
ERR_HQVisualContact anchor;
foreach (ERR_HQVisualContact sample : samples)
{
if (sample.Entity == report.Target && now - sample.ObservedAt >= 0 && now - sample.ObservedAt <= 500)
{
anchor = sample;
break;
}
}
if (!anchor)
return;
report.DetailsObservedAt = anchor.ObservedAt;
report.TravelMode = anchor.Travel;
report.SeenWeapons = anchor.Weapon;
array<IEntity> counted = {};
array<string> weapons = {};
string travel;
foreach (ERR_HQVisualContact sighting : samples)
{
if (!sighting.Escapist || !sighting.Entity || counted.Contains(sighting.Entity) || now - sighting.ObservedAt < 0 || now - sighting.ObservedAt > 500 || vector.DistanceXZ(anchor.Position, sighting.Position) > 100)
continue;
counted.Insert(sighting.Entity);
if (travel.IsEmpty())
travel = sighting.Travel;
else if (travel != sighting.Travel)
travel = "mixed travel";
if (sighting.Weapon != "unknown" && !weapons.Contains(sighting.Weapon) && weapons.Count() < 4)
weapons.Insert(sighting.Weapon);
}
if (counted.IsEmpty())
return; // A visible vehicle does not reveal its hidden occupants.
report.SeenEscapists = counted.Count();
// A vehicle anchor remains a vehicle report, even with people near it.
if (anchor.Escapist)
report.TravelMode = travel;
report.SeenWeapons = "unknown";
if (!weapons.IsEmpty())
{
report.SeenWeapons = weapons[0];
for (int i = 1; i < weapons.Count(); i++)
report.SeenWeapons += ", " + weapons[i];
}
}
}
modded class SCR_AIGroupUtilityComponent
{
void ERR_HQGetVisualTargets(out array<BaseTarget> targets)
{
targets.Clear();
foreach (SCR_AIInfoComponent info : m_aInfoComponents)
{
if (!info || !info.m_Perception)
continue;
AIAgent observer = AIAgent.Cast(info.GetOwner());
if (!observer || !ERR_Actors.CanFight(observer.GetControlledEntity()))
continue;
array<BaseTarget> own = {};
info.m_Perception.GetTargetsList(own, ETargetCategory.ENEMY);
foreach (BaseTarget target : own)
{
if (target && ERR_HQObservation.IsClearSighting(target.GetTimeSinceSeen(), target.GetTraceFraction(), target.GetExposure()))
targets.Insert(target);
}
}
}
}
@@ -0,0 +1,144 @@
// A radio's category is protected in the stock gadget component.
modded class SCR_RadioComponent
{
bool ERR_IsHQManpack()
{
return m_iRadioCategory == ERadioCategory.MANPACK;
}
}
class ERR_HQRadio
{
// 0: no radio, 1: basic radio, 2: manpack. Inventory is checked live.
static int Capability(IEntity character)
{
if (!ERR_Actors.CanFight(character))
return 0;
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(character.FindComponent(InventoryStorageManagerComponent));
if (!inventory)
return 0;
array<IEntity> items = {};
inventory.GetItems(items);
int result;
foreach (IEntity item : items)
{
if (!item || !item.FindComponent(BaseRadioComponent))
continue;
result = 1;
SCR_RadioComponent gadget = SCR_RadioComponent.Cast(item.FindComponent(SCR_RadioComponent));
if (gadget && gadget.ERR_IsHQManpack())
return 2;
}
return result;
}
}
// HQ uses entity identity only for matching observations, never for its origin.
// Visible details are captured at intake and copied as scalar snapshots.
// Reports and orders contain immutable observed coordinates and timestamps.
class ERR_HQReport
{
int MessageId;
IEntity Target;
SCR_AIGroup Source;
vector Position;
vector Velocity;
float ObservedAt = -1;
float LastSent = -60000;
float PerceptionStamp = -1;
bool HasVelocity;
bool Engaged;
bool Distress;
int SeenEscapists = -1;
string TravelMode = "unknown";
string SeenWeapons = "unknown";
float DetailsObservedAt = -1;
ERR_HQReport Snapshot()
{
ERR_HQReport copy = new ERR_HQReport();
copy.MessageId = MessageId;
copy.Target = Target;
copy.Source = Source;
copy.Position = Position;
copy.Velocity = Velocity;
copy.ObservedAt = ObservedAt;
copy.Engaged = Engaged;
copy.Distress = Distress;
copy.HasVelocity = HasVelocity;
copy.SeenEscapists = SeenEscapists;
copy.TravelMode = TravelMode;
copy.SeenWeapons = SeenWeapons;
copy.DetailsObservedAt = DetailsObservedAt;
return copy;
}
string TravelDirection()
{
if (!HasVelocity)
return "unknown";
if (Velocity.Length() < 0.5)
return "stationary";
float x = Math.AbsFloat(Velocity[0]);
float z = Math.AbsFloat(Velocity[2]);
string northSouth = "N";
string eastWest = "E";
if (Velocity[2] < 0)
northSouth = "S";
if (Velocity[0] < 0)
eastWest = "W";
if (x < z * 0.414214)
return northSouth;
if (z < x * 0.414214)
return eastWest;
return northSouth + eastWest;
}
string Description(float now, bool brief = false)
{
if (Distress)
return string.Format("Distress at friendly X=%1 Z=%2; enemy details unknown (%3s ago)", Math.Round(Position[0]), Math.Round(Position[2]), Math.Round(Math.Max(0, now - ObservedAt) / 1000));
string count = "count unknown";
if (SeenEscapists >= 0)
count = "at least " + SeenEscapists.ToString() + " spotted nearby";
string motion = "speed/direction unknown";
if (HasVelocity)
{
float speed = Math.Round(Velocity.Length() * 10) / 10.0;
float azimuth = Math.Atan2(Velocity[0], Velocity[2]) * Math.RAD2DEG;
if (azimuth < 0)
azimuth += 360;
int heading = Math.Round(azimuth);
motion = string.Format("%1 km/h, azimuth %2 degrees (%3)", Math.Round(speed * 3.6), heading % 360, TravelDirection());
}
string details = count + "; " + TravelMode + "; " + motion + "; seen weapons: " + SeenWeapons;
if (brief)
return details;
string velocity = "unknown";
if (HasVelocity)
velocity = string.Format("[%1,%2] m/s", Math.Round(Velocity[0] * 10) / 10.0, Math.Round(Velocity[2] * 10) / 10.0);
return string.Format("X=%1 Z=%2: %3; vector X/Z=%4 (%5s ago)", Math.Round(Position[0]), Math.Round(Position[2]), details, velocity, Math.Round(Math.Max(0, now - ObservedAt) / 1000));
}
static vector Predict(vector position, vector velocity, float seconds)
{
vector offset = velocity * Math.Clamp(seconds, 0, 20);
offset[1] = 0;
if (offset.Length() > 300)
offset = offset.Normalized() * 300;
return position + offset;
}
int Priority(float now)
{
if (Distress)
return 0;
if (now - ObservedAt <= 15000)
{
if (Engaged)
return 3;
return 2;
}
return 1;
}
}
@@ -0,0 +1,31 @@
// An idle rotor or zero speed alone is normal during takeoff, landing and reload.
// Confirm prolonged grounding, but recognize actual loss of flight capability.
class ERR_HelicopterAvailability
{
protected float m_fGroundedSince = -1;
string Check(float now, float spawnedAt, bool destroyed, bool disabled, bool livingPilot, bool playerControlled, bool servicing, float height, float speed)
{
if (destroyed) return "destroyed";
if (now - spawnedAt < 20000)
{
m_fGroundedSince = -1;
return "";
}
if (disabled) return "engine, rotor or airframe disabled";
if (playerControlled)
{
m_fGroundedSince = -1;
return "";
}
if (!livingPilot) return "no living pilot";
if (servicing || height > 5 || speed > 2)
{
m_fGroundedSince = -1;
return "";
}
if (m_fGroundedSince < 0) m_fGroundedSince = now;
if (now - m_fGroundedSince >= 60000) return "grounded for 60 seconds";
return "";
}
}
@@ -0,0 +1,461 @@
// Migrated from the independently authored AI extension; successor-owned physical groups.
// Each site/phase has its own repeat limiter. Changed reasons and lifecycle
// events are immediate; only identical polling results are summarized.
class ERR_MortarTraceState
{
string LastReason;
float NextLog;
int Suppressed;
bool Due(string reason, float now)
{
if (reason != LastReason || now >= NextLog)
{
LastReason = reason;
NextLog = now + 30000;
return true;
}
Suppressed++;
return false;
}
}
class ERR_MortarBattery
{
static const ResourceName GUN = "{D1FFE458E8AC4BDB}Prefabs/Weapons/Mortars/2B14/Mortar_2B14.et";
static const ResourceName SHELL = "{98EC9C526AFBA282}Prefabs/Weapons/Ammo/Ammo_Shell_82mm_HE_O832DU.et";
static const ResourceName CREW = "{86E565387A634103}Prefabs/Characters/Campaign/Final/OPFOR/USSR_Army/Regular/Campaign_USSR_Player_MortarCrew.et";
static const ResourceName RADIO_OPERATOR = "{612F43A4D5AE765F}Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_RTO.et";
IEntity RadioOperator;
IEntity Gun;
SCR_AIGroup Group;
ref SCR_AIStaticArtilleryActivity Activity;
ref ERR_HQReport Report;
ref ERR_HQRoute RadioOrder;
ref ERR_HQReport PendingRadioReport;
ref ERR_HQReport PendingSupplyReport;
protected ref ERR_MortarReadiness m_Readiness;
protected ref ERR_MortarSupplyTransfer m_Transfer;
protected ref array<IEntity> m_AttemptedShells = {};
protected bool m_Stopped;
vector Position;
vector Impact;
vector AimOffset;
int AimedShot = -1;
float FlightTime;
float AimedAt = -1;
float AirspaceUntil;
vector AirspaceImpact;
float AirspaceRadius = 600;
float OrderedAt;
float NextOrder;
float SpawnedAt;
bool StartupActivated;
bool Released;
bool Rejected;
bool Claimed; // keeps the world slot occupied after the battery is destroyed
int SiteId;
int OrderId;
int RadioId;
int SourceId;
int OrderShots;
int TotalShots;
bool CommandOpen;
string LastFailure;
string SpawnFailure;
vector LastCandidate;
ref map<string, int> SearchCounts = new map<string, int>();
ref map<string, ref ERR_MortarTraceState> Traces = new map<string, ref ERR_MortarTraceState>();
void Audit(string kind, string detail)
{
ERR_HQ.Event("MORTAR " + kind, string.Format("site=%1 order=%2 radio=M%3 source=M%4 position=%5; %6", SiteId, OrderId, RadioId, SourceId, Position, detail), RadioId);
}
void Trace(string phase, string reason, string detail)
{
ERR_MortarTraceState state;
if (!Traces.Find(phase, state))
{
state = new ERR_MortarTraceState();
Traces.Insert(phase, state);
}
string previous = state.LastReason;
if (!state.Due(reason, GetGame().GetWorld().GetWorldTime()))
return;
Audit(phase, string.Format("reason=%1; %2; previous=%3 repeated polls omitted=%4", reason, detail, previous, state.Suppressed));
state.Suppressed = 0;
}
void FlushTraces()
{
foreach (string phase, ERR_MortarTraceState state : Traces)
{
if (state.Suppressed > 0)
Audit("REPEATS", string.Format("phase=%1 reason=%2 repeated polls omitted=%3", phase, state.LastReason, state.Suppressed));
}
Traces.Clear();
}
string OperationalReason()
{
if (m_Stopped) return "battery stopped";
if (!Gun) return "gun missing";
if (!SpawnFailure.IsEmpty()) return SpawnFailure;
if (!Group || !Group.GetGroupUtilityComponent()) return "crew group missing";
if (Group.GetFaction() != ERR_GameMode.Get().EnemyFaction()) return "crew changed faction";
if (Group.GetPlayerCount(true) > 0) return "player in crew group";
if (Group.GetAgentsCount() == 0) return "crew group empty";
DamageManagerComponent damage = DamageManagerComponent.Cast(Gun.FindComponent(DamageManagerComponent));
if (damage && damage.IsDestroyed()) return "gun destroyed";
return "";
}
void BeginRequest(ERR_HQReport report, float now)
{
Cancel("superseded by new HQ order");
FlushTraces();
OrderId++;
RadioId = 0;
SourceId = report.MessageId;
OrderShots = 0;
Released = false;
CommandOpen = true;
OrderedAt = now;
LastFailure = "";
Audit("COMMAND", string.Format("requested rounds=%1 HE radius=%2m; %3", ERR_MortarSalvo.ROUNDS, ERR_MortarSalvo.RADIUS_METRES, report.Description(now)));
}
void ObserveProjectile(IEntity projectileEntity, IEntity firingCharacter, bool playerGunner)
{
if (!projectileEntity)
{
Audit("FIRE CALLBACK", "native OnWeaponFired had no projectile; no confirmed shot counted");
return;
}
TotalShots++;
if (CommandOpen && Released && !playerGunner)
{
OrderShots++;
// Only a physical projectile unlocks the next load. It must be aimed again.
Released = false;
AimedAt = -1;
Audit("FIRED", string.Format("physical projectile=%1 origin=%2 order shots=%3 total shots=%4 predicted impact=%5 predicted flight=%6s gunner=%7 (impact not observed)", projectileEntity, projectileEntity.GetOrigin(), OrderShots, TotalShots, Impact, FlightTime, firingCharacter));
}
else
Audit("FIRED UNASSIGNED", string.Format("physical projectile=%1 origin=%2 player gunner=%3 order open=%4 committed=%5 total shots=%6; no active HQ order attribution", projectileEntity, projectileEntity.GetOrigin(), playerGunner, CommandOpen, Released, TotalShots));
}
void ReserveShellAirspace(float now)
{
// Enclose every still-airborne shell, including an earlier, longer flight.
// A later round must not move/shrink the existing exclusion or deadline.
if (now >= AirspaceUntil)
{
AirspaceImpact = Impact;
AirspaceRadius = 600;
}
AirspaceRadius = Math.Max(AirspaceRadius, vector.DistanceXZ(AirspaceImpact, Impact) + 600);
AirspaceUntil = Math.Max(AirspaceUntil, now + (FlightTime + 10) * 1000);
}
bool SpawnFailed(string reason)
{
SpawnFailure = reason;
Audit("DEPLOY FAILED", string.Format("reason=%1 claimed=%2 gun=%3 group=%4", reason, Claimed, Gun, Group));
return false;
}
void SearchResult(vector candidate, string reason)
{
LastCandidate = candidate;
int count;
SearchCounts.Find(reason, count);
SearchCounts.Set(reason, count + 1);
}
void SiteStatus(float now)
{
if (!SearchCounts.IsEmpty())
{
string counts;
foreach (string reason, int count : SearchCounts) counts += string.Format("%1=%2; ", reason, count);
Audit("SITE SEARCH", string.Format("candidate counts since last summary: %1 last candidate=%2", counts, LastCandidate));
SearchCounts.Clear();
}
int agents, living;
int actionState = -1;
if (Group)
{
array<AIAgent> crew = {};
Group.GetAgents(crew);
agents = crew.Count();
foreach (AIAgent agent : crew)
{
if (agent && ERR_Actors.CanFight(agent.GetControlledEntity())) living++;
}
}
if (Activity) actionState = Activity.GetActionState();
bool connected;
ERR_HQ hq = ERR_HQ.Get();
if (hq && Group) connected = hq.MortarConnected(Group);
Audit("SITE STATUS", string.Format("claimed=%1 startup=%2 operational=%3 crew agents=%4 fighting=%5 inventory HE=%6 radio connected=%7 cooldown remaining=%8s", Claimed, StartupActivated, Operational(), agents, living, CountShells(), connected, Math.Max(0, NextOrder - now) / 1000));
Audit("ORDER STATUS", string.Format("open=%1 route pending=%2 native action=%3 shell committed=%4 order shots=%5 total shots=%6 age=%7s last failure=%8", CommandOpen, RadioOrder != null, actionState, Released, OrderShots, TotalShots, Math.Max(0, now - OrderedAt) / 1000, LastFailure));
if (!SpawnFailure.IsEmpty()) Audit("PARTIAL DEPLOYMENT", SpawnFailure);
if (!Operational()) Trace("SITE BLOCK", OperationalReason(), "spawn failure=" + SpawnFailure);
}
bool Operational()
{
return OperationalReason().IsEmpty();
}
int CountShells()
{
if (!Group)
return 0;
int count;
array<IEntity> items = {};
array<AIAgent> agents = {};
Group.GetAgents(agents);
foreach (AIAgent agent : agents)
{
if (!agent || !ERR_Actors.CanFight(agent.GetControlledEntity()))
continue;
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(agent.GetControlledEntity().FindComponent(InventoryStorageManagerComponent));
if (!inventory)
continue;
ERR_Inventory.AppendUnique(inventory, items);
}
foreach (IEntity item : items)
if (item && item.GetPrefabData() && item.GetPrefabData().GetPrefabName() == SHELL) count++;
return count;
}
void Bind(int siteId, SCR_AIGroup group, IEntity gun, float now)
{
SiteId = siteId;
Group = group;
Gun = gun;
Position = gun.GetOrigin();
SpawnedAt = now;
Claimed = true;
m_Readiness = new ERR_MortarReadiness(this);
}
int InventoryShells(InventoryStorageManagerComponent inventory)
{
if (!inventory)
return 0;
int count;
array<IEntity> items = {};
ERR_Inventory.Items(inventory, items);
foreach (IEntity item : items)
{
if (item && item.GetPrefabData() && item.GetPrefabData().GetPrefabName() == SHELL)
count++;
}
return count;
}
bool Stopped() { return m_Stopped; }
bool SupplyPending() { return m_Transfer && m_Transfer.Unresolved(); }
bool SupplyAuthorized(float now)
{
if (!Replication.IsServer() || m_Stopped || !StartupActivated || !Operational() || !CommandOpen || !ERR_HQ.MissionActive()) return false;
ERR_MortarSystem system = ERR_MortarSystem.Get();
if (!system || system.FindGun(Gun) != this) return false;
ERR_HQReport suppliedReport = Report;
if (!suppliedReport) suppliedReport = PendingSupplyReport;
return ERR_MortarPrediction.Fresh(suppliedReport, now);
}
void Stop()
{
if (m_Stopped) return;
m_Stopped = true;
Cancel("HQ stopped");
if (m_Readiness) m_Readiness.Stop();
}
ERR_MortarSupplyState SupplyState(float now)
{
// Observe an existing native operation even after its order was canceled.
// No second request may race an unresolved transfer on this battery.
if (m_Transfer)
{
ERR_MortarSupplyState observed = m_Transfer.Poll(now);
if (m_Transfer.CapturedOrder() == OrderId)
{
if (observed == ERR_MortarSupplyState.READY) m_Transfer = null;
return observed;
}
if (m_Transfer.Unresolved()) return ERR_MortarSupplyState.FAILED;
m_Transfer = null;
}
if (!SupplyAuthorized(now)) return SupplyStateFailed("current HQ order, crew or report is unavailable");
SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(Gun.FindComponent(SCR_AIVehicleUsageComponent));
IEntity gunner;
if (usage && usage.GetTurretCompartmentSlot())
gunner = usage.GetTurretCompartmentSlot().GetOccupant();
array<AIAgent> agents = {};
Group.GetAgents(agents);
float nearest = float.MAX;
if (!gunner)
{
foreach (AIAgent candidate : agents)
{
if (!candidate || candidate.GetControlledEntity() == RadioOperator || !ERR_Actors.CanFight(candidate.GetControlledEntity()))
continue;
float distance = vector.DistanceXZ(Gun.GetOrigin(), candidate.GetControlledEntity().GetOrigin());
if (distance < nearest)
{
nearest = distance;
gunner = candidate.GetControlledEntity();
}
}
}
if (!gunner) return SupplyStateFailed("no fighting gunner found");
if (ERR_Actors.Group(gunner) != Group) return SupplyStateFailed("turret occupant belongs to another group");
if (!ERR_Actors.CanFight(gunner)) return SupplyStateFailed("gunner cannot fight");
InventoryStorageManagerComponent destination = InventoryStorageManagerComponent.Cast(gunner.FindComponent(InventoryStorageManagerComponent));
if (!destination)
return SupplyStateFailed("gunner inventory missing");
if (InventoryShells(destination) > 0)
return ERR_MortarSupplyState.READY;
int nearbyDonors, donorShells, storageRejected;
array<IEntity> consideredShells = {};
foreach (AIAgent bearer : agents)
{
if (!bearer || !ERR_Actors.CanFight(bearer.GetControlledEntity()))
continue;
IEntity donor = bearer.GetControlledEntity();
if (donor == gunner || vector.DistanceXZ(donor.GetOrigin(), gunner.GetOrigin()) > 12)
continue;
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(donor.FindComponent(InventoryStorageManagerComponent));
if (!inventory)
continue;
nearbyDonors++;
array<IEntity> items = {};
ERR_Inventory.Items(inventory, items);
foreach (IEntity item : items)
{
if (!item || !item.GetPrefabData() || item.GetPrefabData().GetPrefabName() != SHELL)
continue;
if (consideredShells.Contains(item) || m_AttemptedShells.Contains(item)) continue;
consideredShells.Insert(item);
donorShells++;
BaseInventoryStorageComponent storage = destination.FindStorageForItem(item, EStoragePurpose.PURPOSE_DEPOSIT);
if (!storage) { storageRejected++; continue; }
m_AttemptedShells.Insert(item); // even rejected/ambiguous requests are never retried
m_Transfer = new ERR_MortarSupplyTransfer(this, donor, gunner, item, storage, now);
if (!m_Transfer.Begin(now)) return SupplyStateFailed("exact shell transfer request rejected; no retry");
Audit("AMMO TRANSFER", string.Format("one exact-item move pending donor=%1 gunner=%2 shell=%3 order=%4; awaiting callback AND physical destination", donor, gunner, item, OrderId));
return ERR_MortarSupplyState.PENDING;
}
}
return SupplyStateFailed(string.Format("gunner empty; fighting donors within 12m=%1 unattempted HE=%2 destination storage rejected=%3", nearbyDonors, donorShells, storageRejected));
}
// Compatibility for existing native callers; request acceptance is NOT ready.
bool SupplyGunner() { return SupplyState(GetGame().GetWorld().GetWorldTime()) == ERR_MortarSupplyState.READY; }
protected ERR_MortarSupplyState SupplyStateFailed(string reason)
{
SupplyFailed(reason);
return ERR_MortarSupplyState.FAILED;
}
bool SupplyFailed(string reason)
{
LastFailure = reason;
Audit("AMMO FAILED", reason);
return false;
}
void Cancel(string reason = "cancel requested")
{
if (CommandOpen)
{
FlushTraces();
Audit("ORDER END", string.Format("reason=%1 observed shots=%2 shell committed=%3 elapsed=%4s last failure=%5", reason, OrderShots, Released, (GetGame().GetWorld().GetWorldTime() - OrderedAt) / 1000, LastFailure));
}
CommandOpen = false;
RadioOrder = null;
PendingRadioReport = null;
PendingSupplyReport = null;
if (m_Transfer) m_Transfer.Invalidate();
Report = null;
AimedAt = -1;
if (Activity)
Activity.Complete();
Activity = null;
}
// Idle distant batteries still report through HQ's scheduler. Their native
// AI needs full detail while firing or when players can interact with them.
protected void UpdateCrewDetail(float now, bool firing = false)
{
if (!Group || Group.GetPlayerCount(true) > 0)
return;
bool active = firing || Activity != null || ERR_MortarSystem.NearPlayer(Position);
int lod = -1;
if (active)
lod = 0;
if (Group.GetPermanentLOD() != lod)
Group.SetPermanentLOD(lod);
if (active && !Group.IsAIActivated())
Group.ActivateAI();
array<AIAgent> agents = {};
Group.GetAgents(agents);
foreach (AIAgent agent : agents)
{
if (!agent || EntityUtils.IsPlayer(agent.GetControlledEntity()))
continue;
if (agent.GetPermanentLOD() != lod)
agent.SetPermanentLOD(lod);
if (active && !agent.IsAIActivated() && ERR_Actors.CanFight(agent.GetControlledEntity()))
agent.ActivateAI();
}
}
void Update(float now)
{
if (m_Stopped) return;
if (!StartupActivated)
{
if (!SpawnFailure.IsEmpty()) return;
if (!m_Readiness) { SpawnFailed("initial support readiness owner missing"); return; }
ERR_MortarSupplyState startup = m_Readiness.Poll(now);
if (startup != ERR_MortarSupplyState.READY) return;
StartupActivated = true;
}
if (m_Transfer) m_Transfer.Poll(now);
if (!Operational())
{
Cancel(OperationalReason());
return;
}
if (Activity)
{
Trace("ACTIVITY", string.Format("native state=%1", Activity.GetActionState()), string.Format("age=%1s aim age=%2s committed=%3 shots=%4", (now - OrderedAt) / 1000, (now - AimedAt) / 1000, Released, OrderShots));
if (Activity.GetActionState() == EAIActionState.FAILED) Cancel("native artillery activity FAILED");
else if (Activity.GetActionState() == EAIActionState.COMPLETED) Cancel("native artillery activity COMPLETED (shot count is separate)");
else if (now - OrderedAt > ERR_MortarSalvo.TIMEOUT_MS) Cancel("120s artillery salvo timeout");
}
if (StartupActivated)
UpdateCrewDetail(now);
}
void Order(ERR_HQReport report, float now)
{
if (m_Stopped || !StartupActivated || !Operational() || !CommandOpen || Activity || !ERR_MortarPrediction.Fresh(report, now)) return;
Report = report.Snapshot();
OrderedAt = now;
NextOrder = now + 30000;
Released = false;
UpdateCrewDetail(now, true);
Activity = new SCR_AIStaticArtilleryActivity(Group.GetGroupUtilityComponent(), null, report.Position, SCR_EAIArtilleryAmmoType.HIGH_EXPLOSIVE, ERR_MortarSalvo.ROUNDS);
Group.GetGroupUtilityComponent().AddAction(Activity);
Audit("AIM", string.Format("native activity created; latest source=M%1 observed=%2", report.MessageId, report.Description(now)));
}
}
@@ -0,0 +1,231 @@
// The dedicated manpack operator has no mortar-shell backpack. Preserve the
// native chooser and its caller's original index for every eligible gunner.
modded class SCR_AIStaticArtilleryActivity
{
protected override AIAgent FindBestAgentForArtillery(notnull array<AIAgent> agents, notnull IEntity artilleryEntity, out int outIndex)
{
ERR_MortarSystem system = ERR_MortarSystem.Get();
ERR_MortarBattery battery;
if (system) battery = system.FindGun(artilleryEntity);
if (!battery) return super.FindBestAgentForArtillery(agents, artilleryEntity, outIndex);
array<AIAgent> gunners = {};
foreach (AIAgent agent : agents)
{
if (agent && agent.GetControlledEntity() != battery.RadioOperator && ERR_Actors.CanFight(agent.GetControlledEntity()))
gunners.Insert(agent);
}
int filteredIndex;
AIAgent selected = super.FindBestAgentForArtillery(gunners, artilleryEntity, filteredIndex);
outIndex = -1;
if (selected) outIndex = agents.Find(selected);
return selected;
}
}
// Leave all other artillery (including player-operated captured guns) native.
modded class SCR_AIGetArtilleryAimDistanceCompensation
{
override ENodeResult EOnTaskSimulate(AIAgent owner, float dt)
{
IEntity gun;
GetVariableIn(PORT_ARTILLERY_ENTITY, gun);
ERR_MortarSystem system = ERR_MortarSystem.Get();
ERR_MortarBattery battery;
if (system)
battery = system.FindGun(gun);
if (!battery)
return super.EOnTaskSimulate(owner, dt);
battery.AimedAt = -1;
float now = GetGame().GetWorld().GetWorldTime();
ERR_HQReport report = system.Latest(battery, now);
if (!ERR_HQ.MissionActive()) { system.Withhold(battery, "aim: mission inactive"); return ENodeResult.FAIL; }
if (!battery.CommandOpen || battery.OrderShots >= ERR_MortarSalvo.ROUNDS) { system.Withhold(battery, "aim: salvo complete or order closed"); return ENodeResult.FAIL; }
if (battery.Released) { system.Withhold(battery, "aim: waiting for committed projectile"); return ENodeResult.FAIL; }
if (!report) { system.Withhold(battery, "aim: " + system.ContactFailure(battery)); return ENodeResult.FAIL; }
battery.Trace("AIM START", "solving moving intercept", string.Format("latest source=M%1; %2", report.MessageId, report.Description(now)));
ResourceName ammo;
GetVariableIn(PORT_AMMO_PREFAB, ammo);
if (ammo != ERR_MortarBattery.SHELL) { system.Withhold(battery, "unsupported ammunition prefab", ammo); return ENodeResult.FAIL; }
Resource resource = Resource.Load(ammo);
if (!resource || !resource.IsValid() || !resource.GetResource()) { system.Withhold(battery, "shell resource load failed", ammo); return ENodeResult.FAIL; }
IEntitySource source = resource.GetResource().ToEntitySource();
if (!source) { system.Withhold(battery, "shell resource has no entity source", ammo); return ENodeResult.FAIL; }
array<float> coefficients = {};
GetAmmoInitialSpeedCoefficients(ammo, coefficients);
if (coefficients.IsEmpty())
coefficients.Insert(1.0);
float minimum, maximum;
GetVerticalAimLimits(gun, minimum, maximum);
float flight = 30;
float offset;
int charge;
vector impact;
vector salvoOffset = ERR_MortarSalvo.Offset(battery.SiteId, battery.OrderId, battery.OrderShots);
bool converged;
// Iterate the moving intercept using the native shell's flight time.
// Reject non-convergence rather than fire with an arbitrary lead time.
for (int iteration = 0; iteration < 4; iteration++)
{
if (!ERR_MortarPrediction.Predict(report, now, flight + 2, impact)) { system.Withhold(battery, "aim prediction: " + ERR_MortarPrediction.FailureReason, string.Format("flight lead=%1s; %2", flight + 2, report.Description(now))); return ENodeResult.FAIL; }
if (!system.OutsideSettlements(impact)) { system.Withhold(battery, "aim target inside settlement exclusion", system.SettlementReason); return ENodeResult.FAIL; }
impact += salvoOffset;
impact[1] = SCR_TerrainHelper.GetTerrainY(impact);
float distance = vector.DistanceXZ(gun.GetOrigin(), impact);
float altitude = impact[1] - gun.GetOrigin()[1];
if (distance < 350 || distance > 4000) { system.Withhold(battery, "predicted impact out of range", string.Format("iteration=%1 distance=%2m impact=%3 allowed=350..4000m", iteration, distance, impact)); return ENodeResult.FAIL; }
bool reachable;
float calculated;
for (int i = 0; i < coefficients.Count(); i++)
{
if (!BallisticTable.GetAimHeightOfProjectileAltitudeFromSource(distance, offset, calculated, source, altitude, coefficients[i]))
continue;
float tangent = (offset + altitude) / distance;
if (calculated <= 0 || calculated > 75 || tangent < Math.Tan(minimum) || tangent > Math.Tan(maximum))
continue;
charge = i;
reachable = true;
break;
}
if (!reachable) { system.Withhold(battery, "no native ballistic solution within elevation/flight-time limits", string.Format("iteration=%1 distance=%2 altitude=%3 charges=%4 elevation radians=%5..%6 flight limit=75s", iteration, distance, altitude, coefficients.Count(), minimum, maximum)); return ENodeResult.FAIL; }
converged = Math.AbsFloat(calculated - flight) < 1;
flight = calculated;
if (converged)
break;
}
if (!converged) { system.Withhold(battery, "moving intercept did not converge in four iterations"); return ENodeResult.FAIL; }
if (!system.Safe(battery, impact, flight + 2)) { system.Withhold(battery, "aim impact safety rejected", system.SafetyReason); return ENodeResult.FAIL; }
battery.Impact = impact;
battery.AimOffset = salvoOffset;
battery.AimedShot = battery.OrderShots;
battery.FlightTime = flight;
battery.AimedAt = now;
battery.LastFailure = "";
battery.Trace("AIM SOLUTION", "ready", string.Format("predicted impact=%1 flight=%2s charge index=%3 aim height offset=%4m latest source=M%5", impact, flight, charge, offset, report.MessageId));
vector aim = impact + Vector(0, offset, 0);
SetVariableOut(PORT_AIM_POS, aim);
SetVariableOut(PORT_INIT_SPEED_ID, charge);
return ENodeResult.SUCCESS;
}
}
modded class SCR_AIShootStaticArtillery
{
override ENodeResult EOnTaskSimulate(AIAgent owner, float dt)
{
IEntity gun;
GetVariableIn(PORT_ARTILLERY_ENTITY, gun);
ERR_MortarSystem system = ERR_MortarSystem.Get();
ERR_MortarBattery battery;
if (system)
battery = system.FindGun(gun);
if (battery && !system.AllowShot(battery))
{
battery.Trace("SHOOT NODE", "authorization rejected", battery.LastFailure);
return ENodeResult.FAIL;
}
ENodeResult result = super.EOnTaskSimulate(owner, dt);
if (battery)
battery.Trace("SHOOT NODE", string.Format("native result=%1", result), "authorization passed; node result does not confirm a physical shot");
return result;
}
}
modded class SCR_MortarMuzzleComponent
{
protected override void TransferShellToMortar()
{
ERR_MortarSystem system = ERR_MortarSystem.Get();
ERR_MortarBattery battery;
if (system && m_CharController && !EntityUtils.IsPlayer(m_CharController.GetOwner()))
battery = system.FindGun(GetOwner());
if (battery)
{
// The loading animation takes time. Recheck at the actual transfer,
// before native inventory insertion triggers the physical projectile.
if (!system.AllowShot(battery))
{
if (m_ShellComponent)
{
m_ShellComponent.GetOnShellUsed().Remove(TransferShellToMortar);
m_ShellComponent.SetLoadedState(false);
}
CharacterAnimationComponent animation = m_CharController.GetAnimationComponent();
if (animation && animation.GetCommandHandler())
animation.GetCommandHandler().FinishItemUse(false);
battery.Audit("ABORT", "final shell transfer rejected; " + battery.LastFailure);
return;
}
battery.Released = true;
battery.ReserveShellAirspace(GetGame().GetWorld().GetWorldTime());
battery.Audit("SHELL COMMIT", string.Format("final safety passed; gunner=%1 predicted impact=%2 flight=%3s; invoking native transfer, awaiting projectile event", m_CharController.GetOwner(), battery.Impact, battery.FlightTime));
}
super.TransferShellToMortar();
}
override void OnWeaponFired(IEntity effectEntity, BaseMuzzleComponent muzzle, IEntity projectileEntity)
{
IEntity firingCharacter;
if (m_CharController) firingCharacter = m_CharController.GetOwner();
super.OnWeaponFired(effectEntity, muzzle, projectileEntity);
ERR_MortarSystem system = ERR_MortarSystem.Get();
ERR_MortarBattery battery;
if (system)
battery = system.FindGun(GetOwner());
if (!battery)
return;
bool playerGunner;
if (firingCharacter) playerGunner = EntityUtils.IsPlayer(firingCharacter);
battery.ObserveProjectile(projectileEntity, firingCharacter, playerGunner);
}
}
// The native tree normally re-aims only every five shots (and skips the first
// re-aim). Each salvo shell needs its own spread point and fresh authorization.
modded class SCR_AIStaticArtilleryBehavior
{
ERR_MortarBattery ERR_GetMortarBattery()
{
ERR_MortarSystem system = ERR_MortarSystem.Get();
if (!system) return null;
return system.FindGun(m_ArtilleryEntity.m_Value);
}
}
modded class SCR_AIStaticArtilleryBehavior_ShootingLogic
{
override ENodeResult EOnTaskSimulate(AIAgent owner, float dt)
{
ERR_MortarBattery battery;
SCR_AIStaticArtilleryBehavior behavior;
if (m_Utility)
{
behavior = SCR_AIStaticArtilleryBehavior.Cast(m_Utility.GetExecutedAction());
if (behavior) battery = behavior.ERR_GetMortarBattery();
}
if (battery)
{
int gate = ERR_MortarSupplyRules.CycleGate(battery.CommandOpen, battery.OrderShots, behavior.GetShotCount(), ERR_MortarSalvo.ROUNDS, ERR_MortarSupplyState.READY);
if (gate < 0) return ENodeResult.FAIL;
if (gate == 0) return ENodeResult.RUNNING;
// Native super increments the behavior counter. Wait BEFORE calling it,
// so repeated pending ticks cannot count the same projectile twice.
if (battery.OrderShots < ERR_MortarSalvo.ROUNDS)
{
ERR_MortarSupplyState supply = battery.SupplyState(GetGame().GetWorld().GetWorldTime());
if (supply == ERR_MortarSupplyState.PENDING) return ENodeResult.RUNNING;
if (supply == ERR_MortarSupplyState.FAILED)
{
ERR_MortarSystem system = ERR_MortarSystem.Get();
if (system) system.Withhold(battery, "next native load lacks confirmed physical gunner ammunition");
return ENodeResult.FAIL;
}
}
}
ENodeResult result = super.EOnTaskSimulate(owner, dt);
if (battery && result == ENodeResult.SUCCESS)
{
SetVariableOut(PORT_AIMING_NEEDED, true);
}
return result;
}
}
@@ -0,0 +1,131 @@
// All target coordinates come from delivered HQ observations, never a player's
// current transform. Road projection stops at an unknown junction/road end.
class ERR_MortarPrediction
{
// Read immediately after a failed synchronous prediction; no extra world scan.
static string FailureReason;
// Includes observation uplink, HQ downlink and native aiming. All stages
// retain the original observation time; radio delivery never renews it.
static const float MAX_REPORT_AGE_MS = 60000;
static bool Fresh(ERR_HQReport report, float now)
{
return report && report.Target && !report.Distress && now >= report.ObservedAt && now - report.ObservedAt <= MAX_REPORT_AGE_MS && report.TravelMode != "aircraft";
}
static bool Reject(string reason)
{
FailureReason = reason;
return false;
}
static vector ClosestOnSegment(vector point, vector start, vector end)
{
vector segment = end - start;
segment[1] = 0;
vector offset = point - start;
offset[1] = 0;
float lengthSq = segment.LengthSq();
if (lengthSq < 0.01)
return start;
return vector.Lerp(start, end, Math.Clamp(vector.Dot(offset, segment) / lengthSq, 0, 1));
}
static bool FollowRoad(array<vector> points, vector observed, vector velocity, float seconds, out vector impact)
{
if (!points || points.Count() < 2)
return Reject("road polyline has fewer than two points");
int segment = -1;
float closest = 20;
vector projected;
for (int i = 0; i < points.Count() - 1; i++)
{
vector candidate = ClosestOnSegment(observed, points[i], points[i + 1]);
float distance = vector.DistanceXZ(candidate, observed);
if (distance < closest)
{
closest = distance;
segment = i;
projected = candidate;
}
}
if (segment < 0)
return Reject("observed vehicle is not within 20m of a road segment");
vector forward = points[segment + 1] - points[segment];
forward[1] = 0;
forward.Normalize();
vector travel = velocity;
travel[1] = 0;
float speed = travel.Length();
travel.Normalize();
float alignment = vector.Dot(forward, travel);
if (Math.AbsFloat(alignment) < 0.7)
return Reject("vehicle heading crosses road; alignment below 0.7");
int step = 1;
int next = segment + 1;
if (alignment < 0)
{
step = -1;
next = segment;
}
float remaining = speed * seconds;
vector position = projected;
while (next >= 0 && next < points.Count())
{
float length = vector.DistanceXZ(position, points[next]);
if (length >= remaining && length > 0.01)
{
impact = vector.Lerp(position, points[next], remaining / length);
return true;
}
remaining -= length;
position = points[next];
next += step;
}
return Reject("prediction reaches unknown road end/junction");
}
static bool Predict(ERR_HQReport report, float now, float flightSeconds, out vector impact)
{
FailureReason = "";
if (!report) return Reject("target report missing");
if (report.Distress) return Reject("distress report cannot authorize fire");
if (now < report.ObservedAt) return Reject("observation timestamp is in the future");
if (now - report.ObservedAt > MAX_REPORT_AGE_MS) return Reject("observation older than 60s");
float seconds = (now - report.ObservedAt) / 1000 + flightSeconds;
if (seconds < 0 || seconds > 90)
return Reject("observation age plus flight outside 0..90s");
if (report.TravelMode == "aircraft") return Reject("aircraft target unsupported");
if (report.TravelMode == "mixed travel") return Reject("mixed travel cannot be predicted");
impact = report.Position;
if (!report.HasVelocity || report.Velocity.Length() < 0.5)
return true;
if (report.Velocity.Length() * seconds > 1800)
return Reject("predicted travel exceeds 1800m");
bool vehicle = report.TravelMode == "vehicle" || report.TravelMode == "in vehicle";
if (vehicle)
{
SCR_AIWorld world = SCR_AIWorld.Cast(GetGame().GetAIWorld());
if (!world || !world.GetRoadNetworkManager())
return Reject("road network unavailable");
BaseRoad road;
float roadDistance;
world.GetRoadNetworkManager().GetClosestRoad(report.Position, road, roadDistance, skipNavlinks: true);
if (!road) return Reject("no road near reported vehicle position");
if (roadDistance > 20) return Reject("reported vehicle farther than 20m from road");
array<vector> points = {};
road.GetPoints(points);
return FollowRoad(points, report.Position, report.Velocity, seconds, impact);
}
impact += report.Velocity * seconds;
return true;
}
static bool ThreatensFriendly(vector impact, vector position, vector velocity, float flightSeconds)
{
velocity[1] = 0;
vector future = position + velocity * Math.Clamp(flightSeconds, 0, 90);
// Protect the entire predicted path, not only where a soldier is now.
return vector.DistanceXZ(impact, ClosestOnSegment(impact, position, future)) <= 100;
}
}
@@ -0,0 +1,177 @@
enum ERR_MortarSupplyState { FAILED = -1, PENDING, READY }
class ERR_MortarSupplyRules
{
static int CycleGate(bool commandOpen, int confirmedShots, int behaviorShots, int limit, int supplyState)
{
if (!commandOpen) return -1;
if (confirmedShots <= behaviorShots) return 0;
if (confirmedShots < limit) return supplyState;
return 1;
}
}
class ERR_MortarInitialItem : ScriptedInventoryOperationCallback
{
bool Finished;
bool Succeeded;
protected void Finish(bool success) { if (!Finished) { Finished = true; Succeeded = success; } }
protected override void OnComplete() { Finish(true); }
protected override void OnFailed() { Finish(false); }
protected override void OnAllComplete() { Finish(true); }
protected override void OnAllFailed() { Finish(false); }
void Rejected() { Finish(false); }
}
// One finite allocation, after the ENTIRE original support crew exists. Failed
// or stopped setup retains physical assets and retires only its pending spawn intent.
class ERR_MortarReadiness
{
protected ERR_MortarBattery m_Battery;
protected ref array<IEntity> m_Members = {};
protected ref array<ref ERR_MortarInitialItem> m_Operations = {};
protected bool m_Allocated;
protected bool m_Ready;
protected bool m_Stopped;
protected bool m_Retired;
protected int m_RequestedShells;
void ERR_MortarReadiness(ERR_MortarBattery battery) { m_Battery = battery; }
static ERR_MortarSupplyState Population(int physical, int gunners, int operators, bool complete, bool expired)
{
if (physical > 4 || gunners > 3 || operators > 1) return ERR_MortarSupplyState.FAILED;
if (physical == 4 && gunners == 3 && operators == 1 && complete && !expired) return ERR_MortarSupplyState.READY;
if (expired) return ERR_MortarSupplyState.FAILED;
return ERR_MortarSupplyState.PENDING;
}
static bool AllocationValid(int shells) { return shells >= 0 && shells <= 9; }
int RequestedShells() { return m_RequestedShells; }
bool Ready() { return m_Ready && !m_Stopped; }
void Stop()
{
if (m_Stopped) return;
m_Stopped = true;
if (m_Ready || m_Retired || !m_Battery || !m_Battery.Group || !Replication.IsServer()) return;
m_Retired = true;
// As in Core initial guard cleanup: stopping the current request alone does
// not retire the native group's still-authored future expansion intent.
RetireGroup(m_Battery.Group);
}
static void RetireGroup(SCR_AIGroup group)
{
if (!group || !Replication.IsServer()) return;
group.SetSpawnImmediately(false);
group.m_aUnitPrefabSlots = new array<ResourceName>();
if (!GetGame()) return;
ChimeraAIWorld world = ChimeraAIWorld.Cast(GetGame().GetAIWorld());
if (world) world.PurgeSpawnRequestsForGroup(group);
}
protected ERR_MortarSupplyState Fail(string reason)
{
m_Battery.SpawnFailed(reason);
Stop();
return ERR_MortarSupplyState.FAILED;
}
protected bool Allocate()
{
m_Allocated = true; // before native requests; never refill or retry a failure
foreach (IEntity actor : m_Members)
{
if (actor == m_Battery.RadioOperator) continue;
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(actor.FindComponent(InventoryStorageManagerComponent));
int existing = m_Battery.InventoryShells(inventory);
if (!AllocationValid(existing)) return false;
if (ERR_HQRadio.Capability(actor) == 0 && !inventory.TrySpawnPrefabToStorage("{E1A5D4B878AA8980}Prefabs/Items/Equipment/Radios/Radio_R148.et"))
m_Battery.Audit("RADIO EQUIP", "optional crew handset did not fit; dedicated manpack remains required");
for (int i = existing; i < 9; i++)
{
ERR_MortarInitialItem operation = new ERR_MortarInitialItem();
m_Operations.Insert(operation);
m_RequestedShells++;
if (!inventory.TrySpawnPrefabToStorage(ERR_MortarBattery.SHELL, purpose: EStoragePurpose.PURPOSE_DEPOSIT, cb: operation))
{
operation.Rejected();
return false;
}
}
}
return true;
}
ERR_MortarSupplyState Poll(float now)
{
if (m_Stopped || !Replication.IsServer() || !m_Battery || m_Battery.Stopped()) return ERR_MortarSupplyState.FAILED;
if (m_Ready) return ERR_MortarSupplyState.READY;
SCR_AIGroup group = m_Battery.Group;
ERR_GameMode mode = ERR_GameMode.Get();
if (!mode || !group || !m_Battery.Gun || group.GetFaction() != mode.EnemyFaction() || group.GetPlayerCount(true) > 0) return Fail("initial support group/gun/faction changed");
DamageManagerComponent damage = DamageManagerComponent.Cast(m_Battery.Gun.FindComponent(DamageManagerComponent));
if (!damage || damage.IsDestroyed()) return Fail("initial support gun missing damage manager or destroyed");
bool expired = now < m_Battery.SpawnedAt || now - m_Battery.SpawnedAt >= 90000;
array<AIAgent> agents = {}; group.GetAgents(agents);
array<IEntity> physical = {};
int gunners, operators;
IEntity operatorActor;
foreach (AIAgent agent : agents)
{
if (!agent || !agent.GetControlledEntity()) continue;
IEntity actor = agent.GetControlledEntity();
if (physical.Contains(actor)) return Fail("initial support group reports duplicate physical actor");
physical.Insert(actor);
if (!ERR_Actors.CanFight(actor) || SCR_FactionManager.SGetFaction(actor) != mode.EnemyFaction() || !actor.GetPrefabData()) return Fail("initial support actor unavailable or has wrong faction/resource");
ResourceName prefab = actor.GetPrefabData().GetPrefabName();
if (prefab == ERR_MortarBattery.CREW) gunners++;
else if (prefab == ERR_MortarBattery.RADIO_OPERATOR) { operators++; operatorActor = actor; }
else return Fail("initial support actor does not belong to authored crew catalog");
}
ERR_MortarSupplyState population = Population(physical.Count(), gunners, operators, group.IsExpandComplete(), expired);
if (population == ERR_MortarSupplyState.FAILED) return Fail("initial four-person support population incomplete/invalid within 90 seconds");
if (population == ERR_MortarSupplyState.PENDING) return population;
if (m_Allocated)
{
foreach (IEntity original : m_Members)
if (!physical.Contains(original)) return Fail("initial support member replaced after finite allocation");
}
foreach (IEntity member : physical)
{
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(member.FindComponent(InventoryStorageManagerComponent));
if (!inventory) return ERR_MortarSupplyState.PENDING;
if (!m_Allocated && member != operatorActor && m_Battery.InventoryShells(inventory) < 9 && !inventory.CanInsertResource(ERR_MortarBattery.SHELL, EStoragePurpose.PURPOSE_DEPOSIT)) return ERR_MortarSupplyState.PENDING;
}
if (ERR_HQRadio.Capability(operatorActor) != 2) return ERR_MortarSupplyState.PENDING;
// Preserve the existing earliest activation delay, but it is not readiness.
if (now - m_Battery.SpawnedAt < 10000) return ERR_MortarSupplyState.PENDING;
if (!m_Allocated)
{
if (!group.GetGroupUtilityComponent() || !group.GetGroupUtilityComponent().m_VehicleMgr) return ERR_MortarSupplyState.PENDING;
SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(m_Battery.Gun.FindComponent(SCR_AIVehicleUsageComponent));
if (!usage || !group.GetGroupUtilityComponent().m_VehicleMgr.TryAddVehicle(usage)) return Fail("native support gun registration failed");
m_Members.Copy(physical); m_Battery.RadioOperator = operatorActor;
if (!Allocate()) return Fail("finite initial support shell allocation rejected; no retry");
return ERR_MortarSupplyState.PENDING; // never accept mutation-frame readiness
}
foreach (ERR_MortarInitialItem operation : m_Operations)
{
if (!operation.Finished) return ERR_MortarSupplyState.PENDING;
if (!operation.Succeeded) return Fail("finite initial support shell operation failed; no retry");
}
foreach (IEntity equipped : m_Members)
{
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(equipped.FindComponent(InventoryStorageManagerComponent));
int shells = m_Battery.InventoryShells(inventory);
if (equipped == operatorActor)
{
if (shells != 0) return Fail("dedicated initial manpack operator unexpectedly carries mortar shells");
}
else if (shells != 9) return ERR_MortarSupplyState.PENDING;
}
if (m_Battery.CountShells() != 27) return ERR_MortarSupplyState.PENDING;
m_Ready = true;
group.ActivateAI();
foreach (AIAgent readyAgent : agents)
{
if (readyAgent) { readyAgent.SetPermanentLOD(0); readyAgent.ActivateAI(); }
}
m_Battery.Audit("CREW READY", string.Format("four original physical members, one manpack, 27 confirmed HE; new shell requests=%1; allocation permanently closed", m_RequestedShells));
return ERR_MortarSupplyState.READY;
}
}
@@ -0,0 +1,16 @@
// One delivered HQ order drives a continuous native loading/firing cycle.
class ERR_MortarSalvo
{
static const int ROUNDS = 8;
static const float RADIUS_METRES = 40;
static const float TIMEOUT_MS = 120000;
static vector Offset(int site, int order, int shot)
{
// Stable throughout one ballistic solve; successive shells cover the disk
// instead of clustering on the same point or changing every iteration.
float radius = RADIUS_METRES * Math.Sqrt((shot + 1.0) / ROUNDS);
float angle = (site * 53 + order * 97 + shot * 137.5) * Math.DEG2RAD;
return Vector(Math.Sin(angle) * radius, 0, Math.Cos(angle) * radius);
}
}
@@ -0,0 +1,108 @@
class ERR_MortarSupplyCallback : ScriptedInventoryOperationCallback
{
ERR_MortarSupplyTransfer Transfer;
protected override void OnComplete() { if (Transfer) Transfer.Acknowledge(true); }
protected override void OnFailed() { if (Transfer) Transfer.Acknowledge(false); }
}
// Exact-item native transaction. Callbacks only record outcomes; the HQ tick
// authorizes progress after checking actual inventory ownership and the order.
class ERR_MortarSupplyTransfer
{
protected ERR_MortarBattery m_Battery;
protected IEntity m_Gun;
protected SCR_AIGroup m_Group;
protected IEntity m_Donor;
protected IEntity m_Gunner;
protected IEntity m_Shell;
protected InventoryStorageManagerComponent m_Source;
protected InventoryStorageManagerComponent m_Destination;
protected BaseInventoryStorageComponent m_Storage;
protected ref ERR_MortarSupplyCallback m_Callback;
protected int m_Order;
protected int m_Acknowledgement;
protected float m_Deadline;
protected bool m_Accepted;
protected bool m_Invalidated;
protected bool m_Resolved;
protected bool m_Ready;
void ERR_MortarSupplyTransfer(ERR_MortarBattery battery, IEntity donor, IEntity gunner, IEntity shell, BaseInventoryStorageComponent storage, float now)
{
m_Battery = battery; m_Gun = battery.Gun; m_Group = battery.Group;
m_Donor = donor; m_Gunner = gunner; m_Shell = shell; m_Storage = storage;
m_Order = battery.OrderId; m_Deadline = now + 8000;
m_Source = InventoryStorageManagerComponent.Cast(donor.FindComponent(InventoryStorageManagerComponent));
m_Destination = InventoryStorageManagerComponent.Cast(gunner.FindComponent(InventoryStorageManagerComponent));
}
static bool Authority(bool valid, bool invalidated, int capturedOrder, int currentOrder)
{
return valid && !invalidated && capturedOrder == currentOrder;
}
static bool Proven(bool callbackComplete, bool sourceContains, bool destinationContains, bool exactSlot)
{
return callbackComplete && !sourceContains && destinationContains && exactSlot;
}
protected bool Contains(InventoryStorageManagerComponent inventory)
{
if (!inventory || !m_Shell) return false;
array<IEntity> items = {}; ERR_Inventory.Items(inventory, items);
return items.Contains(m_Shell);
}
protected bool Valid(float now)
{
if (!m_Battery || !Authority(m_Battery.SupplyAuthorized(now), m_Invalidated, m_Order, m_Battery.OrderId)) return false;
if (m_Battery.Gun != m_Gun || m_Battery.Group != m_Group || !m_Donor || !m_Gunner || m_Donor == m_Gunner || !m_Shell || !m_Source || !m_Destination || !m_Storage) return false;
if (!ERR_Actors.CanFight(m_Donor) || !ERR_Actors.CanFight(m_Gunner) || ERR_Actors.Group(m_Donor) != m_Group || ERR_Actors.Group(m_Gunner) != m_Group) return false;
Faction faction = m_Group.GetFaction();
if (SCR_FactionManager.SGetFaction(m_Donor) != faction || SCR_FactionManager.SGetFaction(m_Gunner) != faction || vector.Distance(m_Donor.GetOrigin(), m_Gunner.GetOrigin()) > 12) return false;
SCR_AIVehicleUsageComponent usage = SCR_AIVehicleUsageComponent.Cast(m_Gun.FindComponent(SCR_AIVehicleUsageComponent));
if (!usage || !usage.GetTurretCompartmentSlot()) return false;
IEntity occupant = usage.GetTurretCompartmentSlot().GetOccupant();
return !occupant || occupant == m_Gunner;
}
void Acknowledge(bool success)
{
if (m_Acknowledgement != 0) return;
if (success) m_Acknowledgement = 1;
else m_Acknowledgement = -1;
}
bool Begin(float now)
{
if (m_Callback || !Replication.IsServer() || !Valid(now) || !Contains(m_Source) || Contains(m_Destination)) return false;
m_Callback = new ERR_MortarSupplyCallback(); m_Callback.Transfer = this;
// Do not use callback.GetItem(): the native contract excludes Move operations.
m_Accepted = m_Source.TryMoveItemToStorage(m_Shell, m_Storage, -1, m_Callback);
if (!m_Accepted) { Acknowledge(false); m_Resolved = true; }
return m_Accepted;
}
void Invalidate() { m_Invalidated = true; m_Ready = false; }
bool Unresolved() { return m_Accepted && !m_Resolved; }
int CapturedOrder() { return m_Order; }
ERR_MortarSupplyState Poll(float now)
{
if (!Replication.IsServer()) return ERR_MortarSupplyState.FAILED;
bool valid = Valid(now);
bool sourceContains = Contains(m_Source);
bool destinationContains = Contains(m_Destination);
bool exactSlot;
InventoryItemComponent item;
if (m_Shell) item = InventoryItemComponent.Cast(m_Shell.FindComponent(InventoryItemComponent));
if (item && item.GetParentSlot()) exactSlot = item.GetParentSlot().GetStorage() == m_Storage;
bool proven = Proven(m_Acknowledgement == 1, sourceContains, destinationContains, exactSlot);
if (proven || m_Acknowledgement < 0) m_Resolved = true;
// A successful callback without physical destination proof is ambiguous.
// Keep it reserved through timeout/cancellation; never start a second move.
if (!valid || now >= m_Deadline)
{
m_Invalidated = true; m_Ready = false;
return ERR_MortarSupplyState.FAILED;
}
if (proven)
{
m_Ready = true;
return ERR_MortarSupplyState.READY;
}
if (m_Acknowledgement < 0 || !m_Accepted) return ERR_MortarSupplyState.FAILED;
return ERR_MortarSupplyState.PENDING;
}
}
@@ -0,0 +1,244 @@
// Owned and ticked by HQ. Initial assets are authored once; losses are never replaced.
class ERR_MortarSystem
{
protected ERR_HQ m_HQ;
protected ref array<ref ERR_MortarBattery> m_Batteries = {};
protected ref ERR_SettlementSafety m_Settlements = new ERR_SettlementSafety();
protected bool m_Prepared;
protected bool m_Stopped;
protected float m_NextDecision;
string SafetyReason;
string SettlementReason;
void ERR_MortarSystem(ERR_HQ hq) { m_HQ = hq; }
static ERR_MortarSystem Get()
{
ERR_HQ hq = ERR_HQ.Get();
if (!hq || !Replication.IsServer()) return null;
return hq.Mortars();
}
static bool NearPlayer(vector position)
{
array<IEntity> players = {};
ERR_Actors.Players(players);
foreach (IEntity player : players)
if (vector.DistanceXZ(player.GetOrigin(), position) <= 1200) return true;
return false;
}
bool Prepare()
{
if (!Replication.IsServer() || m_Prepared || m_Stopped) return false;
m_Prepared = true;
vector position = ERR_Actors.Ground("6000 0 7000");
if (position[1] < 1) return false;
IEntity gun = ERR_Actors.Spawn(ERR_MortarBattery.GUN, position);
SCR_AIGroup group = SCR_AIGroup.Cast(ERR_Actors.Spawn(MortarGroup(), ERR_Actors.Ground(position + "0 0 4")));
if (!gun || !group)
{
ERR_Actors.DeleteSpawned(gun);
ERR_MortarReadiness.RetireGroup(group);
ERR_Actors.DeleteSpawned(group);
return false;
}
if (group.GetFaction() != ERR_GameMode.Get().EnemyFaction())
{
ERR_Actors.DeleteSpawned(gun);
ERR_MortarReadiness.RetireGroup(group);
ERR_Actors.DeleteSpawned(group);
return false;
}
FactionAffiliationComponent affiliation = FactionAffiliationComponent.Cast(gun.FindComponent(FactionAffiliationComponent));
if (affiliation) affiliation.SetAffiliatedFaction(ERR_GameMode.Get().EnemyFaction());
ERR_MortarBattery battery = new ERR_MortarBattery();
battery.Bind(1, group, gun, GetGame().GetWorld().GetWorldTime());
m_Batteries.Insert(battery);
ERR_GameMode mode = ERR_GameMode.Get();
mode.Own(gun);
mode.RegisterGroup(group);
m_HQ.ReserveGroup(group);
battery.Audit("DEPLOY", "authored gun and four-person crew; finite ammunition initialization pending");
return true;
}
static ResourceName MortarGroup() { return "{B84C05941C4C81B8}Prefabs/ERR/MortarCrew.et"; }
ERR_MortarBattery FindGun(IEntity gun)
{
foreach (ERR_MortarBattery battery : m_Batteries)
if (gun && battery.Gun == gun) return battery;
return null;
}
ERR_MortarBattery FindGroup(SCR_AIGroup group)
{
foreach (ERR_MortarBattery battery : m_Batteries)
if (group && battery.Group == group) return battery;
return null;
}
ERR_HQReport Latest(ERR_MortarBattery battery, float now)
{
// Only the coordinates actually delivered to this battery are available.
// A newer HQ contact cannot update a gun's knowledge without another downlink.
if (!battery || !ERR_MortarPrediction.Fresh(battery.Report, now)) return null;
return battery.Report;
}
string ContactFailure(ERR_MortarBattery battery)
{
if (!battery.Report) return "no delivered target report";
return "delivered target report expired or invalid";
}
bool OutsideSettlements(vector impact)
{
bool clear = m_Settlements.OutsideSettlements(impact);
SettlementReason = m_Settlements.SettlementReason;
return clear;
}
bool Safe(ERR_MortarBattery battery, vector impact, float flight)
{
SafetyReason = "clear";
if (!battery.Operational()) { SafetyReason = battery.OperationalReason(); return false; }
if (!OutsideSettlements(impact)) { SafetyReason = SettlementReason; return false; }
if (SCR_TerrainHelper.GetTerrainY(impact) < 0) { SafetyReason = "impact below Everon sea level"; return false; }
Faction faction = battery.Group.GetFaction();
if (!faction) { SafetyReason = "battery faction missing"; return false; }
array<IEntity> friendlies = {};
m_HQ.PhysicalForces(friendlies);
foreach (IEntity entity : friendlies)
{
Faction friendly = SCR_FactionManager.SGetFaction(entity);
if (!friendly || faction.IsFactionEnemy(friendly) || !ERR_Actors.Alive(entity)) continue;
vector velocity;
IEntity moving = CompartmentAccessComponent.GetVehicleIn(entity);
if (!moving) moving = entity;
if (moving.GetPhysics()) velocity = moving.GetPhysics().GetVelocity();
if (ERR_MortarPrediction.ThreatensFriendly(impact, entity.GetOrigin(), velocity, flight))
{
SafetyReason = "friendly physical force can enter the impact area";
return false;
}
}
return true;
}
bool Withhold(ERR_MortarBattery battery, string reason, string detail = "")
{
battery.LastFailure = reason + "; " + detail;
battery.Trace("WITHHELD", reason, detail);
// Finish the activity from the next HQ tick, never from inside its own node.
battery.Rejected = true;
return false;
}
bool AllowShot(ERR_MortarBattery battery)
{
float now = GetGame().GetWorld().GetWorldTime();
if (m_Stopped || !ERR_HQ.MissionActive()) return Withhold(battery, "mission inactive or HQ stopped");
if (!battery.Operational()) return Withhold(battery, battery.OperationalReason());
if (!battery.CommandOpen || battery.OrderShots >= ERR_MortarSalvo.ROUNDS) return Withhold(battery, "salvo complete or order closed");
if (battery.Released) return Withhold(battery, "waiting for committed projectile");
if (battery.AimedShot != battery.OrderShots || battery.AimedAt < 0 || now - battery.AimedAt > 10000) return Withhold(battery, "fresh aim solution required");
ERR_HQReport report = Latest(battery, now);
if (!report) return Withhold(battery, ContactFailure(battery));
vector updated;
if (!ERR_MortarPrediction.Predict(report, now, battery.FlightTime, updated)) return Withhold(battery, ERR_MortarPrediction.FailureReason);
updated += battery.AimOffset;
if (vector.DistanceXZ(updated, battery.Impact) > 60) return Withhold(battery, "predicted target left aimed impact area");
if (!OutsideSettlements(updated)) return Withhold(battery, SettlementReason);
if (!Safe(battery, battery.Impact, battery.FlightTime)) return Withhold(battery, SafetyReason);
return true;
}
protected void AdvanceOrder(ERR_MortarBattery battery, float now)
{
if (battery.RadioOrder)
{
int deliveredState = battery.RadioOrder.Advance(now, m_HQ.Journal());
if (deliveredState == 0) return;
ERR_HQReport delivered = battery.PendingRadioReport;
battery.RadioOrder = null;
battery.PendingRadioReport = null;
if (deliveredState < 0 || !ERR_MortarPrediction.Fresh(delivered, now) || !battery.Operational() || battery.Activity || !battery.CommandOpen)
{
battery.Cancel("radio delivery, report freshness or battery availability failed");
battery.NextOrder = now + 10000;
return;
}
battery.PendingSupplyReport = delivered;
}
if (!battery.PendingSupplyReport) return;
if (!battery.CommandOpen || !ERR_MortarPrediction.Fresh(battery.PendingSupplyReport, now) || !battery.Operational() || battery.Activity)
{
battery.Cancel("delivered order expired or became unavailable while awaiting physical ammunition");
battery.NextOrder = now + 10000;
return;
}
ERR_MortarSupplyState supply = battery.SupplyState(now);
if (supply == ERR_MortarSupplyState.PENDING) return;
if (supply == ERR_MortarSupplyState.FAILED)
{
battery.Cancel("physical gunner ammunition unavailable or transfer failed");
battery.NextOrder = now + 10000;
return;
}
ERR_HQReport ready = battery.PendingSupplyReport;
battery.PendingSupplyReport = null;
battery.Order(ready, now);
}
void Tick(float now)
{
if (m_Stopped || !Replication.IsServer()) return;
foreach (ERR_MortarBattery battery : m_Batteries)
{
if (battery.Rejected && !battery.Released)
{
battery.Cancel("native aim or firing authorization rejected");
battery.NextOrder = now + 10000;
}
battery.Rejected = false;
battery.Update(now);
AdvanceOrder(battery, now);
}
if (now < m_NextDecision) return;
m_NextDecision = now + 10000;
array<ref ERR_HQReport> reports = {};
m_HQ.SupportContacts(reports, now);
ERR_MortarBattery selected;
ERR_HQReport target;
float distance = float.MAX;
foreach (ERR_MortarBattery battery : m_Batteries)
{
if (!battery.StartupActivated || !battery.Operational() || battery.Activity || battery.RadioOrder || battery.PendingSupplyReport || battery.SupplyPending() || now < battery.NextOrder || battery.CountShells() == 0) continue;
foreach (ERR_HQReport report : reports)
{
float candidate = vector.DistanceXZ(battery.Position, report.Position);
if (candidate < 350 || candidate > 4000 || candidate >= distance || !OutsideSettlements(report.Position)) continue;
selected = battery;
target = report;
distance = candidate;
}
}
if (!selected || !target) return;
ERR_HQRoute route = m_HQ.Downlink(selected.Group, "MORTAR ORDER", target.Description(now), target.MessageId);
if (!route) return;
selected.BeginRequest(target, now);
selected.RadioId = route.MessageId;
selected.RadioOrder = route;
selected.PendingRadioReport = target.Snapshot();
m_NextDecision = now + 20000;
}
void AppendGuns(array<IEntity> entities)
{
foreach (ERR_MortarBattery battery : m_Batteries)
if (battery.Gun && !entities.Contains(battery.Gun)) entities.Insert(battery.Gun);
}
string Status()
{
int ready, shells;
foreach (ERR_MortarBattery battery : m_Batteries)
{
if (battery.StartupActivated && battery.Operational()) ready++;
shells += battery.CountShells();
}
return string.Format("mortars %1/%2; HE shells %3", ready, m_Batteries.Count(), shells);
}
void Stop()
{
m_Stopped = true;
foreach (ERR_MortarBattery battery : m_Batteries) battery.Stop();
}
}
@@ -0,0 +1,241 @@
#ifdef WORKBENCH
// Explicit synthetic observation only. Delivery, HQ scheduling and native fire
// are unchanged; this helper never writes directly into the HQ contact list.
modded class ERR_HQ
{
int ERR_QueueMortarFixtureReport(SCR_AIGroup source, IEntity target, vector position, float now)
{
if (!ERR_NativeMortarFiringProbe.Enabled() || !target || !m_Contacts.IsEmpty()) return 0;
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.Group != source || !unit.ReservedForSupport || !unit.Radio || unit.Uplink || unit.PendingReport) continue;
ERR_HQRoute route = m_Network.Route(unit.Radio);
if (!route || route.Nodes.IsEmpty()) return 0;
ERR_HQReport report = new ERR_HQReport();
report.MessageId = m_Journal.Message(); report.Target = target; report.Source = source;
report.Position = position; report.ObservedAt = now; report.DetailsObservedAt = now;
report.HasVelocity = true; report.Velocity = vector.Zero;
report.TravelMode = "on foot"; report.SeenEscapists = 1; report.SeenWeapons = "fixture observation";
route.MessageId = report.MessageId; route.Payload = "EXPLICIT SYNTHETIC OBSERVATION: " + report.Description(now);
unit.PendingReport = report; unit.Uplink = route;
m_Journal.Write("FIXTURE REPORT", route.Payload, report.MessageId);
return report.MessageId;
}
return 0;
}
void ERR_RemoveMortarFixtureReport(IEntity target)
{
if (!target) return;
for (int i = m_Contacts.Count() - 1; i >= 0; i--)
if (m_Contacts[i].Target == target) m_Contacts.Remove(i);
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.PendingReport && unit.PendingReport.Target == target) { unit.PendingReport = null; unit.Uplink = null; }
if ((unit.PendingOrder && unit.PendingOrder.Target == target) || (unit.Assignment && unit.Assignment.Target == target)) unit.Release();
}
}
}
// Observe only the actual native event. Node SUCCESS, accepted inventory moves
// and committed shell loading are never counted as physical projectiles.
modded class SCR_MortarMuzzleComponent
{
override void OnWeaponFired(IEntity effectEntity, BaseMuzzleComponent muzzle, IEntity projectileEntity)
{
ERR_NativeMortarFiringProbe probe = ERR_NativeMortarFiringProbe.Active();
if (probe) probe.NativeProjectile(GetOwner(), projectileEntity);
super.OnWeaponFired(effectEntity, muzzle, projectileEntity);
}
}
class ERR_NativeMortarFiringProbe
{
protected static ERR_NativeMortarFiringProbe s_Active;
protected ERR_GameMode m_Mode;
protected ERR_MortarBattery m_Battery;
protected IEntity m_Gun;
protected SCR_AIGroup m_Group;
protected IEntity m_Target;
protected vector m_Impact;
protected ref array<IEntity> m_Crew = {};
protected ref array<IEntity> m_InitialShells = {};
protected ref array<IEntity> m_Projectiles = {};
protected int m_Source;
protected int m_Order;
protected int m_Step;
protected int m_Events;
protected int m_StoppedShells;
protected float m_Deadline;
protected float m_NextDiagnostic;
protected float m_StopUntil;
protected bool m_Unsafe;
protected bool m_BadProjectile;
protected bool m_SawUplink;
protected bool m_SawDownlink;
protected bool m_SawActivity;
protected bool m_Stopped;
protected string m_BadReason;
static bool Enabled()
{
string enabled, outcome;
return Replication.IsServer() && System.GetCLIParam("errSmoke", enabled) && enabled == "1" && System.GetCLIParam("errSmokeOutcome", outcome) && outcome == "mortar-fire";
}
static ERR_NativeMortarFiringProbe Active() { return s_Active; }
void ERR_NativeMortarFiringProbe(ERR_GameMode mode)
{
m_Mode = mode;
m_Deadline = GetGame().GetWorld().GetWorldTime() + 180000;
if (Enabled() && !s_Active) s_Active = this;
}
protected bool Check(bool condition, string detail)
{
if (condition) { Print("ERR SMOKE PASS: mortar firing " + detail); return true; }
Print("ERR SMOKE FAIL: mortar firing " + detail, LogLevel.ERROR); Stop(); return false;
}
protected void Shells(out array<IEntity> shells)
{
shells.Clear();
foreach (IEntity actor : m_Crew)
{
if (!actor) continue;
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(actor.FindComponent(InventoryStorageManagerComponent));
array<IEntity> items = {}; ERR_Inventory.Items(inventory, items);
foreach (IEntity item : items)
if (item && item.GetPrefabData() && item.GetPrefabData().GetPrefabName() == ERR_MortarBattery.SHELL && !shells.Contains(item)) shells.Insert(item);
}
}
protected bool CheckNoOccupants(IEntity entity)
{
if (ChimeraCharacter.Cast(entity) || Vehicle.Cast(entity)) { m_Unsafe = true; return false; }
return true;
}
protected bool EmptyImpact(vector position)
{
m_Unsafe = false;
GetGame().GetWorld().QueryEntitiesByAABB(position - "200 5000 200", position + "200 5000 200", CheckNoOccupants, null, EQueryEntitiesFlags.ALL);
return !m_Unsafe;
}
protected bool SelectImpact(ERR_MortarSystem system)
{
// Bounded candidate survey: no clearance assumption from coordinates alone.
array<vector> offsets = {"-800 0 -600", "-600 0 -800", "0 0 -1000", "600 0 -800", "-1000 0 0", "800 0 -600", "-800 0 600", "0 0 1000"};
foreach (vector offset : offsets)
{
vector candidate = ERR_Actors.Ground(m_Battery.Position + offset);
if (candidate[1] < 1 || !EmptyImpact(candidate) || !system.Safe(m_Battery, candidate, 75)) continue;
bool clear = true;
for (int shot = 0; shot < ERR_MortarSalvo.ROUNDS; shot++)
{
vector spread = ERR_Actors.Ground(candidate + ERR_MortarSalvo.Offset(m_Battery.SiteId, m_Battery.OrderId + 1, shot));
if (!system.Safe(m_Battery, spread, 75)) { clear = false; break; }
}
if (!clear) continue;
m_Impact = candidate;
PrintFormat("ERR MORTAR FIXTURE IMPACT: position=%1 batteryDistance=%2; no characters/vehicles in 400m square; production settlement/friendly exclusions passed", candidate, vector.DistanceXZ(candidate, m_Battery.Position));
return true;
}
return false;
}
protected void Diagnose(float now)
{
if (now < m_NextDiagnostic) return;
m_NextDiagnostic = now + 5000;
if (!m_Battery) { Print("ERR MORTAR FIXTURE: waiting for one authored battery"); return; }
PrintFormat("ERR MORTAR FIXTURE: step=%1 startup=%2 source=M%3 observedEvents=%4 ready=%5 failure=%6", m_Step, m_Battery.StartupActivated, m_Source, m_Events, m_Battery.Operational(), m_Battery.SpawnFailure);
m_Battery.SiteStatus(now);
}
void NativeProjectile(IEntity gun, IEntity projectile)
{
if (m_Stopped || !m_Battery || gun != m_Gun) return;
if (!projectile) { m_BadProjectile = true; m_BadReason = "native fired event has no physical projectile"; return; }
if (m_Projectiles.Contains(projectile)) { m_BadProjectile = true; m_BadReason = "same physical projectile observed twice"; return; }
m_Projectiles.Insert(projectile); m_Events++;
float now = GetGame().GetWorld().GetWorldTime();
if (m_Step != 1 || !m_Battery.CommandOpen || !m_Battery.Released || m_Battery.SourceId != m_Source || m_Battery.AimedAt < 0 || now - m_Battery.AimedAt > 10000 || m_Battery.FlightTime <= 0)
{ m_BadProjectile = true; m_BadReason = "projectile lacks this delivered order and fresh native aim/commit"; }
PrintFormat("ERR MORTAR FIXTURE PROJECTILE: event=%1 entity=%2 origin=%3 order=%4 source=M%5 aimAge=%6 flight=%7; impact is not measured", m_Events, projectile, projectile.GetOrigin(), m_Battery.OrderId, m_Battery.SourceId, now - m_Battery.AimedAt, m_Battery.FlightTime);
}
int Tick(float now)
{
if (m_Stopped) return -1;
if (!Enabled() || s_Active != this || !m_Mode || !m_Mode.Active()) { Check(false, "explicit active fixture context retained"); return -1; }
ERR_HQ hq = ERR_HQ.Get();
ERR_MortarSystem system;
if (hq) system = hq.Mortars();
if (!system) { Check(false, "real HQ mortar service available"); return -1; }
if (!m_Battery)
{
array<IEntity> guns = {}; system.AppendGuns(guns);
if (guns.Count() == 1) { m_Gun = guns[0]; m_Battery = system.FindGun(m_Gun); }
}
Diagnose(now);
if (now >= m_Deadline) { Check(false, "bounded deadline; inspect readiness/route/activity/aim diagnostics"); return -1; }
if (m_BadProjectile) { Check(false, m_BadReason); return -1; }
if (!m_Battery) return 0;
if (!m_Battery.SpawnFailure.IsEmpty()) { Check(false, "battery startup failed: " + m_Battery.SpawnFailure); return -1; }
if (m_Step == 0)
{
if (!m_Battery.StartupActivated || !m_Battery.Operational() || !hq.MortarConnected(m_Battery.Group)) return 0;
m_Group = m_Battery.Group;
if (!Check(m_Group && m_Group.IsExpandComplete() && m_Group.GetAgentsCount() == 4 && m_Battery.TotalShots == 0 && m_Battery.OrderId == 0 && !m_Battery.CommandOpen && !m_Battery.Activity && !m_Battery.RadioOrder, "untasked original gun and complete four-person crew start without shots")) return -1;
array<AIAgent> agents = {}; m_Group.GetAgents(agents);
foreach (AIAgent agent : agents)
{
IEntity actor; if (agent) actor = agent.GetControlledEntity();
if (!Check(ERR_Actors.CanFight(actor) && !m_Crew.Contains(actor), "initial physical crew member is conscious and unique")) return -1;
m_Crew.Insert(actor);
}
if (!Check(m_Battery.RadioOperator && ERR_HQRadio.Capability(m_Battery.RadioOperator) == 2, "dedicated actual manpack supplies the radio route")) return -1;
Shells(m_InitialShells);
if (!Check(m_InitialShells.Count() == 27 && m_Battery.CountShells() == 27, "exactly 27 distinct physical initial HE shells")) return -1;
if (!Check(SelectImpact(system), "bounded candidate survey finds an unoccupied production-safe impact area")) return -1;
m_Target = ERR_Actors.Spawn(ERR_Resources.IntelFolder(), m_Impact);
if (!Check(m_Target != null, "fixture-owned inert report identity exists; no enemy perception is claimed")) return -1;
m_Source = hq.ERR_QueueMortarFixtureReport(m_Group, m_Target, m_Impact, now);
if (!Check(m_Source > 0, "synthetic observation enters actual existing radio uplink once")) return -1;
m_SawUplink = true; m_Deadline = now + 90000; m_Step = 1; return 0;
}
if (m_Battery.Gun != m_Gun || m_Battery.Group != m_Group) { Check(false, "original gun and crew identity retained"); return -1; }
if (!EmptyImpact(m_Impact)) { Check(false, "impact exclusion stays unoccupied before native firing/cancellation"); return -1; }
array<IEntity> remaining = {}; Shells(remaining);
foreach (IEntity item : remaining)
if (!m_InitialShells.Contains(item)) { Check(false, "no replacement HE shell appears after initialization"); return -1; }
if (m_Step == 1)
{
if (m_Battery.RadioOrder && m_Battery.SourceId == m_Source) { m_SawDownlink = true; m_Order = m_Battery.OrderId; }
if (m_Battery.Activity && m_Battery.Report && m_Battery.Report.MessageId == m_Source) m_SawActivity = true;
if (m_Battery.OrderId > 1 || (m_Battery.SourceId != 0 && m_Battery.SourceId != m_Source)) { Check(false, "one unchanged fixture source creates only one HQ order"); return -1; }
if (m_Events == 0) return 0;
if (!Check(m_Events == 1 && m_Battery.TotalShots == 1 && m_Battery.OrderShots == 1 && !m_Battery.Released && m_SawUplink && m_SawDownlink && m_SawActivity && m_Order == 1, "one physical projectile follows real uplink/downlink, native activity and fresh aim")) return -1;
if (!Check(remaining.Count() == 26 && m_Battery.CountShells() == 26, "one fired projectile consumes one of 27 original inventory shells")) return -1;
// Cancel on this later fixture tick, never reentrantly inside the firing node.
hq.ERR_RemoveMortarFixtureReport(m_Target);
system.Stop(); system.Stop();
if (!Check(!m_Battery.CommandOpen && !m_Battery.Activity && !m_Battery.RadioOrder, "explicit support Stop closes native order and route idempotently")) return -1;
m_StoppedShells = remaining.Count(); m_StopUntil = now + 12000; m_Deadline = m_StopUntil + 2000; m_Step = 2; return 0;
}
if (now < m_StopUntil) return 0;
if (!Check(m_Battery.TotalShots == 1 && m_Events == 1 && m_Battery.OrderId == m_Order && remaining.Count() == m_StoppedShells && !m_Battery.CommandOpen && !m_Battery.Activity && !m_Battery.RadioOrder, "stopped service issues no duplicate order, projectile or replenishment over 12 seconds")) return -1;
array<AIAgent> finalCrew = {}; m_Group.GetAgents(finalCrew);
if (!Check(finalCrew.Count() == 4 && m_Battery.Gun == m_Gun, "original group and gun retain four crew")) return -1;
foreach (AIAgent finalAgent : finalCrew)
if (!Check(finalAgent && m_Crew.Contains(finalAgent.GetControlledEntity()) && ERR_Actors.CanFight(finalAgent.GetControlledEntity()), "final conscious crew entity belongs to original physical roster")) return -1;
Stop(); return 1;
}
void Stop()
{
if (m_Stopped) return;
m_Stopped = true;
ERR_HQ hq = ERR_HQ.Get();
if (hq)
{
hq.ERR_RemoveMortarFixtureReport(m_Target);
if (m_Battery && m_Battery.SourceId == m_Source && m_Source > 0) m_Battery.Cancel("mortar firing fixture cleanup");
}
ERR_Actors.DeleteSpawned(m_Target); m_Target = null;
if (s_Active == this) s_Active = null;
}
void ~ERR_NativeMortarFiringProbe() { Stop(); }
}
#endif
@@ -0,0 +1,87 @@
#ifdef WORKBENCH
// Test access only: trigger the real delivered-order method on an existing
// registered squad. Radio transit is intentionally not simulated by this test.
modded class ERR_HQ
{
bool ERR_TestPatrolSearch(SCR_AIGroup group, out AIWaypoint search)
{
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.Group != group) continue;
if (unit.Assignment || unit.PendingOrder || unit.Waypoint || !unit.Eligible(m_Mode)) return false;
ERR_HQReport order = new ERR_HQReport();
order.Position = group.GetOrigin() + "40 0 0";
order.ObservedAt = GetGame().GetWorld().GetWorldTime();
order.MessageId = m_Journal.Message();
unit.PendingOrder = order;
DeliverOrder(unit, order.ObservedAt);
search = unit.Waypoint;
return search && unit.Assignment == order;
}
return false;
}
bool ERR_TestPatrolRelease(SCR_AIGroup group, AIWaypoint search)
{
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.Group != group || unit.Waypoint != search) continue;
unit.Release();
return !unit.Assignment && !unit.PendingOrder && !unit.Waypoint;
}
return false;
}
}
class ERR_NativePatrolHQProbe
{
protected ERR_GameMode m_Mode;
protected ERR_SiteRuntime m_Site;
protected AIWaypoint m_Search;
protected ref array<AIWaypoint> m_Baseline = {};
protected int m_Step;
protected float m_Wait;
void ERR_NativePatrolHQProbe(ERR_GameMode mode) { m_Mode = mode; }
protected bool Check(bool condition, string detail)
{
if (condition) { Print("ERR SMOKE PASS: patrol HQ " + detail); return true; }
Print("ERR SMOKE FAIL: patrol HQ " + detail, LogLevel.ERROR); return false;
}
int Tick(float now)
{
if (now < m_Wait) return 0;
ERR_HQ hq = ERR_HQ.Get();
if (!Check(hq != null, "real HQ available")) return -1;
if (m_Step == 0)
{
m_Site = m_Mode.Sites().Find("everon-outpost-1");
if (!Check(m_Site && m_Site.Group && m_Site.PatrolCycle, "existing outpost route available")) return -1;
m_Site.Group.GetWaypoints(m_Baseline);
if (!Check(!m_Baseline.IsEmpty() && hq.ERR_TestPatrolSearch(m_Site.Group, m_Search), "real delivered-order method assigns existing squad")) return -1;
m_Step = 1; m_Wait = now + 750; return 0;
}
if (m_Step == 1)
{
array<AIWaypoint> queue = {};
m_Site.Group.GetWaypoints(queue);
if (!Check(m_Search && !queue.IsEmpty() && queue[0] == m_Search && m_Site.Group.GetCurrentWaypoint() == m_Search, "Search preempts native patrol")) return -1;
foreach (AIWaypoint waypoint : m_Baseline)
if (!Check(queue.Contains(waypoint), "preempted baseline route remains queued")) return -1;
if (!Check(hq.ERR_TestPatrolRelease(m_Site.Group, m_Search), "real HQ release removes only its assignment")) return -1;
m_Step = 2; m_Wait = now + 750; return 0;
}
if (m_Step == 2)
{
AIWaypoint current = m_Site.Group.GetCurrentWaypoint();
if (!Check(current && (current == m_Site.PatrolCycle || m_Site.PatrolWaypoints.Contains(current)), "native patrol resumes after Search release")) return -1;
m_Step = 3; return 1;
}
return 1;
}
void Stop()
{
ERR_HQ hq = ERR_HQ.Get();
if (hq && m_Site && m_Search) hq.ERR_TestPatrolRelease(m_Site.Group, m_Search);
}
void ~ERR_NativePatrolHQProbe() { Stop(); }
}
#endif
@@ -0,0 +1,63 @@
// Vanilla named settlements supply exclusion areas; no original mission location system.
// Shared town/village exclusion for mortar impacts, roadblocks and mine sites.
// Fixed distance from mapped settlement centres, independent of mission
// activation radii. Scattered buildings and props are not settlements.
class ERR_SettlementSafety
{
static const float RADIUS = 200;
string SettlementReason;
protected vector m_SafeImpact;
protected bool m_SettlementNear;
protected vector m_LastSettlementImpact;
protected float m_LastSettlementCheck = -1;
protected bool m_LastSettlementClear;
bool OutsideSettlements(vector impact)
{
float now = GetGame().GetWorld().GetWorldTime();
if (m_LastSettlementCheck >= 0 && now >= m_LastSettlementCheck && now - m_LastSettlementCheck < 1000 && vector.DistanceXZ(impact, m_LastSettlementImpact) == 0)
return m_LastSettlementClear;
m_LastSettlementCheck = now;
m_LastSettlementImpact = impact;
m_LastSettlementClear = false;
m_SafeImpact = impact;
m_SettlementNear = false;
SettlementReason = "clear";
// Also cover named native map settlements, independent of whether the
// mission placed a garrison marker there. Generic building entities also
// include deer stands, bridge pillars, rubble and electrical cabinets.
// Broad vertical bounds keep the 200m distance horizontal on hills.
GetGame().GetWorld().QueryEntitiesByAABB(impact - Vector(RADIUS, 5000, RADIUS), impact + Vector(RADIUS, 5000, RADIUS), CheckSettlement, FilterSettlement, EQueryEntitiesFlags.ALL);
m_LastSettlementClear = !m_SettlementNear;
return m_LastSettlementClear;
}
protected bool FilterSettlement(IEntity entity)
{
return entity && entity.FindComponent(MapDescriptorComponent);
}
protected bool CheckSettlement(IEntity entity)
{
float radius;
MapDescriptorComponent descriptor = MapDescriptorComponent.Cast(entity.FindComponent(MapDescriptorComponent));
if (descriptor)
{
int type = descriptor.GetBaseType();
if (type == EMapDescriptorType.MDT_NAME_CITY)
radius = RADIUS;
else if (type == EMapDescriptorType.MDT_NAME_TOWN)
radius = RADIUS;
else if (type == EMapDescriptorType.MDT_NAME_VILLAGE || type == EMapDescriptorType.MDT_NAME_SETTLEMENT)
radius = RADIUS;
}
if (radius > 0 && vector.DistanceXZ(m_SafeImpact, entity.GetOrigin()) <= radius)
{
m_SettlementNear = true;
SettlementReason = string.Format("named map settlement entity=%1 position=%2 distance=%3m exclusion=%4m", entity, entity.GetOrigin(), vector.DistanceXZ(m_SafeImpact, entity.GetOrigin()), radius);
return false;
}
return true;
}
}
@@ -0,0 +1,9 @@
modded class ERR_ScenarioComponent
{
protected override bool PrepareAdditionalForces()
{
if (!super.PrepareAdditionalForces()) return false;
ERR_HQ hq = ERR_HQ.Get();
return hq && hq.PrepareSupport();
}
}
@@ -0,0 +1,9 @@
GameProject {
ID "ERR_Ai"
GUID "5192138CB9D5B911"
TITLE "Escapists Rereintroduced - Ai"
Dependencies {
"58D0FB3206B6F859"
"2528466DE220D91C"
}
}
@@ -0,0 +1,11 @@
SCR_MissionHeader {
World "{B6C516F86302C679}Worlds/ERR_Everon.ent"
SystemsConfig "{C50579A2EC48E8EF}Configs/Systems/MissionSystems.conf"
m_sName "Rereintroduced: Everon (development)"
m_sAuthor "Rereintroduced contributors"
m_sDescription "Independent escape prototype. Development scenario; runtime validation in progress."
m_sGameMode "Escape"
m_iPlayerCount 12
m_eSaveTypes 0
m_bShowInScenarioMenu 1
}
@@ -0,0 +1,9 @@
MetaFileClass {
Name "{C1E20667DCE324ED}Missions/ERR_Everon.conf"
Configurations {
ResourceClass PC {
}
ResourceClass HEADLESS : PC {
}
}
}
@@ -0,0 +1,36 @@
// Companion-specific commands extend Core's authenticated transport.
modded class ERR_AdminService
{
protected override string Setting(string section, string option)
{
if (section == "hq")
{
if (option == "interval") return "reportIntervalSeconds";
if (option == "squads") return "supportSquadLimit";
if (option == "radius") return "responseRadiusMetres";
}
if (section == "intel")
{
if (option == "carrying") return "aiIntelChancePercent";
}
return super.Setting(section, option);
}
protected override bool Extension(ERR_GameMode mode, string arguments, array<string> replies)
{
if (arguments != "status" && arguments != "hq show" && arguments != "hq log") return super.Extension(mode, arguments, replies);
ERR_HQ hq = ERR_HQ.Cast(mode.Command());
if (!hq) { replies.Insert("HQ unavailable"); return true; }
if (arguments == "hq show" || arguments == "status") replies.Insert(hq.Status());
else
{
int cursor;
hq.Journal().Read(Math.Max(0, hq.Journal().Sequence() - 8), replies, cursor);
if (replies.IsEmpty()) replies.Insert("HQ journal is empty.");
}
return true;
}
protected override string Help()
{
return super.Help() + " | hq show|log | hq interval|squads|radius show|set N | intel carrying show|set N";
}
}
@@ -0,0 +1,10 @@
#ifdef WORKBENCH
modded class ERR_MortarSystem
{
ERR_MortarBattery ERR_ProbeBattery()
{
if (m_Batteries.Count() != 1) return null;
return m_Batteries[0];
}
}
#endif
@@ -0,0 +1,114 @@
// Opt-in engine fixture: physical radios and production delivery routes only.
#ifdef WORKBENCH
modded class ERR_HQ
{
vector ERR_ProbeResponseOrigin()
{
foreach (ERR_HQUnit unit : m_Units)
if (!unit.ReservedForSupport && unit.Group) return unit.Group.GetOrigin() + "0 0 20";
return vector.Zero;
}
bool ERR_ProbeDeliveredResponse()
{
foreach (ERR_HQUnit unit : m_Units)
if (unit.Assignment && unit.Waypoint && unit.Group != unit.Assignment.Source) return true;
return false;
}
bool ERR_ProbeUniqueAssignments()
{
array<AIWaypoint> waypoints = {};
foreach (ERR_HQUnit unit : m_Units)
{
if (!unit.Waypoint) continue;
if (!unit.Assignment || waypoints.Contains(unit.Waypoint)) return false;
waypoints.Insert(unit.Waypoint);
}
return waypoints.Count() > 0 && Assigned() <= m_Mode.Settings().Get("supportSquadLimit");
}
string ERR_ProbePerception()
{
int targets, sightings, radios;
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.Radio) radios++;
if (!unit.Utility) continue;
array<ref ERR_HQVisualContact> samples = {};
ERR_HQObservation.Gather(unit.Utility, GetGame().GetWorld().GetWorldTime(), samples);
sightings += samples.Count();
if (unit.Utility.m_Perception) targets += unit.Utility.m_Perception.m_aTargets.Count();
}
return string.Format("%1; radios=%2 targets=%3 fresh visual samples=%4", Status(), radios, targets, sightings);
}
ERR_HQRoute ERR_ProbeRoute(IEntity carrier = null, bool downlink = false)
{
if (carrier) return m_Network.Route(carrier, downlink);
foreach (ERR_HQUnit unit : m_Units)
if (unit.Radio) return m_Network.Route(unit.Radio, downlink);
return null;
}
bool ERR_ProbeSquadsReady()
{
int infantry;
foreach (ERR_HQUnit unit : m_Units)
{
if (unit.ReservedForSupport) continue;
infantry++;
if (!unit.Group || ERR_HQRadio.Capability(unit.Radio) != 2) return false;
array<AIAgent> agents = {};
unit.Group.GetAgents(agents);
if (agents.Count() != 6) return false;
}
return infantry == 6;
}
}
class ERR_NativeRadioProbe
{
protected ref ERR_HQRoute m_Route;
protected IEntity m_Carrier;
protected int m_Step;
int Tick(ERR_HQ hq, float now)
{
if (!hq) return -1;
if (m_Step == 0)
{
if (!hq.ERR_ProbeSquadsReady()) return 0;
Print("ERR SMOKE PASS: six physical six-person squads each have a manpack operator");
m_Route = hq.ERR_ProbeRoute();
if (!m_Route || m_Route.Nodes.IsEmpty()) return -1;
m_Carrier = m_Route.Nodes[0].Carrier;
m_Route.MessageId = hq.Journal().Message();
m_Step = 1;
}
int result = m_Route.Advance(now, hq.Journal());
if (result == 0) return 0;
if (m_Step == 3)
{
if (result >= 0) return -1;
Print("ERR SMOKE PASS: removing receiving manpack interrupts an in-flight HQ order");
return 1;
}
if (result < 0) return -1;
if (m_Step == 1) Print("ERR SMOKE PASS: physical manpack uplink delivers to HQ");
if (m_Step == 2) Print("ERR SMOKE PASS: HQ downlink delivers to a physical receiver");
m_Route = hq.ERR_ProbeRoute(m_Carrier, true);
if (!m_Route || m_Route.Nodes.IsEmpty()) return -1;
m_Route.MessageId = hq.Journal().Message();
m_Step++;
if (m_Step == 3)
{
// Start HQ transmission, then remove the actual receiving equipment.
if (m_Route.Advance(now, hq.Journal()) != 0) return -1;
IEntity receiver = m_Route.Nodes[0].Carrier;
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(receiver.FindComponent(InventoryStorageManagerComponent));
if (!inventory) return -1;
array<IEntity> items = {};
inventory.GetItems(items);
foreach (IEntity item : items)
if (item && item.FindComponent(BaseRadioComponent)) SCR_EntityHelper.DeleteEntityAndChildren(item);
}
return 0;
}
}
#endif
@@ -0,0 +1,434 @@
// Explicit, local Workbench diagnostic only. Never compiled into game/server builds.
#ifdef WORKBENCH
modded class ERR_GameMode
{
protected bool m_ERRTestPatrolHQ;
protected ref ERR_NativePatrolProbe m_ERRHQPatrolMovement;
protected ref ERR_NativePatrolHQProbe m_ERRHQPatrolOrder;
protected int m_ERRSmokeStep;
protected float m_ERRSmokeDeadline;
protected float m_ERRSmokeWait;
protected IEntity m_ERRSmokePlayer;
protected BaseDoorComponent m_ERRGate;
protected ERR_LocationComponent m_ERRSmokeRadio;
protected bool m_ERRSmokeDone;
protected bool m_ERRTestLostHelicopter;
protected bool m_ERRTestPlayerDeath;
protected bool m_ERRTestRadioNetwork;
protected bool m_ERRTestHQResponse;
protected bool m_ERRTestMortar;
protected bool m_ERRTestMortarFire;
protected ref ERR_NativeMortarFiringProbe m_ERRMortarFire;
protected float m_ERRNextProbeLog;
protected ref ERR_NativeRadioProbe m_ERRRadioProbe;
protected ref array<IEntity> m_ERRCacheFolders = {};
protected override void EOnInit(IEntity owner)
{
super.EOnInit(owner);
string enabled;
if (SCR_Global.IsEditMode() || !Replication.IsServer() || !System.GetCLIParam("errSmoke", enabled) || enabled != "1") return;
string outcome;
m_ERRTestLostHelicopter = System.GetCLIParam("errSmokeOutcome", outcome) && outcome == "lost-helicopter";
m_ERRTestRadioNetwork = outcome == "radio-network";
m_ERRTestHQResponse = outcome == "hq-response";
m_ERRTestMortar = outcome == "mortar-inventory";
m_ERRTestMortarFire = outcome == "mortar-fire";
m_ERRTestPatrolHQ = outcome == "patrol-hq";
m_ERRTestPlayerDeath = outcome == "player-death" || m_ERRTestRadioNetwork || m_ERRTestHQResponse || m_ERRTestMortar;
m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 150000;
if (m_ERRTestMortarFire) m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 330000;
if (m_ERRTestPatrolHQ) m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 420000;
OnStop().Insert(ERR_StopHQPatrol);
OnPhaseChanged().Insert(ERR_SmokePhase);
GetGame().GetCallqueue().CallLater(ERR_SmokeTick, 500, true);
Print("ERR SMOKE: scripted integration test enabled; gameplay acceptance remains separate");
}
protected bool ERR_Check(bool condition, string name)
{
if (condition) { Print("ERR SMOKE PASS: " + name); return true; }
ERR_StopHQPatrol();
Print("ERR SMOKE FAIL: " + name, LogLevel.ERROR);
m_ERRSmokeDone = true;
GetGame().GetCallqueue().Remove(ERR_SmokeTick);
return false;
}
protected void ERR_StopHQPatrol()
{
if (m_ERRMortarFire) m_ERRMortarFire.Stop();
if (m_ERRHQPatrolMovement) m_ERRHQPatrolMovement.Stop();
if (m_ERRHQPatrolOrder) m_ERRHQPatrolOrder.Stop();
}
protected void ERR_MovePlayer(vector position)
{
vector transform[4];
m_ERRSmokePlayer.GetWorldTransform(transform);
transform[3] = ERR_Actors.Ground(position);
ChimeraCharacter.Cast(m_ERRSmokePlayer).Teleport(transform);
}
protected ERR_UnlockPrisonAction ERR_FindLock(IEntity entity)
{
BaseActionsManagerComponent manager = BaseActionsManagerComponent.Cast(entity.FindComponent(BaseActionsManagerComponent));
if (manager)
{
array<BaseUserAction> actions = {};
manager.GetActionsList(actions);
foreach (BaseUserAction action : actions)
{
ERR_UnlockPrisonAction lock = ERR_UnlockPrisonAction.Cast(action);
if (lock) return lock;
}
}
IEntity child = entity.GetChildren();
while (child)
{
ERR_UnlockPrisonAction lock = ERR_FindLock(child);
if (lock) return lock;
child = child.GetSibling();
}
return null;
}
protected void ERR_SmokePhase(ERR_Phase previous, ERR_Phase current)
{
if (m_ERRSmokeDone || !ERR_MissionRules.Terminal(current)) return;
if (m_ERRTestMortarFire)
{
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 151, "native mortar first shot and stop complete before explicit reset")) return;
m_ERRSmokeDone = true;
GetGame().GetCallqueue().Remove(ERR_SmokeTick);
ERR_StopHQPatrol();
Print("ERR SMOKE COMPLETE: native HQ radio to first mortar projectile and explicit stop; fixture reset requested");
return;
}
if (m_ERRTestPatrolHQ)
{
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 133, "HQ patrol preemption and physical resumption before explicit reset")) return;
m_ERRSmokeDone = true;
GetGame().GetCallqueue().Remove(ERR_SmokeTick);
Print("ERR SMOKE COMPLETE: native HQ patrol preemption and physical resumption");
return;
}
if (m_ERRTestPlayerDeath)
{
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 91, "death exhausts round life and reaches defeat after spectator grace")) return;
}
else if (m_ERRTestLostHelicopter)
{
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 8, "lost extraction helicopter causes defeat")) return;
}
else if (!ERR_Check(current == ERR_Phase.VICTORY && m_ERRSmokeStep == 7, "scripted escape reaches victory after physical vehicle occupancy")) return;
m_ERRSmokeDone = true;
GetGame().GetCallqueue().Remove(ERR_SmokeTick);
PrintFormat("ERR SMOKE COMPLETE: terminal=%1 lostHelicopterCase=%2 playerDeathCase=%3", current, m_ERRTestLostHelicopter, m_ERRTestPlayerDeath);
GetGame().GetCallqueue().CallLater(ERR_EndScreenshot, 4000);
}
protected bool ERR_CheckRoster()
{
ERR_PlayerRoster roster = new ERR_PlayerRoster();
UUID first = "00e77100-0000-0000-0000-000000000101";
UUID second = "00e77100-0000-0000-0000-000000000202";
if (!ERR_Check(roster.Bind(101, first) && roster.CanEnter(101, ERR_Phase.PRISON), "new identity may enter prison")) return false;
roster.Spawned(101, m_ERRSmokePlayer);
if (!ERR_Check(!roster.CanEnter(101, ERR_Phase.PRISON), "spawn consumes identity life")) return false;
roster.Disconnect(101);
if (!ERR_Check(roster.HasSurvivor() && !roster.Get(101), "disconnect retains living actor and clears connection")) return false;
if (!ERR_Check(roster.Bind(202, first) && !roster.CanEnter(202, ERR_Phase.PRISON), "reconnected identity retains spent life")) return false;
if (!ERR_Check(!roster.Bind(303, first), "duplicate active identity rejected")) return false;
if (!ERR_Check(roster.Bind(101, second) && roster.CanEnter(101, ERR_Phase.RADIO_DEFENCE) && !roster.CanEnter(101, ERR_Phase.EXTRACTION), "recycled connection receives independent life and extraction admission policy")) return false;
return true;
}
protected bool ERR_CheckCompanionCommands()
{
array<string> replies = {};
array<string> commands = {"hq interval show", "hq squads show", "hq radius show", "intel carrying show", "intel reveal show"};
array<string> keys = {"reportIntervalSeconds", "supportSquadLimit", "responseRadiusMetres", "aiIntelChancePercent", "intelRevealChancePercent"};
for (int i = 0; i < commands.Count(); i++)
{
Admin().Execute(this, true, commands[i], replies);
if (!ERR_Check(replies.Count() == 1 && replies[0] == keys[i] + "=" + Settings().Get(keys[i]).ToString(), "companion command retained: " + commands[i])) return false;
}
Admin().Execute(this, false, "hq log", replies);
if (!ERR_Check(replies.Count() == 1 && replies[0] == "Administrator access required.", "companion journal is behind Core admin authorization")) return false;
Admin().Execute(this, true, "hq show", replies);
ERR_HQ hq = ERR_HQ.Cast(Command());
if (!ERR_Check(hq && replies.Count() == 1 && replies[0] == hq.Status(), "companion HQ status uses the shared command service")) return false;
return true;
}
protected void ERR_PrisonScreenshot() { System.MakeScreenshot("$logs:err-prison"); }
protected void ERR_EndScreenshot() { System.MakeScreenshot("$logs:err-result"); }
protected void ERR_SmokeTick()
{
float now = GetWorld().GetWorldTime();
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 == 150)
{
int result = m_ERRMortarFire.Tick(now);
if (result < 0) { ERR_Check(false, "native mortar firing probe failed; see diagnostics"); return; }
if (result == 1) { m_ERRSmokeStep = 151; Transition(ERR_Phase.DEFEAT); }
return;
}
if (m_ERRSmokeStep == 130 || m_ERRSmokeStep == 132)
{
int result = m_ERRHQPatrolMovement.Tick(now);
if (result < 0) { ERR_StopHQPatrol(); GetGame().GetCallqueue().Remove(ERR_SmokeTick); return; }
if (result == 1)
{
if (m_ERRSmokeStep == 130) { m_ERRHQPatrolOrder = new ERR_NativePatrolHQProbe(this); m_ERRSmokeStep = 131; }
else { m_ERRSmokeStep = 133; Transition(ERR_Phase.DEFEAT); }
}
return;
}
if (m_ERRSmokeStep == 131)
{
int result = m_ERRHQPatrolOrder.Tick(now);
if (result < 0) { ERR_StopHQPatrol(); GetGame().GetCallqueue().Remove(ERR_SmokeTick); return; }
if (result == 1) { m_ERRHQPatrolMovement = new ERR_NativePatrolProbe(this); m_ERRSmokeStep = 132; }
return;
}
if (m_ERRSmokeStep == 0)
{
array<IEntity> players = {};
ERR_Actors.Players(players, true);
if (players.Count() != 1 || Phase() != ERR_Phase.PRISON) return;
m_ERRSmokePlayer = players[0];
if (!ERR_CheckRoster() || !ERR_NativeContractsProbe.Run(this, m_ERRSmokePlayer) || !ERR_CheckCompanionCommands()) return;
if (m_ERRTestPatrolHQ)
{
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
m_ERRHQPatrolMovement = new ERR_NativePatrolProbe(this);
m_ERRSmokeStep = 130;
return;
}
if (m_ERRTestMortarFire)
{
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
m_ERRMortarFire = new ERR_NativeMortarFiringProbe(this);
m_ERRSmokeStep = 150;
return;
}
if (m_ERRTestMortar)
{
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
m_ERRSmokeStep = 120;
return;
}
if (m_ERRTestHQResponse)
{
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
m_ERRSmokeStep = 110;
return;
}
if (m_ERRTestRadioNetwork)
{
m_ERRRadioProbe = new ERR_NativeRadioProbe();
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
m_ERRSmokeStep = 100;
return;
}
if (m_ERRTestPlayerDeath)
{
m_ERRSmokeStep = 9;
SCR_CharacterDamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(SCR_CharacterDamageManagerComponent)).Kill(Instigator.CreateInstigator(m_ERRSmokePlayer));
m_ERRSmokeWait = now + 4000;
return;
}
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
if (!ERR_Check(vector.DistanceXZ(m_ERRSmokePlayer.GetOrigin(), PrisonPosition()) < 5, "initial prisoner position")) return;
foreach (ERR_LocationComponent location : m_Locations)
if (location.Kind() == ERR_LocationKind.RADIO) m_ERRSmokeRadio = location;
if (!ERR_Check(m_ERRSmokeRadio && ERR_Actors.Alive(ExtractionVehicle()), "radio and extraction vehicle exist")) return;
ERR_UnlockPrisonAction lock;
foreach (IEntity tracked : m_OwnedEntities)
{
if (tracked) lock = ERR_FindLock(tracked);
if (lock) break;
}
if (!ERR_Check(lock != null, "authored gate exposes lock action")) return;
ERR_MovePlayer(lock.GetOwner().GetOrigin() + "1 0 1");
vector gateLow, gateHigh;
lock.GetOwner().GetWorldBounds(gateLow, gateHigh);
PrintFormat("ERR GEOMETRY: gate low=%1 high=%2", gateLow, gateHigh);
IEntity wall = lock.GetOwner().GetParent().GetChildren();
while (wall)
{
vector wallLow, wallHigh;
wall.GetWorldBounds(wallLow, wallHigh);
PrintFormat("ERR GEOMETRY: child origin=%1 low=%2 high=%3", wall.GetOrigin(), wallLow, wallHigh);
wall = wall.GetSibling();
}
GetGame().GetCallqueue().CallLater(ERR_PrisonScreenshot, 2000);
if (!ERR_Check(lock.CanBePerformedScript(m_ERRSmokePlayer), "lock permits prisoner")) return;
m_ERRGate = BaseDoorComponent.Cast(lock.GetOwner().FindComponent(BaseDoorComponent));
lock.PerformAction(lock.GetOwner(), m_ERRSmokePlayer);
if (!ERR_Check(Phase() == ERR_Phase.RADIO_SEARCH, "lock action advances mission")) return;
array<IEntity> cacheStock = {};
ERR_Inventory.Items(InventoryStorageManagerComponent.Cast(Sites().Find("everon-supply-1").Container.FindComponent(InventoryStorageManagerComponent)), cacheStock);
foreach (IEntity tracked : cacheStock)
{
if (tracked && tracked.GetPrefabData() && tracked.GetPrefabData().GetPrefabName() == ERR_Resources.ObjectiveDocument()) m_ERRCacheFolders.Insert(tracked);
}
if (!ERR_Check(m_ERRCacheFolders.Count() == 2, "two guaranteed physical cache documents")) return;
if (!ERR_Check(m_Settings.Set("aiIntelChancePercent", 0), "test does not rely on random intel")) return;
if (!ERR_Check(m_Settings.Set("radioDefenceSeconds", 30), "isolated test profile defence duration")) return;
m_ERRSmokeStep = 1;
}
else if (m_ERRSmokeStep == 1 || m_ERRSmokeStep == 2)
{
if (m_ERRSmokeStep == 2 && !ERR_Check(m_ERRGate && m_ERRGate.IsOpen() && m_ERRGate.CanCharacterPass(0.6), "unlocked gate physically permits passage")) return;
ERR_MovePlayer(Sites().Find("everon-supply-1").Container.GetOrigin() + "0 0 2");
SCR_InventoryStorageManagerComponent inventory = SCR_InventoryStorageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(SCR_InventoryStorageManagerComponent));
InventoryStorageManagerComponent source = InventoryStorageManagerComponent.Cast(Sites().Find("everon-supply-1").Container.FindComponent(InventoryStorageManagerComponent));
BaseInventoryStorageComponent destination = inventory.FindStorageForItem(m_ERRCacheFolders[m_ERRSmokeStep - 1]);
if (!ERR_Check(destination && source.TryMoveItemToStorage(m_ERRCacheFolders[m_ERRSmokeStep - 1], destination), "authored cache document recovered into inventory")) return;
m_ERRSmokeStep++;
m_ERRSmokeWait = now + 2500;
}
else if (m_ERRSmokeStep == 3)
{
if (!ERR_Check(m_ERRSmokeRadio.Knowledge() == 2, "carried intel identifies radio through intel service")) return;
if (!ERR_Check(!TuneRadio(m_ERRSmokePlayer, m_ERRSmokeRadio), "radio rejects distant player")) return;
ERR_MovePlayer(m_ERRSmokeRadio.Position() + "2 0 0");
m_ERRSmokeStep = 30;
m_ERRSmokeWait = now + 1000;
}
else if (m_ERRSmokeStep == 30)
{
PrintFormat("ERR SMOKE: radio=%1 player=%2", m_ERRSmokeRadio.Position(), m_ERRSmokePlayer.GetOrigin());
if (!ERR_Check(TuneRadio(m_ERRSmokePlayer, m_ERRSmokeRadio), "identified radio starts defence")) return;
m_ERRSmokeStep = 4;
m_ERRSmokeWait = now + 3000;
}
else if (m_ERRSmokeStep == 4)
{
if (!ERR_Check(DefenceOccupied(), "occupied defence timer running")) return;
ERR_MovePlayer(m_ERRSmokeRadio.Position() + "90 0 0");
m_ERRSmokeStep = 5;
m_ERRSmokeWait = now + 2500;
}
else if (m_ERRSmokeStep == 5)
{
if (!ERR_Check(!DefenceOccupied() && Phase() == ERR_Phase.RADIO_DEFENCE, "leaving area resets defence")) return;
ERR_MovePlayer(m_ERRSmokeRadio.Position() + "2 0 0");
m_ERRSmokeStep = 6;
m_ERRSmokeWait = now + 33000;
}
else if (m_ERRSmokeStep == 6)
{
if (!ERR_Check(Phase() == ERR_Phase.EXTRACTION, "continuous occupied defence completes")) return;
if (m_ERRTestLostHelicopter)
{
m_ERRSmokeStep = 8;
ERR_Actors.DeleteSpawned(ExtractionVehicle());
return;
}
CompartmentAccessComponent access = CompartmentAccessComponent.Cast(m_ERRSmokePlayer.FindComponent(CompartmentAccessComponent));
BaseCompartmentSlot slot = access.FindFreeCompartment(ExtractionVehicle(), ECompartmentType.PILOT);
if (!ERR_Check(slot && access.GetInVehicle(ExtractionVehicle(), slot, true, -1, ECloseDoorAfterActions.INVALID, false), "boarding extraction vehicle")) return;
m_ERRSmokeStep = 7;
m_ERRSmokeWait = now + 3000;
}
else if (m_ERRSmokeStep == 120)
{
ERR_MortarBattery battery = ERR_MortarSystem.Get().ERR_ProbeBattery();
if (!battery || !battery.StartupActivated) return;
if (!ERR_Check(battery.Operational() && battery.Group.GetAgentsCount() == 4, "authored physical mortar and four-person crew initialize")) return;
if (!ERR_Check(ERR_HQRadio.Capability(battery.RadioOperator) == 2, "mortar has a dedicated physical manpack operator")) return;
if (!ERR_Check(battery.CountShells() == 27, "mortar starts with exactly 27 physical HE shells")) return;
array<AIAgent> agents = {};
battery.Group.GetAgents(agents);
foreach (AIAgent agent : agents)
{
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(agent.GetControlledEntity().FindComponent(InventoryStorageManagerComponent));
array<IEntity> items = {};
ERR_Inventory.Items(inventory, items);
foreach (IEntity item : items)
if (item && item.GetPrefabData() && item.GetPrefabData().GetPrefabName() == ERR_MortarBattery.SHELL) SCR_EntityHelper.DeleteEntityAndChildren(item);
}
m_ERRSmokeStep = 121;
m_ERRSmokeWait = now + 15000;
}
else if (m_ERRSmokeStep == 121)
{
ERR_MortarBattery battery = ERR_MortarSystem.Get().ERR_ProbeBattery();
if (!ERR_Check(battery.CountShells() == 0 && battery.TotalShots == 0, "depleted mortar inventory stays empty without fabricated ammunition")) return;
ERR_Actors.DeleteSpawned(battery.Gun);
ERR_Actors.DeleteSpawned(battery.Group);
m_ERRSmokeStep = 122;
m_ERRSmokeWait = now + 12000;
}
else if (m_ERRSmokeStep == 122)
{
ERR_MortarBattery battery = ERR_MortarSystem.Get().ERR_ProbeBattery();
if (!ERR_Check(battery && !battery.Gun && !battery.Group && !battery.Operational(), "lost mortar and crew remain lost without replacement spawning")) return;
m_ERRSmokeStep = 9;
SCR_CharacterDamageManagerComponent damage = SCR_CharacterDamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(SCR_CharacterDamageManagerComponent));
damage.EnableDamageHandling(true);
damage.Kill(Instigator.CreateInstigator(m_ERRSmokePlayer));
m_ERRSmokeWait = now + 4000;
}
else if (m_ERRSmokeStep == 110)
{
ERR_HQ hq = ERR_HQ.Cast(Command());
if (!hq || !hq.ERR_ProbeSquadsReady()) return;
ERR_MovePlayer(hq.ERR_ProbeResponseOrigin());
m_ERRSmokeStep = 111;
m_ERRSmokeWait = now + 1000;
}
else if (m_ERRSmokeStep == 111)
{
ERR_HQ hq = ERR_HQ.Cast(Command());
if (now >= m_ERRNextProbeLog)
{
Print("ERR HQ PROBE: " + hq.ERR_ProbePerception());
m_ERRNextProbeLog = now + 10000;
}
if (!hq.ERR_ProbeDeliveredResponse()) return;
if (!ERR_Check(true, "native visual contact reaches HQ and orders a different existing squad")) return;
if (!ERR_Check(hq.ERR_ProbeUniqueAssignments(), "HQ uses distinct waypoints within the existing force and order limits")) return;
m_ERRSmokeStep = 9;
SCR_CharacterDamageManagerComponent damage = SCR_CharacterDamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(SCR_CharacterDamageManagerComponent));
damage.EnableDamageHandling(true);
damage.Kill(Instigator.CreateInstigator(m_ERRSmokePlayer));
m_ERRSmokeWait = now + 4000;
}
else if (m_ERRSmokeStep == 100)
{
int result = m_ERRRadioProbe.Tick(ERR_HQ.Cast(Command()), now);
if (result == 0) return;
if (!ERR_Check(result == 1, "native radio delivery and interruption sequence")) return;
m_ERRSmokeStep = 9;
SCR_CharacterDamageManagerComponent damage = SCR_CharacterDamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(SCR_CharacterDamageManagerComponent));
damage.EnableDamageHandling(true);
damage.Kill(Instigator.CreateInstigator(m_ERRSmokePlayer));
m_ERRSmokeWait = now + 4000;
}
else if (m_ERRSmokeStep == 9)
{
SCR_PlayerController controller = SCR_PlayerController.Cast(GetGame().GetPlayerController());
if (!ERR_Check(!ERR_Actors.Alive(m_ERRSmokePlayer), "native damage kills prisoner")) return;
if (!ERR_Check(controller && controller.ERR_ObserverState() == ERR_ObserverReason.SPENT_LIFE, "death selects spectator without another life")) return;
if (!ERR_Check(controller.ERR_HasObserverCamera() && SCR_ManualCamera.Cast(GetGame().GetCameraManager().CurrentCamera()), "spectator camera activates after native death")) return;
m_ERRSmokeStep = 91;
}
else if (m_ERRSmokeStep == 7)
{
if (!ERR_Check(CompartmentAccessComponent.GetVehicleIn(m_ERRSmokePlayer) == ExtractionVehicle(), "physical extraction occupancy")) return;
// Controlled transport tests the boundary detector, not piloting skill.
ExtractionVehicle().SetOrigin(m_EscapeCenter + Vector(m_EscapeRadius + 100, 300, 0));
m_ERRSmokeWait = now + 5000;
}
}
void ~ERR_GameMode()
{
if (GetGame())
{
GetGame().GetCallqueue().Remove(ERR_SmokeTick);
GetGame().GetCallqueue().Remove(ERR_PrisonScreenshot);
GetGame().GetCallqueue().Remove(ERR_EndScreenshot);
}
}
}
#endif
@@ -0,0 +1,16 @@
#ifndef WORKBENCH
modded class ArmaReforgerScripted
{
override protected ResourceName ERR_DiagnosticHeader(string project)
{
if (project == "chat") return "{C1E20667DCE324ED}Missions/ERR_Everon.conf";
return super.ERR_DiagnosticHeader(project);
}
override protected string ERR_DiagnosticAddon(string project)
{
if (project == "chat") return "FA804F411BDDF2C6";
return super.ERR_DiagnosticAddon(project);
}
}
#endif
@@ -0,0 +1,51 @@
[WorkbenchPluginAttribute(name: "Validate Rereintroduced scenario", wbModules: {"WorldEditor"})]
class ERR_ValidateWorldPlugin : WorldEditorPlugin
{
protected bool m_Obstructed;
protected bool CheckClearance(IEntity entity)
{
if (entity && entity.GetVObject()) m_Obstructed = true;
return !m_Obstructed;
}
override void Run() { Validate(); }
override void RunCommandline() { Validate(); }
protected void Validate()
{
WorldEditor editor = Workbench.GetModule(WorldEditor);
if (!editor) { Print("ERR VALIDATION: World Editor missing", LogLevel.ERROR); return; }
WorldEditorAPI api = editor.GetApi();
if (!api) { Print("ERR VALIDATION: world API missing", LogLevel.ERROR); return; }
PrintFormat("ERR VALIDATION: prison terrain=%1, radio terrain=%2, extraction terrain=%3", api.GetTerrainSurfaceY(6090,7160), api.GetTerrainSurfaceY(6500,7200), api.GetTerrainSurfaceY(7000,7500));
for (int dx = -6; dx <= 6; dx += 3)
for (int dz = -6; dz <= 6; dz += 3)
PrintFormat("ERR TERRAIN: x=%1 z=%2 y=%3", 6090 + dx, 7160 + dz, api.GetTerrainSurfaceY(6090 + dx, 7160 + dz));
float bestSlope = 1000;
vector bestPosition;
for (int x = 5800; x <= 6200; x += 10)
{
for (int z = 6800; z <= 7200; z += 10)
{
float low = 10000;
float high = -10000;
for (int sx = -9; sx <= 9; sx += 3)
for (int sz = -15; sz <= 9; sz += 3)
{
float height = api.GetTerrainSurfaceY(x + sx, z + sz);
low = Math.Min(low, height);
high = Math.Max(high, height);
}
if (low > 5 && high - low < bestSlope)
{
m_Obstructed = false;
api.GetWorld().QueryEntitiesByAABB(Vector(x - 10, low + 0.1, z - 16), Vector(x + 10, high + 5, z + 10), CheckClearance);
if (m_Obstructed) continue;
bestSlope = high - low;
bestPosition = Vector(x, api.GetTerrainSurfaceY(x, z), z);
}
}
}
PrintFormat("ERR SITE CANDIDATE: position=%1 elevationRange=%2", bestPosition, bestSlope);
string play;
if (System.GetCLIParam("errPlay", play) && play == "1") editor.SwitchToGameMode();
}
}
@@ -0,0 +1,12 @@
GameProject {
ID "ERR_Chat"
GUID "FA804F411BDDF2C6"
TITLE "Escapists Rereintroduced - Chat"
Dependencies {
"58D0FB3206B6F859"
"2528466DE220D91C"
"5192138CB9D5B911"
"D31039C7C53E348A"
"9AAEE9041D79809E"
}
}
@@ -0,0 +1,136 @@
ERR_ScenarioDefinition {
MinimumRadioSources 2
Sites {
ERR_SiteDefinition {
Id "everon-prison-1"
Label "Prison"
Kind 0
Prefab "{BE6B8D56349038A6}Prefabs/ERR/Prison.et"
Position 6090 0 7160
Guarded 1
GuardOffset 35 0 0
Container "{40986810D0B1F4AE}Prefabs/ERR/SupplyCache.et"
ContainerOffset -4 0 0
Stock {
ERR_SiteStock { Prefab "{C0F7DD85A86B2900}Prefabs/Weapons/Handguns/PM/Handgun_PM.et" Count 5 }
ERR_SiteStock { Prefab "{8B853CDD11BA916E}Prefabs/Weapons/Magazines/Magazine_9x18_PM_8rnd_Ball.et" Count 8 }
ERR_SiteStock { Prefab "{13772C903CB5E4F7}Prefabs/Items/Equipment/Maps/Map_Paper_01/PaperMap_01_folded.et" Count 1 }
}
}
ERR_SiteDefinition {
Id "everon-supply-1"
Label "Southern supply cache"
Kind 4
Prefab "{7C3D16C17C24D351}Prefabs/ERR/SupplySite.et"
Position 6150 0 7050
Guarded 1
GuardOffset 18 0 0
Container "{40986810D0B1F4AE}Prefabs/ERR/SupplyCache.et"
ContainerOffset 0 0 0
Stock {
ERR_SiteStock { Prefab "{FA5C25BF66A53DCF}Prefabs/Weapons/Rifles/AK74/Rifle_AK74.et" Count 8 }
ERR_SiteStock { Prefab "{BBB50A815A2F916B}Prefabs/Weapons/Magazines/Magazine_545x39_AK_30rnd_Ball.et" Count 16 }
ERR_SiteStock { Prefab "{C3F1FA1E2EC2B345}Prefabs/Items/Medicine/FieldDressing_01/FieldDressing_USSR_01.et" Count 12 }
ERR_SiteStock { Prefab "{554159A6740C3F3E}Prefabs/ERR/ObjectiveDocument.et" Count 2 TargetId "everon-radio-1" }
}
RevealOnEscape 1
}
ERR_SiteDefinition {
Id "everon-radio-1"
Label "Radio station"
DiscoverRadius 8
Kind 1
Prefab "{F7E7E3D6ACF0C860}Prefabs/ERR/Radio.et"
Position 6500 0 7200
Guarded 1
GuardOffset 30 0 0
}
ERR_SiteDefinition {
Id "everon-extraction-1"
Label "Initial helicopter pickup site"
Kind 2
Prefab "{033503110AC34EAC}Prefabs/ERR/Extraction.et"
Position 7000 0 7500
Guarded 1
GuardOffset 30 0 0
}
ERR_SiteDefinition {
Id "everon-supply-2"
Label "Western supply cache"
Kind 4
Prefab "{7C3D16C17C24D351}Prefabs/ERR/SupplySite.et"
Position 5960 0 7220
Guarded 1
GuardOffset 16 0 0
Patrol {
ERR_SitePatrolPoint { Offset 18 0 0 }
ERR_SitePatrolPoint { Offset 18 0 24 }
ERR_SitePatrolPoint { Offset -6 0 24 }
ERR_SitePatrolPoint { Offset -6 0 0 }
}
Container "{40986810D0B1F4AE}Prefabs/ERR/SupplyCache.et"
DiscoverRadius 25
RevealOnEscape 1
Transport ERR_SiteTransport {
Prefab "{259EE7B78C51B624}Prefabs/Vehicles/Wheeled/UAZ469/UAZ469.et"
Offset 0 0 -8
Heading 180
ClearanceRadius 4
MaximumTerrainRange 1
}
Stock {
ERR_SiteStock { Prefab "{FA5C25BF66A53DCF}Prefabs/Weapons/Rifles/AK74/Rifle_AK74.et" Count 4 }
ERR_SiteStock { Prefab "{BBB50A815A2F916B}Prefabs/Weapons/Magazines/Magazine_545x39_AK_30rnd_Ball.et" Count 8 }
ERR_SiteStock { Prefab "{C3F1FA1E2EC2B345}Prefabs/Items/Medicine/FieldDressing_01/FieldDressing_USSR_01.et" Count 6 }
ERR_SiteStock { Prefab "{554159A6740C3F3E}Prefabs/ERR/ObjectiveDocument.et" Count 2 TargetId "everon-radio-1" }
}
}
ERR_SiteDefinition {
Id "everon-medical-1"
Label "Medical stash"
Kind 4
Prefab "{7C3D16C17C24D351}Prefabs/ERR/SupplySite.et"
Position 6340 0 7400
Guarded 0
GuardOffset 16 0 0
Container "{40986810D0B1F4AE}Prefabs/ERR/SupplyCache.et"
DiscoverRadius 25
RevealOnEscape 0
Stock {
ERR_SiteStock { Prefab "{C3F1FA1E2EC2B345}Prefabs/Items/Medicine/FieldDressing_01/FieldDressing_USSR_01.et" Count 12 }
ERR_SiteStock { Prefab "{527D7C5D2E476BDC}Prefabs/Items/Medicine/SalineBag_01/SalineBag_USSR_01.et" Count 6 }
ERR_SiteStock { Prefab "{0D9A5DCF89AE7AA9}Prefabs/Items/Medicine/MorphineInjection_01/MorphineInjection_01.et" Count 6 }
ERR_SiteStock { Prefab "{13772C903CB5E4F7}Prefabs/Items/Equipment/Maps/Map_Paper_01/PaperMap_01_folded.et" Count 3 }
}
}
ERR_SiteDefinition {
Id "everon-outpost-1"
Label "Eastern guard outpost"
Kind 3
Prefab "{7C3D16C17C24D351}Prefabs/ERR/SupplySite.et"
Position 6740 0 7300
Guarded 1
GuardOffset 16 0 0
Patrol {
ERR_SitePatrolPoint { Offset 18 0 0 }
ERR_SitePatrolPoint { Offset 18 0 24 }
ERR_SitePatrolPoint { Offset -6 0 24 }
ERR_SitePatrolPoint { Offset -6 0 0 }
}
Container "{40986810D0B1F4AE}Prefabs/ERR/SupplyCache.et"
DiscoverRadius 35
RevealOnEscape 0
Stock {
ERR_SiteStock { Prefab "{FA5C25BF66A53DCF}Prefabs/Weapons/Rifles/AK74/Rifle_AK74.et" Count 2 }
ERR_SiteStock { Prefab "{BBB50A815A2F916B}Prefabs/Weapons/Magazines/Magazine_545x39_AK_30rnd_Ball.et" Count 10 }
ERR_SiteStock { Prefab "{243948B23D90BECB}Prefabs/Items/Equipment/Binoculars/Binoculars_B8/Binoculars_B8.et" Count 2 }
ERR_SiteStock { Prefab "{C3F1FA1E2EC2B345}Prefabs/Items/Medicine/FieldDressing_01/FieldDressing_USSR_01.et" Count 4 }
}
Props {
ERR_SiteProp { Prefab "{4B6AC1D8701C35A1}Prefabs/ERR/FieldCover.et" Offset 0 0 -4 }
ERR_SiteProp { Prefab "{4B6AC1D8701C35A1}Prefabs/ERR/FieldCover.et" Offset -4 0 0 Angles 90 0 0 }
ERR_SiteProp { Prefab "{4B6AC1D8701C35A1}Prefabs/ERR/FieldCover.et" Offset 4 0 0 Angles 90 0 0 }
}
}
}
}
@@ -0,0 +1,9 @@
MetaFileClass {
Name "{BC310DC0CD27F523}Configs/ERR/EveronSites.conf"
Configurations {
ResourceClass PC {
}
ResourceClass HEADLESS : PC {
}
}
}
@@ -0,0 +1,24 @@
SCR_EntityCatalogMultiList {
m_eEntityCatalogType VEHICLE
m_aMultiLists {
SCR_EntityCatalogMultiListEntry {
m_sIdentifier "Mission transport"
m_aEntities {
SCR_EntityCatalogEntry {
m_sEntityPrefab "{259EE7B78C51B624}Prefabs/Vehicles/Wheeled/UAZ469/UAZ469.et"
m_aEntityDataList {
SCR_EntityCatalogEditorData { m_eValidEditorModes 33 }
SCR_EntityCatalogSpawnerData { m_eSlotTypes 24 }
}
}
SCR_EntityCatalogEntry {
m_sEntityPrefab "{DF5CCB7C0FF049F4}Prefabs/Vehicles/Helicopters/Mi8MT/Mi8MT_unarmed_transport.et"
m_aEntityDataList {
SCR_EntityCatalogEditorData { m_eValidEditorModes 33 }
SCR_EntityCatalogSpawnerData { m_eSlotTypes VEHICLE_LARGE }
}
}
}
}
}
}
@@ -0,0 +1,7 @@
MetaFileClass {
Name "{E4785D3AF1D043C2}Configs/ERR/Factions/MissionVehicles.conf"
Configurations {
ResourceClass PC {}
ResourceClass HEADLESS : PC {}
}
}
@@ -0,0 +1,277 @@
SCR_Faction : "{E7B7EA4823DD81F0}Configs/Factions/BLUFOR.conf" {
FactionKey "US"
UIInfo SCR_FactionUIInfo "{528C961236B7DCD3}" {
Name "#AR-Faction_US"
Icon "{EB7F65DBC9392557}UI/Textures/Editor/EditableEntities/Factions/EditableEntity_Faction_USA.edds"
m_sNameUpper "#AR-Faction_US-UC"
}
"Identity of soldiers" FactionIdentity "{570D128F4022EF5A}" : "{B600946E9ACC17C2}Configs/Identities/FactionIdentity_US.conf" {
}
"Radio encryption key" "chickenNuggets"
m_sFactionFlag "{46FB2FB2C2125A3C}UI/Textures/Flags/US-flag-base-3it.edds"
m_FactionFlagMaterial "{610803CC3F3D6649}Assets/Props/Fabric/Flags/Data/Flag_1_2_USA.emat"
m_FactionLabel FACTION_US
m_CallsignInfo SCR_FactionCallsignInfo "{5DA0F2A6677ADA9E}" : "{CB7824D572DD0D5C}Configs/Callsigns/Callsigns_US.conf" {
}
m_iFactionRadioFrequency 48000
m_aEntityCatalogs {
SCR_EntityCatalogMultiList "{5C68A0EE815FA292}" : "{B56E8B4D4B195559}Configs/EntityCatalog/US/Characters_EntityCatalog_US.conf" {
}
SCR_EntityCatalogMultiList "{5C9E82F29B327997}" : "{E4785D3AF1D043C2}Configs/ERR/Factions/MissionVehicles.conf" {
}
SCR_EntityCatalogMultiList "{5C68A0EE8B97CA50}" : "{4E70E7C4C2C17D4A}Configs/EntityCatalog/US/Groups_EntityCatalog_US.conf" {
}
SCR_EntityCatalog "{5C68A0EEB7DB3E84}" : "{0E4B62F186F97C43}Configs/EntityCatalog/US/WeaponTripod_EntityCatalog_US.conf" {
}
SCR_EntityCatalogMultiList "{5C68A0EEB3F124F9}" : "{5F7EC52FC40A03E2}Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf" {
}
SCR_EntityCatalog "{5C9EDDD37394AD40}" : "{0BF36EFF9FFAF92B}Configs/EntityCatalog/US/SupplyContainerItems_EntityCatalog_US.conf" {
}
}
m_aFlagNames +{
}
m_aBaseCallsigns {
SCR_MilitaryBaseCallsign "{5C90D92F493E764B}" {
m_sCallsign "#AR-Campaign_PointAlabama"
m_sCallsignShort "#AR-Comm_Variable_Base_Alabama_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Alabama_US_UC"
m_iSignalIndex 0
}
SCR_MilitaryBaseCallsign "{5C90D92F49F79967}" {
m_sCallsign "#AR-Campaign_PointAlaska"
m_sCallsignShort "#AR-Comm_Variable_Base_Alaska_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Alaska_US_UC"
m_iSignalIndex 1
}
SCR_MilitaryBaseCallsign "{5C90D92F482DA59B}" {
m_sCallsign "#AR-Campaign_PointArizona"
m_sCallsignShort "#AR-Comm_Variable_Base_Arizona_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Arizona_US_UC"
m_iSignalIndex 2
}
SCR_MilitaryBaseCallsign "{5C90D92F483330D2}" {
m_sCallsign "#AR-Campaign_PointArkansas"
m_sCallsignShort "#AR-Comm_Variable_Base_Arkansas_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Arkansas_US_UC"
m_iSignalIndex 3
}
SCR_MilitaryBaseCallsign "{5C90D92F48170DA8}" {
m_sCallsign "#AR-Campaign_PointCalifornia"
m_sCallsignShort "#AR-Comm_Variable_Base_California_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_California_US_UC"
m_iSignalIndex 4
}
SCR_MilitaryBaseCallsign "{5C90D92F487834E8}" {
m_sCallsign "#AR-Campaign_PointColorado"
m_sCallsignShort "#AR-Comm_Variable_Base_Colorado_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Colorado_US_UC"
m_iSignalIndex 5
}
SCR_MilitaryBaseCallsign "{5C90D92F48410A86}" {
m_sCallsign "#AR-Campaign_PointConnecticut"
m_sCallsignShort "#AR-Comm_Variable_Base_Connecticut_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Connecticut_US_UC"
m_iSignalIndex 6
}
SCR_MilitaryBaseCallsign "{5C90D92F48A4E31F}" {
m_sCallsign "#AR-Campaign_PointDelaware"
m_sCallsignShort "#AR-Comm_Variable_Base_Delaware_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Delaware_US_UC"
m_iSignalIndex 7
}
SCR_MilitaryBaseCallsign "{5C90D92F488C6B57}" {
m_sCallsign "#AR-Campaign_PointFlorida"
m_sCallsignShort "#AR-Comm_Variable_Base_Florida_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Florida_US_UC"
m_iSignalIndex 8
}
SCR_MilitaryBaseCallsign "{5C90D92F4896F764}" {
m_sCallsign "#AR-Campaign_PointGeorgia"
m_sCallsignShort "#AR-Comm_Variable_Base_Georgia_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Georgia_US_UC"
m_iSignalIndex 9
}
SCR_MilitaryBaseCallsign "{5C90D92F48FBD90E}" {
m_sCallsign "#AR-Campaign_PointHawaii"
m_sCallsignShort "#AR-Comm_Variable_Base_Hawaii_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Hawaii_US_UC"
m_iSignalIndex 10
}
SCR_MilitaryBaseCallsign "{5C90D92F48DFF562}" {
m_sCallsign "#AR-Campaign_PointIdaho"
m_sCallsignShort "#AR-Comm_Variable_Base_Idaho_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Idaho_US_UC"
m_iSignalIndex 11
}
SCR_MilitaryBaseCallsign "{5C90D92F7724C851}" {
m_sCallsign "#AR-Campaign_PointIllinois"
m_sCallsignShort "#AR-Comm_Variable_Base_Illinois_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Illinois_US_UC"
m_iSignalIndex 12
}
SCR_MilitaryBaseCallsign "{5C90D92F77097F3F}" {
m_sCallsign "#AR-Campaign_PointIndiana"
m_sCallsignShort "#AR-Comm_Variable_Base_Indiana_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Indiana_US_UC"
m_iSignalIndex 13
}
SCR_MilitaryBaseCallsign "{5C90D92F77102B55}" {
m_sCallsign "#AR-Campaign_PointIowa"
m_sCallsignShort "#AR-Comm_Variable_Base_Iowa_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Iowa_US_UC"
m_iSignalIndex 14
}
SCR_MilitaryBaseCallsign "{5C90D92F777ABD04}" {
m_sCallsign "#AR-Campaign_PointKansas"
m_sCallsignShort "#AR-Comm_Variable_Base_Kansas_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Kansas_US_UC"
m_iSignalIndex 15
}
SCR_MilitaryBaseCallsign "{5C90D92F775EBBC1}" {
m_sCallsign "#AR-Campaign_PointKentucky"
m_sCallsignShort "#AR-Comm_Variable_Base_Kentucky_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Kentucky_US_UC"
m_iSignalIndex 16
}
SCR_MilitaryBaseCallsign "{5C90D92F77A28EB6}" {
m_sCallsign "#AR-Campaign_PointLouisiana"
m_sCallsignShort "#AR-Comm_Variable_Base_Louisiana_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Louisiana_US_UC"
m_iSignalIndex 17
}
SCR_MilitaryBaseCallsign "{5C90D92F77871C23}" {
m_sCallsign "#AR-Campaign_PointMaine"
m_sCallsignShort "#AR-Comm_Variable_Base_Maine_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Maine_US_UC"
m_iSignalIndex 18
}
SCR_MilitaryBaseCallsign "{5C90D92F77EB96A0}" {
m_sCallsign "#AR-Campaign_PointMaryland"
m_sCallsignShort "#AR-Comm_Variable_Base_Maryland_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Maryland_US_UC"
m_iSignalIndex 19
}
SCR_MilitaryBaseCallsign "{5C90D92F77CC2518}" {
m_sCallsign "#AR-Campaign_PointMassachusetts"
m_sCallsignShort "#AR-Comm_Variable_Base_Massachusetts_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Massachusetts_US_UC"
m_iSignalIndex 20
}
SCR_MilitaryBaseCallsign "{5C90D92F77D3715B}" {
m_sCallsign "#AR-Campaign_PointMichigan"
m_sCallsignShort "#AR-Comm_Variable_Base_Michigan_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Michigan_US_UC"
m_iSignalIndex 21
}
SCR_MilitaryBaseCallsign "{5C90D92F7635D418}" {
m_sCallsign "#AR-Campaign_PointMinnesota"
m_sCallsignShort "#AR-Comm_Variable_Base_Minnesota_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Minnesota_US_UC"
m_iSignalIndex 22
}
SCR_MilitaryBaseCallsign "{5C90D92F761C3FF2}" {
m_sCallsign "#AR-Campaign_PointMississippi"
m_sCallsignShort "#AR-Comm_Variable_Base_Mississippi_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Mississippi_US_UC"
m_iSignalIndex 23
}
SCR_MilitaryBaseCallsign "{5C90D92F7660CFAA}" {
m_sCallsign "#AR-Campaign_PointMissouri"
m_sCallsignShort "#AR-Comm_Variable_Base_Missouri_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Missouri_US_UC"
m_iSignalIndex 24
}
SCR_MilitaryBaseCallsign "{5C90D92F764A6E6B}" {
m_sCallsign "#AR-Campaign_PointMontana"
m_sCallsignShort "#AR-Comm_Variable_Base_Montana_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Montana_US_UC"
m_iSignalIndex 25
}
SCR_MilitaryBaseCallsign "{5C90D92F76AD4D35}" {
m_sCallsign "#AR-Campaign_PointNebraska"
m_sCallsignShort "#AR-Comm_Variable_Base_Nebraska_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Nebraska_US_UC"
m_iSignalIndex 26
}
SCR_MilitaryBaseCallsign "{5C90D92F76B1EF3A}" {
m_sCallsign "#AR-Campaign_PointNevada"
m_sCallsignShort "#AR-Comm_Variable_Base_Nevada_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Nevada_US_UC"
m_iSignalIndex 27
}
SCR_MilitaryBaseCallsign "{5C90D92F7695FF2F}" {
m_sCallsign "#AR-Campaign_PointNewYork"
m_sCallsignShort "#AR-Comm_Variable_Base_NewYork_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_NewYork_US_UC"
m_iSignalIndex 28
}
SCR_MilitaryBaseCallsign "{5C90D92F76FF94B1}" {
m_sCallsign "#AR-Campaign_PointOhio"
m_sCallsignShort "#AR-Comm_Variable_Base_Ohio_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Ohio_US_UC"
m_iSignalIndex 29
}
SCR_MilitaryBaseCallsign "{5C90D92F76C68EED}" {
m_sCallsign "#AR-Campaign_PointOklahoma"
m_sCallsignShort "#AR-Comm_Variable_Base_Oklahoma_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Oklahoma_US_UC"
m_iSignalIndex 30
}
SCR_MilitaryBaseCallsign "{5C90D92F752A9F29}" {
m_sCallsign "#AR-Campaign_PointOregon"
m_sCallsignShort "#AR-Comm_Variable_Base_Oregon_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Oregon_US_UC"
m_iSignalIndex 31
}
SCR_MilitaryBaseCallsign "{5C90D92F750E6FB9}" {
m_sCallsign "#AR-Campaign_PointPennsylvania"
m_sCallsignShort "#AR-Comm_Variable_Base_Pennsylvania_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Pennsylvania_US_UC"
m_iSignalIndex 32
}
SCR_MilitaryBaseCallsign "{5C90D92F7517240F}" {
m_sCallsign "#AR-Campaign_PointTexas"
m_sCallsignShort "#AR-Comm_Variable_Base_Texas_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Texas_US_UC"
m_iSignalIndex 33
}
SCR_MilitaryBaseCallsign "{5C90D92F7574D867}" {
m_sCallsign "#AR-Campaign_PointUtah"
m_sCallsignShort "#AR-Comm_Variable_Base_Utah_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Utah_US_UC"
m_iSignalIndex 34
}
SCR_MilitaryBaseCallsign "{5C90D92F755C4871}" {
m_sCallsign "#AR-Campaign_PointVermont"
m_sCallsignShort "#AR-Comm_Variable_Base_Vermont_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Vermont_US_UC"
m_iSignalIndex 35
}
SCR_MilitaryBaseCallsign "{5C90D92F75A0502B}" {
m_sCallsign "#AR-Campaign_PointVirginia"
m_sCallsignShort "#AR-Comm_Variable_Base_Virginia_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Virginia_US_UC"
m_iSignalIndex 36
}
SCR_MilitaryBaseCallsign "{5C90D92F758ABFD3}" {
m_sCallsign "#AR-Campaign_PointWashington"
m_sCallsignShort "#AR-Comm_Variable_Base_Washington_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Washington_US_UC"
m_iSignalIndex 37
}
SCR_MilitaryBaseCallsign "{5C90D92F75EF8263}" {
m_sCallsign "#AR-Campaign_PointWisconsin"
m_sCallsignShort "#AR-Comm_Variable_Base_Wisconsin_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Wisconsin_US_UC"
m_iSignalIndex 38
}
SCR_MilitaryBaseCallsign "{5C90D92F75F0F224}" {
m_sCallsign "#AR-Campaign_PointWyoming"
m_sCallsignShort "#AR-Comm_Variable_Base_Wyoming_US"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Wyoming_US_UC"
m_iSignalIndex 39
}
}
m_FactionHomeTerritoryConfig SCR_FactionHomeTerritoryConfig "{5AEE94D54FB58C33}" : "{B548A5B264939A98}Configs/Identities/Territories/FactionHomeTerritory_US.conf" {
}
}
@@ -0,0 +1,7 @@
MetaFileClass {
Name "{5C67A1DDE0044806}Configs/ERR/Factions/US.conf"
Configurations {
ResourceClass PC {}
ResourceClass HEADLESS : PC {}
}
}
@@ -0,0 +1,276 @@
SCR_Faction : "{B122E3B10BB3404B}Configs/Factions/OPFOR.conf" {
FactionKey "USSR"
UIInfo SCR_FactionUIInfo "{528C96127F8B6B08}" {
Name "#AR-Faction_USSR"
Icon "{40B12B0DF911B856}UI/Textures/Editor/EditableEntities/Factions/EditableEntity_Faction_USSR.edds"
m_sNameUpper "#AR-Faction_USSR-UC"
}
"Identity of soldiers" FactionIdentity "{570CFDC6685B6B25}" : "{FBBCD73926989580}Configs/Identities/FactionIdentity_USSR.conf" {
}
"Radio encryption key" "coldBorscht"
m_sFactionFlag "{50824EB9F2C215AB}UI/Textures/Flags/USSR-flag-base-3it.edds"
m_FactionFlagMaterial "{B47B52D9DA68905D}Assets/Props/Fabric/Flags/Data/Flag_1_2_SovietArmy.emat"
m_FactionLabel FACTION_USSR
m_CallsignInfo SCR_FactionCallsignInfo "{5DA0F2A67DFB8809}" : "{958043CE1648EC43}Configs/Callsigns/Callsigns_USSR.conf" {
}
m_iFactionRadioFrequency 42000
m_aEntityCatalogs {
SCR_EntityCatalogMultiList "{5C68A0E9BD5E5DD9}" : "{3B679F1799D55F6F}Configs/EntityCatalog/USSR/Characters_EntityCatalog_USSR.conf" {
}
SCR_EntityCatalogMultiList "{5C9E82F285C09E24}" : "{E4785D3AF1D043C2}Configs/ERR/Factions/MissionVehicles.conf" {
}
SCR_EntityCatalogMultiList "{5C68A0E9B9AA3C2D}" : "{37D5B75AAC3E72EA}Configs/EntityCatalog/USSR/Groups_EntityCatalog_USSR.conf" {
}
SCR_EntityCatalog "{5C68A0E9A51460AB}" : "{DDF17C8C140BD1F2}Configs/EntityCatalog/USSR/WeaponTripod_EntityCatalog_USSR.conf" {
}
SCR_EntityCatalogMultiList "{5C68A0E9AFE1E631}" : "{C53421647C3D0D2E}Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf" {
}
SCR_EntityCatalog "{5C9EDDD378BA3298}" : "{B4CA6761AC935808}Configs/EntityCatalog/USSR/SupplyContainerItems_EntityCatalog_USSR.conf" {
}
}
m_iIdentityVoiceSignal 100
m_aBaseCallsigns {
SCR_MilitaryBaseCallsign "{5C9108F95F3FB520}" {
m_sCallsign "#AR-Campaign_PointArena"
m_sCallsignShort "#AR-Comm_Variable_Base_Arena_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Arena_RU_UC"
m_iSignalIndex 0
}
SCR_MilitaryBaseCallsign "{5C9108F95F0034DB}" {
m_sCallsign "#AR-Campaign_PointAvrora"
m_sCallsignShort "#AR-Comm_Variable_Base_Avrora_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Avrora_RU_UC"
m_iSignalIndex 1
}
SCR_MilitaryBaseCallsign "{5C9108F95F6514E7}" {
m_sCallsign "#AR-Campaign_PointBekas"
m_sCallsignShort "#AR-Comm_Variable_Base_Bekas_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Bekas_RU_UC"
m_iSignalIndex 2
}
SCR_MilitaryBaseCallsign "{5C9108F95F4EE8BF}" {
m_sCallsign "#AR-Campaign_PointBizon"
m_sCallsignShort "#AR-Comm_Variable_Base_Bizon_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Bizon_RU_UC"
m_iSignalIndex 3
}
SCR_MilitaryBaseCallsign "{5C9108F95F5021F9}" {
m_sCallsign "#AR-Campaign_PointBolero"
m_sCallsignShort "#AR-Comm_Variable_Base_Bolero_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Bolero_RU_UC"
m_iSignalIndex 4
}
SCR_MilitaryBaseCallsign "{5C9108F95FBA4C89}" {
m_sCallsign "#AR-Campaign_PointCafftan"
m_sCallsignShort "#AR-Comm_Variable_Base_Cafftan_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Cafftan_RU_UC"
m_iSignalIndex 5
}
SCR_MilitaryBaseCallsign "{5C9108F95F9C00A9}" {
m_sCallsign "#AR-Campaign_PointKaban"
m_sCallsignShort "#AR-Comm_Variable_Base_Kaban_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Kaban_RU_UC"
m_iSignalIndex 6
}
SCR_MilitaryBaseCallsign "{5C9108F95FE17E10}" {
m_sCallsign "#AR-Campaign_PointConsul"
m_sCallsignShort "#AR-Comm_Variable_Base_Consul_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Consul_RU_UC"
m_iSignalIndex 7
}
SCR_MilitaryBaseCallsign "{5C9108F95FCBA475}" {
m_sCallsign "#AR-Campaign_PointDimok"
m_sCallsignShort "#AR-Comm_Variable_Base_Dimok_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Dimok_RU_UC"
m_iSignalIndex 8
}
SCR_MilitaryBaseCallsign "{5C9108F95E2B2963}" {
m_sCallsign "#AR-Campaign_PointEffir"
m_sCallsignShort "#AR-Comm_Variable_Base_Effir_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Effir_RU_UC"
m_iSignalIndex 9
}
SCR_MilitaryBaseCallsign "{5C9108F95E3040F5}" {
m_sCallsign "#AR-Campaign_PointFakir"
m_sCallsignShort "#AR-Comm_Variable_Base_Fakir_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Fakir_RU_UC"
m_iSignalIndex 10
}
SCR_MilitaryBaseCallsign "{5C9108F95E17C67D}" {
m_sCallsign "#AR-Campaign_PointGips"
m_sCallsignShort "#AR-Comm_Variable_Base_Gips_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Gips_RU_UC"
m_iSignalIndex 11
}
SCR_MilitaryBaseCallsign "{5C9108F95E797F8A}" {
m_sCallsign "#AR-Campaign_PointGussar"
m_sCallsignShort "#AR-Comm_Variable_Base_Gussar_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Gussar_RU_UC"
m_iSignalIndex 12
}
SCR_MilitaryBaseCallsign "{5C9108F95E431F83}" {
m_sCallsign "#AR-Campaign_PointIgla"
m_sCallsignShort "#AR-Comm_Variable_Base_Igla_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Igla_RU_UC"
m_iSignalIndex 13
}
SCR_MilitaryBaseCallsign "{5C9108F95EA7F87E}" {
m_sCallsign "#AR-Campaign_PointKhek"
m_sCallsignShort "#AR-Comm_Variable_Base_Khek_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Khek_RU_UC"
m_iSignalIndex 14
}
SCR_MilitaryBaseCallsign "{5C9108F95E88C6B9}" {
m_sCallsign "#AR-Campaign_PointLednik"
m_sCallsignShort "#AR-Comm_Variable_Base_Lednik_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Lednik_RU_UC"
m_iSignalIndex 15
}
SCR_MilitaryBaseCallsign "{5C9108F95EEDE322}" {
m_sCallsign "#AR-Campaign_PointMatros"
m_sCallsignShort "#AR-Comm_Variable_Base_Matros_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Matros_RU_UC"
m_iSignalIndex 16
}
SCR_MilitaryBaseCallsign "{5C9108F95EF6244A}" {
m_sCallsign "#AR-Campaign_PointMuskat"
m_sCallsignShort "#AR-Comm_Variable_Base_Muskat_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Muskat_RU_UC"
m_iSignalIndex 17
}
SCR_MilitaryBaseCallsign "{5C9108F95EDAF04A}" {
m_sCallsign "#AR-Campaign_PointNagan"
m_sCallsignShort "#AR-Comm_Variable_Base_Nagan_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Nagan_RU_UC"
m_iSignalIndex 18
}
SCR_MilitaryBaseCallsign "{5C9108F95D3CCF27}" {
m_sCallsign "#AR-Campaign_PointNitka"
m_sCallsignShort "#AR-Comm_Variable_Base_Nitka_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Nitka_RU_UC"
m_iSignalIndex 19
}
SCR_MilitaryBaseCallsign "{5C9108F95D076483}" {
m_sCallsign "#AR-Campaign_PointOmega"
m_sCallsignShort "#AR-Comm_Variable_Base_Omega_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Omega_RU_UC"
m_iSignalIndex 20
}
SCR_MilitaryBaseCallsign "{5C9108F95D68D0F3}" {
m_sCallsign "#AR-Campaign_PointPlazma"
m_sCallsignShort "#AR-Comm_Variable_Base_Plazma_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Plazma_RU_UC"
m_iSignalIndex 21
}
SCR_MilitaryBaseCallsign "{5C9108F95D4C0F8E}" {
m_sCallsign "#AR-Campaign_PointPolyn"
m_sCallsignShort "#AR-Comm_Variable_Base_Polyn_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Polyn_RU_UC"
m_iSignalIndex 22
}
SCR_MilitaryBaseCallsign "{5C9108F95D56EEEE}" {
m_sCallsign "#AR-Campaign_PointProlog"
m_sCallsignShort "#AR-Comm_Variable_Base_Prolog_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Prolog_RU_UC"
m_iSignalIndex 23
}
SCR_MilitaryBaseCallsign "{5C9108F95DBA92EE}" {
m_sCallsign "#AR-Campaign_PointRabkor"
m_sCallsignShort "#AR-Comm_Variable_Base_Rabkor_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Rabkor_RU_UC"
m_iSignalIndex 24
}
SCR_MilitaryBaseCallsign "{5C9108F95C69680D}" {
m_sCallsign "#AR-Campaign_PointRadon"
m_sCallsignShort "#AR-Comm_Variable_Base_Radon_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Radon_RU_UC"
m_iSignalIndex 25
}
SCR_MilitaryBaseCallsign "{5C9108F95C4FD930}" {
m_sCallsign "#AR-Campaign_PointSadko"
m_sCallsignShort "#AR-Comm_Variable_Base_Sadko_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Sadko_RU_UC"
m_iSignalIndex 26
}
SCR_MilitaryBaseCallsign "{5C9108F95C5255FD}" {
m_sCallsign "#AR-Campaign_PointSekret"
m_sCallsignShort "#AR-Comm_Variable_Base_Sekret_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Sekret_RU_UC"
m_iSignalIndex 27
}
SCR_MilitaryBaseCallsign "{5C9108F95CB621AE}" {
m_sCallsign "#AR-Campaign_PointShtanga"
m_sCallsignShort "#AR-Comm_Variable_Base_Shtanga_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Shtanga_RU_UC"
m_iSignalIndex 28
}
SCR_MilitaryBaseCallsign "{5C9108F95C9545BC}" {
m_sCallsign "#AR-Campaign_PointShuka"
m_sCallsignShort "#AR-Comm_Variable_Base_Shuka_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Shuka_RU_UC"
m_iSignalIndex 29
}
SCR_MilitaryBaseCallsign "{5C9108F95CFE26C3}" {
m_sCallsign "#AR-Campaign_PointTabor"
m_sCallsignShort "#AR-Comm_Variable_Base_Tabor_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Tabor_RU_UC"
m_iSignalIndex 30
}
SCR_MilitaryBaseCallsign "{5C9108F95CDD263C}" {
m_sCallsign "#AR-Campaign_PointTenor"
m_sCallsignShort "#AR-Comm_Variable_Base_Tenor_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Tenor_RU_UC"
m_iSignalIndex 31
}
SCR_MilitaryBaseCallsign "{5C9108F95B27128C}" {
m_sCallsign "#AR-Campaign_PointTsikson"
m_sCallsignShort "#AR-Comm_Variable_Base_Tsikson_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Tsikson_RU_UC"
m_iSignalIndex 32
}
SCR_MilitaryBaseCallsign "{5C9108F95B08D83D}" {
m_sCallsign "#AR-Campaign_PointUlan"
m_sCallsignShort "#AR-Comm_Variable_Base_Ulan_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Ulan_RU_UC"
m_iSignalIndex 33
}
SCR_MilitaryBaseCallsign "{5C9108F95B6D3FC2}" {
m_sCallsign "#AR-Campaign_PointVermout"
m_sCallsignShort "#AR-Comm_Variable_Base_Vermout_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Vermout_RU_UC"
m_iSignalIndex 34
}
SCR_MilitaryBaseCallsign "{5C9108F95B712949}" {
m_sCallsign "#AR-Campaign_PointViympel"
m_sCallsignShort "#AR-Comm_Variable_Base_Viympel_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Viympel_RU_UC"
m_iSignalIndex 35
}
SCR_MilitaryBaseCallsign "{5C9108F95B57D185}" {
m_sCallsign "#AR-Campaign_PointYantar"
m_sCallsignShort "#AR-Comm_Variable_Base_Yantar_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Yantar_RU_UC"
m_iSignalIndex 36
}
SCR_MilitaryBaseCallsign "{5C9108F95BB17114}" {
m_sCallsign "#AR-Campaign_PointYolka"
m_sCallsignShort "#AR-Comm_Variable_Base_Yolka_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Yolka_RU_UC"
m_iSignalIndex 37
}
SCR_MilitaryBaseCallsign "{5C9108F95B97C054}" {
m_sCallsign "#AR-Campaign_PointZheton"
m_sCallsignShort "#AR-Comm_Variable_Base_Zheton_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Zheton_RU_UC"
m_iSignalIndex 38
}
SCR_MilitaryBaseCallsign "{5C9108F95BFC33E5}" {
m_sCallsign "#AR-Campaign_PointZurna"
m_sCallsignShort "#AR-Comm_Variable_Base_Zurna_RU"
m_sCallsignUpperCase "#AR-Comm_Variable_Base_Zurna_RU_UC"
m_iSignalIndex 39
}
}
m_FactionHomeTerritoryConfig SCR_FactionHomeTerritoryConfig "{5AEE94D5517C30BD}" : "{31FC78AF00523A99}Configs/Identities/Territories/FactionHomeTerritory_USSR.conf" {
}
}
@@ -0,0 +1,7 @@
MetaFileClass {
Name "{D7A5CFA62A36480D}Configs/ERR/Factions/USSR.conf"
Configurations {
ResourceClass PC {}
ResourceClass HEADLESS : PC {}
}
}
@@ -0,0 +1,21 @@
SCR_GameOverScreenConfig : "{651583FFFB7FC765}Configs/GameOverScreen/BaseGameOverScreensConfig.conf" {
m_aGameOverScreens {
ERR_EscapeGameOverScreenInfo "{6B193DC8DDC63507}" {
m_GameOverScreenId VICTORY
m_GameOverContentLayout "{C4507D07F3C54831}UI/layouts/HUD/GameOver/EndScreen/EndScreenContent_NoImage.layout"
m_OptionalParams SCR_BaseGameOverScreenInfoOptional "{4984A5C1BFEFC04E}" {
m_sTitle "Escape complete"
m_sAudioOneShot "SOUND_ONVICTORY"
}
}
ERR_FailureGameOverScreenInfo "{E66F29A7A8AD7438}" {
m_GameOverScreenId LOOSE
m_GameOverContentLayout "{C4507D07F3C54831}UI/layouts/HUD/GameOver/EndScreen/EndScreenContent_NoImage.layout"
m_OptionalParams SCR_BaseGameOverScreenInfoOptional "{3DBF0BDE715945FA}" {
m_sTitle "Escape failed"
m_sDebriefing "No surviving prisoners can complete the escape, or the extraction helicopter has been lost."
m_sAudioOneShot "SOUND_ONDEFEAT"
}
}
}
}
@@ -0,0 +1,9 @@
MetaFileClass {
Name "{F6633922A25F9441}Configs/ERR/GameOverScreens.conf"
Configurations {
ResourceClass PC {
}
ResourceClass HEADLESS : PC {
}
}
}
@@ -0,0 +1,7 @@
ERR_FactionCatalog {
PlayerFactionKey "US"
EnemyFactionKey "USSR"
PrisonerPrefab "{3FF693715C9F8928}Prefabs/ERR/Prisoner.et"
GuardGroupPrefab "{D5A4D0D3AE1A3E26}Prefabs/ERR/Patrol.et"
ExtractionPrefab "{DF5CCB7C0FF049F4}Prefabs/Vehicles/Helicopters/Mi8MT/Mi8MT_unarmed_transport.et"
}
@@ -0,0 +1,9 @@
MetaFileClass {
Name "{BE50B97B8E2B36E6}Configs/ERR/VanillaFactions.conf"
Configurations {
ResourceClass PC {
}
ResourceClass HEADLESS : PC {
}
}
}
@@ -0,0 +1,11 @@
SCR_MissionHeader {
World "{B6C516F86302C679}Worlds/ERR_Everon.ent"
SystemsConfig "{C50579A2EC48E8EF}Configs/Systems/MissionSystems.conf"
m_sName "Rereintroduced: Everon Base (development)"
m_sAuthor "Rereintroduced contributors"
m_sDescription "Independent base escape mission using vanilla Reforger. Companion addons optional. Development scenario."
m_sGameMode "Escape"
m_iPlayerCount 12
m_eSaveTypes 0
m_bShowInScenarioMenu 1
}
@@ -0,0 +1,9 @@
MetaFileClass {
Name "{AD62322D5213C440}Missions/ERR_Everon_Base.conf"
Configurations {
ResourceClass PC {
}
ResourceClass HEADLESS : PC {
}
}
}

Some files were not shown because too many files have changed in this diff Show More