Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"status": "working scratch core, measured resource dependency pending; not integrated or native-qualified",
|
||||
"scope": "Default prison or independently authored static crash aftermath; no aircraft control or alternate admission/loadout.",
|
||||
"implementation": [
|
||||
"Once-only server settings choice frozen before first scenario Prepare, replicated int StartMode; invalid choice refuses preparation and later saved edits cannot change this round.",
|
||||
"Guarded PREPARING->RADIO_SEARCH requires frozen crash choice and successful full scenario/extraction/environment readiness. Existing default phase edges retained. Both initial exit paths reset dormant force clocks; production prison AI release/listeners receive actual RADIO_SEARCH.",
|
||||
"Fresh runtime single-start definition becomes owned empty crash site+one static wreck prop, preserving finite container/stock/map/site ID and internal PRISON start-slot role. Removes only start guards/route/responders/old props; no new forces or grants.",
|
||||
"Crash transformation follows WB-only definition overrides. It forces regular generated survey; terrain-independent scheduler already calls same common survey. Both keep full original start/cache square plus padded measured wreck volume, rotated around actual heading.",
|
||||
"Explicit prison escape service mode guard; standard spawn/one-life/reconnect/preload unchanged. Scenario normal catalog/generated allowlist includes crash-start while exact latest patrol-hq helper remains byte-for-byte."
|
||||
],
|
||||
"resource_contract": {
|
||||
"owner": "convoy_supply_pool",
|
||||
"class": "ERR_CrashSiteResources",
|
||||
"methods": [
|
||||
"SitePrefab()",
|
||||
"WreckPrefab()",
|
||||
"Bounds(out vector minimum,out vector maximum)"
|
||||
],
|
||||
"measurement": "No guessed constants. Current resource draft Bounds returns false until root measured exact native replicated wrapper. Core Configure and survey fail closed if false.",
|
||||
"geometry": "Measured local bounds must be finite/nondegenerate, coordinates and extents bounded30m; offset places nearest hullX at12m; overall offset<=40m. Rounded measured footprint +1m padding, halfsize<=20m, vertical extent+1<=20m. These are refusal caps, not invented dimensions. Existing original16spawn slots and cache remain in original10m survey."
|
||||
},
|
||||
"verification": {
|
||||
"new_test": "tests/test_crash_start.py",
|
||||
"exit": 0,
|
||||
"actual_methods": [
|
||||
"ERR_StartRules.Valid/Geometry",
|
||||
"ERR_StartSetup.IsCrash/Geometry/Configure",
|
||||
"ERR_GameMode.FreezeStartMode",
|
||||
"ERR_GameMode.Transition admission prefix",
|
||||
"ERR_MissionRules.Terminal/CanTransition",
|
||||
"ERR_CampTerrain.Site"
|
||||
],
|
||||
"boundaries": "Resource measurement, definition.Valid, native actor allocation and trace/terrain primitives doubled; source-order checks bind full startup, replicated getter, prison guard and both placement callers. Actual native geometry/replication/crash route remain pending.",
|
||||
"baseline_red": "Not claimed: this adds an absent feature; new-class behavior tested directly."
|
||||
},
|
||||
"unmodified": [
|
||||
"ERR_SpawnLogic / roster / inventory admission",
|
||||
"SiteService finite stock and owned cleanup",
|
||||
"TerrainSites (shared survey used without edits)",
|
||||
"PrisonAI production hold/release",
|
||||
"latest patrol-hq finite responders and runtime radius/queue fixture",
|
||||
"settings/admin/UI files owned by separate agent",
|
||||
"live successor and original"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c
|
||||
@@ -26,6 +26,20 @@
|
||||
m_SelectedPlayerFaction = player; m_SelectedEnemyFaction = enemy; Replication.BumpMe();
|
||||
}
|
||||
protected ref ERR_Settings m_Settings;
|
||||
+ [RplProp()] protected int m_StartMode;
|
||||
+ protected bool m_StartModeFrozen;
|
||||
+ protected bool m_StartPrepared;
|
||||
+ int StartMode() { return m_StartMode; }
|
||||
+ protected bool FreezeStartMode()
|
||||
+ {
|
||||
+ if (!Replication.IsServer() || m_Stopped || m_NativeEndHandled || m_Phase != ERR_Phase.PREPARING || !m_Settings) return false;
|
||||
+ if (m_StartModeFrozen) return true;
|
||||
+ int selected = m_Settings.Get("startMode");
|
||||
+ if (!ERR_StartRules.Valid(selected)) return false;
|
||||
+ m_StartMode = selected; m_StartModeFrozen = true;
|
||||
+ Replication.BumpMe();
|
||||
+ return true;
|
||||
+ }
|
||||
[RplProp(onRplName: "ApplyLocalViewDistance")]
|
||||
protected int m_MissionViewDistance;
|
||||
protected ref ERR_ViewDistance m_LocalViewDistance = new ERR_ViewDistance();
|
||||
@@ -313,10 +327,11 @@
|
||||
}
|
||||
bool Transition(ERR_Phase phase)
|
||||
{
|
||||
- if (!Replication.IsServer() || !m_PreparationError.IsEmpty() || !ERR_MissionRules.CanTransition(m_Phase, phase)) return false;
|
||||
+ if (!Replication.IsServer() || !m_PreparationError.IsEmpty() || !ERR_MissionRules.CanTransition(m_Phase, phase, m_StartModeFrozen && m_StartPrepared && m_StartMode == 1)) return false;
|
||||
+ if (m_Phase == ERR_Phase.PREPARING && !m_StartPrepared) return false;
|
||||
ERR_Phase previous = m_Phase;
|
||||
m_Phase = phase;
|
||||
- if (previous == ERR_Phase.PRISON && phase == ERR_Phase.RADIO_SEARCH)
|
||||
+ if ((previous == ERR_Phase.PRISON || previous == ERR_Phase.PREPARING) && phase == ERR_Phase.RADIO_SEARCH)
|
||||
{
|
||||
// Dormant patrols must not catch up the time spent waiting in prison.
|
||||
for (int i = 0; i < m_Forces.Count(); i++)
|
||||
@@ -475,6 +490,7 @@
|
||||
if (!m_FactionSelection || !m_FactionSelection.Prepare(this)) { FailPreparation("Three enabled faction profiles are required for the mission roles."); return; }
|
||||
if (!m_Factions || !m_Factions.WorldReady()) { FailPreparation("The configured player and enemy factions or required assets are missing, invalid or not hostile."); return; }
|
||||
if (!m_Content || !m_Content.PrepareFactions(this)) { FailPreparation("The content registry or enabled faction profiles are invalid. Check faction keys, guard groups and the mission faction manager."); return; }
|
||||
+ if (!FreezeStartMode()) { FailPreparation("The selected mission start is invalid."); return; }
|
||||
// Scenario content is created through a separate authoring component.
|
||||
ERR_ScenarioComponent scenario = ERR_ScenarioComponent.Cast(FindComponent(ERR_ScenarioComponent));
|
||||
ERR_PrepareResult prepared = ERR_PrepareResult.FAILED;
|
||||
@@ -498,7 +514,9 @@
|
||||
}
|
||||
if (!m_Environment.Start(this)) { FailPreparation("The selected date or vanilla weather profile could not be initialized."); return; }
|
||||
if (!m_Time.Start(this)) { FailPreparation("The world clock could not be initialized."); return; }
|
||||
- Transition(ERR_Phase.PRISON);
|
||||
+ m_StartPrepared = true;
|
||||
+ if (m_StartMode == 1) Transition(ERR_Phase.RADIO_SEARCH);
|
||||
+ else Transition(ERR_Phase.PRISON);
|
||||
}
|
||||
|
||||
protected void ExtractionResolved(ERR_ExtractionState result)
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_GeneratedSites.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_GeneratedSites.c
|
||||
@@ -25,7 +25,7 @@
|
||||
vector rotation[3]; Math3D.AnglesToMatrix(Vector(heading, 0, 0), rotation);
|
||||
return Vector(vector.Dot(offset, rotation[0]), offset[1], vector.Dot(offset, rotation[2]));
|
||||
}
|
||||
- bool Clear(vector center, float heading, float halfSize, float maximumRange, out float lowest)
|
||||
+ bool Clear(vector center, float heading, float halfSize, float maximumRange, out float lowest, float clearanceHeight = 4)
|
||||
{
|
||||
lowest = float.MAX; float highest = -float.MAX;
|
||||
for (int x = -1; x <= 1; x++)
|
||||
@@ -49,7 +49,7 @@
|
||||
vector cell = center + Rotate(Vector(cx, 0, cz), heading);
|
||||
float ground = GetGame().GetWorld().GetSurfaceY(cell[0], cell[2]);
|
||||
TraceBox trace = new TraceBox();
|
||||
- trace.Start = Vector(cell[0], ground + 0.12, cell[2]); trace.End = trace.Start + "0 4 0";
|
||||
+ trace.Start = Vector(cell[0], ground + 0.12, cell[2]); trace.End = trace.Start + Vector(0, clearanceHeight, 0);
|
||||
// Bounding the rotated cell conservatively also protects the exit corridor.
|
||||
trace.Mins = "-1.42 0 -1.42"; trace.Maxs = "1.42 0.1 1.42";
|
||||
trace.Flags = TraceFlags.ENTS | TraceFlags.WORLD;
|
||||
@@ -70,6 +70,13 @@
|
||||
aiWorld.GetRoadNetworkManager().GetClosestRoad(position, road, distance, skipNavlinks: true);
|
||||
if (road && distance < 12) return false;
|
||||
if (!Clear(position, heading, 10, 0.6, baseHeight)) return false;
|
||||
+ if (ERR_StartSetup.IsCrash(site))
|
||||
+ {
|
||||
+ vector offset, center; float halfSize, height;
|
||||
+ if (!ERR_StartSetup.Geometry(offset, center, halfSize, height)) return false;
|
||||
+ float wreckFloor;
|
||||
+ if (!Clear(position + Rotate(center, heading), heading, halfSize, 0.6, wreckFloor, height)) return false;
|
||||
+ }
|
||||
float guardHeight;
|
||||
if (site.Guarded && !Clear(position + Rotate(site.GuardOffset, heading), heading, 6, 0.6, guardHeight)) return false;
|
||||
if (site.ResponseCount > 0 && !Clear(position + Rotate(site.ResponseOffset, heading), heading, 6, 0.6, guardHeight)) return false;
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_MissionRules.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_MissionRules.c
|
||||
@@ -17,11 +17,15 @@
|
||||
return phase == ERR_Phase.VICTORY || phase == ERR_Phase.DEFEAT;
|
||||
}
|
||||
|
||||
- static bool CanTransition(int from, int to)
|
||||
+ static bool CanTransition(int from, int to, bool crashStart = false)
|
||||
{
|
||||
if (Terminal(from) || from == to) return false;
|
||||
if (to == ERR_Phase.DEFEAT) return from >= ERR_Phase.PRISON && from <= ERR_Phase.EXTRACTION;
|
||||
- if (from == ERR_Phase.PREPARING) return to == ERR_Phase.PRISON;
|
||||
+ if (from == ERR_Phase.PREPARING)
|
||||
+ {
|
||||
+ if (crashStart) return to == ERR_Phase.RADIO_SEARCH;
|
||||
+ return to == ERR_Phase.PRISON;
|
||||
+ }
|
||||
if (from == ERR_Phase.PRISON) return to == ERR_Phase.RADIO_SEARCH;
|
||||
if (from == ERR_Phase.RADIO_SEARCH) return to == ERR_Phase.RADIO_DEFENCE;
|
||||
if (from == ERR_Phase.RADIO_DEFENCE) return to == ERR_Phase.EXTRACTION;
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonEscapeService.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonEscapeService.c
|
||||
@@ -94,7 +94,7 @@
|
||||
m_Samples.Clear();
|
||||
if (!Replication.IsServer() || m_Stopped || current != ERR_Phase.PRISON || m_Registered) return;
|
||||
m_RegistrationReason = "no unique owned authored prison";
|
||||
- if (!m_Mode || !m_Mode.Sites()) return;
|
||||
+ if (!m_Mode || m_Mode.StartMode() != 0 || !m_Mode.Sites()) return;
|
||||
array<ERR_LocationComponent> locations = {};
|
||||
m_Mode.Locations(locations);
|
||||
IEntity prison;
|
||||
@@ -146,7 +146,7 @@
|
||||
}
|
||||
void Tick(float now)
|
||||
{
|
||||
- if (!Replication.IsServer() || m_Stopped || !m_Mode || m_Mode.Phase() != ERR_Phase.PRISON || !m_Mode.Active() || !m_Registered) return;
|
||||
+ if (!Replication.IsServer() || m_Stopped || !m_Mode || m_Mode.Phase() != ERR_Phase.PRISON || m_Mode.StartMode() != 0 || !m_Mode.Active() || !m_Registered) return;
|
||||
ref map<UUID, ref ERR_PrisonEscapeSample> next = new map<UUID, ref ERR_PrisonEscapeSample>();
|
||||
array<ref ERR_PlayerLife> lives = {};
|
||||
m_Mode.Players().Participants(lives);
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_ScenarioComponent.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_ScenarioComponent.c
|
||||
@@ -46,7 +46,7 @@
|
||||
m_Started = true;
|
||||
#ifdef WORKBENCH
|
||||
string historicalFixture;
|
||||
- if (!m_TerrainIndependent && System.GetCLIParam("errSmokeOutcome", historicalFixture) && historicalFixture != "normal-escape-route" && historicalFixture != "mounted-ammo" && historicalFixture != "alarm-hearing" && historicalFixture != "optional-site-skip" && historicalFixture != "infantry-combat" && historicalFixture != "site-garrisons" && historicalFixture != "generated-sites" && historicalFixture != "opening-tools" && historicalFixture != "airfield-markers" && historicalFixture != "air-recon" && historicalFixture != "air-logistics" && historicalFixture != "air-assault")
|
||||
+ if (!m_TerrainIndependent && System.GetCLIParam("errSmokeOutcome", historicalFixture) && historicalFixture != "normal-escape-route" && historicalFixture != "crash-start" && historicalFixture != "mounted-ammo" && historicalFixture != "alarm-hearing" && historicalFixture != "optional-site-skip" && historicalFixture != "infantry-combat" && historicalFixture != "site-garrisons" && historicalFixture != "generated-sites" && historicalFixture != "opening-tools" && historicalFixture != "airfield-markers" && historicalFixture != "air-recon" && historicalFixture != "air-logistics" && historicalFixture != "air-assault")
|
||||
m_Definition = "{ACA98B44E2173605}Configs/ERR/Tests/LegacySites.conf";
|
||||
#endif
|
||||
m_RuntimeDefinition = ERR_ScenarioDefinition.Cast(SCR_BaseContainerTools.CreateInstanceFromPrefab(m_Definition));
|
||||
@@ -54,10 +54,11 @@
|
||||
#ifdef WORKBENCH
|
||||
// Existing deterministic probes intentionally use authored coordinates.
|
||||
string fixture;
|
||||
- if (!m_TerrainIndependent && System.GetCLIParam("errSmokeOutcome", fixture) && fixture != "normal-escape-route" && fixture != "mounted-ammo" && fixture != "alarm-hearing" && fixture != "optional-site-skip" && fixture != "infantry-combat" && fixture != "site-garrisons" && fixture != "generated-sites" && fixture != "airfield-markers" && fixture != "air-recon" && fixture != "air-logistics" && fixture != "air-assault")
|
||||
+ if (!m_TerrainIndependent && System.GetCLIParam("errSmokeOutcome", fixture) && fixture != "normal-escape-route" && fixture != "crash-start" && fixture != "mounted-ammo" && fixture != "alarm-hearing" && fixture != "optional-site-skip" && fixture != "infantry-combat" && fixture != "site-garrisons" && fixture != "generated-sites" && fixture != "airfield-markers" && fixture != "air-recon" && fixture != "air-logistics" && fixture != "air-assault")
|
||||
foreach (ERR_SiteDefinition fixedSite : m_RuntimeDefinition.Sites) fixedSite.RandomClear = false;
|
||||
if (!ERR_ConfigurePatrolHQFixture(fixture)) { m_Failed = true; return ERR_PrepareResult.FAILED; }
|
||||
#endif
|
||||
+ if (!ERR_StartSetup.Configure(m_RuntimeDefinition, mode.StartMode())) { m_Failed = true; return ERR_PrepareResult.FAILED; }
|
||||
if (m_TerrainIndependent) m_Generated = new ERR_TerrainSites();
|
||||
else m_Generated = new ERR_GeneratedSites();
|
||||
if (!m_Generated.Begin(m_RuntimeDefinition)) { m_Failed = true; return ERR_PrepareResult.FAILED; }
|
||||
--- /dev/null
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_StartRules.c
|
||||
@@ -0,0 +1,23 @@
|
||||
+// Start selection is fixed once per mission. Geometry uses measured native
|
||||
+// model bounds only; it never substitutes guessed helicopter dimensions.
|
||||
+class ERR_StartRules
|
||||
+{
|
||||
+ static bool Valid(int mode) { return mode == 0 || mode == 1; }
|
||||
+ static bool Geometry(vector minimum, vector maximum, out vector offset, out vector center, out float halfSize, out float height)
|
||||
+ {
|
||||
+ offset = vector.Zero; center = vector.Zero; halfSize = 0; height = 0;
|
||||
+ for (int axis = 0; axis < 3; axis++)
|
||||
+ if (!ERR_ForceRules.Finite(minimum[axis]) || !ERR_ForceRules.Finite(maximum[axis]) || Math.AbsFloat(minimum[axis]) > 30 || Math.AbsFloat(maximum[axis]) > 30 || minimum[axis] >= maximum[axis] || maximum[axis] - minimum[axis] > 30) return false;
|
||||
+ // Keep the measured wreck at least 12m east of the start anchor: all sixteen
|
||||
+ // standing slots and the existing cache remain inside the original survey.
|
||||
+ vector placed = Vector(12 - minimum[0], -minimum[1], 0);
|
||||
+ float radius = Math.Ceil(Math.Max(maximum[0] - minimum[0], maximum[2] - minimum[2]) * 0.5 + 1);
|
||||
+ float clearance = Math.Ceil(maximum[1] - minimum[1] + 1);
|
||||
+ if (placed.Length() > 40 || radius > 20 || clearance > 20) return false;
|
||||
+ offset = placed;
|
||||
+ center = placed + (minimum + maximum) * 0.5;
|
||||
+ center[1] = 0;
|
||||
+ halfSize = radius; height = clearance;
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_StartSetup.c
|
||||
@@ -0,0 +1,47 @@
|
||||
+// PRISON remains the internal single-start-slot role for existing catalog,
|
||||
+// map-stock and terrain-spacing rules. Crash gameplay never enters PRISON.
|
||||
+class ERR_StartSetup
|
||||
+{
|
||||
+ static bool IsCrash(ERR_SiteDefinition site)
|
||||
+ {
|
||||
+ return site && site.Kind == ERR_LocationKind.PRISON && site.Prefab == ERR_CrashSiteResources.SitePrefab();
|
||||
+ }
|
||||
+ static bool Geometry(out vector offset, out vector center, out float halfSize, out float height)
|
||||
+ {
|
||||
+ offset = vector.Zero; center = vector.Zero; halfSize = 0; height = 0;
|
||||
+ vector minimum, maximum;
|
||||
+ return ERR_CrashSiteResources.Bounds(minimum, maximum) && ERR_StartRules.Geometry(minimum, maximum, offset, center, halfSize, height);
|
||||
+ }
|
||||
+ static bool Configure(ERR_ScenarioDefinition definition, int mode)
|
||||
+ {
|
||||
+ if (!ERR_StartRules.Valid(mode) || !definition) return false;
|
||||
+ if (mode == 0) return true;
|
||||
+ ERR_SiteDefinition start;
|
||||
+ int count;
|
||||
+ foreach (ERR_SiteDefinition site : definition.Sites)
|
||||
+ {
|
||||
+ if (!site || site.Kind != ERR_LocationKind.PRISON) continue;
|
||||
+ start = site; count++;
|
||||
+ }
|
||||
+ if (count != 1 || !start || start.Container.IsEmpty()) return false;
|
||||
+ vector offset, center; float halfSize, height;
|
||||
+ if (!Geometry(offset, center, halfSize, height)) return false;
|
||||
+ for (int axis = 0; axis < 3; axis++)
|
||||
+ if (!ERR_ForceRules.Finite(start.ContainerOffset[axis])) return false;
|
||||
+ if (Math.AbsFloat(start.ContainerOffset[0]) > 8 || Math.AbsFloat(start.ContainerOffset[2]) > 8 || Math.AbsFloat(start.ContainerOffset[1]) > 1) return false;
|
||||
+ start.Prefab = ERR_CrashSiteResources.SitePrefab();
|
||||
+ start.Label = "Crash site";
|
||||
+ start.RootHeight = 0;
|
||||
+ start.Guarded = false; start.Guards = ""; start.GuardCount = 0;
|
||||
+ start.ResponseCount = 0; start.AllowFactionPool = false;
|
||||
+ start.Patrol = null;
|
||||
+ start.RandomClear = true;
|
||||
+ start.Props = new array<ref ERR_SiteProp>();
|
||||
+ ERR_SiteProp wreck = new ERR_SiteProp();
|
||||
+ wreck.Prefab = ERR_CrashSiteResources.WreckPrefab();
|
||||
+ wreck.Offset = offset;
|
||||
+ start.Props.Insert(wreck);
|
||||
+ // Preserve the original finite cache, stock, radio clues, map and site ID.
|
||||
+ return definition.Valid();
|
||||
+ }
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/tests/test_crash_start.py
|
||||
@@ -0,0 +1,124 @@
|
||||
+"""Actual start policy/setup/freeze methods; engine/resource/terrain boundaries doubled."""
|
||||
+import os,sys
|
||||
+from pathlib import Path
|
||||
+ROOT=Path(os.environ.get('ERR_REPO','/home/jakub/devel/escapistsrereintroduced'))
|
||||
+P=Path(os.environ.get('ERR_CRASH_CORE_ROOT',ROOT))
|
||||
+sys.path.insert(0,str(ROOT/'tests'))
|
||||
+from policy_harness import body,run
|
||||
+C='addons/core/Scripts/Game/ERR/00_Core/'
|
||||
+def source(name):return P/C/name
|
||||
+
|
||||
+def cpp(s):
|
||||
+ for a,b in [('protected ',''),('ERR_ForceRules.','ERR_ForceRules::'),('ERR_StartRules.','Rules::'),('ERR_CrashSiteResources.','Resources::'),('ERR_LocationKind.','Kind::'),('Math.','Math::'),('vector.Zero','vector{}'),('out vector ','vector& '),('out float ','float& ')]:s=s.replace(a,b)
|
||||
+ return s
|
||||
+rules='\n'.join(cpp(body(source('ERR_StartRules.c'),sig)) for sig in ['static bool Valid(','static bool Geometry('])
|
||||
+setup='\n'.join(cpp(body(source('ERR_StartSetup.c'),sig)) for sig in ['static bool IsCrash(','static bool Geometry(','static bool Configure('])
|
||||
+for a,b in [('ERR_SiteDefinition site','Site* site'),('ERR_SiteDefinition start;','Site* start=nullptr;'),('ERR_ScenarioDefinition definition','Definition* definition'),('ERR_SiteProp wreck','Prop* wreck'),('ref Prop*','Prop*'),('new ERR_SiteProp()','new Prop()'),('new array<ref ERR_SiteProp>()','new Array<Prop*>()'),('foreach (','for ('),('int count;','int count=0;')]:setup=setup.replace(a,b)
|
||||
+for var in ['site','start','definition','wreck']:setup=setup.replace(var+'.',var+'->')
|
||||
+setup=setup.replace('start->Props.Insert','start->Props->Insert').replace('.IsEmpty()','.empty()')
|
||||
+run(r'''
|
||||
+#include <cassert>
|
||||
+#include <cmath>
|
||||
+#include <limits>
|
||||
+#include <vector>
|
||||
+#include <string>
|
||||
+#define null nullptr
|
||||
+struct vector{float a[3]{};float&operator[](int i){return a[i];}float operator[](int i)const{return a[i];}float Length(){return std::sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);}};
|
||||
+vector Vector(float x,float y,float z){return{{x,y,z}};}vector operator+(vector a,vector b){return Vector(a[0]+b[0],a[1]+b[1],a[2]+b[2]);}vector operator*(vector a,float b){return Vector(a[0]*b,a[1]*b,a[2]*b);}
|
||||
+namespace ERR_ForceRules{bool Finite(float x){return std::isfinite(x);}}
|
||||
+namespace Math{float Ceil(float x){return std::ceil(x);}float Max(float x,float y){return std::fmax(x,y);}float AbsFloat(float x){return std::fabs(x);}}
|
||||
+struct Rules{RULES};
|
||||
+namespace Kind{constexpr int PRISON=0;}
|
||||
+template<class T>struct Array:std::vector<T>{using std::vector<T>::operator=;void Insert(T x){this->push_back(x);}};
|
||||
+struct Prop{std::string Prefab;vector Offset;};
|
||||
+struct Site{int Kind=0,GuardCount=6,ResponseCount=2;bool Guarded=true,AllowFactionPool=true,RandomClear=false;std::string Prefab="prison",Label="Prison",Guards="guards",Container="finite-bag",Id="original";float RootHeight=2;int*Patrol=(int*)1;void*Stock=(void*)2;vector ContainerOffset=Vector(-4,0,0);Array<Prop*>*Props=nullptr;};
|
||||
+struct Definition{Array<Site*>Sites;bool valid=true;int calls=0;bool Valid(){calls++;return valid;}};
|
||||
+namespace Resources{bool ready=true;vector low=Vector(-4,-1,-3),high=Vector(6,4,3);std::string SitePrefab(){return"crash-site";}std::string WreckPrefab(){return"wreck";}bool Bounds(vector&lo,vector&hi){lo=low;hi=high;return ready;}}
|
||||
+struct Setup{SETUP};
|
||||
+int main(){
|
||||
+ assert(Rules::Valid(0)&&Rules::Valid(1)&&!Rules::Valid(-1)&&!Rules::Valid(2));
|
||||
+ vector offset,center;float half,height;
|
||||
+ assert(Rules::Geometry(Resources::low,Resources::high,offset,center,half,height));assert(offset[0]+Resources::low[0]==12&&offset[1]==1&&half==6&&height==6);
|
||||
+ for(int a=0;a<3;a++)for(float bad:{std::numeric_limits<float>::infinity(),std::numeric_limits<float>::quiet_NaN()}){vector lo=Resources::low;lo[a]=bad;assert(!Rules::Geometry(lo,Resources::high,offset,center,half,height)&&half==0&&height==0&&offset[0]==0);}
|
||||
+ assert(!Rules::Geometry(Vector(0,0,100),Vector(1,1,101),offset,center,half,height));assert(!Rules::Geometry(Vector(0,0,0),Vector(0,1,1),offset,center,half,height));assert(!Rules::Geometry(Vector(-50,0,0),Vector(-49,1,1),offset,center,half,height));assert(!Rules::Geometry(Vector(0,0,0),Vector(31,1,1),offset,center,half,height));assert(!Rules::Geometry(Vector(0,0,0),Vector(1,21,1),offset,center,half,height));
|
||||
+ Site prison;Definition original;original.Sites={&prison};Resources::ready=false;assert(Setup::Configure(&original,0)&&prison.Guarded&&prison.Prefab=="prison"&&prison.ResponseCount==2&&prison.RootHeight==2&&original.calls==0);
|
||||
+ assert(!Setup::Configure(&original,1)&&prison.Prefab=="prison");Resources::ready=true;
|
||||
+ assert(Setup::Configure(&original,1)&&original.calls==1&&Setup::IsCrash(&prison));assert(!prison.Guarded&&prison.Guards.empty()&&prison.GuardCount==0&&prison.ResponseCount==0&&!prison.Patrol&&!prison.AllowFactionPool&&prison.RandomClear&&prison.RootHeight==0);
|
||||
+ assert(prison.Stock==(void*)2&&prison.Container=="finite-bag"&&prison.Id=="original"&&prison.ContainerOffset[0]==-4&&prison.Props->size()==1&&(*prison.Props)[0]->Prefab=="wreck"&&(*prison.Props)[0]->Offset[0]==16);
|
||||
+ for(int fault=0;fault<7;fault++){Site a,b;Definition d;d.Sites={&a};if(fault==0)d.Sites.clear();if(fault==1)d.Sites.push_back(&b);if(fault==2)a.Container="";if(fault==3)a.ContainerOffset[0]=9;if(fault==4)a.ContainerOffset[1]=2;if(fault==5)d.valid=false;assert(!Setup::Configure(fault==6?nullptr:&d,1));}
|
||||
+ assert(!Setup::Configure(&original,-1));
|
||||
+}
|
||||
+'''.replace('RULES',rules).replace('SETUP',setup))
|
||||
+# Actual once-only server freeze, including failed settings and restart/new owner.
|
||||
+freeze=body(source('ERR_GameMode.c'),'protected bool FreezeStartMode(').replace('protected ','').replace('Replication.','Replication::').replace('ERR_Phase.','Phase::').replace('ERR_StartRules.','Rules::').replace('m_Settings.','m_Settings->')
|
||||
+run(r'''
|
||||
+#include <cassert>
|
||||
+#include <string>
|
||||
+namespace Replication{bool server=true;int bumps=0;bool IsServer(){return server;}void BumpMe(){bumps++;}}
|
||||
+namespace Phase{constexpr int PREPARING=0;}
|
||||
+namespace Rules{bool Valid(int n){return n==0||n==1;}}
|
||||
+struct Settings{int value=0,reads=0;int Get(std::string key){assert(key=="startMode");reads++;return value;}};
|
||||
+struct Mode{bool m_Stopped=false,m_NativeEndHandled=false,m_StartModeFrozen=false;int m_Phase=0,m_StartMode=0;Settings*m_Settings=nullptr;METHOD};
|
||||
+int main(){Settings s;Mode p;p.m_Settings=&s;assert(p.FreezeStartMode()&&p.m_StartMode==0);s.value=1;assert(p.FreezeStartMode()&&p.m_StartMode==0&&s.reads==1);Mode restart;restart.m_Settings=&s;assert(restart.FreezeStartMode()&&restart.m_StartMode==1);for(int f=0;f<6;f++){Mode x;x.m_Settings=&s;if(f==0)Replication::server=false;if(f==1)x.m_Stopped=true;if(f==2)x.m_NativeEndHandled=true;if(f==3)x.m_Phase=1;if(f==4)x.m_Settings=nullptr;if(f==5)s.value=2;assert(!x.FreezeStartMode()&&!x.m_StartModeFrozen);Replication::server=true;s.value=1;}}
|
||||
+'''.replace('METHOD',freeze))
|
||||
+# Actual transition policy retains all default edges; crash authorization adds
|
||||
+# only initial RADIO_SEARCH and cannot add a terminal or downstream shortcut.
|
||||
+policy='\n'.join(body(source('ERR_MissionRules.c'),sig) for sig in ['static bool Terminal(','static bool CanTransition(']).replace('ERR_Phase.','Phase::')
|
||||
+run(r'''
|
||||
+#include <cassert>
|
||||
+namespace Phase{enum{PREPARING,PRISON,RADIO_SEARCH,RADIO_DEFENCE,EXTRACTION,VICTORY,DEFEAT};}
|
||||
+POLICY
|
||||
+int main(){for(int from=0;from<=6;from++)for(int to=0;to<=6;to++){bool old=(from<5&&to==from+1)||(from>=1&&from<=4&&to==6);assert(CanTransition(from,to)==old);assert(CanTransition(from,to,true)==(from==0?to==2:old));}}
|
||||
+'''.replace('POLICY',policy))
|
||||
+mode=source('ERR_GameMode.c').read_text();scenario=source('ERR_ScenarioComponent.c').read_text()
|
||||
+transition=body(source('ERR_GameMode.c'),'bool Transition(')
|
||||
+assert 'm_StartModeFrozen && m_StartPrepared && m_StartMode == 1' in transition
|
||||
+assert 'm_Phase == ERR_Phase.PREPARING && !m_StartPrepared' in transition
|
||||
+start=body(source('ERR_GameMode.c'),'protected void StartScenario(')
|
||||
+assert start.index('FreezeStartMode()')<start.index('scenario.Prepare()')<start.index('m_StartPrepared = true;')<start.index('Transition(ERR_Phase.RADIO_SEARCH)')
|
||||
+assert start.index('m_Time.Start(this)')<start.index('m_StartPrepared = true;')
|
||||
+assert 'previous == ERR_Phase.PREPARING' in transition
|
||||
+assert '[RplProp()] protected int m_StartMode;' in mode
|
||||
+assert scenario.index('ERR_ConfigurePatrolHQFixture(fixture)')<scenario.index('ERR_StartSetup.Configure(')<scenario.index('m_Generated.Begin(')
|
||||
+assert 'historicalFixture != "crash-start"' in scenario and 'fixture != "crash-start"' in scenario
|
||||
+assert 'm_Mode.StartMode() != 0' in body(source('ERR_PrisonEscapeService.c'),'void PhaseChanged(')
|
||||
+# Both generated and terrain-independent placement dispatch through this exact
|
||||
+# shared Site method; actual Clear is native trace geometry (not simulated here).
|
||||
+survey=body(source('ERR_GeneratedSites.c'),'bool Site(')
|
||||
+assert 'ERR_StartSetup.IsCrash(site)' in survey and 'ERR_StartSetup.Geometry(offset, center, halfSize, height)' in survey
|
||||
+assert 'Clear(position + Rotate(center, heading), heading, halfSize, 0.6, wreckFloor, height)' in survey
|
||||
+assert 'm_Terrain.Site(site, position, heading, floor)' in (ROOT/C/'ERR_TerrainSites.c').read_text()
|
||||
+print('PASS: actual crash geometry, detached definition setup, frozen server choice and guarded phase policy; integration/source ordering checked')
|
||||
+# Execute actual GameMode transition admission prefix (effects after acceptance
|
||||
+# are existing mission hooks); callers cannot use selected crash mode before
|
||||
+# ordinary scenario/extraction/environment preparation has completed.
|
||||
+admit=body(source('ERR_GameMode.c'),'bool Transition(').split('\n\t\tERR_Phase previous',1)[0]+'\n return true;\n}'
|
||||
+admit=admit.replace('ERR_Phase phase','int phase').replace('Replication.','Replication::').replace('ERR_MissionRules.','Policy::').replace('ERR_Phase.','Phase::').replace('m_PreparationError.IsEmpty()','m_PreparationError.empty()')
|
||||
+run(r'''
|
||||
+#include <cassert>
|
||||
+#include <string>
|
||||
+namespace Replication{bool server=true;bool IsServer(){return server;}}
|
||||
+namespace Phase{enum{PREPARING,PRISON,RADIO_SEARCH,RADIO_DEFENCE,EXTRACTION,VICTORY,DEFEAT};}
|
||||
+namespace Policy{POLICY}
|
||||
+struct Mode{int m_Phase=0,m_StartMode=1;bool m_StartModeFrozen=false,m_StartPrepared=false;std::string m_PreparationError;ADMIT};
|
||||
+int main(){Mode crash;assert(!crash.Transition(2));crash.m_StartModeFrozen=true;assert(!crash.Transition(2));crash.m_StartPrepared=true;assert(crash.Transition(2)&&!crash.Transition(1));crash.m_PreparationError="failed";assert(!crash.Transition(2));crash.m_PreparationError="";Replication::server=false;assert(!crash.Transition(2));Replication::server=true;Mode prison;prison.m_StartMode=0;prison.m_StartModeFrozen=true;prison.m_StartPrepared=true;assert(prison.Transition(1)&&!prison.Transition(2));prison.m_Phase=1;assert(prison.Transition(2));}
|
||||
+'''.replace('POLICY',policy).replace('ADMIT',admit))
|
||||
+# Execute actual common site survey to prove both measured wreck and start/cache
|
||||
+# areas are required and that unknown measured bounds cannot fall back to10m.
|
||||
+site=body(source('ERR_GeneratedSites.c'),'bool Site(')
|
||||
+for a,b in [('ERR_SiteDefinition site','SiteData* site'),('site.','site->'),('foreach (','for ('),('ERR_LocationKind.','Kind::'),('ERR_StartSetup.','StartSetup::'),('SCR_AIWorld aiWorld = SCR_AIWorld.Cast(GetGame().GetAIWorld());','AIWorld* aiWorld = &world;'),('aiWorld.GetRoadNetworkManager()','aiWorld->GetRoadNetworkManager()'),('GetRoadNetworkManager().','GetRoadNetworkManager()->'),('BaseRoad road; float distance;','Road* road=nullptr; float distance=0;'),('skipNavlinks: true','true'),('out float ','float& '),('vector.DistanceXZ','DistanceXZ')]:site=site.replace(a,b)
|
||||
+run(r'''
|
||||
+#include <cassert>
|
||||
+#include <cmath>
|
||||
+#include <vector>
|
||||
+#define null nullptr
|
||||
+struct vector{float x=0,y=0,z=0;};vector operator+(vector a,vector b){return{a.x+b.x,a.y+b.y,a.z+b.z};}float DistanceXZ(vector a,vector b){return std::hypot(a.x-b.x,a.z-b.z);}
|
||||
+namespace Kind{constexpr int PRISON=0;}
|
||||
+struct SiteData{int Kind=0,ResponseCount=0;bool Guarded=false,crash=false;vector GuardOffset,ResponseOffset;};
|
||||
+namespace StartSetup{bool measured=true;bool IsCrash(SiteData*s){return s->crash;}bool Geometry(vector&offset,vector¢er,float&half,float&height){offset={16,1,0};center={17,0,0};half=6;height=6;return measured;}}
|
||||
+struct Road{};struct RoadManager{void GetClosestRoad(vector,Road*&,float&,bool){}};struct AIWorld{RoadManager roads;RoadManager*GetRoadNetworkManager(){return &roads;}};
|
||||
+struct Call{vector p;float half,height;};
|
||||
+struct Survey{AIWorld world;std::vector<vector>m_Airfields;std::vector<Call>calls;int refuse=0;vector Rotate(vector p,float h){assert(h==90);return{p.z,p.y,-p.x};}bool Clear(vector p,float,float half,float,float&floor,float height=4){calls.push_back({p,half,height});floor=42;return int(calls.size())!=refuse;}SITE};
|
||||
+int main(){SiteData a;float floor=0;Survey normal;assert(normal.Site(&a,{100,0,200},90,floor)&&normal.calls.size()==1&&normal.calls[0].half==10&&normal.calls[0].height==4);a.crash=true;Survey crash;assert(crash.Site(&a,{100,0,200},90,floor)&&crash.calls.size()==2);assert(crash.calls[1].p.x==100&&crash.calls[1].p.z==183&&crash.calls[1].half==6&&crash.calls[1].height==6);for(int refusal:{1,2}){Survey blocked;blocked.refuse=refusal;assert(!blocked.Site(&a,{100,0,200},90,floor));}StartSetup::measured=false;Survey unknown;assert(!unknown.Site(&a,{100,0,200},90,floor)&&unknown.calls.size()==1);}
|
||||
+'''.replace('SITE',site))
|
||||
+print('PASS: actual GameMode readiness admission and common full-footprint survey require crash authorization and both surveyed areas')
|
||||
@@ -0,0 +1,2 @@
|
||||
PASS: actual crash geometry, detached definition setup, frozen server choice and guarded phase policy; integration/source ordering checked
|
||||
PASS: actual GameMode readiness admission and common full-footprint survey require crash authorization and both surveyed areas
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/tests/test_crash_start.py
|
||||
+++ b/tests/test_crash_start.py
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Actual start policy/setup/freeze methods; engine/resource/terrain boundaries doubled."""
|
||||
import os,sys
|
||||
from pathlib import Path
|
||||
-ROOT=Path(os.environ.get('ERR_REPO','/home/jakub/devel/escapistsrereintroduced'))
|
||||
+ROOT=Path(os.environ.get('ERR_REPO',Path(__file__).resolve().parents[1]))
|
||||
P=Path(os.environ.get('ERR_CRASH_CORE_ROOT',ROOT))
|
||||
sys.path.insert(0,str(ROOT/'tests'))
|
||||
from policy_harness import body,run
|
||||
@@ -0,0 +1,2 @@
|
||||
PASS: actual crash geometry, detached definition setup, frozen server choice and guarded phase policy; integration/source ordering checked
|
||||
PASS: actual GameMode readiness admission and common full-footprint survey require crash authorization and both surveyed areas
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
PASS: actual crash geometry, detached definition setup, frozen server choice and guarded phase policy; integration/source ordering checked
|
||||
PASS: actual GameMode readiness admission and common full-footprint survey require crash authorization and both surveyed areas
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"file": "tests/test_crash_start.py",
|
||||
"baseline_sha256": "22ec3e0627a3c2f8ef79a39dafc933ed3489b24acca4bb53b136c56a98d56d6b",
|
||||
"proposed_sha256": "b65da31d60b5cdaacc8e729155b05eb1388284c9a6241549eaac49d59e1f4552",
|
||||
"patch_sha256": "814432d578ffeed5e4aa11cf1975d44e22285ce67d8e7a3f6202cd84f2118646",
|
||||
"original_proposal_preserved": true,
|
||||
"tests": {
|
||||
"scratch_override": {
|
||||
"exit": 0,
|
||||
"log": "d01e24f45cb53afede40230165f9f2aba874fdb0c34de14f893c9a136b9d2edb"
|
||||
},
|
||||
"isolated_default_no_environment_overrides": {
|
||||
"exit": 0,
|
||||
"log": "d01e24f45cb53afede40230165f9f2aba874fdb0c34de14f893c9a136b9d2edb"
|
||||
}
|
||||
},
|
||||
"compiler_work_finished": true,
|
||||
"live_edits": false,
|
||||
"native_runs": 0
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"code_review_approved": true,
|
||||
"validation_scope": "Read-only bounded source integration review; no tests/compiler/native run",
|
||||
"proposal_patch_sha256": "82d2f6c481caef7dc777fd6bf3d92258a4af4b9bf87b207aa7bc1ff4c3aabead",
|
||||
"reviewed_source_hashes": {
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c": "9a0536377f0e93f70972838de6480dfbdb44bfda198f70daaa541616eb046fd6",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_MissionRules.c": "17d1f48878b02a457eebbe5ff87c4267488d68d2a9b3121dda77a8bc8e69c8c6",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ScenarioComponent.c": "d7c953fc8617c21e03f7d501c4a4c00a034b6375060072fd03c751fc2970feeb",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_StartRules.c": "ab7c21ef700343cbe769d8d51d91f167db37285b466d6af9873e121b3adf4ade",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_StartSetup.c": "58a6b617b22910d0ce9255f82091dc11cd1284417a66adf1cdaa7b661c1ed01c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_GeneratedSites.c": "addd7850e58a2f5c4a0ca6672033f2b42f5879e9a1a6a7ab86aa730419cef97b",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonEscapeService.c": "ed180448cb516bc4ec521aedd366810a47787628c7f5ee9c9afdbd185d980751"
|
||||
},
|
||||
"settings_manifest_sha256": "9295723e6653bea750b438f22366e3a9f3bc62e1645766ba42047bc1337cb5ee",
|
||||
"findings": [
|
||||
"Settings startMode0/1 missing-default0 and replicated int GameMode.StartMode match. Freeze runs before first Scenario.Prepare and is idempotent across pending preparation retries. Saved mid-round edits cannot change frozen selector; restart/new GameMode reads saved choice.",
|
||||
"Transition grants PREPARING->RADIO_SEARCH only with frozen crash choice and readiness latch set after scenario, extraction, environment and clock initialization. Default prison edge and downstream phase rules remain separate.",
|
||||
"Fresh runtime scenario instance is transformed before generated-site Begin. Internal PRISON site role remains the one start-anchor/catalog slot, without entering PRISON gameplay phase in crash mode.",
|
||||
"Existing SpawnLogic selects surviving canonical actors after RADIO_SEARCH and falls back to original sixteen start-anchor slots for first arrival. Life, reconnection, reserved positions and finalization-ticket guards remain unchanged.",
|
||||
"Prison escape service explicitly excludes crash mode; existing SiteService.PhaseChanged reveals intended clue/supply locations on initial RADIO_SEARCH. Force time reset is generalized to the authorized direct initial phase."
|
||||
],
|
||||
"limits": [
|
||||
"Geometry constants depend on independent installed-resource/native bounds proof; current review does not establish physical terrain clearance, spawn safety or native static wreck support.",
|
||||
"Source fixture and tests use doubled native boundaries; parent owns subsequent full-suite and engine validation.",
|
||||
"No manual human/MP, crash physics, flight or search/escape route qualification."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"files": {
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c": {
|
||||
"baseline_sha256": "89a29c03ba225acbbb9fa3c58a721aced91a77bc0c77046d697005a6d7c48bb9",
|
||||
"proposed_sha256": "9a0536377f0e93f70972838de6480dfbdb44bfda198f70daaa541616eb046fd6",
|
||||
"new_file": false
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_GeneratedSites.c": {
|
||||
"baseline_sha256": "4a23058f27e3ab074df6f8f7bb6f08a8fd26fbadb8943c6fb8d64dcc9c221751",
|
||||
"proposed_sha256": "addd7850e58a2f5c4a0ca6672033f2b42f5879e9a1a6a7ab86aa730419cef97b",
|
||||
"new_file": false
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_MissionRules.c": {
|
||||
"baseline_sha256": "f7abc38ad8fdc375ce7fa63a65f0bade027d22b37e09de5e3f94ba8c3c63cc41",
|
||||
"proposed_sha256": "17d1f48878b02a457eebbe5ff87c4267488d68d2a9b3121dda77a8bc8e69c8c6",
|
||||
"new_file": false
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonEscapeService.c": {
|
||||
"baseline_sha256": "535cf17e21fc8e62716c7d9da88d976ee2f526501c6a4752b822f1252e742bf4",
|
||||
"proposed_sha256": "ed180448cb516bc4ec521aedd366810a47787628c7f5ee9c9afdbd185d980751",
|
||||
"new_file": false
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ScenarioComponent.c": {
|
||||
"baseline_sha256": "7fe3e8ee04a15a50fe6d665027a5ef0ff945b4c587113713b9d462382b0eccd1",
|
||||
"proposed_sha256": "d7c953fc8617c21e03f7d501c4a4c00a034b6375060072fd03c751fc2970feeb",
|
||||
"new_file": false
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_StartRules.c": {
|
||||
"baseline_sha256": null,
|
||||
"proposed_sha256": "ab7c21ef700343cbe769d8d51d91f167db37285b466d6af9873e121b3adf4ade",
|
||||
"new_file": true
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_StartSetup.c": {
|
||||
"baseline_sha256": null,
|
||||
"proposed_sha256": "58a6b617b22910d0ce9255f82091dc11cd1284417a66adf1cdaa7b661c1ed01c",
|
||||
"new_file": true
|
||||
},
|
||||
"tests/test_crash_start.py": {
|
||||
"baseline_sha256": null,
|
||||
"proposed_sha256": "22ec3e0627a3c2f8ef79a39dafc933ed3489b24acca4bb53b136c56a98d56d6b",
|
||||
"new_file": true
|
||||
}
|
||||
},
|
||||
"patch_sha256": "82d2f6c481caef7dc777fd6bf3d92258a4af4b9bf87b207aa7bc1ff4c3aabead",
|
||||
"finding_sha256": "090260582f37f01ffa7984ee5da743f670e51c231164d6db82d75d800ebf0d85",
|
||||
"test_log_sha256": "d01e24f45cb53afede40230165f9f2aba874fdb0c34de14f893c9a136b9d2edb",
|
||||
"test_exit": 0,
|
||||
"compilers_finished": true,
|
||||
"pending": "Rawls native-measured resource bounds and root full integration/native validation",
|
||||
"live_edits": false,
|
||||
"native_runs": 0
|
||||
}
|
||||
+588
@@ -0,0 +1,588 @@
|
||||
{
|
||||
"basis": "Read-only original package path inventory. Category assignment is an inference from file names and directories, not a code audit or proof of feature equivalence. All original script entries have a tracked responsibility; none is marked complete solely from this mapping.",
|
||||
"acceptance": "docs/acceptance.json",
|
||||
"features": [
|
||||
{
|
||||
"id": "alternate_starts",
|
||||
"title": "Helicopter-crash and hideout starts",
|
||||
"scope": "later",
|
||||
"status": "pending",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Components/ESCT_HelicrashHelicopterComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_HelicrashStartComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_HideoutStartComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_HelicrashLocationHolder.c"
|
||||
],
|
||||
"replacement_files": [],
|
||||
"remaining": "Author separate layouts and progression rules after the prison release."
|
||||
},
|
||||
{
|
||||
"id": "spectators",
|
||||
"title": "Spectators and follow cameras",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Camera/Components/ESCT_AssignTargetManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_AttachToPlayerManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_LookAtTargetManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_OrbitDistanceManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_OrbitPlayerManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_SpectatorUIManualCameraComponent.c",
|
||||
"Scripts/Game/Components/Editor/ESCT_SpectatorMenuLayoutEditorComponent.c",
|
||||
"Scripts/Game/Components/PlayerController/ESCT_SpectatorComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_AmbientCameraDirectorComponent.c",
|
||||
"Scripts/Game/UI/ScreenEffects/ESCT_SpectatorBleedingScreenEffect.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Observer.c"
|
||||
],
|
||||
"remaining": "Spectator reason messages and survivor-cycling guidance are added and compile. Verify visible presentation, remote streaming, target changes and death/reconnect on real clients."
|
||||
},
|
||||
{
|
||||
"id": "environment",
|
||||
"title": "Time, weather, lights and night options",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/AI/ScriptedNodes/Conditions/ESCT_AIDecoIsSunset.c",
|
||||
"Scripts/Game/Actions/ESCT_LightUserAction.c",
|
||||
"Scripts/Game/Actions/ESCT_SwitchLightUserAction.c",
|
||||
"Scripts/Game/Components/ESCT_IndoorLampComponent.c",
|
||||
"Scripts/Game/Components/ESCT_IndoorLampSwitchProxyComponent.c",
|
||||
"Scripts/Game/Editor/Containers/Actions/ESCT_ToggleLocalEditorLimitedNightModeToolbarAction.c",
|
||||
"Scripts/Game/GameMode/ESCT_NightModeGameModeComponent.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_TimeOfDay.c",
|
||||
"Scripts/Game/Misc/ESCT_Weather.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_EnvironmentTab.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_TimeService.c",
|
||||
"docs/mission-time.md",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_EnvironmentService.c",
|
||||
"docs/environment.md"
|
||||
],
|
||||
"remaining": "Local native clock, saved date/weather choices and two real restart rounds pass. Remote agreement, lighting and long-running day/night transitions still require validation."
|
||||
},
|
||||
{
|
||||
"id": "presentation_audio",
|
||||
"title": "Voice, music, feedback and effects",
|
||||
"scope": "later",
|
||||
"status": "pending",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Components/ESCT_BarrelDamageManager.c",
|
||||
"Scripts/Game/Components/ESCT_BarrelSoundEffectComponent.c",
|
||||
"Scripts/Game/Components/FlareMine/ESCT_ProjectileSpawnerComponent.c",
|
||||
"Scripts/Game/Components/PlayerController/ESCT_EscapistsFeedbackComponent.c",
|
||||
"Scripts/Game/Components/Radio/ESCT_RadioSoundComponent.c",
|
||||
"Scripts/Game/EffectModule/ESCT_RocketBarrageEffectsModule.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_VoiceoverComponent.c",
|
||||
"Scripts/Game/Misc/ESCT_BarrelFlammableHitZone.c",
|
||||
"Scripts/Game/Misc/ESCT_EscapistsHint.c",
|
||||
"Scripts/Game/Music/ESCT_ApproachHelipadMusic.c",
|
||||
"Scripts/Game/Music/ESCT_DefendRadioMusic.c",
|
||||
"Scripts/Game/Music/ESCT_FlyAwayMusic.c",
|
||||
"Scripts/Game/Systems/ESCT_VoiceoverSystem.c",
|
||||
"Scripts/Game/VON/ESCT_VONController.c"
|
||||
],
|
||||
"replacement_files": [],
|
||||
"remaining": "Review which feedback is required for clear play; author replacements without importing original audio or UI assets."
|
||||
},
|
||||
{
|
||||
"id": "medical",
|
||||
"title": "Health, unconsciousness and casualty handling",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_LoadCasualtyVehicleUserAction.c",
|
||||
"Scripts/Game/Components/Damage/ESCT_HelicopterDamageManagerComponent.c",
|
||||
"Scripts/Game/Components/ESCT_MedicalStorageArsenalComponent.c",
|
||||
"Scripts/Game/Components/ESCT_PlayerDamageManagerComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticHospitalComponent.c",
|
||||
"Scripts/Game/Components/PlayerController/ESCT_WithstandComponent.c",
|
||||
"Scripts/Game/Components/SupportStations/ESCT_LoadCasualtyVehicleSupportStationComponent.c",
|
||||
"Scripts/Game/Enums/ESCT_EHealthType.c",
|
||||
"Scripts/Game/Misc/ESCT_Health.c",
|
||||
"Scripts/Game/Misc/ESCT_PlayerHitZone.c",
|
||||
"Scripts/Game/UI/HUD/ESCT_UnconsciousInfoDisplay.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Actors.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c"
|
||||
],
|
||||
"remaining": "Local native blood-loss treatment, consumed supplies, consciousness recovery, ground casualty loading and vanilla door removal pass bounded fixtures. Verify ordinary input/animation, remote ownership, bleedout, interrupted treatment and flight with casualties."
|
||||
},
|
||||
{
|
||||
"id": "enemy_coordination",
|
||||
"title": "Enemy coordination, support and threat assessment",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/AI/Behavior/ActivityFeatures/ESCT_AIActivityCallForSupportFeature.c",
|
||||
"Scripts/Game/AI/Behavior/ActivityFeatures/ESCT_AIActivityIllumFlareFeature.c",
|
||||
"Scripts/Game/AI/Behavior/ESCT_AICallForSupportActivity.c",
|
||||
"Scripts/Game/AI/Behavior/ESCT_AICallSupportToBehavior.c",
|
||||
"Scripts/Game/AI/Behavior/ESCT_AIVehicleBehavior.c",
|
||||
"Scripts/Game/AI/Components/ESCT_AIGroupInfoComponent.c",
|
||||
"Scripts/Game/AI/Components/ESCT_AIGroupUtilityComponent.c",
|
||||
"Scripts/Game/AI/Reaction/ESCT_AIGoalReaction.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Generated/EscapistsSendGoalMessage.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Generated/EscapistsSendInfoMessage.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Generated/EscapistsSendOrder.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Groups/ESCT_AICallSupport.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Groups/ESCT_AICallSupportTo.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Messages/ESCT_AIMessage.c",
|
||||
"Scripts/Game/Components/ESCT_EditableSupportComponent.c",
|
||||
"Scripts/Game/Components/ESCT_SupportCallerComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliBehaviourBaseComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliFlyByComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliLoiterComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliStrikeFireComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliStrikeMovementComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_AIGroup.c",
|
||||
"Scripts/Game/Enums/ESCT_ESupportStationType.c",
|
||||
"Scripts/Game/Enums/Support/ESCT_ESupportState.c",
|
||||
"Scripts/Game/Enums/Support/ESCT_ESupportType.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_WaypointManager.c",
|
||||
"Scripts/Game/Misc/ESCT_AirstrikeConfig.c",
|
||||
"Scripts/Game/Support/ESCT_SupportInfo.c",
|
||||
"Scripts/Game/Support/ESCT_SupportPicker.c",
|
||||
"Scripts/Game/Support/ESCT_SupportPresentationConfig.c",
|
||||
"Scripts/Game/Support/ESCT_SupportSystemConfig.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_HeliLoiterSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_HeliStrikeSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_IlluminationMortarBarrageSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_LightVehicleSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_MortarBarrageBase.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_MortarBarrageSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_QRFSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_QRFVehicleSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_RocketArtillerySupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_SmokeMortarBarrageSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_SpecOpsSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_SupportBase.c",
|
||||
"Scripts/Game/Systems/ESCT_SupportSystem.c",
|
||||
"Scripts/Game/Tasks/SupportEntities/ESCT_BaseTaskSupportEntity.c",
|
||||
"Scripts/Game/Tasks/SupportEntities/ESCT_DefendRadioTaskSupportEntity.c",
|
||||
"Scripts/Game/ThreatAssessment/ESCT_ThreatAssessmentConfig.c",
|
||||
"Scripts/Game/Utility/ESCT_GroupDirector.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQNetwork.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_MortarSystem.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQMemory.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQCoverage.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQPursuit.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQWatch.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQRoadIntercept.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_InfantrySupplyPool.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c",
|
||||
"docs/hq-air-support.md",
|
||||
"docs/multiconvoy-resupply.md",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_EngineerMine.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_EngineerMineSite.c"
|
||||
],
|
||||
"remaining": "HQ coordinates responses through delivered radio reports, bounded movement memory, search coverage, temporary infantry road interception, missing-patrol investigations and body-driven site defence. Mortars, hunters, airborne support and finite infantry resupply from all existing convoy ammo trucks are implemented. Finite engineer mine placement is connected to existing delivered infantry road posts with original-item custody, withdrawal and friendly-clearance guards; physical mine placement/arming remains unqualified. Mounted resupply is integrated but physical rearming remains unproved. Finite convoy mine resupply supports one-to-two top-ups and zero-to-one replacement for original startup-designated engineers, without generating stock or resetting placement attempts; physical delivery remains unqualified. One or two original armed escorts from the same convoy can receive finite road-interception orders from delivered travel history. A pair occupies spaced positions on one road only after both real downlinks arrive; native interception movement/hold/rejoin remain unqualified. Barricade props and full original roadblock parity remain absent. Ordinary autonomous resupply, interrupted/lost support, long sessions and multiplayer need qualification. Experimental helicopter flight remains paused."
|
||||
},
|
||||
{
|
||||
"id": "ambient",
|
||||
"title": "Ambient patrols, vehicles and civilians",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/AmbientEvents/AmbientEventTypes/ESCT_AmbientEventBase.c",
|
||||
"Scripts/Game/AmbientEvents/AmbientEventTypes/ESCT_HeliFlybyEvent.c",
|
||||
"Scripts/Game/AmbientEvents/AmbientEventTypes/ESCT_VehiclePatrolEvent.c",
|
||||
"Scripts/Game/AmbientEvents/ESCT_AmbientEventInfo.c",
|
||||
"Scripts/Game/AmbientEvents/ESCT_AmbientEventPicker.c",
|
||||
"Scripts/Game/AmbientEvents/ESCT_AmbientSystemConfig.c",
|
||||
"Scripts/Game/Components/ESCT_AmbientPatrolSpawnPointComponent.c",
|
||||
"Scripts/Game/Components/ESCT_AmbientVehicleSpawnPointComponent.c",
|
||||
"Scripts/Game/Components/ESCT_EditableAmbientEventComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_CivilianPresenceComponent.c",
|
||||
"Scripts/Game/Enums/AmbientEvent/ESCT_EAmbientEventType.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_AmbientVehicleComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_CivilianManagerComponent.c",
|
||||
"Scripts/Game/Systems/ESCT_AmbientEventSystem.c",
|
||||
"Scripts/Game/Systems/ESCT_AmbientPatrolSystem.c",
|
||||
"Scripts/Game/Systems/ESCT_AmbientVehicleSystem.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_TownGarrisons.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_ScoutSystem.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_SupplyConvoySystem.c",
|
||||
"docs/town-garrisons.md",
|
||||
"docs/hill-scouts.md",
|
||||
"docs/supply-convoys.md"
|
||||
],
|
||||
"remaining": "Finite patrols, road supply convoys, hill scouts and once-per-round town garrisons feed the force ledger and HQ. Original random ambient-event spawning is intentionally not reproduced. Civilian ambient population and broader civilian activity remain absent. Qualify ordinary encounters, navigation, losses and measured runtime cost; dormant-route arithmetic is not operational distant-unit virtualization or an FPS improvement."
|
||||
},
|
||||
{
|
||||
"id": "factions",
|
||||
"title": "Faction, group and asset catalogs",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/EntityCatalog/ESCT_EntityCatalogManagerComponent.c",
|
||||
"Scripts/Game/EntityCatalog/EntityCatalogEntryData/ESCT_EntityCatalogEntryData.c",
|
||||
"Scripts/Game/Enums/ESCT_EFactionType.c",
|
||||
"Scripts/Game/Enums/ESCT_EInsurgentsOption.c",
|
||||
"Scripts/Game/Enums/ESCT_ELookupExclusionType.c",
|
||||
"Scripts/Game/Enums/ESCT_EMilitaryBranchType.c",
|
||||
"Scripts/Game/Enums/ESCT_EUnitRole.c",
|
||||
"Scripts/Game/Factions/ESCT_Faction.c",
|
||||
"Scripts/Game/Factions/ESCT_FactionLookupValue.c",
|
||||
"Scripts/Game/Factions/ESCT_FactionManager.c",
|
||||
"Scripts/Game/Factions/ESCT_PlayerFactionInfo.c",
|
||||
"Scripts/Game/Factions/FactionLookup/ESCT_CharacterLookup.c",
|
||||
"Scripts/Game/Factions/FactionLookup/ESCT_FactionLookup.c",
|
||||
"Scripts/Game/Factions/FactionLookup/ESCT_GroupLookup.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_MilBranchInfo.c",
|
||||
"Scripts/Game/Utility/ESCT_EntityCatalogHelper.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_FactionCatalog.c",
|
||||
"addons/core/Configs/ERR/VanillaFactions.conf",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_FactionSelection.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ContentDefinition.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ContentSettings.c",
|
||||
"addons/core/Configs/ERR/Content/Registry.conf",
|
||||
"docs/content-packs.md",
|
||||
"docs/external-addons.md"
|
||||
],
|
||||
"remaining": "Vanilla US/USSR/FIA and enabled registered RHS factions support saved Escapists, enemy and independent role choices. The combined addon declares authorized RHS Status Quo, WCS Armaments and WCS BMP-1 dependencies; faction choices do not replace every specialist vehicle or kit. Verify all supported faction combinations, remote affiliation and full-mission inventory/medical/radio behavior. Installed-resource compatibility errors remain unresolved."
|
||||
},
|
||||
{
|
||||
"id": "prison",
|
||||
"title": "Prison layout, locks and initial equipment",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_LockedDoorUserAction.c",
|
||||
"Scripts/Game/Actions/ESCT_LockpickDoor.c",
|
||||
"Scripts/Game/Components/ESCT_EquipmentSlotArsenalPrisonComponent.c",
|
||||
"Scripts/Game/Components/ESCT_LockedDoorComponent.c",
|
||||
"Scripts/Game/Components/ESCT_PrisonDoorComponent.c",
|
||||
"Scripts/Game/Components/ESCT_WeaponRackArsenalPrisonComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_PrisonComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_StartAreaComponent.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_StartArea.c",
|
||||
"Scripts/Game/Enums/ESCT_EStartType.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_StartAreaSelector.c",
|
||||
"Scripts/Game/Tasks/ESCT_LockpickTask.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Prefabs/ERR/Prison.et",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Actions.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonEscapeService.c",
|
||||
"docs/prison-opening.md"
|
||||
],
|
||||
"remaining": "The authored prison, held lock action, finite starter backpack, enemy opening hold/release and alternate physical escape detection are implemented; scripted opening checks pass. Verify ordinary held input, vault/collision behavior, twelve-player access to shared finite equipment, threat balance and placement. Prison input automation remains paused."
|
||||
},
|
||||
{
|
||||
"id": "extraction",
|
||||
"title": "Extraction vehicle and round results",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Components/ESCT_EscapeHelicopterComponent.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_Helipad.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_WinLoseHandlerComponent.c",
|
||||
"Scripts/Game/GameOverScreen/ESCT_EGameOverTypes.c",
|
||||
"Scripts/Game/UI/GameOverScreens/ESCT_GameOverScreenEscapistsUIComponent.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ExtractionService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PlayerEscapeResult.c",
|
||||
"addons/core/Configs/ERR/GameOverScreens.conf",
|
||||
"docs/combined-candidate-2026-09-30.md"
|
||||
],
|
||||
"remaining": "Physical occupancy, per-player results, aircraft settling and ground casualty loading have bounded native evidence. The combined 30 September normal-catalog scripted route reaches victory and the result screen; fixture positioning is not manual piloting. Manual boarding/piloting, real reconnect, empty-server flight, remote rescue contention and multiplayer loss/restart acceptance remain."
|
||||
},
|
||||
{
|
||||
"id": "objectives_intel",
|
||||
"title": "Radio objectives, tasks and discovery",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_RadioAction.c",
|
||||
"Scripts/Game/Actions/ESCT_ReceiveRadioMessageAction.c",
|
||||
"Scripts/Game/Actions/ESCT_TuneRadioFrequencyAction.c",
|
||||
"Scripts/Game/Components/ESCT_LocationMapUIComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticInsurgentRadioStationComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticRadioStationComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_DefendRadioTaskPresentation.c",
|
||||
"Scripts/Game/Entities/ESCT_Radio.c",
|
||||
"Scripts/Game/Entities/ESCT_RadioSlotEntity.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_RadioStation.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_TaskAssignerComponent.c",
|
||||
"Scripts/Game/Systems/ESCT_KnownLocationsSystem.c",
|
||||
"Scripts/Game/Tasks/ESCT_DefendRadioTask.c",
|
||||
"Scripts/Game/Tasks/ESCT_RadioTask.c",
|
||||
"Scripts/Game/Tasks/ESCT_Task.c",
|
||||
"Scripts/Game/Tasks/ESCT_TaskInfoConfig.c",
|
||||
"Scripts/Game/Tasks/ESCT_TriggerTask.c",
|
||||
"Scripts/Game/UI/Components/ESCT_EscapistsMapUIBase.c",
|
||||
"Scripts/Game/UI/Escapists/ESCT_MapEscapistsUI.c",
|
||||
"Scripts/Game/UI/HUD/ESCT_DefendTaskDisplay.c",
|
||||
"Scripts/Game/Utility/ESCT_TaskFuncs.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Objectives.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_DiscoveryService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_DiscoveryMap.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_RadioDefenceService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveDetails.c",
|
||||
"addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelService.c",
|
||||
"docs/player-route.md"
|
||||
],
|
||||
"remaining": "Independent radio defence, carried physical intel, partial/identified discovery, shared map and native task-detail refresh are implemented. The combined scripted prison-to-radio-to-extraction route completes. A current native admin fixture completes two rerolls for 126 actors and the scripted escape; the earlier 129-actor timeout remains retained. Validate ordinary task/map usability, simultaneous real clients, discovery replication and the complete manual objective route."
|
||||
},
|
||||
{
|
||||
"id": "scavenging",
|
||||
"title": "Physical equipment, storage and scavenging",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_OpenVehicleStorageAction.c",
|
||||
"Scripts/Game/Actions/ESCT_ResourceContainerVehicleLoadAction.c",
|
||||
"Scripts/Game/Actions/ESCT_ResourceContainerVehicleUnloadAction.c",
|
||||
"Scripts/Game/Actions/ESCT_ResourceEntityRefundAction.c",
|
||||
"Scripts/Game/Components/ESCT_EditableStorageComponent.c",
|
||||
"Scripts/Game/Components/ESCT_EditableVehicleStorageComponent.c",
|
||||
"Scripts/Game/Components/ESCT_EquipmentSlotArsenalComponent.c",
|
||||
"Scripts/Game/Components/ESCT_LocationStorageComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StorageArsenalComponent.c",
|
||||
"Scripts/Game/Components/ESCT_WeaponRackArsenalComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationStorageManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationWeaponRackManagerComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_EquipmentSlotEntity.c",
|
||||
"Scripts/Game/Entities/ESCT_StorageSlotEntity.c",
|
||||
"Scripts/Game/Entities/ESCT_WeaponRack.c",
|
||||
"Scripts/Game/Entities/ESCT_WeaponRackSlotEntity.c",
|
||||
"Scripts/Game/Enums/ESCT_EMilitaryCrateType.c",
|
||||
"Scripts/Game/GameMode/Loadout/ESCT_EArsenalGameModeType.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_EquipmentInfo.c",
|
||||
"Scripts/Game/Misc/ESCT_ArsenalItem.c",
|
||||
"Scripts/Game/Misc/ESCT_ArsenalItemDisplayData.c",
|
||||
"Scripts/Game/State/ESCT_EquipmentSlotState.c",
|
||||
"Scripts/Game/State/ESCT_StorageState.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c",
|
||||
"addons/core/Prefabs/ERR/SupplyCache.et",
|
||||
"docs/field-sites.md",
|
||||
"docs/ground-transport.md"
|
||||
],
|
||||
"remaining": "Finite clue caches, hospital medical stock, field-camp weapons/documents, convoy cargo and repair/refuel supplies are authored. Physical document transfers and selected stock/medical interactions have bounded native evidence. Verify ordinary inventory access, twelve-player route balance, actual repair/refuel use, destruction and network ownership. Original unlimited refill/refund systems are not implemented."
|
||||
},
|
||||
{
|
||||
"id": "vehicles",
|
||||
"title": "Usable vehicles, locks, alarms and navigation",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_BreakIntoVehicleAction.c",
|
||||
"Scripts/Game/Actions/ESCT_CompartmentHoldAction.c",
|
||||
"Scripts/Game/Actions/ESCT_GetInUserAction.c",
|
||||
"Scripts/Game/Actions/ESCT_OpenVehicleDoorUserAction.c",
|
||||
"Scripts/Game/Components/ESCT_CarAlarmComponent.c",
|
||||
"Scripts/Game/Components/ESCT_CharacterSpawnVehicleAssistantComponent.c",
|
||||
"Scripts/Game/Components/ESCT_VehicleForceEjectComponent.c",
|
||||
"Scripts/Game/Components/ESCT_VehicleOccupantReactionComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationVehicleManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationVehiclePatrolManagerComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_VehicleSpawnPoint.c",
|
||||
"Scripts/Game/Global/ESCT_VehicleDirector.c",
|
||||
"Scripts/Game/Misc/ESCT_VehicleHitZone.c",
|
||||
"Scripts/Game/State/ESCT_PatrolVehicleState.c",
|
||||
"Scripts/Game/State/ESCT_VehicleSpawnPointState.c",
|
||||
"Scripts/Game/Utility/ESCT_RoadNavigation.c",
|
||||
"Scripts/Game/Vehicle/ESCT_VehicleControllerComponent.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c",
|
||||
"docs/ground-transport.md",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_VehicleSecurityComponent.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_VehicleSecurityActions.c",
|
||||
"docs/vehicle-security.md",
|
||||
"docs/supply-convoys.md"
|
||||
],
|
||||
"remaining": "A once-only optional locked UAZ is now configured at the normal Southern cache; parking/readiness failures preserve the clue route. One normal-catalog native run confirms safe parking, owned identity and locked state; ordinary driving remains unqualified. The supply UAZ held breach action and replicated entry/door guards are implemented. Historical Western-fixture native checks cover lock rejection/unlock, seats, engine, fuel depletion and no replacement after loss; convoy route/tactical code also exists. One-shot horn alarm playback and tagged local native hearing into radio-delivered, single-mobile-group HQ investigation are implemented. A controlled native scene now verifies hearing and original-time radio delivery into memory; audible/spatial presentation, ordinary breach input, physical investigation arrival and remote hearing/radio behavior remain unqualified. Verify ordinary held-input cancellation, manual driving, repair/refuel use, sustained navigation and remote ownership/lock replication."
|
||||
},
|
||||
{
|
||||
"id": "population",
|
||||
"title": "Locations, compositions and population ownership",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Components/ESCT_LocationItemComponent.c",
|
||||
"Scripts/Game/Components/ESCT_LocationPatrollerComponent.c",
|
||||
"Scripts/Game/Components/ESCT_PopulatedBuildingComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticLocationComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticOutpostComponent.c",
|
||||
"Scripts/Game/Components/Locations/CompositionComponents/ESCT_CheckpointCompositionComponent.c",
|
||||
"Scripts/Game/Components/Locations/CompositionComponents/ESCT_LocationCompositionComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_BaseCharacterManager.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationCharacterManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationItemManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationMilBuildingManager.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationPatrolManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationTurretManagerComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_DisableLocationEntity.c",
|
||||
"Scripts/Game/Entities/ESCT_RandomLocationHolder.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_Checkpoint.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_City.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_Location.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_LocationBase.c",
|
||||
"Scripts/Game/Enums/ESCT_ELocationSpawnReason.c",
|
||||
"Scripts/Game/Enums/ESCT_ELocationType.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_LocationConfig.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_LocationPreparer.c",
|
||||
"Scripts/Game/LocationState/ESCT_EntityState.c",
|
||||
"Scripts/Game/LocationState/ESCT_LocationState.c",
|
||||
"Scripts/Game/Misc/ESCT_LocationPatrolPoint.c",
|
||||
"Scripts/Game/State/ESCT_CharacterState.c",
|
||||
"Scripts/Game/Systems/ESCT_LocationStateSystem.c",
|
||||
"Scripts/Game/Systems/ESCT_LocationSystem.c",
|
||||
"Scripts/Game/Utility/ESCT_LocationCatalog.c",
|
||||
"Scripts/Game/Utility/ESCT_LocationFuncs.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteDefinition.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c",
|
||||
"addons/core/Prefabs/ERR/FieldCover.et",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_TownGarrisons.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_ScoutSystem.c",
|
||||
"docs/field-sites.md",
|
||||
"docs/town-garrisons.md"
|
||||
],
|
||||
"remaining": "Randomized field hospitals/camps with separate permanent defenders and mobile teams, finite settlement garrisons, hill scouts and existing objective sites are implemented. Optional-site placement may safely skip unavailable sites; later proximity does not replenish lost squads. Full checkpoint/city composition and turret-population parity remain absent. Qualify ordinary access/encounters, balance, retained losses, multiplayer cleanup and performance."
|
||||
},
|
||||
{
|
||||
"id": "lifecycle",
|
||||
"title": "Player identity, spawning and reconnect",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Character/ESCT_CharacterControllerComponent.c",
|
||||
"Scripts/Game/Character/ESCT_ChimeraCharacter.c",
|
||||
"Scripts/Game/Components/ESCT_CharacterInitComponent.c",
|
||||
"Scripts/Game/Components/ESCT_SpawnPosition.c",
|
||||
"Scripts/Game/Components/PlayerController/ESCT_EscapistsNetworkComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_CharacterSpawnPoint.c",
|
||||
"Scripts/Game/Entities/ESCT_SpawnPoint.c",
|
||||
"Scripts/Game/Enums/ESCT_ESpawnState.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_OrphanEscapistHandlerComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_SpawnLogic.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_TrackablePlayer.c",
|
||||
"Scripts/Game/Global/ESCT_CharacterHelper.c",
|
||||
"Scripts/Game/Global/ESCT_Player.c",
|
||||
"Scripts/Game/Global/ESCT_SpawnHelpers.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PlayerRoster.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnLogic.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnPlacement.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnFinalization.c"
|
||||
],
|
||||
"remaining": "Local native slot reservations, final-assignment guards and owned pending cleanup have evidence. Admission retries are bounded and obsolete callbacks cannot consume a reconnected controller's retry allowance. Real dedicated-server concurrent joins, preload races, reconnects, connection-ID reuse, spent lives, late arrivals and spectator streaming remain to be qualified."
|
||||
},
|
||||
{
|
||||
"id": "setup",
|
||||
"title": "Mission setup, configuration and administration",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Enums/ESCT_EEditableEntityLabel.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_EscapistsConfigComponent.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_GeneralConfig.c",
|
||||
"Scripts/Game/Misc/ESCT_EditableLabelConfig.c",
|
||||
"Scripts/Game/Misc/ESCT_MissionHeader.c",
|
||||
"Scripts/Game/Misc/ESCT_SetupConfig.c",
|
||||
"Scripts/Game/Misc/ESCT_Skill.c",
|
||||
"Scripts/Game/UI/Components/ESCT_SliderComponent.c",
|
||||
"Scripts/Game/UI/Components/ESCT_SpinboxComponent.c",
|
||||
"Scripts/Game/UI/Components/ESCT_ToolboxComponent.c",
|
||||
"Scripts/Game/UI/Menus/ESCT_ClientWaitScreen.c",
|
||||
"Scripts/Game/UI/Menus/ESCT_SetupMenu.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_DifficultyTab.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_MainTab.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_MenuTabBase.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_MiscTab.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_FactionMenu.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ContentMenu.c",
|
||||
"docs/content-packs.md",
|
||||
"docs/single-mod.md",
|
||||
"docs/combined-candidate-2026-09-30.md"
|
||||
],
|
||||
"remaining": "Mission-owned administration/chat, content-pack toggles, distinct faction role drafts, saved environment/settings and next-round choices are implemented. The sealed 2 October transfer-fixes package includes the recent radio/supply/mortar corrections and starts the normal mission with a local prisoner; strict packaging and installed-resource errors remain retained. Ordinary remote authorization, simultaneous administrators, full setup/restart behavior and clean package qualification remain unverified; no complete original difficulty-menu parity is claimed."
|
||||
},
|
||||
{
|
||||
"id": "mission",
|
||||
"title": "Mission state, restart and base framework",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Enums/ESCT_EGameState.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_GameModeBaseComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_GameStartComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_GameStateManagerComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_RestartTimeoutComponent.c",
|
||||
"Scripts/Game/GameMode/ESCT_EscapistsGameMode.c",
|
||||
"Scripts/Game/GameMode/ESCT_EscapistsManager.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_MissionRules.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_RadioDefenceService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ExtractionService.c",
|
||||
"docs/combined-candidate-2026-09-30.md"
|
||||
],
|
||||
"remaining": "Independent mission progression, objective services, player lifecycle, round outcomes and restart/cleanup paths are implemented. The current combined scripted escape reaches victory; historical restart fixtures retain their original scope. Complete manual play, adversarial multiplayer failure/restart/cleanup, clean package qualification and equivalent-workload performance acceptance remain pending."
|
||||
},
|
||||
{
|
||||
"id": "utilities",
|
||||
"title": "General helpers, editor labels and shared types",
|
||||
"scope": "review",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_DisableAudioWarningAction.c",
|
||||
"Scripts/Game/Actions/ESCT_HoldAction.c",
|
||||
"Scripts/Game/ESCT_Constants.c",
|
||||
"Scripts/Game/Enums/ESCT_EEditorMode.c",
|
||||
"Scripts/Game/Enums/ESCT_EGroupSize.c",
|
||||
"Scripts/Game/Global/ESCT_ActionHelper.c",
|
||||
"Scripts/Game/Global/ESCT_ComponentHelper.c",
|
||||
"Scripts/Game/Global/ESCT_EntityHelper.c",
|
||||
"Scripts/Game/Global/ESCT_GroupHelper.c",
|
||||
"Scripts/Game/Global/ESCT_Identifier.c",
|
||||
"Scripts/Game/Global/ESCT_Logger.c",
|
||||
"Scripts/Game/Global/ESCT_Misc.c",
|
||||
"Scripts/Game/Misc/ESCT_BoolValue.c",
|
||||
"Scripts/Game/Misc/ESCT_CameraPosition.c",
|
||||
"Scripts/Game/Misc/ESCT_EntitySearch.c",
|
||||
"Scripts/Game/Misc/ESCT_FloatVal.c",
|
||||
"Scripts/Game/Misc/ESCT_IntVal.c",
|
||||
"Scripts/Game/Misc/ESCT_MilBuildingSearch.c",
|
||||
"Scripts/Game/Misc/ESCT_TargetSearch.c",
|
||||
"Scripts/Game/Utility/ESCT_CumulativeWeightPicker.c",
|
||||
"Scripts/Game/Utility/ESCT_DisplayFuncs.c",
|
||||
"Scripts/Game/Utility/ESCT_Math.c",
|
||||
"Scripts/Game/Utility/ESCT_UI.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Actors.c"
|
||||
],
|
||||
"remaining": "Use vanilla utilities or small independent helpers as each consumer is replaced. A filename match does not establish equivalent behavior."
|
||||
}
|
||||
],
|
||||
"resource_work": "The 474 original prefabs, 31 layers, 24 layouts, six worlds and other original resources are not included. Required replacements are independently authored using vanilla assets and the authorized external dependencies. External asset bytes remain outside this repository; resource counts do not imply one-for-one replacements."
|
||||
}
|
||||
+594
@@ -0,0 +1,594 @@
|
||||
{
|
||||
"basis": "Read-only original package path inventory. Category assignment is an inference from file names and directories, not a code audit or proof of feature equivalence. All original script entries have a tracked responsibility; none is marked complete solely from this mapping.",
|
||||
"acceptance": "docs/acceptance.json",
|
||||
"features": [
|
||||
{
|
||||
"id": "alternate_starts",
|
||||
"title": "Helicopter-crash and hideout starts",
|
||||
"scope": "later",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Components/ESCT_HelicrashHelicopterComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_HelicrashStartComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_HideoutStartComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_HelicrashLocationHolder.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_StartRules.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_StartSetup.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_CrashSiteResources.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c",
|
||||
"docs/mission-starts.md"
|
||||
],
|
||||
"remaining": "Independent static on-foot crash aftermath and persisted next-round Prison/Crash choice are implemented. Native geometry measurement passes; integrated native crash-start flow, full human escape and multiplayer remain unqualified. Hideout starts and animated helicopter crashes remain absent; no equivalence to protected original crash logic is claimed."
|
||||
},
|
||||
{
|
||||
"id": "spectators",
|
||||
"title": "Spectators and follow cameras",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Camera/Components/ESCT_AssignTargetManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_AttachToPlayerManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_LookAtTargetManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_OrbitDistanceManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_OrbitPlayerManualCameraComponent.c",
|
||||
"Scripts/Game/Camera/Components/ESCT_SpectatorUIManualCameraComponent.c",
|
||||
"Scripts/Game/Components/Editor/ESCT_SpectatorMenuLayoutEditorComponent.c",
|
||||
"Scripts/Game/Components/PlayerController/ESCT_SpectatorComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_AmbientCameraDirectorComponent.c",
|
||||
"Scripts/Game/UI/ScreenEffects/ESCT_SpectatorBleedingScreenEffect.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Observer.c"
|
||||
],
|
||||
"remaining": "Spectator reason messages and survivor-cycling guidance are added and compile. Verify visible presentation, remote streaming, target changes and death/reconnect on real clients."
|
||||
},
|
||||
{
|
||||
"id": "environment",
|
||||
"title": "Time, weather, lights and night options",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/AI/ScriptedNodes/Conditions/ESCT_AIDecoIsSunset.c",
|
||||
"Scripts/Game/Actions/ESCT_LightUserAction.c",
|
||||
"Scripts/Game/Actions/ESCT_SwitchLightUserAction.c",
|
||||
"Scripts/Game/Components/ESCT_IndoorLampComponent.c",
|
||||
"Scripts/Game/Components/ESCT_IndoorLampSwitchProxyComponent.c",
|
||||
"Scripts/Game/Editor/Containers/Actions/ESCT_ToggleLocalEditorLimitedNightModeToolbarAction.c",
|
||||
"Scripts/Game/GameMode/ESCT_NightModeGameModeComponent.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_TimeOfDay.c",
|
||||
"Scripts/Game/Misc/ESCT_Weather.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_EnvironmentTab.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_TimeService.c",
|
||||
"docs/mission-time.md",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_EnvironmentService.c",
|
||||
"docs/environment.md"
|
||||
],
|
||||
"remaining": "Local native clock, saved date/weather choices and two real restart rounds pass. Remote agreement, lighting and long-running day/night transitions still require validation."
|
||||
},
|
||||
{
|
||||
"id": "presentation_audio",
|
||||
"title": "Voice, music, feedback and effects",
|
||||
"scope": "later",
|
||||
"status": "pending",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Components/ESCT_BarrelDamageManager.c",
|
||||
"Scripts/Game/Components/ESCT_BarrelSoundEffectComponent.c",
|
||||
"Scripts/Game/Components/FlareMine/ESCT_ProjectileSpawnerComponent.c",
|
||||
"Scripts/Game/Components/PlayerController/ESCT_EscapistsFeedbackComponent.c",
|
||||
"Scripts/Game/Components/Radio/ESCT_RadioSoundComponent.c",
|
||||
"Scripts/Game/EffectModule/ESCT_RocketBarrageEffectsModule.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_VoiceoverComponent.c",
|
||||
"Scripts/Game/Misc/ESCT_BarrelFlammableHitZone.c",
|
||||
"Scripts/Game/Misc/ESCT_EscapistsHint.c",
|
||||
"Scripts/Game/Music/ESCT_ApproachHelipadMusic.c",
|
||||
"Scripts/Game/Music/ESCT_DefendRadioMusic.c",
|
||||
"Scripts/Game/Music/ESCT_FlyAwayMusic.c",
|
||||
"Scripts/Game/Systems/ESCT_VoiceoverSystem.c",
|
||||
"Scripts/Game/VON/ESCT_VONController.c"
|
||||
],
|
||||
"replacement_files": [],
|
||||
"remaining": "Review which feedback is required for clear play; author replacements without importing original audio or UI assets."
|
||||
},
|
||||
{
|
||||
"id": "medical",
|
||||
"title": "Health, unconsciousness and casualty handling",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_LoadCasualtyVehicleUserAction.c",
|
||||
"Scripts/Game/Components/Damage/ESCT_HelicopterDamageManagerComponent.c",
|
||||
"Scripts/Game/Components/ESCT_MedicalStorageArsenalComponent.c",
|
||||
"Scripts/Game/Components/ESCT_PlayerDamageManagerComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticHospitalComponent.c",
|
||||
"Scripts/Game/Components/PlayerController/ESCT_WithstandComponent.c",
|
||||
"Scripts/Game/Components/SupportStations/ESCT_LoadCasualtyVehicleSupportStationComponent.c",
|
||||
"Scripts/Game/Enums/ESCT_EHealthType.c",
|
||||
"Scripts/Game/Misc/ESCT_Health.c",
|
||||
"Scripts/Game/Misc/ESCT_PlayerHitZone.c",
|
||||
"Scripts/Game/UI/HUD/ESCT_UnconsciousInfoDisplay.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Actors.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c"
|
||||
],
|
||||
"remaining": "Local native blood-loss treatment, consumed supplies, consciousness recovery, ground casualty loading and vanilla door removal pass bounded fixtures. Verify ordinary input/animation, remote ownership, bleedout, interrupted treatment and flight with casualties."
|
||||
},
|
||||
{
|
||||
"id": "enemy_coordination",
|
||||
"title": "Enemy coordination, support and threat assessment",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/AI/Behavior/ActivityFeatures/ESCT_AIActivityCallForSupportFeature.c",
|
||||
"Scripts/Game/AI/Behavior/ActivityFeatures/ESCT_AIActivityIllumFlareFeature.c",
|
||||
"Scripts/Game/AI/Behavior/ESCT_AICallForSupportActivity.c",
|
||||
"Scripts/Game/AI/Behavior/ESCT_AICallSupportToBehavior.c",
|
||||
"Scripts/Game/AI/Behavior/ESCT_AIVehicleBehavior.c",
|
||||
"Scripts/Game/AI/Components/ESCT_AIGroupInfoComponent.c",
|
||||
"Scripts/Game/AI/Components/ESCT_AIGroupUtilityComponent.c",
|
||||
"Scripts/Game/AI/Reaction/ESCT_AIGoalReaction.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Generated/EscapistsSendGoalMessage.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Generated/EscapistsSendInfoMessage.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Generated/EscapistsSendOrder.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Groups/ESCT_AICallSupport.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Groups/ESCT_AICallSupportTo.c",
|
||||
"Scripts/Game/AI/ScriptedNodes/Messages/ESCT_AIMessage.c",
|
||||
"Scripts/Game/Components/ESCT_EditableSupportComponent.c",
|
||||
"Scripts/Game/Components/ESCT_SupportCallerComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliBehaviourBaseComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliFlyByComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliLoiterComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliStrikeFireComponent.c",
|
||||
"Scripts/Game/Components/Heli/ESCT_HeliStrikeMovementComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_AIGroup.c",
|
||||
"Scripts/Game/Enums/ESCT_ESupportStationType.c",
|
||||
"Scripts/Game/Enums/Support/ESCT_ESupportState.c",
|
||||
"Scripts/Game/Enums/Support/ESCT_ESupportType.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_WaypointManager.c",
|
||||
"Scripts/Game/Misc/ESCT_AirstrikeConfig.c",
|
||||
"Scripts/Game/Support/ESCT_SupportInfo.c",
|
||||
"Scripts/Game/Support/ESCT_SupportPicker.c",
|
||||
"Scripts/Game/Support/ESCT_SupportPresentationConfig.c",
|
||||
"Scripts/Game/Support/ESCT_SupportSystemConfig.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_HeliLoiterSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_HeliStrikeSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_IlluminationMortarBarrageSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_LightVehicleSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_MortarBarrageBase.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_MortarBarrageSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_QRFSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_QRFVehicleSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_RocketArtillerySupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_SmokeMortarBarrageSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_SpecOpsSupport.c",
|
||||
"Scripts/Game/Support/SupportTypes/ESCT_SupportBase.c",
|
||||
"Scripts/Game/Systems/ESCT_SupportSystem.c",
|
||||
"Scripts/Game/Tasks/SupportEntities/ESCT_BaseTaskSupportEntity.c",
|
||||
"Scripts/Game/Tasks/SupportEntities/ESCT_DefendRadioTaskSupportEntity.c",
|
||||
"Scripts/Game/ThreatAssessment/ESCT_ThreatAssessmentConfig.c",
|
||||
"Scripts/Game/Utility/ESCT_GroupDirector.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQNetwork.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_MortarSystem.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQMemory.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQCoverage.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQPursuit.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQWatch.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQRoadIntercept.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_InfantrySupplyPool.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c",
|
||||
"docs/hq-air-support.md",
|
||||
"docs/multiconvoy-resupply.md",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_EngineerMine.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_EngineerMineSite.c"
|
||||
],
|
||||
"remaining": "HQ coordinates responses through delivered radio reports, bounded movement memory, search coverage, temporary infantry road interception, missing-patrol investigations and body-driven site defence. Mortars, hunters, airborne support and finite infantry resupply from all existing convoy ammo trucks are implemented. Finite engineer mine placement is connected to existing delivered infantry road posts with original-item custody, withdrawal and friendly-clearance guards; physical mine placement/arming remains unqualified. Mounted resupply is integrated but physical rearming remains unproved. Finite convoy mine resupply supports one-to-two top-ups and zero-to-one replacement for original startup-designated engineers, without generating stock or resetting placement attempts; physical delivery remains unqualified. One or two original armed escorts from the same convoy can receive finite road-interception orders from delivered travel history. A pair occupies spaced positions on one road only after both real downlinks arrive; native interception movement/hold/rejoin remain unqualified. Barricade props and full original roadblock parity remain absent. Ordinary autonomous resupply, interrupted/lost support, long sessions and multiplayer need qualification. Experimental helicopter flight remains paused."
|
||||
},
|
||||
{
|
||||
"id": "ambient",
|
||||
"title": "Ambient patrols, vehicles and civilians",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/AmbientEvents/AmbientEventTypes/ESCT_AmbientEventBase.c",
|
||||
"Scripts/Game/AmbientEvents/AmbientEventTypes/ESCT_HeliFlybyEvent.c",
|
||||
"Scripts/Game/AmbientEvents/AmbientEventTypes/ESCT_VehiclePatrolEvent.c",
|
||||
"Scripts/Game/AmbientEvents/ESCT_AmbientEventInfo.c",
|
||||
"Scripts/Game/AmbientEvents/ESCT_AmbientEventPicker.c",
|
||||
"Scripts/Game/AmbientEvents/ESCT_AmbientSystemConfig.c",
|
||||
"Scripts/Game/Components/ESCT_AmbientPatrolSpawnPointComponent.c",
|
||||
"Scripts/Game/Components/ESCT_AmbientVehicleSpawnPointComponent.c",
|
||||
"Scripts/Game/Components/ESCT_EditableAmbientEventComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_CivilianPresenceComponent.c",
|
||||
"Scripts/Game/Enums/AmbientEvent/ESCT_EAmbientEventType.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_AmbientVehicleComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_CivilianManagerComponent.c",
|
||||
"Scripts/Game/Systems/ESCT_AmbientEventSystem.c",
|
||||
"Scripts/Game/Systems/ESCT_AmbientPatrolSystem.c",
|
||||
"Scripts/Game/Systems/ESCT_AmbientVehicleSystem.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_TownGarrisons.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_ScoutSystem.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_SupplyConvoySystem.c",
|
||||
"docs/town-garrisons.md",
|
||||
"docs/hill-scouts.md",
|
||||
"docs/supply-convoys.md"
|
||||
],
|
||||
"remaining": "Finite patrols, road supply convoys, hill scouts and once-per-round town garrisons feed the force ledger and HQ. Original random ambient-event spawning is intentionally not reproduced. Civilian ambient population and broader civilian activity remain absent. Qualify ordinary encounters, navigation, losses and measured runtime cost; dormant-route arithmetic is not operational distant-unit virtualization or an FPS improvement."
|
||||
},
|
||||
{
|
||||
"id": "factions",
|
||||
"title": "Faction, group and asset catalogs",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/EntityCatalog/ESCT_EntityCatalogManagerComponent.c",
|
||||
"Scripts/Game/EntityCatalog/EntityCatalogEntryData/ESCT_EntityCatalogEntryData.c",
|
||||
"Scripts/Game/Enums/ESCT_EFactionType.c",
|
||||
"Scripts/Game/Enums/ESCT_EInsurgentsOption.c",
|
||||
"Scripts/Game/Enums/ESCT_ELookupExclusionType.c",
|
||||
"Scripts/Game/Enums/ESCT_EMilitaryBranchType.c",
|
||||
"Scripts/Game/Enums/ESCT_EUnitRole.c",
|
||||
"Scripts/Game/Factions/ESCT_Faction.c",
|
||||
"Scripts/Game/Factions/ESCT_FactionLookupValue.c",
|
||||
"Scripts/Game/Factions/ESCT_FactionManager.c",
|
||||
"Scripts/Game/Factions/ESCT_PlayerFactionInfo.c",
|
||||
"Scripts/Game/Factions/FactionLookup/ESCT_CharacterLookup.c",
|
||||
"Scripts/Game/Factions/FactionLookup/ESCT_FactionLookup.c",
|
||||
"Scripts/Game/Factions/FactionLookup/ESCT_GroupLookup.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_MilBranchInfo.c",
|
||||
"Scripts/Game/Utility/ESCT_EntityCatalogHelper.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_FactionCatalog.c",
|
||||
"addons/core/Configs/ERR/VanillaFactions.conf",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_FactionSelection.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ContentDefinition.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ContentSettings.c",
|
||||
"addons/core/Configs/ERR/Content/Registry.conf",
|
||||
"docs/content-packs.md",
|
||||
"docs/external-addons.md"
|
||||
],
|
||||
"remaining": "Vanilla US/USSR/FIA and enabled registered RHS factions support saved Escapists, enemy and independent role choices. The combined addon declares authorized RHS Status Quo, WCS Armaments and WCS BMP-1 dependencies; faction choices do not replace every specialist vehicle or kit. Verify all supported faction combinations, remote affiliation and full-mission inventory/medical/radio behavior. Installed-resource compatibility errors remain unresolved."
|
||||
},
|
||||
{
|
||||
"id": "prison",
|
||||
"title": "Prison layout, locks and initial equipment",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_LockedDoorUserAction.c",
|
||||
"Scripts/Game/Actions/ESCT_LockpickDoor.c",
|
||||
"Scripts/Game/Components/ESCT_EquipmentSlotArsenalPrisonComponent.c",
|
||||
"Scripts/Game/Components/ESCT_LockedDoorComponent.c",
|
||||
"Scripts/Game/Components/ESCT_PrisonDoorComponent.c",
|
||||
"Scripts/Game/Components/ESCT_WeaponRackArsenalPrisonComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_PrisonComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_StartAreaComponent.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_StartArea.c",
|
||||
"Scripts/Game/Enums/ESCT_EStartType.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_StartAreaSelector.c",
|
||||
"Scripts/Game/Tasks/ESCT_LockpickTask.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Prefabs/ERR/Prison.et",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Actions.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonEscapeService.c",
|
||||
"docs/prison-opening.md"
|
||||
],
|
||||
"remaining": "The authored prison, held lock action, finite starter backpack, enemy opening hold/release and alternate physical escape detection are implemented; scripted opening checks pass. Verify ordinary held input, vault/collision behavior, twelve-player access to shared finite equipment, threat balance and placement. Prison input automation remains paused."
|
||||
},
|
||||
{
|
||||
"id": "extraction",
|
||||
"title": "Extraction vehicle and round results",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Components/ESCT_EscapeHelicopterComponent.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_Helipad.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_WinLoseHandlerComponent.c",
|
||||
"Scripts/Game/GameOverScreen/ESCT_EGameOverTypes.c",
|
||||
"Scripts/Game/UI/GameOverScreens/ESCT_GameOverScreenEscapistsUIComponent.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ExtractionService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PlayerEscapeResult.c",
|
||||
"addons/core/Configs/ERR/GameOverScreens.conf",
|
||||
"docs/combined-candidate-2026-09-30.md"
|
||||
],
|
||||
"remaining": "Physical occupancy, per-player results, aircraft settling and ground casualty loading have bounded native evidence. The combined 30 September normal-catalog scripted route reaches victory and the result screen; fixture positioning is not manual piloting. Manual boarding/piloting, real reconnect, empty-server flight, remote rescue contention and multiplayer loss/restart acceptance remain."
|
||||
},
|
||||
{
|
||||
"id": "objectives_intel",
|
||||
"title": "Radio objectives, tasks and discovery",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_RadioAction.c",
|
||||
"Scripts/Game/Actions/ESCT_ReceiveRadioMessageAction.c",
|
||||
"Scripts/Game/Actions/ESCT_TuneRadioFrequencyAction.c",
|
||||
"Scripts/Game/Components/ESCT_LocationMapUIComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticInsurgentRadioStationComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticRadioStationComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_DefendRadioTaskPresentation.c",
|
||||
"Scripts/Game/Entities/ESCT_Radio.c",
|
||||
"Scripts/Game/Entities/ESCT_RadioSlotEntity.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_RadioStation.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_TaskAssignerComponent.c",
|
||||
"Scripts/Game/Systems/ESCT_KnownLocationsSystem.c",
|
||||
"Scripts/Game/Tasks/ESCT_DefendRadioTask.c",
|
||||
"Scripts/Game/Tasks/ESCT_RadioTask.c",
|
||||
"Scripts/Game/Tasks/ESCT_Task.c",
|
||||
"Scripts/Game/Tasks/ESCT_TaskInfoConfig.c",
|
||||
"Scripts/Game/Tasks/ESCT_TriggerTask.c",
|
||||
"Scripts/Game/UI/Components/ESCT_EscapistsMapUIBase.c",
|
||||
"Scripts/Game/UI/Escapists/ESCT_MapEscapistsUI.c",
|
||||
"Scripts/Game/UI/HUD/ESCT_DefendTaskDisplay.c",
|
||||
"Scripts/Game/Utility/ESCT_TaskFuncs.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Objectives.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_DiscoveryService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_DiscoveryMap.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_RadioDefenceService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveDetails.c",
|
||||
"addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelService.c",
|
||||
"docs/player-route.md"
|
||||
],
|
||||
"remaining": "Independent radio defence, carried physical intel, partial/identified discovery, shared map and native task-detail refresh are implemented. The combined scripted prison-to-radio-to-extraction route completes. A current native admin fixture completes two rerolls for 126 actors and the scripted escape; the earlier 129-actor timeout remains retained. Validate ordinary task/map usability, simultaneous real clients, discovery replication and the complete manual objective route."
|
||||
},
|
||||
{
|
||||
"id": "scavenging",
|
||||
"title": "Physical equipment, storage and scavenging",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_OpenVehicleStorageAction.c",
|
||||
"Scripts/Game/Actions/ESCT_ResourceContainerVehicleLoadAction.c",
|
||||
"Scripts/Game/Actions/ESCT_ResourceContainerVehicleUnloadAction.c",
|
||||
"Scripts/Game/Actions/ESCT_ResourceEntityRefundAction.c",
|
||||
"Scripts/Game/Components/ESCT_EditableStorageComponent.c",
|
||||
"Scripts/Game/Components/ESCT_EditableVehicleStorageComponent.c",
|
||||
"Scripts/Game/Components/ESCT_EquipmentSlotArsenalComponent.c",
|
||||
"Scripts/Game/Components/ESCT_LocationStorageComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StorageArsenalComponent.c",
|
||||
"Scripts/Game/Components/ESCT_WeaponRackArsenalComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationStorageManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationWeaponRackManagerComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_EquipmentSlotEntity.c",
|
||||
"Scripts/Game/Entities/ESCT_StorageSlotEntity.c",
|
||||
"Scripts/Game/Entities/ESCT_WeaponRack.c",
|
||||
"Scripts/Game/Entities/ESCT_WeaponRackSlotEntity.c",
|
||||
"Scripts/Game/Enums/ESCT_EMilitaryCrateType.c",
|
||||
"Scripts/Game/GameMode/Loadout/ESCT_EArsenalGameModeType.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_EquipmentInfo.c",
|
||||
"Scripts/Game/Misc/ESCT_ArsenalItem.c",
|
||||
"Scripts/Game/Misc/ESCT_ArsenalItemDisplayData.c",
|
||||
"Scripts/Game/State/ESCT_EquipmentSlotState.c",
|
||||
"Scripts/Game/State/ESCT_StorageState.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c",
|
||||
"addons/core/Prefabs/ERR/SupplyCache.et",
|
||||
"docs/field-sites.md",
|
||||
"docs/ground-transport.md"
|
||||
],
|
||||
"remaining": "Finite clue caches, hospital medical stock, field-camp weapons/documents, convoy cargo and repair/refuel supplies are authored. Physical document transfers and selected stock/medical interactions have bounded native evidence. Verify ordinary inventory access, twelve-player route balance, actual repair/refuel use, destruction and network ownership. Original unlimited refill/refund systems are not implemented."
|
||||
},
|
||||
{
|
||||
"id": "vehicles",
|
||||
"title": "Usable vehicles, locks, alarms and navigation",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_BreakIntoVehicleAction.c",
|
||||
"Scripts/Game/Actions/ESCT_CompartmentHoldAction.c",
|
||||
"Scripts/Game/Actions/ESCT_GetInUserAction.c",
|
||||
"Scripts/Game/Actions/ESCT_OpenVehicleDoorUserAction.c",
|
||||
"Scripts/Game/Components/ESCT_CarAlarmComponent.c",
|
||||
"Scripts/Game/Components/ESCT_CharacterSpawnVehicleAssistantComponent.c",
|
||||
"Scripts/Game/Components/ESCT_VehicleForceEjectComponent.c",
|
||||
"Scripts/Game/Components/ESCT_VehicleOccupantReactionComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationVehicleManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationVehiclePatrolManagerComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_VehicleSpawnPoint.c",
|
||||
"Scripts/Game/Global/ESCT_VehicleDirector.c",
|
||||
"Scripts/Game/Misc/ESCT_VehicleHitZone.c",
|
||||
"Scripts/Game/State/ESCT_PatrolVehicleState.c",
|
||||
"Scripts/Game/State/ESCT_VehicleSpawnPointState.c",
|
||||
"Scripts/Game/Utility/ESCT_RoadNavigation.c",
|
||||
"Scripts/Game/Vehicle/ESCT_VehicleControllerComponent.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c",
|
||||
"docs/ground-transport.md",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_VehicleSecurityComponent.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_VehicleSecurityActions.c",
|
||||
"docs/vehicle-security.md",
|
||||
"docs/supply-convoys.md"
|
||||
],
|
||||
"remaining": "A once-only optional locked UAZ is now configured at the normal Southern cache; parking/readiness failures preserve the clue route. One normal-catalog native run confirms safe parking, owned identity and locked state; ordinary driving remains unqualified. The supply UAZ held breach action and replicated entry/door guards are implemented. Historical Western-fixture native checks cover lock rejection/unlock, seats, engine, fuel depletion and no replacement after loss; convoy route/tactical code also exists. One-shot horn alarm playback and tagged local native hearing into radio-delivered, single-mobile-group HQ investigation are implemented. A controlled native scene now verifies hearing and original-time radio delivery into memory; audible/spatial presentation, ordinary breach input, physical investigation arrival and remote hearing/radio behavior remain unqualified. Verify ordinary held-input cancellation, manual driving, repair/refuel use, sustained navigation and remote ownership/lock replication."
|
||||
},
|
||||
{
|
||||
"id": "population",
|
||||
"title": "Locations, compositions and population ownership",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Components/ESCT_LocationItemComponent.c",
|
||||
"Scripts/Game/Components/ESCT_LocationPatrollerComponent.c",
|
||||
"Scripts/Game/Components/ESCT_PopulatedBuildingComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticLocationComponent.c",
|
||||
"Scripts/Game/Components/ESCT_StaticOutpostComponent.c",
|
||||
"Scripts/Game/Components/Locations/CompositionComponents/ESCT_CheckpointCompositionComponent.c",
|
||||
"Scripts/Game/Components/Locations/CompositionComponents/ESCT_LocationCompositionComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_BaseCharacterManager.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationCharacterManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationItemManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationMilBuildingManager.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationPatrolManagerComponent.c",
|
||||
"Scripts/Game/Components/Locations/ESCT_LocationTurretManagerComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_DisableLocationEntity.c",
|
||||
"Scripts/Game/Entities/ESCT_RandomLocationHolder.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_Checkpoint.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_City.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_Location.c",
|
||||
"Scripts/Game/Entities/Locations/ESCT_LocationBase.c",
|
||||
"Scripts/Game/Enums/ESCT_ELocationSpawnReason.c",
|
||||
"Scripts/Game/Enums/ESCT_ELocationType.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_LocationConfig.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_LocationPreparer.c",
|
||||
"Scripts/Game/LocationState/ESCT_EntityState.c",
|
||||
"Scripts/Game/LocationState/ESCT_LocationState.c",
|
||||
"Scripts/Game/Misc/ESCT_LocationPatrolPoint.c",
|
||||
"Scripts/Game/State/ESCT_CharacterState.c",
|
||||
"Scripts/Game/Systems/ESCT_LocationStateSystem.c",
|
||||
"Scripts/Game/Systems/ESCT_LocationSystem.c",
|
||||
"Scripts/Game/Utility/ESCT_LocationCatalog.c",
|
||||
"Scripts/Game/Utility/ESCT_LocationFuncs.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteDefinition.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c",
|
||||
"addons/core/Prefabs/ERR/FieldCover.et",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_TownGarrisons.c",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_ScoutSystem.c",
|
||||
"docs/field-sites.md",
|
||||
"docs/town-garrisons.md"
|
||||
],
|
||||
"remaining": "Randomized field hospitals/camps with separate permanent defenders and mobile teams, finite settlement garrisons, hill scouts and existing objective sites are implemented. Optional-site placement may safely skip unavailable sites; later proximity does not replenish lost squads. Full checkpoint/city composition and turret-population parity remain absent. Qualify ordinary access/encounters, balance, retained losses, multiplayer cleanup and performance."
|
||||
},
|
||||
{
|
||||
"id": "lifecycle",
|
||||
"title": "Player identity, spawning and reconnect",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Character/ESCT_CharacterControllerComponent.c",
|
||||
"Scripts/Game/Character/ESCT_ChimeraCharacter.c",
|
||||
"Scripts/Game/Components/ESCT_CharacterInitComponent.c",
|
||||
"Scripts/Game/Components/ESCT_SpawnPosition.c",
|
||||
"Scripts/Game/Components/PlayerController/ESCT_EscapistsNetworkComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_CharacterSpawnPoint.c",
|
||||
"Scripts/Game/Entities/ESCT_SpawnPoint.c",
|
||||
"Scripts/Game/Enums/ESCT_ESpawnState.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_OrphanEscapistHandlerComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_SpawnLogic.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_TrackablePlayer.c",
|
||||
"Scripts/Game/Global/ESCT_CharacterHelper.c",
|
||||
"Scripts/Game/Global/ESCT_Player.c",
|
||||
"Scripts/Game/Global/ESCT_SpawnHelpers.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PlayerRoster.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnLogic.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnPlacement.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnFinalization.c"
|
||||
],
|
||||
"remaining": "Local native slot reservations, final-assignment guards and owned pending cleanup have evidence. Admission retries are bounded and obsolete callbacks cannot consume a reconnected controller's retry allowance. Real dedicated-server concurrent joins, preload races, reconnects, connection-ID reuse, spent lives, late arrivals and spectator streaming remain to be qualified."
|
||||
},
|
||||
{
|
||||
"id": "setup",
|
||||
"title": "Mission setup, configuration and administration",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Enums/ESCT_EEditableEntityLabel.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_EscapistsConfigComponent.c",
|
||||
"Scripts/Game/GameMode/Misc/ESCT_GeneralConfig.c",
|
||||
"Scripts/Game/Misc/ESCT_EditableLabelConfig.c",
|
||||
"Scripts/Game/Misc/ESCT_MissionHeader.c",
|
||||
"Scripts/Game/Misc/ESCT_SetupConfig.c",
|
||||
"Scripts/Game/Misc/ESCT_Skill.c",
|
||||
"Scripts/Game/UI/Components/ESCT_SliderComponent.c",
|
||||
"Scripts/Game/UI/Components/ESCT_SpinboxComponent.c",
|
||||
"Scripts/Game/UI/Components/ESCT_ToolboxComponent.c",
|
||||
"Scripts/Game/UI/Menus/ESCT_ClientWaitScreen.c",
|
||||
"Scripts/Game/UI/Menus/ESCT_SetupMenu.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_DifficultyTab.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_MainTab.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_MenuTabBase.c",
|
||||
"Scripts/Game/UI/Menus/SetupMenuTabs/ESCT_MiscTab.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_FactionMenu.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ContentMenu.c",
|
||||
"docs/content-packs.md",
|
||||
"docs/single-mod.md",
|
||||
"docs/combined-candidate-2026-09-30.md"
|
||||
],
|
||||
"remaining": "Mission-owned administration/chat, content-pack toggles, distinct faction role drafts, saved environment/settings and next-round choices are implemented. The sealed 2 October transfer-fixes package includes the recent radio/supply/mortar corrections and starts the normal mission with a local prisoner; strict packaging and installed-resource errors remain retained. Ordinary remote authorization, simultaneous administrators, full setup/restart behavior and clean package qualification remain unverified; no complete original difficulty-menu parity is claimed."
|
||||
},
|
||||
{
|
||||
"id": "mission",
|
||||
"title": "Mission state, restart and base framework",
|
||||
"scope": "first-release",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Enums/ESCT_EGameState.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_GameModeBaseComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_GameStartComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_GameStateManagerComponent.c",
|
||||
"Scripts/Game/GameMode/Components/ESCT_RestartTimeoutComponent.c",
|
||||
"Scripts/Game/GameMode/ESCT_EscapistsGameMode.c",
|
||||
"Scripts/Game/GameMode/ESCT_EscapistsManager.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_MissionRules.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_RadioDefenceService.c",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ExtractionService.c",
|
||||
"docs/combined-candidate-2026-09-30.md"
|
||||
],
|
||||
"remaining": "Independent mission progression, objective services, player lifecycle, round outcomes and restart/cleanup paths are implemented. The current combined scripted escape reaches victory; historical restart fixtures retain their original scope. Complete manual play, adversarial multiplayer failure/restart/cleanup, clean package qualification and equivalent-workload performance acceptance remain pending."
|
||||
},
|
||||
{
|
||||
"id": "utilities",
|
||||
"title": "General helpers, editor labels and shared types",
|
||||
"scope": "review",
|
||||
"status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Actions/ESCT_DisableAudioWarningAction.c",
|
||||
"Scripts/Game/Actions/ESCT_HoldAction.c",
|
||||
"Scripts/Game/ESCT_Constants.c",
|
||||
"Scripts/Game/Enums/ESCT_EEditorMode.c",
|
||||
"Scripts/Game/Enums/ESCT_EGroupSize.c",
|
||||
"Scripts/Game/Global/ESCT_ActionHelper.c",
|
||||
"Scripts/Game/Global/ESCT_ComponentHelper.c",
|
||||
"Scripts/Game/Global/ESCT_EntityHelper.c",
|
||||
"Scripts/Game/Global/ESCT_GroupHelper.c",
|
||||
"Scripts/Game/Global/ESCT_Identifier.c",
|
||||
"Scripts/Game/Global/ESCT_Logger.c",
|
||||
"Scripts/Game/Global/ESCT_Misc.c",
|
||||
"Scripts/Game/Misc/ESCT_BoolValue.c",
|
||||
"Scripts/Game/Misc/ESCT_CameraPosition.c",
|
||||
"Scripts/Game/Misc/ESCT_EntitySearch.c",
|
||||
"Scripts/Game/Misc/ESCT_FloatVal.c",
|
||||
"Scripts/Game/Misc/ESCT_IntVal.c",
|
||||
"Scripts/Game/Misc/ESCT_MilBuildingSearch.c",
|
||||
"Scripts/Game/Misc/ESCT_TargetSearch.c",
|
||||
"Scripts/Game/Utility/ESCT_CumulativeWeightPicker.c",
|
||||
"Scripts/Game/Utility/ESCT_DisplayFuncs.c",
|
||||
"Scripts/Game/Utility/ESCT_Math.c",
|
||||
"Scripts/Game/Utility/ESCT_UI.c"
|
||||
],
|
||||
"replacement_files": [
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Actors.c"
|
||||
],
|
||||
"remaining": "Use vanilla utilities or small independent helpers as each consumer is replaced. A filename match does not establish equivalent behavior."
|
||||
}
|
||||
],
|
||||
"resource_work": "The 474 original prefabs, 31 layers, 24 layouts, six worlds and other original resources are not included. Required replacements are independently authored using vanilla assets and the authorized external dependencies. External asset bytes remain outside this repository; resource counts do not imply one-for-one replacements."
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
--- /dev/null
|
||||
+++ b/docs/mission-starts.md
|
||||
@@ -0,0 +1,29 @@
|
||||
+# Mission starts
|
||||
+
|
||||
+Prison remains the default. Administrators can choose a static crash aftermath for the next round in `/esc menu` → Settings, or through chat:
|
||||
+
|
||||
+| Command | Effect |
|
||||
+| --- | --- |
|
||||
+| `/esc mission start show` | Show the saved next start and this round’s selected start |
|
||||
+| `/esc mission start set prison` | Save Prison for the next round |
|
||||
+| `/esc mission start set crash` | Save Crash for the next round |
|
||||
+
|
||||
+Numeric `0` and `1` are also accepted. There is no random start or reroll. Changing the saved choice does not move current players, replace the start site, or restart the mission.
|
||||
+
|
||||
+The server freezes the selection before preparing sites and replicates it to clients. Late joins and reconnects use that same round selection. A new round adopts the saved choice. The server stores it as integer `mission.startMode` in [`$profile:Escapists.json`](configuration.md#one-server-configuration); older files without this field select Prison. For manual edits, stop the mission, preserve the rest of the configuration, change only that field, and restart.
|
||||
+
|
||||
+## Playing from the crash site
|
||||
+
|
||||
+Crash mode places you on foot beside a static helicopter wreck. Search the salvage backpack for weapons and a field map, then follow the marked clue sites to find the radio. There is no prison gate to unlock. This is an aftermath scene: it does not fly or crash an aircraft, seat players, apply crash injuries, or grant a second life.
|
||||
+
|
||||
+The start cache and map retain their finite authored stock. Clue folders, radio defence, medical recovery and extraction use the existing mission rules; changing start type does not refill supplies or reveal the radio. Existing one-life admission and reconnect rules still apply. New arrivals use the normal survivor-near placement, with the starting area as fallback.
|
||||
+
|
||||
+Extraction distance is measured from the starting area in either mode. Gather everyone intended for rescue before flying beyond the boundary; only living prisoners aboard escape, including unconscious passengers. Players left behind do not escape.
|
||||
+
|
||||
+Placement checks the admission/cache area and the measured wreck footprint before spawning. If the configured composition or terrain cannot satisfy preparation, spawning is withheld with the normal administrator diagnosis; there is no silent fallback to Prison.
|
||||
+
|
||||
+## Resources and validation
|
||||
+
|
||||
+The aftermath uses an audited vanilla static wreck and successor-owned start setup. It adds no new external addon dependency. The current project still requires its declared RHS, WCS Armament, WCS BMP and Parachute Framework dependencies and their dependency closure; choosing Prison does not unload them. See the [external addon inventory](external-addons.json) for exact identities.
|
||||
+
|
||||
+The [native geometry run](evidence/native-2026-10-03-crash-geometry/report.json) passed 32 assertions and one completion with no script failures, while retaining 13 engine/resource errors. It measured the inert wreck’s bounds and verified owned probe cleanup. That run predates the integrated crash-start flow and does not prove crash terrain placement, player admission, a full escape, manual UI use, multiplayer or FPS. Focused settings and core-policy tests use native boundaries represented by test doubles. A native crash-start flow check is still pending; hideout starts and animated helicopter crashes are not implemented by this feature.
|
||||
--- a/docs/original-feature-coverage.json
|
||||
+++ b/docs/original-feature-coverage.json
|
||||
@@ -6,15 +6,21 @@
|
||||
"id": "alternate_starts",
|
||||
"title": "Helicopter-crash and hideout starts",
|
||||
"scope": "later",
|
||||
- "status": "pending",
|
||||
+ "status": "partial",
|
||||
"original_scripts": [
|
||||
"Scripts/Game/Components/ESCT_HelicrashHelicopterComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_HelicrashStartComponent.c",
|
||||
"Scripts/Game/Components/Start/ESCT_HideoutStartComponent.c",
|
||||
"Scripts/Game/Entities/ESCT_HelicrashLocationHolder.c"
|
||||
],
|
||||
- "replacement_files": [],
|
||||
- "remaining": "Author separate layouts and progression rules after the prison release."
|
||||
+ "replacement_files": [
|
||||
+ "addons/core/Scripts/Game/ERR/00_Core/ERR_StartRules.c",
|
||||
+ "addons/core/Scripts/Game/ERR/00_Core/ERR_StartSetup.c",
|
||||
+ "addons/core/Scripts/Game/ERR/00_Core/ERR_CrashSiteResources.c",
|
||||
+ "addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c",
|
||||
+ "docs/mission-starts.md"
|
||||
+ ],
|
||||
+ "remaining": "Independent static on-foot crash aftermath and persisted next-round Prison/Crash choice are implemented. Native geometry measurement passes; integrated native crash-start flow, full human escape and multiplayer remain unqualified. Hideout starts and animated helicopter crashes remain absent; no equivalence to protected original crash logic is claimed."
|
||||
},
|
||||
{
|
||||
"id": "spectators",
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"approved_schema": true,
|
||||
"source": "/tmp/erri-workbench-crash-geometry-20261003-1852/profile/Escapists.json",
|
||||
"source_sha256": "129d444c2c052d1dbea668ad0f26cc54b8bb79d9c4bfef19be5c97d2878c51a5",
|
||||
"source_version": 1,
|
||||
"source_startMode": "absent; current parser defaults0",
|
||||
"target_change": "Copy complete object into fresh private profile/Escapists.json and set mission.startMode to integer1 only. Preserve all other fields and sections.",
|
||||
"evidence": [
|
||||
"ERR_ProfileConfig.Section maps ERR_Settings.PATH to mission.",
|
||||
"ERR_Settings.AddedDefault(startMode)==0; Valid accepts only0or1; Parse rejects fractional/out-of-range values."
|
||||
],
|
||||
"profile_writes_performed": false
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"files": {
|
||||
"docs/mission-starts.md": {
|
||||
"baseline_sha256": null,
|
||||
"proposal_sha256": "918748db17ca8a277b9627fd040f231a88ce9ea25669efcf7dad27d9408c745a"
|
||||
},
|
||||
"docs/original-feature-coverage.json": {
|
||||
"baseline_sha256": "fec7f3fa341b40db09b1d7c9d96907929210b2474048127c4415de0de27f4383",
|
||||
"proposal_sha256": "d311527b59f49fbe49b09b96947e42cfa8cdbb244c00a116e179d3163bd6e9e7"
|
||||
}
|
||||
},
|
||||
"patch_sha256": "cd4abda604635fab53fb2acbe76e123468b565a4151abacca4d60ed2780b2541",
|
||||
"scope": "Scratch documentation proposal only. No current-status update or live writes. Native crash route pending."
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"conclusion": "IsAIActivated does not identify prison hold. SDK explicitly says agents are disabled at maxLOD. The failed all-active assertion does not prove a prison-release defect. Individual failed agent LOD/cause was not logged, so distance dormancy remains a source-supported explanation, not established attribution.",
|
||||
"sdk": {
|
||||
"path": "/tmp/erri-vanilla-stock/scripts/Game/generated/AI/AIAgent.c",
|
||||
"sha256": "83d066ddd047136cc045228ce41e6a5f50f2b603c33fc7a0b4140061844f2a98",
|
||||
"lines": "20-37 GetLOD/SetPermanentLOD/PreventMaxLOD/AllowMaxLOD and native maxLOD disable semantics"
|
||||
},
|
||||
"phase_history": "Smoke EOnInit subscribes before scheduled StartScenario (1500ms); crash flag assigned before subscription. ERR_SmokePhase records any entered PRISON. Initial route requires RADIO_SEARCH. Existing source ERR_PrisonPhaseChanged unsubscribes and releases on current==RADIO_SEARCH without depending on previous; test now explicitly covers0->2 and1->2.",
|
||||
"limits": [
|
||||
"Probe enumerates currently retained force-ledger group agents; no claim of a historical roster snapshot or replacement detection.",
|
||||
"Active/dormant counts are diagnostic only and do not attribute dormancy to one engine subsystem.",
|
||||
"No native rerun by reviewer; no proof of crash full route yet."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c
|
||||
@@ -4,6 +4,10 @@
|
||||
modded class SCR_ChimeraAIAgent
|
||||
{
|
||||
protected ERR_GameMode m_ERRPrisonMode;
|
||||
+#ifdef WORKBENCH
|
||||
+ // Observe only this mission hold; native distance LOD may independently deactivate AI.
|
||||
+ bool ERR_PrisonHeldForTest() { return m_ERRPrisonMode != null; }
|
||||
+#endif
|
||||
|
||||
void ERR_HoldForPrison()
|
||||
{
|
||||
--- a/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
||||
@@ -541,6 +541,29 @@
|
||||
PrintFormat("ERR PRISON AI: checked=%1 active=%2", checked, active);
|
||||
return checked > 0;
|
||||
}
|
||||
+ protected bool ERR_CrashPrisonHoldReleased()
|
||||
+ {
|
||||
+ if (!Forces() || Forces().Count() > 256) return false;
|
||||
+ int checked, held, active, dormant;
|
||||
+ for (int i = 0; i < Forces().Count(); i++)
|
||||
+ {
|
||||
+ ERR_ForceRecord record = Forces().At(i);
|
||||
+ if (!record || !record.Group) continue;
|
||||
+ array<AIAgent> agents = {};
|
||||
+ record.Group.GetAgents(agents);
|
||||
+ if (agents.Count() > 128) return false;
|
||||
+ foreach (AIAgent original : agents)
|
||||
+ {
|
||||
+ SCR_ChimeraAIAgent agent = SCR_ChimeraAIAgent.Cast(original);
|
||||
+ if (!agent || !agent.GetControlledEntity()) return false;
|
||||
+ checked++;
|
||||
+ if (agent.ERR_PrisonHeldForTest()) held++;
|
||||
+ if (agent.IsAIActivated()) active++; else dormant++;
|
||||
+ }
|
||||
+ }
|
||||
+ PrintFormat("ERR CRASH PRISON HOLD: checked=%1 held=%2 active=%3 dormant=%4; native activation is independent", checked, held, active, dormant);
|
||||
+ return checked > 0 && held == 0;
|
||||
+ }
|
||||
protected void ERR_EndScreenshot() { System.MakeScreenshot("$logs:err-result"); }
|
||||
protected void ERR_BeginProtectedDeathProbe(float now)
|
||||
{
|
||||
@@ -906,7 +929,7 @@
|
||||
}
|
||||
if (m_ERRTestCrashStart)
|
||||
{
|
||||
- if (!ERR_Check(!m_ERRCrashEnteredPrison && ERR_PrisonAIState(true), "crash start never enters prison and existing enemies are active")) return;
|
||||
+ if (!ERR_Check(!m_ERRCrashEnteredPrison && ERR_CrashPrisonHoldReleased(), "crash start never enters prison and existing enemies have no prison hold")) return;
|
||||
if (!ERR_NativeCrashStartProbe.Run(this, m_ERRSmokePlayer)) { m_ERRSmokeDone = true; GetGame().GetCallqueue().Remove(ERR_SmokeTick); return; }
|
||||
}
|
||||
else
|
||||
--- a/tests/test_prison_ai.py
|
||||
+++ b/tests/test_prison_ai.py
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Run the production prison hold/release callbacks with engine boundaries stubbed."""
|
||||
from policy_harness import ROOT, body, run
|
||||
-source = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c'
|
||||
+from pathlib import Path
|
||||
+import os
|
||||
+source = Path(os.environ.get('ERR_PRISON_AI_SOURCE', ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c'))
|
||||
def cpp(signature):
|
||||
s=body(source,signature).replace('protected ','')
|
||||
for ns in ('Replication','SCR_Global','ERR_GameMode','ERR_Phase','ERR_Actors','SCR_FactionManager'):
|
||||
@@ -32,16 +34,17 @@
|
||||
struct Agent {ERR_GameMode* m_ERRPrisonMode=nullptr;Actor* actor=nullptr;bool pending=false,active=true;int starts=0;
|
||||
Actor* GetControlledEntity(){return actor;}bool IsPlayerPending_S(){return pending;}
|
||||
void DeactivateAI(){active=false;}void ActivateAI(){active=true;starts++;}
|
||||
-'''+cpp('void ERR_HoldForPrison(')+cpp('protected void ERR_PrisonUnsubscribe(')+cpp('protected void ERR_PrisonPhaseChanged(')+cpp('protected void ERR_PrisonStopped(')+r'''
|
||||
+'''+cpp('bool ERR_PrisonHeldForTest(')+cpp('void ERR_HoldForPrison(')+cpp('protected void ERR_PrisonUnsubscribe(')+cpp('protected void ERR_PrisonPhaseChanged(')+cpp('protected void ERR_PrisonStopped(')+r'''
|
||||
};
|
||||
int main(){
|
||||
for(int phase=0;phase<=1;phase++){
|
||||
ERR_GameMode mode;mode.phase=phase;ERR_GameMode::current=&mode;Actor actor;Agent a;a.actor=&actor;
|
||||
- a.ERR_HoldForPrison();assert(!a.active&&mode.phases.callbacks.size()==1&&mode.stops.callbacks.size()==1);
|
||||
+ a.ERR_HoldForPrison();assert(a.ERR_PrisonHeldForTest());assert(!a.active&&mode.phases.callbacks.size()==1&&mode.stops.callbacks.size()==1);
|
||||
a.active=true;a.ERR_HoldForPrison();assert(!a.active&&mode.phases.inserted==1);
|
||||
a.ERR_PrisonPhaseChanged(0,1);assert(!a.active&&a.m_ERRPrisonMode==&mode);
|
||||
- mode.phase=2;a.ERR_PrisonPhaseChanged(1,2);assert(a.active&&a.starts==1&&!a.m_ERRPrisonMode&&mode.phases.callbacks.empty()&&mode.stops.callbacks.empty());
|
||||
+ mode.phase=2;a.ERR_PrisonPhaseChanged(phase,2);assert(a.active&&a.starts==1&&!a.m_ERRPrisonMode&&mode.phases.callbacks.empty()&&mode.stops.callbacks.empty());
|
||||
a.ERR_HoldForPrison();assert(a.active&&mode.phases.inserted==1);
|
||||
+ assert(!a.ERR_PrisonHeldForTest());a.DeactivateAI();assert(!a.active&&!a.ERR_PrisonHeldForTest());
|
||||
}
|
||||
for(int fault=0;fault<8;fault++){
|
||||
ERR_GameMode mode;ERR_GameMode::current=&mode;Actor actor;Agent a;a.actor=&actor;
|
||||
@@ -0,0 +1 @@
|
||||
PASS: production prison AI hold/release, repeat activation, authority/faction/player exclusion, dead actor and stop cleanup
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"scope": "Read-only proposed nearby activation witness; current parent native run not modified.",
|
||||
"source_sha256": "c8767f6eb946655df3c0cfcdc471e3b51b5d13cd2859c39591b12c3f5906deb9",
|
||||
"sdk_sha256": "83d066ddd047136cc045228ce41e6a5f50f2b603c33fc7a0b4140061844f2a98",
|
||||
"recommendation": "Crash-only observation at existing step3 before radio movement, after two existing2500ms waits at everon-supply-1 cache. Require at least one living nonplayer guard from exact pinned original cache roster within100m of canonical player with IsAIActivated true. Preserve original group/member identity; never spawn/activate/changeLOD. Log checked/living/nearby/nearbyActive with current GetLOD/GetPermanentLOD and prison hold flags for nearby members.",
|
||||
"identity_limit": "SiteRuntime.InitialGuardCount is a count, not retained member identities; pin initial group and agents at step0 if the assertion says original. Current GetAgents alone supports only current guard claim.",
|
||||
"sdk_limit": "Generated AIAgent documents maxLOD disabled state and native GetLOD/IsAIActivated. It does not promise reactivation within5000ms. A failed observation is retained qualification evidence, not proof of a particular production defect.",
|
||||
"changes": [],
|
||||
"compiler_or_native_runs": false
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"files": {
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c": {
|
||||
"baseline_sha256": "8709753e86dc2ca777183f08cb8fbb9851e0c0de495ca01520ebcb1b3dfa59b9",
|
||||
"proposed_sha256": "67f8b444824634fc37fc253c60fd24b56d06d971f48e56a8d53095c97aaf0070"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c": {
|
||||
"baseline_sha256": "ce55c8be0047406e17ec4dced1912332ab4347bfa1f204921302392099a9e67b",
|
||||
"proposed_sha256": "c8767f6eb946655df3c0cfcdc471e3b51b5d13cd2859c39591b12c3f5906deb9"
|
||||
},
|
||||
"tests/test_prison_ai.py": {
|
||||
"baseline_sha256": "557015a4a3191aede258dcd7dee4ec4f555c3efde02331687185ed124cebb4fc",
|
||||
"proposed_sha256": "9c0db6205bde7df7710acfc6bb20231f9e893b0f3913b7a2c4cfcf45e219a70d"
|
||||
}
|
||||
},
|
||||
"patch_sha256": "341f2a50aef996328b866830125f613ede1c94abd8f3342be210fe7d9e6d5f49",
|
||||
"test": {
|
||||
"exit_code": 0,
|
||||
"green_sha256": "63ef1dee605d5ea050f379a0fdfd398c5593126bc0db3d7cb48e12e1151c1523",
|
||||
"actual_methods": "ERR_HoldForPrison, ERR_PrisonPhaseChanged, ERR_PrisonUnsubscribe, ERR_PrisonStopped and WB getter",
|
||||
"controls": "Original assertions retained, both PREPARING and PRISON previous phases directly tested; native deactivation after release remains distinct from hold."
|
||||
},
|
||||
"scope": "WORKBENCH diagnostic only; production hold, phase callbacks, activation and stop behavior unchanged."
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"ERR_TerrainTakeover.c": "/tmp/erri-optional-identity-1509/test-root/addons/core/Scripts/Game/ERR/00_Core/ERR_TerrainTakeover.c",
|
||||
"ERR_TerrainTakeoverManagers.c": "/tmp/erri-optional-identity-1509/test-root/addons/core/Scripts/Game/ERR/00_Core/ERR_TerrainTakeoverManagers.c"
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
--- a/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c
|
||||
@@ -3,6 +3,28 @@
|
||||
// actor relocation, damage or inventory creation in this probe.
|
||||
class ERR_NativeCrashStartProbe
|
||||
{
|
||||
+ protected static SCR_AIGroup s_ClueGroup;
|
||||
+ protected static ref array<SCR_ChimeraAIAgent> s_ClueAgents = {};
|
||||
+ protected static ref array<IEntity> s_ClueBodies = {};
|
||||
+ static bool NearbyEnemies(ERR_GameMode mode, IEntity player)
|
||||
+ {
|
||||
+ ERR_SiteRuntime clue = mode.Sites().Find("everon-supply-1");
|
||||
+ if (!clue || clue.Group != s_ClueGroup || !s_ClueGroup || s_ClueAgents.IsEmpty() || s_ClueAgents.Count() != s_ClueBodies.Count()) return false;
|
||||
+ array<AIAgent> current = {}; s_ClueGroup.GetAgents(current);
|
||||
+ int nearby, active;
|
||||
+ for (int index = 0; index < s_ClueAgents.Count(); index++)
|
||||
+ {
|
||||
+ SCR_ChimeraAIAgent agent = s_ClueAgents[index]; IEntity actor = s_ClueBodies[index];
|
||||
+ if (!agent || !actor || agent.GetControlledEntity() != actor || !current.Contains(agent) || !ERR_Actors.CanFight(actor) || ERR_Actors.Player(actor)) continue;
|
||||
+ if (vector.DistanceXZ(actor.GetOrigin(), player.GetOrigin()) > 100) continue;
|
||||
+ nearby++;
|
||||
+ bool awake = agent.IsAIActivated();
|
||||
+ PrintFormat("ERR CRASH NEARBY AI: index=%1 active=%2 lod=%3 permanentLod=%4 prisonHeld=%5", index, awake, agent.GetLOD(), agent.GetPermanentLOD(), agent.ERR_PrisonHeldForTest());
|
||||
+ if (awake && !agent.ERR_PrisonHeldForTest()) active++;
|
||||
+ }
|
||||
+ PrintFormat("ERR CRASH NEARBY AI TOTAL: retained=%1 nearby=%2 active=%3; ordinary native activation after scripted cache approach, no activation override", s_ClueAgents.Count(), nearby, active);
|
||||
+ return active > 0;
|
||||
+ }
|
||||
protected static bool Check(bool condition, string message)
|
||||
{
|
||||
if (condition) { Print("ERR SMOKE PASS: crash start " + message); return true; }
|
||||
@@ -24,6 +46,18 @@
|
||||
static bool Run(ERR_GameMode mode, IEntity player)
|
||||
{
|
||||
if (!Check(mode && mode.StartMode() == 1 && mode.Phase() == ERR_Phase.RADIO_SEARCH, "frozen choice enters radio search directly")) return false;
|
||||
+ s_ClueAgents.Clear(); s_ClueBodies.Clear(); s_ClueGroup = null;
|
||||
+ ERR_SiteRuntime clue = mode.Sites().Find("everon-supply-1");
|
||||
+ if (!Check(clue && clue.Group, "retains original clue defenders before approach")) return false;
|
||||
+ s_ClueGroup = clue.Group;
|
||||
+ array<AIAgent> guards = {}; s_ClueGroup.GetAgents(guards);
|
||||
+ if (guards.IsEmpty() || guards.Count() > 16) return false;
|
||||
+ foreach (AIAgent guard : guards)
|
||||
+ {
|
||||
+ SCR_ChimeraAIAgent original = SCR_ChimeraAIAgent.Cast(guard);
|
||||
+ if (!original || !original.GetControlledEntity()) return false;
|
||||
+ s_ClueAgents.Insert(original); s_ClueBodies.Insert(original.GetControlledEntity());
|
||||
+ }
|
||||
ERR_PlayerLife life = mode.Players().CurrentActor(player);
|
||||
CompartmentAccessComponent access = CompartmentAccessComponent.Cast(player.FindComponent(CompartmentAccessComponent));
|
||||
if (!Check(life && life.UsedLife && access && !access.IsInCompartment() && ERR_Actors.CanFight(player), "ordinary canonical one-life survivor starts conscious on foot")) return false;
|
||||
--- a/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
||||
@@ -985,6 +985,7 @@
|
||||
}
|
||||
else if (m_ERRSmokeStep == 3)
|
||||
{
|
||||
+ if (m_ERRTestCrashStart && !ERR_Check(ERR_NativeCrashStartProbe.NearbyEnemies(this, m_ERRSmokePlayer), "an original nearby clue defender has native AI active after crash-route approach")) return;
|
||||
if (!ERR_CheckRouteExtras(now)) return;
|
||||
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;
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"files": {
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c": {
|
||||
"baseline_sha256": "d039027a462cc57d35d5e4f722e5b6b03e8f95a38fe66b19982092df983b1db0",
|
||||
"proposal_sha256": "957f40e36bfc025b8bc752b1f41dc177c8d0844c69ee5994321a47cf3ddea1ad"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c": {
|
||||
"baseline_sha256": "c8767f6eb946655df3c0cfcdc471e3b51b5d13cd2859c39591b12c3f5906deb9",
|
||||
"proposal_sha256": "e2a32dbe372edc2f5cd03a55dcb3dd11689ad8b60940a7a318b0c829d464d3e2"
|
||||
}
|
||||
},
|
||||
"patch_sha256": "7fe4cd7ef0df12e4e3930adfc958dea980c1ced2b030964e2c60fbd82612cb47"
|
||||
}
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
{
|
||||
"Assets/Items/Equipment/Maps/Map_Paper_01/Map_Paper_01_folded.xob": "E443663E5241622A",
|
||||
"Assets/Items/Equipment/Radios/Radio_R107M/Radio_R107M_01_item.xob": "77C9FCF3FB1246E9",
|
||||
"Assets/Items/Equipment/workspaces/paper_map.agr": "83675D0B0AB1B2C3",
|
||||
"Assets/Items/Equipment/workspaces/player_map.asi": "56794534F6B8C3D7",
|
||||
"Assets/Props/Fabric/Flags/Data/Flag_1_2_SovietArmy.emat": "B47B52D9DA68905D",
|
||||
"Assets/Props/Fabric/Flags/Data/Flag_1_2_USA.emat": "610803CC3F3D6649",
|
||||
"Assets/Props/Military/AmmoBox/EquipmentBoxWooden_01/Data/EquipmentBoxWooden_Weapon_01_USSR.emat": "7D2E831AFA5CF50D",
|
||||
"Assets/Props/Military/AmmoBox/EquipmentBoxWooden_01/EquipmentBoxWooden_Weapon_01.xob": "819ED3266EE5113B",
|
||||
"Assets/Props/Military/Sandbags/Data/Sandbags_01_Burlap_MLOD.emat": "2169E8EB73E1C127",
|
||||
"Assets/Props/Military/Sandbags/Data/Sandbags_01_short_Burlap.emat": "31529E064AA7C917",
|
||||
"Assets/Props/Military/Sandbags/Sandbag_01_short.xob": "268DBDABB3C94AD7",
|
||||
"Assets/Structures/BuildingsParts/Doors/DoorFrame_door_metal_A_RIGHT_EXT_B.xob": "E3BC73BFBC7AA497",
|
||||
"Assets/Structures/Walls/Concrete/ConcreteWall_01_3m.xob": "0B96D139FEBCA006",
|
||||
"Configs/Callsigns/Callsigns_US.conf": "CB7824D572DD0D5C",
|
||||
"Configs/Callsigns/Callsigns_USSR.conf": "958043CE1648EC43",
|
||||
"Configs/EntityCatalog/US/Characters_EntityCatalog_US.conf": "B56E8B4D4B195559",
|
||||
"Configs/EntityCatalog/US/Groups_EntityCatalog_US.conf": "4E70E7C4C2C17D4A",
|
||||
"Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf": "5F7EC52FC40A03E2",
|
||||
"Configs/EntityCatalog/US/SupplyContainerItems_EntityCatalog_US.conf": "0BF36EFF9FFAF92B",
|
||||
"Configs/EntityCatalog/US/WeaponTripod_EntityCatalog_US.conf": "0E4B62F186F97C43",
|
||||
"Configs/EntityCatalog/USSR/Characters_EntityCatalog_USSR.conf": "3B679F1799D55F6F",
|
||||
"Configs/EntityCatalog/USSR/Groups_EntityCatalog_USSR.conf": "37D5B75AAC3E72EA",
|
||||
"Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf": "C53421647C3D0D2E",
|
||||
"Configs/EntityCatalog/USSR/SupplyContainerItems_EntityCatalog_USSR.conf": "B4CA6761AC935808",
|
||||
"Configs/EntityCatalog/USSR/WeaponTripod_EntityCatalog_USSR.conf": "DDF17C8C140BD1F2",
|
||||
"Configs/Factions/BLUFOR.conf": "E7B7EA4823DD81F0",
|
||||
"Configs/Factions/FIA.conf": "8053DB656DD18B14",
|
||||
"Configs/Factions/OPFOR.conf": "B122E3B10BB3404B",
|
||||
"Configs/GameOverScreen/BaseGameOverScreensConfig.conf": "651583FFFB7FC765",
|
||||
"Configs/Identities/FactionIdentity_US.conf": "B600946E9ACC17C2",
|
||||
"Configs/Identities/FactionIdentity_USSR.conf": "FBBCD73926989580",
|
||||
"Configs/Identities/Territories/FactionHomeTerritory_US.conf": "B548A5B264939A98",
|
||||
"Configs/Identities/Territories/FactionHomeTerritory_USSR.conf": "31FC78AF00523A99",
|
||||
"Configs/Map/MapPlain.conf": "A786DD4868598F15",
|
||||
"Configs/Navmesh/Navmesh_GM_Eden_Soldier.conf": "8BBC73472092902E",
|
||||
"Configs/Navmesh/Navmesh_GM_Eden_Vehicle.conf": "0228A79846FD8A97",
|
||||
"Configs/System/ActionContext/ManualCameraContext.conf": "C538807EEE48BED8",
|
||||
"Configs/System/chimeraInputCommon.conf": "795184CF9AD764DB",
|
||||
"Configs/System/chimeraMenus.conf": "C747AFB6B750CE9A",
|
||||
"Configs/Systems/MissionSystems.conf": "C50579A2EC48E8EF",
|
||||
"Prefabs/AI/Groups/Group_Base.et": "000CD338713F2B5A",
|
||||
"Prefabs/AI/SCR_AIWorld.et": "E0A05C76552E7F58",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_Cycle.et": "35BD6541CBB8AC08",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_Defend.et": "93291E72AC23930F",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_GetIn.et": "712F4795CF8B91C7",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_GetOut.et": "C40316EE26846CAB",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_Move.et": "750A8D1695BD6998",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_SearchAndDestroy.et": "B3E7B8DC2BAB8ACC",
|
||||
"Prefabs/Characters/Campaign/Final/OPFOR/USSR_Army/Regular/Campaign_USSR_Player_MortarCrew.et": "86E565387A634103",
|
||||
"Prefabs/Characters/Core/Character_Base.et": "37578B1666981FCE",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_Base.et": "836E7E39AAC5888B",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_HeliPilot.et": "42A502E3BB727CEB",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_Sniper.et": "0F6689B491641155",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_Unarmed.et": "2F912ED6E399FF47",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/GreenBerets/Character_US_SF.et": "36E28C628A2F83CB",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/GreenBerets/Character_US_SF_Medic.et": "9A234C5857D92187",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_AR.et": "23ADBBC31B6A3DC6",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_AT.et": "1C78331E156A3D65",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_HeliPilot.et": "A62FA97C4EC64F14",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_LAT.et": "BF643BE4ADBDFDD3",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_RTO.et": "612F43A4D5AE765F",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_Rifleman.et": "DCB41B3746FDD1BE",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_SL.et": "5436629450D8387A",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_SR.et": "333DA6244C7DA34C",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_Sharpshooter.et": "976AC400219898FA",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Spetsnaz/Character_USSR_SF.et": "2DB452B3EC386B92",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Spetsnaz/Character_USSR_SF_Medic.et": "8CA70597606992EC",
|
||||
"Prefabs/Characters/Footwear/CombatBoots_US_01.et": "DAAFD15478BDE1C3",
|
||||
"Prefabs/Characters/HeadGear/Hat_Patrol_US_01/Hat_Patrol_US_01.et": "F545C1BE7C99954A",
|
||||
"Prefabs/Characters/HeadGear/Helmet_PASGT_01/Helmet_PASGT_01_base.et": "8A2B2A544F3ED831",
|
||||
"Prefabs/Characters/Uniforms/Jacket_US_BDU_rolledup.et": "3CCA7A9BB4FD3197",
|
||||
"Prefabs/Characters/Uniforms/Pants_US_BDU.et": "604BB72BE8E023C2",
|
||||
"Prefabs/Decals/Dirt/Decal_Dirt_Patch_03.et": "4AD6EB80A8B1FA3A",
|
||||
"Prefabs/Groups/BLUFOR/Group_US_FireTeam.et": "84E5BBAB25EA23E5",
|
||||
"Prefabs/Groups/INDFOR/Group_FIA_FireTeam.et": "5BEA04939D148B1D",
|
||||
"Prefabs/Groups/OPFOR/Group_USSR_Base.et": "8DE0C0830FE0C33D",
|
||||
"Prefabs/Groups/OPFOR/Group_USSR_RifleSquad.et": "E552DABF3636C2AD",
|
||||
"Prefabs/Items/Core/Item_Base.et": "C95E11C60810F432",
|
||||
"Prefabs/Items/Equipment/Backpacks/Backpack_Kolobok.et": "41A9C55B61F375F0",
|
||||
"Prefabs/Items/Equipment/Binoculars/Binoculars_B8/Binoculars_B8.et": "243948B23D90BECB",
|
||||
"Prefabs/Items/Equipment/Kits/MedicalKit_01/MedicalKit_01_US.et": "AE578EEA4244D41F",
|
||||
"Prefabs/Items/Equipment/Kits/MedicalKit_01/MedicalKit_01_USSR.et": "21EF98BFC1EB3793",
|
||||
"Prefabs/Items/Equipment/Kits/RepairKit_01/RepairKit_01_wrench.et": "33B2DFDCD0EBA3DB",
|
||||
"Prefabs/Items/Equipment/Maps/Map_Paper_01/PaperMap_01_folded.et": "13772C903CB5E4F7",
|
||||
"Prefabs/Items/Equipment/Radios/Radio_ANPRC77.et": "9B6B61BB3FE3DFB0",
|
||||
"Prefabs/Items/Equipment/Radios/Radio_R107M.et": "54C68E438DD34265",
|
||||
"Prefabs/Items/Equipment/Radios/Radio_R148.et": "E1A5D4B878AA8980",
|
||||
"Prefabs/Items/Equipment/Watches/Watch_SandY184A.et": "78ED4FEF62BBA728",
|
||||
"Prefabs/Items/Fuel/Jerrycan_01/Jerrycan_01_item.et": "12D5AD21E383B768",
|
||||
"Prefabs/Items/Medicine/FieldDressing_01/FieldDressing_USSR_01.et": "C3F1FA1E2EC2B345",
|
||||
"Prefabs/Items/Medicine/FieldDressing_01/FieldDressing_US_01.et": "A81F501D3EF6F38E",
|
||||
"Prefabs/Items/Medicine/MorphineInjection_01/MorphineInjection_01.et": "0D9A5DCF89AE7AA9",
|
||||
"Prefabs/Items/Medicine/SalineBag_01/SalineBag_USSR_01.et": "527D7C5D2E476BDC",
|
||||
"Prefabs/Items/Medicine/SalineBag_01/SalineBag_US_01.et": "00E36F41CA310E2A",
|
||||
"Prefabs/Items/Medicine/Tourniquet_01/Tourniquet_US_01.et": "D70216B1B2889129",
|
||||
"Prefabs/Items/Misc/IntelligenceFolder_E_01/IntelligenceFolder_E_01.et": "6D56FED1E55A8F84",
|
||||
"Prefabs/MP/Managers/Factions/FactionManager_Base.et": "A242612865F2A48E",
|
||||
"Prefabs/MP/Managers/Factions/FactionManager_USxUSSR.et": "589540B35EBA8CDC",
|
||||
"Prefabs/MP/Managers/Loadouts/LoadoutManager_USxUSSR.et": "97EF4C1A41F63DDB",
|
||||
"Prefabs/MP/Modes/GameMode_Base.et": "0F307326459A1395",
|
||||
"Prefabs/MP/ScriptedChatEntity.et": "F69BC912AC8236F9",
|
||||
"Prefabs/Props/EmptyStorages/USSR_AmmoBox_empty.et": "EBBC859CCD94D96D",
|
||||
"Prefabs/Props/Furniture/Table_01.et": "53506DCB398C7EBE",
|
||||
"Prefabs/Props/Military/Antennas/Antenna_FIA_02/Antenna_FIA_02_base.et": "B3949F6D215A9F78",
|
||||
"Prefabs/Props/Military/Sandbags/Sandbag_01_short_burlap.et": "CFFEB23FBEA00322",
|
||||
"Prefabs/Structures/BuildingParts/Doors/DoorSet_Base.et": "87CADB5ADC989993",
|
||||
"Prefabs/Structures/BuildingParts/Doors/Door_MetalGate_01_Short_LEFT_EXT_ST_B.et": "34B08027DBDE322A",
|
||||
"Prefabs/Structures/BuildingParts/Doors/Door_Metal_A_RIGHT_EXT_COV_B.et": "67F17696FF278AE0",
|
||||
"Prefabs/Structures/Military/Camps/TentSmallUS_01/TentSmallUS_01.et": "01AE5FD77A9A4C21",
|
||||
"Prefabs/Structures/Military/Camps/TentUSSR_01/TentUSSR_01_base.et": "BE5D5CFA90224646",
|
||||
"Prefabs/Structures/Military/Camps/TentUS_01/TentUSMedical_01.et": "F8427C3EFC52644E",
|
||||
"Prefabs/Structures/Walls/BarbedWire/BarbedTape_01/BarbedTape_01_Long_noStake.et": "46904AF5D473FB75",
|
||||
"Prefabs/Structures/Walls/BarbedWire/BarbedTape_01/BarbedTape_01_Short_noStake.et": "CAE1588B6265A2AB",
|
||||
"Prefabs/Structures/Walls/Concrete/ConcreteWall_01/ConcreteWall_01_3m.et": "60E5729BEA18F875",
|
||||
"Prefabs/Systems/Radio/RadioManager.et": "B8E09FAB91C4ECCD",
|
||||
"Prefabs/Tasks/BaseTask.et": "1D0F815858EE24AD",
|
||||
"Prefabs/Vehicles/Helicopters/Mi8MT/Mi8MT_armed.et": "7BD282AF716ED639",
|
||||
"Prefabs/Vehicles/Helicopters/Mi8MT/Mi8MT_unarmed_transport.et": "DF5CCB7C0FF049F4",
|
||||
"Prefabs/Vehicles/Wheeled/UAZ469/UAZ469.et": "259EE7B78C51B624",
|
||||
"Prefabs/Vehicles/Wheeled/UAZ469/UAZ469_PKM.et": "0B4DEA8078B78A9B",
|
||||
"Prefabs/Vehicles/Wheeled/UAZ469/VehParts/Seats/UAZ469_seats_rear.et": "780AAF0A51AEE61A",
|
||||
"Prefabs/Vehicles/Wheeled/Ural4320/Ural4320_ammo.et": "3336BE330C4F355B",
|
||||
"Prefabs/Vehicles/Wheeled/Ural4320/Ural4320_transport.et": "16C1F16C9B053801",
|
||||
"Prefabs/Weapons/Ammo/Ammo_Shell_82mm_HE_O832DU.et": "98EC9C526AFBA282",
|
||||
"Prefabs/Weapons/Attachments/Optics/Optic_4x20/Optic_4x20.et": "BD496EE1B40DC510",
|
||||
"Prefabs/Weapons/Attachments/Optics/Optic_ARTII/Optic_ARTII.et": "D2018EDB1BBF4C88",
|
||||
"Prefabs/Weapons/Attachments/Optics/Optic_PSO1/Optic_PSO1.et": "C850A33226B8F9C1",
|
||||
"Prefabs/Weapons/Core/VehiclePeriscope_DummyWeapon_Base.et": "7E1DD1CE4D6A23F4",
|
||||
"Prefabs/Weapons/Explosives/Mine_PMN4/Mine_PMN4.et": "B05A816C0BF50802",
|
||||
"Prefabs/Weapons/Handguns/PM/Handgun_PM.et": "C0F7DD85A86B2900",
|
||||
"Prefabs/Weapons/Magazines/Magazine_545x39_AK_30rnd_Ball.et": "BBB50A815A2F916B",
|
||||
"Prefabs/Weapons/Magazines/Magazine_762x51_M14_20rnd_SpecialBall.et": "627255315038152A",
|
||||
"Prefabs/Weapons/Magazines/Magazine_762x54_SVD_10rnd_Sniper.et": "9CCB46C6EE632C1A",
|
||||
"Prefabs/Weapons/Magazines/Magazine_9x18_PM_8rnd_Ball.et": "8B853CDD11BA916E",
|
||||
"Prefabs/Weapons/Mortars/2B14/Mortar_2B14.et": "D1FFE458E8AC4BDB",
|
||||
"Prefabs/Weapons/Rifles/AK74/Rifle_AK74.et": "FA5C25BF66A53DCF",
|
||||
"Prefabs/World/Game/PerceptionManager.et": "028DAEAD63E056BE",
|
||||
"Sounds/Items/_SharedData/PickUp/Items_PickUp_Map.acp": "13F8D0DE67678118",
|
||||
"Sounds/Vehicles/Wheeled/UAZ469/Vehicles_UAZ469_Horn.acp": "7E64D37BE3E1F3FA",
|
||||
"UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt": "3E7733BAC8C831F6",
|
||||
"UI/Textures/DeployMenu/Loadout-BG/Loadout_BG_USSR.imageset": "21533F2089005056",
|
||||
"UI/Textures/DeployMenu/Loadout-BG/Loadout_US_BG.imageset": "F8AC305446D5D480",
|
||||
"UI/Textures/Editor/EditableEntities/Factions/EditableEntity_Faction_USA.edds": "EB7F65DBC9392557",
|
||||
"UI/Textures/Editor/EditableEntities/Factions/EditableEntity_Faction_USSR.edds": "40B12B0DF911B856",
|
||||
"UI/Textures/Flags/US-flag-base-3it.edds": "46FB2FB2C2125A3C",
|
||||
"UI/Textures/Flags/USSR-flag-base-3it.edds": "50824EB9F2C215AB",
|
||||
"UI/Textures/Icons/icons_mapMarkersUI-glow.imageset": "67B3A6DC2D712B52",
|
||||
"UI/Textures/Icons/icons_mapMarkersUI.imageset": "E23427CAC80DA8B7",
|
||||
"UI/Textures/Icons/icons_wrapperUI-glow.imageset": "00FE3DBDFD15227B",
|
||||
"UI/Textures/Icons/icons_wrapperUI.imageset": "3262679C50EF4F01",
|
||||
"UI/layouts/HUD/GameOver/EndScreen/EndScreenContent_NoImage.layout": "C4507D07F3C54831",
|
||||
"UI/layouts/Menus/PauseMenu/PauseMenuButton.layout": "9ECCD201BCF07E95",
|
||||
"UI/layouts/Task/TaskListEntry.layout": "B71975032150BAFB",
|
||||
"UI/layouts/Task/TaskListEntryDescription.layout": "552EB1921B5C548C",
|
||||
"UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout": "75C912A1C89BE6C2",
|
||||
"UI/layouts/WidgetLibrary/ComboBox/WLib_ComboBox.layout": "4B5AE6E64037FFB4",
|
||||
"UI/layouts/WidgetLibrary/EditBox/WLib_EditBox.layout": "0022F0B45ADBC5AC",
|
||||
"system/textures/defWhite.edds": "A64A8C63E0FBAE87",
|
||||
"worlds/Eden/Eden.ent": "853E92315D1D9EFE",
|
||||
"worlds/MP/Navmeshes/LowResEden.nmn": "5E19E60F26327356"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
PASS actual runner selector/admission; unchanged default display/audio; authored identity consistency and bounded cleanup source controls. No native/managed-lifetime/geometry execution proof.
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"verdict": "No concrete resource placement or ownership conflict found in bounded read-only review.",
|
||||
"core_patch_sha256": "82d2f6c481caef7dc777fd6bf3d92258a4af4b9bf87b207aa7bc1ff4c3aabead",
|
||||
"core_manifest_sha256": "fb7315649ff74edc39375459df6acfd2018c11115dcf3a8f1ec44f7576d08161",
|
||||
"inspected_live": {
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c": "15a28876954bbbe0e80d5b5b19e7336f154023cd05b67d65dd709ae7fd9ac712",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c": "8709753e86dc2ca777183f08cb8fbb9851e0c0de495ca01520ebcb1b3dfa59b9"
|
||||
},
|
||||
"findings": [
|
||||
"Site prop elevation offset is reapplied after terrain grounding, preserving derived -minimumY.",
|
||||
"Site prop yaw and offset rotation match shared survey heading.",
|
||||
"Exact spawned static wrapper is appended to rollback ownership and site props before native navmesh rebuild.",
|
||||
"Ready mode ownership retains existing normal cleanup path; preparation failure deletes own wrapper via existing Rollback.",
|
||||
"Preparing to RadioSearch transition invokes existing prison-AI phase handler and wakes original mission forces.",
|
||||
"Two measured bounded surveys retain existing start/cache square and cover padded wreck AABB square."
|
||||
],
|
||||
"limits": [
|
||||
"No compiler or native execution by reviewer.",
|
||||
"Source Bounds intentionally false until exact measurement.",
|
||||
"Terrain sampling, physical placement, remote replication and manual play require native follow-up."
|
||||
]
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"verdict": "Verified exact raw/archive/current-source binding and strengthened scene/nearby guard evidence.",
|
||||
"archive": "/home/jakub/devel/escapistsrereintroduced/docs/evidence/native-2026-10-03-crash-start-nearby",
|
||||
"raw": "/tmp/erri-workbench-crash-nearby-20261003-1918/logs/logs_2026-10-03_19-19-25",
|
||||
"byte_verified_files": {
|
||||
"console.log.txt": "452172a013b7e38d4bc39a04b127dfea26cd590af2ab6e0cad4c6f08390938ed",
|
||||
"script.log.txt": "c0537e90f36254c930ae48b3bf2a7541726141c3885a7643f950bb73b40876e9",
|
||||
"error.log.txt": "b2f9ba80ba656a90981d456d45267e70cff7555a85af89268d5ee5ef5df002b7",
|
||||
"rereintroduced-hq.log.txt": "772b3e7d9a3d46d404b64a37a7efb95f91b322d03dc7ba656fca2a26843eba23",
|
||||
"runner.json.txt": "396397efca4b20057a563bf6120372383f663f89ea2df0111e87010302c855f9",
|
||||
"external-addons-inputs.json.txt": "f28aa36e1e9c8352773836551ad58e47df1703de3c742b069596b6fb622c6fa3",
|
||||
"launch-source.json": "4db9240e6f220a903b3b5daca0c8e319c15cfaab588627c0db185cc224f7ca31",
|
||||
"launch-source-sha256.json": "513004bc879f0850f5ffb6959725b5958df1ad737635d6b3b47be43ea35c9f5e"
|
||||
},
|
||||
"source_manifest_sha256": "513004bc879f0850f5ffb6959725b5958df1ad737635d6b3b47be43ea35c9f5e",
|
||||
"authored_source_files": 437,
|
||||
"all_current_authored_match_launch": true,
|
||||
"assertions_passed": 66,
|
||||
"smoke_completions": 1,
|
||||
"script_failures": 0,
|
||||
"engine_errors_retained": 13,
|
||||
"cleanup_confirmed": true,
|
||||
"scene": {
|
||||
"direct_start": "RADIO_SEARCH without PRISON",
|
||||
"root": "one generated owned replicated CrashSite, no prison guards/gate",
|
||||
"wreck": "one exact owned static UH1H wrapper, measured bounds fit on all3axes, offset outside all16slot positions",
|
||||
"salvage": "one finite owned bag",
|
||||
"current_direct_stock": [
|
||||
{
|
||||
"item": "PM pistols",
|
||||
"effective_resource": "{C0F7DD85A86B2900}Prefabs/Weapons/Handguns/PM/Handgun_PM.et",
|
||||
"count": 5
|
||||
},
|
||||
{
|
||||
"item": "loose PM magazines",
|
||||
"effective_resource": "{8B853CDD11BA916E}Prefabs/Weapons/Magazines/Magazine_9x18_PM_8rnd_Ball.et",
|
||||
"count": 8
|
||||
},
|
||||
{
|
||||
"item": "shared field map",
|
||||
"effective_resource": "{A46500E4A30B653B}Prefabs/Items/Equipment/ERRM_SharedFieldMap.et",
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"stock_proof": "Passing actual count==definition.Count assertions with native direct reciprocal bag storage; current counts, not immutable startup identity ledger."
|
||||
},
|
||||
"enemy_release": {
|
||||
"global_observation": {
|
||||
"checked": 75,
|
||||
"prison_held": 0,
|
||||
"native_active": 1,
|
||||
"native_dormant": 74
|
||||
},
|
||||
"nearby_originals": {
|
||||
"retained": 5,
|
||||
"nearby_within_100m": 5,
|
||||
"active": 5,
|
||||
"lod": 0,
|
||||
"permanent_lod": -1,
|
||||
"prison_held": 0,
|
||||
"identity_checks": "Exact captured original agents/bodies, retained group/current membership, alive fighting nonplayer and distance; no replaced group accepted.",
|
||||
"threshold_limit": "Fixture requires at least one active original; this native run actually logged all five active."
|
||||
},
|
||||
"activation_overrides_in_probe_or_smoke": false
|
||||
},
|
||||
"scope": [
|
||||
"Scripted local Workbench route uses player teleports and damage-protected player.",
|
||||
"Actual native inventory transfers recover existing clue documents; configured defence shortened to30seconds with interruption/reset control.",
|
||||
"Existing extraction occupancy is forced through native GetInVehicle; no manual interaction or flight proof.",
|
||||
"No multiplayer/JIP, FPS, combat survival, route walkability or helicopter flight qualification.",
|
||||
"Static wreck geometry/native placement is observed; no simulated crash, forced injuries, flight or seat transfer at initial spawn.",
|
||||
"Default prison run is separate and was still active; this review makes no claim about its completion."
|
||||
],
|
||||
"review_execution": "Read-only source/hash/log inspection only; no compiler/native run."
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
{
|
||||
"verdict": "No missing authorized dependency declaration or forbidden original Escapists requirement found.",
|
||||
"authored_files_validated": 437,
|
||||
"project": {
|
||||
"core": {
|
||||
"id": "ERR_Core",
|
||||
"guid": "2528466DE220D91C",
|
||||
"dependencies": [
|
||||
"58D0FB3206B6F859",
|
||||
"595F2BF2F44836FB",
|
||||
"5E524E4FEECCA92B",
|
||||
"629B2BA37EFFD577",
|
||||
"65930CB4CD0237B2"
|
||||
]
|
||||
}
|
||||
},
|
||||
"external_policy_sha256": "47c644504a55074c781f0e004b2b086c01dda30748240c3e5cdeb90eb40be869",
|
||||
"installed_addons": {
|
||||
"1337C0DE5DABBEEF": {
|
||||
"title": "RHS: Status Quo - Content Pack 01",
|
||||
"dependencies": [
|
||||
"58D0FB3206B6F859"
|
||||
],
|
||||
"project_sha256": "65197c50ff6e906a5732564e8b440d80ef1cdbcffead9eb388e1e2b56c1322bc",
|
||||
"rdb_sha256": "e8706d6b9bb2474b65f7c588de9fcfad4516bd26dc12e7b6b687e7973a41e7a6",
|
||||
"matches_last_native_inputs": true
|
||||
},
|
||||
"595F2BF2F44836FB": {
|
||||
"title": "RHS: Status Quo",
|
||||
"dependencies": [
|
||||
"1337C0DE5DABBEEF",
|
||||
"58D0FB3206B6F859",
|
||||
"BADC0DEDABBEDA5E"
|
||||
],
|
||||
"project_sha256": "1b83e9df126db639cfcdb6d5119e65a1581c028becd6c09998143ed527ad0721",
|
||||
"rdb_sha256": "25f6405084fd228ff400868b21f033c4c43d44162ce73de562e06d8003b94a49",
|
||||
"matches_last_native_inputs": true
|
||||
},
|
||||
"5E389BB9F58B79A6": {
|
||||
"title": "WCS_SpaceCore",
|
||||
"dependencies": [
|
||||
"58D0FB3206B6F859",
|
||||
"629B2BA37EFFD577"
|
||||
],
|
||||
"project_sha256": "2db2e318e6f45bede0d1173d77af03314f888aedfb31bc767d569ccfb6e70a34",
|
||||
"rdb_sha256": "c4293fef30948a3538751533cc52c9ce449ffada931b47a8fdf1ca48c1618e75",
|
||||
"matches_last_native_inputs": true
|
||||
},
|
||||
"5E524E4FEECCA92B": {
|
||||
"title": "WCS_BMP-1",
|
||||
"dependencies": [
|
||||
"58D0FB3206B6F859",
|
||||
"5E389BB9F58B79A6",
|
||||
"629B2BA37EFFD577"
|
||||
],
|
||||
"project_sha256": "ad44151140adf62e99eaa639984c2b9c400be17481e934186d61c307b5221259",
|
||||
"rdb_sha256": "c65677e8767d92c96c6f35b482350d56e3dccfa026a3c5470b332120990f047c",
|
||||
"matches_last_native_inputs": true
|
||||
},
|
||||
"629B2BA37EFFD577": {
|
||||
"title": "WCS_Armaments",
|
||||
"dependencies": [
|
||||
"58D0FB3206B6F859"
|
||||
],
|
||||
"project_sha256": "e6ffcf559a2e7898848349c090300ea8eca8cb2e13ecef456a108bcc82efc8b1",
|
||||
"rdb_sha256": "7f38b7ed578b0b47864648a7b70288fe49dae4cc2556d5754377a1c28b2b6532",
|
||||
"matches_last_native_inputs": true
|
||||
},
|
||||
"65930CB4CD0237B2": {
|
||||
"title": "Parachute Framework",
|
||||
"dependencies": [
|
||||
"58D0FB3206B6F859"
|
||||
],
|
||||
"project_sha256": "183fbb521382a95ad33af9efc547147a80241bd536a29d124c93064b5ae5e8bc",
|
||||
"rdb_sha256": "0994a4b1fcfacdd8d8f69759ba6bde878d633545e380a5774a05e4cac3b6b2c4",
|
||||
"matches_last_native_inputs": true
|
||||
},
|
||||
"BADC0DEDABBEDA5E": {
|
||||
"title": "RHS: Status Quo - Content Pack 02",
|
||||
"dependencies": [
|
||||
"58D0FB3206B6F859"
|
||||
],
|
||||
"project_sha256": "6ebd73d663ed6dbf981cd8bc7d19cfd5bcd3c9dec3b9a706fa331d992ef200b4",
|
||||
"rdb_sha256": "736bcd2e60177e5af99d93c6b5f07ad79a950899aaca23000f33ad405cd1b74e",
|
||||
"matches_last_native_inputs": true
|
||||
}
|
||||
},
|
||||
"exact_external_resource_identities": [
|
||||
{
|
||||
"path": "Prefabs/Weapons/Attachments/Optics/Optic_PSO1/Optic_PSO1M2.et",
|
||||
"guid": "A1D5833FF10C6503",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Weapons/Attachments/Optics/1p21/Optic_1P21.et",
|
||||
"guid": "695AAA77F84EB238",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Weapons/Attachments/Optics/m8541/Optic_M8541.et",
|
||||
"guid": "333A794F0B55C019",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Weapons/Attachments/Optics/1p78/Optic_1P78.et",
|
||||
"guid": "8D4BAA235F7EDBEA",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Configs/Factions/RHS_ION.conf",
|
||||
"guid": "CB76A36EACFBDF35",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Configs/Factions/RHS_RF_MSV.conf",
|
||||
"guid": "627A8CDE681D223D",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Configs/Factions/RHS_US_USMC.conf",
|
||||
"guid": "F33C7BF22CBF3A8A",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Groups/BLUFOR/RHS_USAF/RHS_USAF_USMC_MEF/Group_USAF_USMC_MEF_FireTeam.et",
|
||||
"guid": "19843E954790DF28",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Groups/INDFOR/RHS_ION/RHS_ION_COY/Group_RHS_ION_COY_StaticSecurityTeam.et",
|
||||
"guid": "516C8C7400DF2C4D",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Groups/OPFOR/RHS_AFRF/MSV/Flora/Group_RHS_RF_MSV_Flora_FireGroup.et",
|
||||
"guid": "AB905EF799E0A0AE",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Characters/Factions/BLUFOR/RHS_USAF/RHS_USAF_MARSOC/RandomSoldiers/Character_RHS_USMC_MARSOC_Rifleman_Random.et",
|
||||
"guid": "844936B168DFAB8E",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Characters/Factions/BLUFOR/RHS_USAF/RHS_USAF_MARSOC/RandomSoldiers/Character_RHS_USMC_MARSOC_Medic_Random.et",
|
||||
"guid": "DBB8D1F13930220E",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Characters/Factions/OPFOR/RHS_AFRF/MSV/Flora/Character_RHS_RF_MSV_Flora_SL.et",
|
||||
"guid": "B3C496CCFA72D25E",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Characters/Factions/OPFOR/RHS_AFRF/MSV/Flora/Character_RHS_RF_MSV_Flora_Medic.et",
|
||||
"guid": "D9AF475A4E5DC52C",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Characters/Factions/INDFOR/RHS_ION_Coy/RandomSoldiers/Character_RHS_ION_Coy_Rifleman_Random.et",
|
||||
"guid": "140001FC383DF9A2",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Characters/Factions/INDFOR/RHS_ION_Coy/RandomSoldiers/Character_RHS_ION_Coy_Medic_Random.et",
|
||||
"guid": "0FA8ACE19A772327",
|
||||
"addon": "595F2BF2F44836FB",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Vehicles/Tracked/BMP1/BMP1_Base.et",
|
||||
"guid": "1DC01AAACFFA8B63",
|
||||
"addon": "5E524E4FEECCA92B",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Weapons/Launchers/FIM92_Stinger/Launcher_FIM92_Stinger.et",
|
||||
"guid": "3DF204EEE0534EF2",
|
||||
"addon": "629B2BA37EFFD577",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Weapons/Launchers/9K38_IGLA/Launcher_9K38_IGLA.et",
|
||||
"guid": "962C400354E4BD6C",
|
||||
"addon": "629B2BA37EFFD577",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/Weapons/Core/Armament_Empty.et",
|
||||
"guid": "52120E4BA120661B",
|
||||
"addon": "629B2BA37EFFD577",
|
||||
"unique_installed_identity": true
|
||||
},
|
||||
{
|
||||
"path": "Prefabs/DeployedParachutes/Core/DeployedParachuteMK4.et",
|
||||
"guid": "9ADD554959C09197",
|
||||
"addon": "65930CB4CD0237B2",
|
||||
"unique_installed_identity": true
|
||||
}
|
||||
],
|
||||
"source_package_contract": [
|
||||
"Current437 authored files pass actual source_bundle.inventory + validate read-only.",
|
||||
"Exact direct dependency set is vanilla + RHS StatusQuo + WCS Armaments + WCS BMP1 + Parachute Framework.",
|
||||
"Audited transitive closure includes two RHS content packs and WCS SpaceCore; seven external addons total.",
|
||||
"Source bundle contains own addon source plus dependency metadata; external assets are not embedded.",
|
||||
"Known original ecosystem namespaces ESCT/SCRTC_/SCRT_/EAI_ rejected in authored payload; closed project and dependency identity checks exclude original Escapists addon.",
|
||||
"Native package copy_payload delegates actual source bundle validation, copies only addons/ owned payload, and exposes external addons via exact audited private-profile links.",
|
||||
"External-profile policy rejects unrelated addon directories/changed manifests/unreviewed dependency edges."
|
||||
],
|
||||
"tools": {
|
||||
"tools/source_bundle.py": "5d1d0150d8009f24a950ee85501d0da8b1f69d5fcbb5a7118b08957f14658f57",
|
||||
"tools/native_package.py": "32195bf9b43024028e9931a99885d0a131b28ba1b77b32e9d6ed70b914625559",
|
||||
"tools/external_addons.py": "c389b76c4d5f0f763420cd7d564d3ff5ebb7350cac10d2a26164c17f59b72dde",
|
||||
"tools/check.py": "2965f354c39b6dd44f9f8a0c8d923fc65056fb1464d0227adf75ad98ab707d36",
|
||||
"tools/source_manifest.py": "c1a985348bad16f3b5b69ef7e545b6341eca298d8ae08111b8340b31535cc199",
|
||||
"addons/core/addon.gproj": "73e973a1f1c5910393e16f86a3a40d792031bb2fa3fc7f4dd87a06a16c3e34a4"
|
||||
},
|
||||
"native_input_reference": {
|
||||
"path": "/tmp/erri-workbench-crash-nearby-20261003-1918/logs/logs_2026-10-03_19-19-25/external-addons-inputs.json",
|
||||
"sha256": "f28aa36e1e9c8352773836551ad58e47df1703de3c742b069596b6fb622c6fa3"
|
||||
},
|
||||
"limits": [
|
||||
"Read-only Python validation and manifest/RDB identity hashing; no native process, compiler, package build or live mutation.",
|
||||
"No new runtime candidate created or existing package requalified.",
|
||||
"This checks explicit declared dependencies and admitted resource identities, not redistribution/licensing of external assets."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
{
|
||||
"Assets/Items/Equipment/Maps/Map_Paper_01/Map_Paper_01_folded.xob": "E443663E5241622A",
|
||||
"Assets/Items/Equipment/Radios/Radio_R107M/Radio_R107M_01_item.xob": "77C9FCF3FB1246E9",
|
||||
"Assets/Items/Equipment/workspaces/paper_map.agr": "83675D0B0AB1B2C3",
|
||||
"Assets/Items/Equipment/workspaces/player_map.asi": "56794534F6B8C3D7",
|
||||
"Assets/Props/Fabric/Flags/Data/Flag_1_2_SovietArmy.emat": "B47B52D9DA68905D",
|
||||
"Assets/Props/Fabric/Flags/Data/Flag_1_2_USA.emat": "610803CC3F3D6649",
|
||||
"Assets/Props/Military/AmmoBox/EquipmentBoxWooden_01/Data/EquipmentBoxWooden_Weapon_01_USSR.emat": "7D2E831AFA5CF50D",
|
||||
"Assets/Props/Military/AmmoBox/EquipmentBoxWooden_01/EquipmentBoxWooden_Weapon_01.xob": "819ED3266EE5113B",
|
||||
"Assets/Props/Military/Sandbags/Data/Sandbags_01_Burlap_MLOD.emat": "2169E8EB73E1C127",
|
||||
"Assets/Props/Military/Sandbags/Data/Sandbags_01_short_Burlap.emat": "31529E064AA7C917",
|
||||
"Assets/Props/Military/Sandbags/Sandbag_01_short.xob": "268DBDABB3C94AD7",
|
||||
"Assets/Structures/BuildingsParts/Doors/DoorFrame_door_metal_A_RIGHT_EXT_B.xob": "E3BC73BFBC7AA497",
|
||||
"Assets/Structures/Walls/Concrete/ConcreteWall_01_3m.xob": "0B96D139FEBCA006",
|
||||
"Configs/Callsigns/Callsigns_US.conf": "CB7824D572DD0D5C",
|
||||
"Configs/Callsigns/Callsigns_USSR.conf": "958043CE1648EC43",
|
||||
"Configs/EntityCatalog/US/Characters_EntityCatalog_US.conf": "B56E8B4D4B195559",
|
||||
"Configs/EntityCatalog/US/Groups_EntityCatalog_US.conf": "4E70E7C4C2C17D4A",
|
||||
"Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf": "5F7EC52FC40A03E2",
|
||||
"Configs/EntityCatalog/US/SupplyContainerItems_EntityCatalog_US.conf": "0BF36EFF9FFAF92B",
|
||||
"Configs/EntityCatalog/US/WeaponTripod_EntityCatalog_US.conf": "0E4B62F186F97C43",
|
||||
"Configs/EntityCatalog/USSR/Characters_EntityCatalog_USSR.conf": "3B679F1799D55F6F",
|
||||
"Configs/EntityCatalog/USSR/Groups_EntityCatalog_USSR.conf": "37D5B75AAC3E72EA",
|
||||
"Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf": "C53421647C3D0D2E",
|
||||
"Configs/EntityCatalog/USSR/SupplyContainerItems_EntityCatalog_USSR.conf": "B4CA6761AC935808",
|
||||
"Configs/EntityCatalog/USSR/WeaponTripod_EntityCatalog_USSR.conf": "DDF17C8C140BD1F2",
|
||||
"Configs/Factions/BLUFOR.conf": "E7B7EA4823DD81F0",
|
||||
"Configs/Factions/FIA.conf": "8053DB656DD18B14",
|
||||
"Configs/Factions/OPFOR.conf": "B122E3B10BB3404B",
|
||||
"Configs/GameOverScreen/BaseGameOverScreensConfig.conf": "651583FFFB7FC765",
|
||||
"Configs/Identities/FactionIdentity_US.conf": "B600946E9ACC17C2",
|
||||
"Configs/Identities/FactionIdentity_USSR.conf": "FBBCD73926989580",
|
||||
"Configs/Identities/Territories/FactionHomeTerritory_US.conf": "B548A5B264939A98",
|
||||
"Configs/Identities/Territories/FactionHomeTerritory_USSR.conf": "31FC78AF00523A99",
|
||||
"Configs/Map/MapPlain.conf": "A786DD4868598F15",
|
||||
"Configs/Navmesh/Navmesh_GM_Eden_Soldier.conf": "8BBC73472092902E",
|
||||
"Configs/Navmesh/Navmesh_GM_Eden_Vehicle.conf": "0228A79846FD8A97",
|
||||
"Configs/System/ActionContext/ManualCameraContext.conf": "C538807EEE48BED8",
|
||||
"Configs/System/chimeraInputCommon.conf": "795184CF9AD764DB",
|
||||
"Configs/System/chimeraMenus.conf": "C747AFB6B750CE9A",
|
||||
"Configs/Systems/MissionSystems.conf": "C50579A2EC48E8EF",
|
||||
"Prefabs/AI/Groups/Group_Base.et": "000CD338713F2B5A",
|
||||
"Prefabs/AI/SCR_AIWorld.et": "E0A05C76552E7F58",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_Cycle.et": "35BD6541CBB8AC08",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_Defend.et": "93291E72AC23930F",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_GetIn.et": "712F4795CF8B91C7",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_GetOut.et": "C40316EE26846CAB",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_Move.et": "750A8D1695BD6998",
|
||||
"Prefabs/AI/Waypoints/AIWaypoint_SearchAndDestroy.et": "B3E7B8DC2BAB8ACC",
|
||||
"Prefabs/Characters/Campaign/Final/OPFOR/USSR_Army/Regular/Campaign_USSR_Player_MortarCrew.et": "86E565387A634103",
|
||||
"Prefabs/Characters/Core/Character_Base.et": "37578B1666981FCE",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_Base.et": "836E7E39AAC5888B",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_HeliPilot.et": "42A502E3BB727CEB",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_Sniper.et": "0F6689B491641155",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_Unarmed.et": "2F912ED6E399FF47",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/GreenBerets/Character_US_SF.et": "36E28C628A2F83CB",
|
||||
"Prefabs/Characters/Factions/BLUFOR/US_Army/GreenBerets/Character_US_SF_Medic.et": "9A234C5857D92187",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_AR.et": "23ADBBC31B6A3DC6",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_AT.et": "1C78331E156A3D65",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_HeliPilot.et": "A62FA97C4EC64F14",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_LAT.et": "BF643BE4ADBDFDD3",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_RTO.et": "612F43A4D5AE765F",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_Rifleman.et": "DCB41B3746FDD1BE",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_SL.et": "5436629450D8387A",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_SR.et": "333DA6244C7DA34C",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Character_USSR_Sharpshooter.et": "976AC400219898FA",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Spetsnaz/Character_USSR_SF.et": "2DB452B3EC386B92",
|
||||
"Prefabs/Characters/Factions/OPFOR/USSR_Army/Spetsnaz/Character_USSR_SF_Medic.et": "8CA70597606992EC",
|
||||
"Prefabs/Characters/Footwear/CombatBoots_US_01.et": "DAAFD15478BDE1C3",
|
||||
"Prefabs/Characters/HeadGear/Hat_Patrol_US_01/Hat_Patrol_US_01.et": "F545C1BE7C99954A",
|
||||
"Prefabs/Characters/HeadGear/Helmet_PASGT_01/Helmet_PASGT_01_base.et": "8A2B2A544F3ED831",
|
||||
"Prefabs/Characters/Uniforms/Jacket_US_BDU_rolledup.et": "3CCA7A9BB4FD3197",
|
||||
"Prefabs/Characters/Uniforms/Pants_US_BDU.et": "604BB72BE8E023C2",
|
||||
"Prefabs/Decals/Dirt/Decal_Dirt_Patch_03.et": "4AD6EB80A8B1FA3A",
|
||||
"Prefabs/Groups/BLUFOR/Group_US_FireTeam.et": "84E5BBAB25EA23E5",
|
||||
"Prefabs/Groups/INDFOR/Group_FIA_FireTeam.et": "5BEA04939D148B1D",
|
||||
"Prefabs/Groups/OPFOR/Group_USSR_Base.et": "8DE0C0830FE0C33D",
|
||||
"Prefabs/Groups/OPFOR/Group_USSR_RifleSquad.et": "E552DABF3636C2AD",
|
||||
"Prefabs/Items/Core/Item_Base.et": "C95E11C60810F432",
|
||||
"Prefabs/Items/Equipment/Backpacks/Backpack_Kolobok.et": "41A9C55B61F375F0",
|
||||
"Prefabs/Items/Equipment/Binoculars/Binoculars_B8/Binoculars_B8.et": "243948B23D90BECB",
|
||||
"Prefabs/Items/Equipment/Kits/MedicalKit_01/MedicalKit_01_US.et": "AE578EEA4244D41F",
|
||||
"Prefabs/Items/Equipment/Kits/MedicalKit_01/MedicalKit_01_USSR.et": "21EF98BFC1EB3793",
|
||||
"Prefabs/Items/Equipment/Kits/RepairKit_01/RepairKit_01_wrench.et": "33B2DFDCD0EBA3DB",
|
||||
"Prefabs/Items/Equipment/Maps/Map_Paper_01/PaperMap_01_folded.et": "13772C903CB5E4F7",
|
||||
"Prefabs/Items/Equipment/Radios/Radio_ANPRC77.et": "9B6B61BB3FE3DFB0",
|
||||
"Prefabs/Items/Equipment/Radios/Radio_R107M.et": "54C68E438DD34265",
|
||||
"Prefabs/Items/Equipment/Radios/Radio_R148.et": "E1A5D4B878AA8980",
|
||||
"Prefabs/Items/Equipment/Watches/Watch_SandY184A.et": "78ED4FEF62BBA728",
|
||||
"Prefabs/Items/Fuel/Jerrycan_01/Jerrycan_01_item.et": "12D5AD21E383B768",
|
||||
"Prefabs/Items/Medicine/FieldDressing_01/FieldDressing_USSR_01.et": "C3F1FA1E2EC2B345",
|
||||
"Prefabs/Items/Medicine/FieldDressing_01/FieldDressing_US_01.et": "A81F501D3EF6F38E",
|
||||
"Prefabs/Items/Medicine/MorphineInjection_01/MorphineInjection_01.et": "0D9A5DCF89AE7AA9",
|
||||
"Prefabs/Items/Medicine/SalineBag_01/SalineBag_USSR_01.et": "527D7C5D2E476BDC",
|
||||
"Prefabs/Items/Medicine/SalineBag_01/SalineBag_US_01.et": "00E36F41CA310E2A",
|
||||
"Prefabs/Items/Medicine/Tourniquet_01/Tourniquet_US_01.et": "D70216B1B2889129",
|
||||
"Prefabs/Items/Misc/IntelligenceFolder_E_01/IntelligenceFolder_E_01.et": "6D56FED1E55A8F84",
|
||||
"Prefabs/MP/Managers/Factions/FactionManager_Base.et": "A242612865F2A48E",
|
||||
"Prefabs/MP/Managers/Factions/FactionManager_USxUSSR.et": "589540B35EBA8CDC",
|
||||
"Prefabs/MP/Managers/Loadouts/LoadoutManager_USxUSSR.et": "97EF4C1A41F63DDB",
|
||||
"Prefabs/MP/Modes/GameMode_Base.et": "0F307326459A1395",
|
||||
"Prefabs/MP/ScriptedChatEntity.et": "F69BC912AC8236F9",
|
||||
"Prefabs/Props/EmptyStorages/USSR_AmmoBox_empty.et": "EBBC859CCD94D96D",
|
||||
"Prefabs/Props/Furniture/Table_01.et": "53506DCB398C7EBE",
|
||||
"Prefabs/Props/Military/Antennas/Antenna_FIA_02/Antenna_FIA_02_base.et": "B3949F6D215A9F78",
|
||||
"Prefabs/Props/Military/Sandbags/Sandbag_01_short_burlap.et": "CFFEB23FBEA00322",
|
||||
"Prefabs/Props/Wrecks/UH1H_wreck/UH1H_wreck_static.et": "74DCE1AEC6832E18",
|
||||
"Prefabs/Structures/BuildingParts/Doors/DoorSet_Base.et": "87CADB5ADC989993",
|
||||
"Prefabs/Structures/BuildingParts/Doors/Door_MetalGate_01_Short_LEFT_EXT_ST_B.et": "34B08027DBDE322A",
|
||||
"Prefabs/Structures/BuildingParts/Doors/Door_Metal_A_RIGHT_EXT_COV_B.et": "67F17696FF278AE0",
|
||||
"Prefabs/Structures/Military/Camps/TentSmallUS_01/TentSmallUS_01.et": "01AE5FD77A9A4C21",
|
||||
"Prefabs/Structures/Military/Camps/TentUSSR_01/TentUSSR_01_base.et": "BE5D5CFA90224646",
|
||||
"Prefabs/Structures/Military/Camps/TentUS_01/TentUSMedical_01.et": "F8427C3EFC52644E",
|
||||
"Prefabs/Structures/Walls/BarbedWire/BarbedTape_01/BarbedTape_01_Long_noStake.et": "46904AF5D473FB75",
|
||||
"Prefabs/Structures/Walls/BarbedWire/BarbedTape_01/BarbedTape_01_Short_noStake.et": "CAE1588B6265A2AB",
|
||||
"Prefabs/Structures/Walls/Concrete/ConcreteWall_01/ConcreteWall_01_3m.et": "60E5729BEA18F875",
|
||||
"Prefabs/Systems/Radio/RadioManager.et": "B8E09FAB91C4ECCD",
|
||||
"Prefabs/Tasks/BaseTask.et": "1D0F815858EE24AD",
|
||||
"Prefabs/Vehicles/Helicopters/Mi8MT/Mi8MT_armed.et": "7BD282AF716ED639",
|
||||
"Prefabs/Vehicles/Helicopters/Mi8MT/Mi8MT_unarmed_transport.et": "DF5CCB7C0FF049F4",
|
||||
"Prefabs/Vehicles/Wheeled/UAZ469/UAZ469.et": "259EE7B78C51B624",
|
||||
"Prefabs/Vehicles/Wheeled/UAZ469/UAZ469_PKM.et": "0B4DEA8078B78A9B",
|
||||
"Prefabs/Vehicles/Wheeled/UAZ469/VehParts/Seats/UAZ469_seats_rear.et": "780AAF0A51AEE61A",
|
||||
"Prefabs/Vehicles/Wheeled/Ural4320/Ural4320_ammo.et": "3336BE330C4F355B",
|
||||
"Prefabs/Vehicles/Wheeled/Ural4320/Ural4320_transport.et": "16C1F16C9B053801",
|
||||
"Prefabs/Weapons/Ammo/Ammo_Shell_82mm_HE_O832DU.et": "98EC9C526AFBA282",
|
||||
"Prefabs/Weapons/Attachments/Optics/Optic_4x20/Optic_4x20.et": "BD496EE1B40DC510",
|
||||
"Prefabs/Weapons/Attachments/Optics/Optic_ARTII/Optic_ARTII.et": "D2018EDB1BBF4C88",
|
||||
"Prefabs/Weapons/Attachments/Optics/Optic_PSO1/Optic_PSO1.et": "C850A33226B8F9C1",
|
||||
"Prefabs/Weapons/Core/VehiclePeriscope_DummyWeapon_Base.et": "7E1DD1CE4D6A23F4",
|
||||
"Prefabs/Weapons/Explosives/Mine_PMN4/Mine_PMN4.et": "B05A816C0BF50802",
|
||||
"Prefabs/Weapons/Handguns/PM/Handgun_PM.et": "C0F7DD85A86B2900",
|
||||
"Prefabs/Weapons/Magazines/Magazine_545x39_AK_30rnd_Ball.et": "BBB50A815A2F916B",
|
||||
"Prefabs/Weapons/Magazines/Magazine_762x51_M14_20rnd_SpecialBall.et": "627255315038152A",
|
||||
"Prefabs/Weapons/Magazines/Magazine_762x54_SVD_10rnd_Sniper.et": "9CCB46C6EE632C1A",
|
||||
"Prefabs/Weapons/Magazines/Magazine_9x18_PM_8rnd_Ball.et": "8B853CDD11BA916E",
|
||||
"Prefabs/Weapons/Mortars/2B14/Mortar_2B14.et": "D1FFE458E8AC4BDB",
|
||||
"Prefabs/Weapons/Rifles/AK74/Rifle_AK74.et": "FA5C25BF66A53DCF",
|
||||
"Prefabs/World/Game/PerceptionManager.et": "028DAEAD63E056BE",
|
||||
"Sounds/Items/_SharedData/PickUp/Items_PickUp_Map.acp": "13F8D0DE67678118",
|
||||
"Sounds/Vehicles/Wheeled/UAZ469/Vehicles_UAZ469_Horn.acp": "7E64D37BE3E1F3FA",
|
||||
"UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt": "3E7733BAC8C831F6",
|
||||
"UI/Textures/DeployMenu/Loadout-BG/Loadout_BG_USSR.imageset": "21533F2089005056",
|
||||
"UI/Textures/DeployMenu/Loadout-BG/Loadout_US_BG.imageset": "F8AC305446D5D480",
|
||||
"UI/Textures/Editor/EditableEntities/Factions/EditableEntity_Faction_USA.edds": "EB7F65DBC9392557",
|
||||
"UI/Textures/Editor/EditableEntities/Factions/EditableEntity_Faction_USSR.edds": "40B12B0DF911B856",
|
||||
"UI/Textures/Flags/US-flag-base-3it.edds": "46FB2FB2C2125A3C",
|
||||
"UI/Textures/Flags/USSR-flag-base-3it.edds": "50824EB9F2C215AB",
|
||||
"UI/Textures/Icons/icons_mapMarkersUI-glow.imageset": "67B3A6DC2D712B52",
|
||||
"UI/Textures/Icons/icons_mapMarkersUI.imageset": "E23427CAC80DA8B7",
|
||||
"UI/Textures/Icons/icons_wrapperUI-glow.imageset": "00FE3DBDFD15227B",
|
||||
"UI/Textures/Icons/icons_wrapperUI.imageset": "3262679C50EF4F01",
|
||||
"UI/layouts/HUD/GameOver/EndScreen/EndScreenContent_NoImage.layout": "C4507D07F3C54831",
|
||||
"UI/layouts/Menus/PauseMenu/PauseMenuButton.layout": "9ECCD201BCF07E95",
|
||||
"UI/layouts/Task/TaskListEntry.layout": "B71975032150BAFB",
|
||||
"UI/layouts/Task/TaskListEntryDescription.layout": "552EB1921B5C548C",
|
||||
"UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout": "75C912A1C89BE6C2",
|
||||
"UI/layouts/WidgetLibrary/ComboBox/WLib_ComboBox.layout": "4B5AE6E64037FFB4",
|
||||
"UI/layouts/WidgetLibrary/EditBox/WLib_EditBox.layout": "0022F0B45ADBC5AC",
|
||||
"system/textures/defWhite.edds": "A64A8C63E0FBAE87",
|
||||
"worlds/Eden/Eden.ent": "853E92315D1D9EFE",
|
||||
"worlds/MP/Navmeshes/LowResEden.nmn": "5E19E60F26327356"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"status": "first native measurement proposal ready; exact source geometry unknown",
|
||||
"source_manifest_sha256": "e2d0794b0479de737ac897200fc37ea57471d7aec9c3f31d77a1a65f81bad49f",
|
||||
"patch_sha256": "bb9299bc8bc95c3f63751253eba685611d152b65ce0b113f8da54e30254acc51",
|
||||
"resource_audit_sha256": "6233bc8d785dd8cbb05cec1b2ec1f27a30721f51bb3ef311057a695484987b92",
|
||||
"new_guids_no_live_meta_collision": [
|
||||
"174211DDE2F6422B",
|
||||
"486DDD0B811047EE"
|
||||
],
|
||||
"tests": {
|
||||
"command": "python3 /tmp/erri-crash-resource-1806/test_measurement_contract.py",
|
||||
"test_sha256": "6491b6b289ff93e549f766d987072409109b15b045dc29021aa1e44cd6328f6a",
|
||||
"log_sha256": "e21e2ee6206319a6942dc45008252af6d096d57ca31fe30dc4442945736f8c58",
|
||||
"result": "pass",
|
||||
"scope": "actual Python AST admission; static resource and bounded cleanup source guards, not native execution"
|
||||
},
|
||||
"native_command_options": "--smoke crash-geometry --project chat --rounds 1 --timeout 180",
|
||||
"geometry_contract": "ERR_CrashSiteResources.Bounds(out minimum,out maximum) returns false until exact wrapper native bounds are archived; core derives offset/survey from measured values",
|
||||
"limits": [
|
||||
"No engine launch or compiler executed by author.",
|
||||
"No native placement, collision walkability, multiplayer visibility or FPS qualification.",
|
||||
"No aircraft flight, seat, crew, inventory, injury, fire or control system added.",
|
||||
"Probe creates only static owned wrapper at high altitude then immediately deletes it on both measurement success and refusal.",
|
||||
"Existing scene/player setup runs; crash-geometry never unlocks prison or changes existing actors.",
|
||||
"No third-party prefab/model bytes copied; owned wrapper inherits installed vanilla resource."
|
||||
],
|
||||
"files": [
|
||||
"addons/core/Prefabs/ERR/CrashSite.et",
|
||||
"addons/core/Prefabs/ERR/CrashSite.et.meta",
|
||||
"addons/core/Prefabs/ERR/CrashWreck.et",
|
||||
"addons/core/Prefabs/ERR/CrashWreck.et.meta",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_CrashSiteResources.c",
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashGeometryProbe.c",
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c",
|
||||
"tools/headless_workbench.py",
|
||||
"docs/vanilla-resources.json"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
--- /dev/null
|
||||
+++ b/addons/core/Prefabs/ERR/CrashSite.et
|
||||
@@ -0,0 +1,7 @@
|
||||
+GenericEntity {
|
||||
+ ID "46B3FAD3A89A4EA3"
|
||||
+ components {
|
||||
+ ERR_LocationComponent "{606DF66235E34CA9}" { m_Kind 0 }
|
||||
+ RplComponent "{B6AB8FE43FE143B4}" { Streamable Disabled }
|
||||
+ }
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/addons/core/Prefabs/ERR/CrashSite.et.meta
|
||||
@@ -0,0 +1,7 @@
|
||||
+MetaFileClass {
|
||||
+ Name "{174211DDE2F6422B}Prefabs/ERR/CrashSite.et"
|
||||
+ Configurations {
|
||||
+ ResourceClass PC {}
|
||||
+ ResourceClass HEADLESS : PC {}
|
||||
+ }
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/addons/core/Prefabs/ERR/CrashWreck.et
|
||||
@@ -0,0 +1,9 @@
|
||||
+GenericEntity : "{74DCE1AEC6832E18}Prefabs/Props/Wrecks/UH1H_wreck/UH1H_wreck_static.et" {
|
||||
+ ID "BDBAE020F10A41DF"
|
||||
+ components {
|
||||
+ Hierarchy "{BD920DE465D04435}" {}
|
||||
+ RplComponent "{7E4852E4567E49D6}" { Streamable Disabled }
|
||||
+ }
|
||||
+ coords 0 0 0
|
||||
+ angles 0 0 0
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/addons/core/Prefabs/ERR/CrashWreck.et.meta
|
||||
@@ -0,0 +1,7 @@
|
||||
+MetaFileClass {
|
||||
+ Name "{486DDD0B811047EE}Prefabs/ERR/CrashWreck.et"
|
||||
+ Configurations {
|
||||
+ ResourceClass PC {}
|
||||
+ ResourceClass HEADLESS : PC {}
|
||||
+ }
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_CrashSiteResources.c
|
||||
@@ -0,0 +1,12 @@
|
||||
+// Owned static aftermath; no aircraft, crew, flight or inventory systems.
|
||||
+class ERR_CrashSiteResources
|
||||
+{
|
||||
+ static ResourceName SitePrefab() { return "{174211DDE2F6422B}Prefabs/ERR/CrashSite.et"; }
|
||||
+ static ResourceName WreckPrefab() { return "{486DDD0B811047EE}Prefabs/ERR/CrashWreck.et"; }
|
||||
+ static bool Bounds(out vector minimum, out vector maximum)
|
||||
+ {
|
||||
+ // Fail closed until the exact owned wrapper has native measured bounds.
|
||||
+ minimum = vector.Zero; maximum = vector.Zero;
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashGeometryProbe.c
|
||||
@@ -0,0 +1,82 @@
|
||||
+// Explicit WORKBENCH measurement only. Never moves or seats a player/AI.
|
||||
+#ifdef WORKBENCH
|
||||
+class ERR_NativeCrashGeometryProbe
|
||||
+{
|
||||
+ protected static bool Finite(vector value)
|
||||
+ {
|
||||
+ for (int axis = 0; axis < 3; axis++)
|
||||
+ if (value[axis] != value[axis] || Math.AbsFloat(value[axis]) > 1000000) return false;
|
||||
+ return true;
|
||||
+ }
|
||||
+ protected static bool Measure(IEntity root, out vector minimum, out vector maximum)
|
||||
+ {
|
||||
+ minimum = "1000000 1000000 1000000"; maximum = "-1000000 -1000000 -1000000";
|
||||
+ if (!root || !root.GetVObject() || !root.FindComponent(RplComponent)) return false;
|
||||
+ Physics physics = root.GetPhysics();
|
||||
+ if (!physics || physics.IsDynamic()) return false;
|
||||
+ array<IEntity> nodes = {root};
|
||||
+ int meshes;
|
||||
+ for (int index = 0; index < nodes.Count(); index++)
|
||||
+ {
|
||||
+ IEntity entity = nodes[index];
|
||||
+ if (!entity) return false;
|
||||
+ Physics childPhysics = entity.GetPhysics();
|
||||
+ if (childPhysics && childPhysics.IsDynamic()) return false;
|
||||
+ if (entity.GetVObject())
|
||||
+ {
|
||||
+ vector low, high; entity.GetBounds(low, high);
|
||||
+ if (!Finite(low) || !Finite(high)) return false;
|
||||
+ for (int axis = 0; axis < 3; axis++)
|
||||
+ if (high[axis] <= low[axis] || high[axis] - low[axis] > 40) return false;
|
||||
+ meshes++;
|
||||
+ for (int x = 0; x < 2; x++)
|
||||
+ {
|
||||
+ for (int y = 0; y < 2; y++)
|
||||
+ {
|
||||
+ for (int z = 0; z < 2; z++)
|
||||
+ {
|
||||
+ vector corner = low;
|
||||
+ if (x) corner[0] = high[0];
|
||||
+ if (y) corner[1] = high[1];
|
||||
+ if (z) corner[2] = high[2];
|
||||
+ vector local = root.CoordToLocal(entity.CoordToParent(corner));
|
||||
+ if (!Finite(local)) return false;
|
||||
+ for (int component = 0; component < 3; component++)
|
||||
+ {
|
||||
+ minimum[component] = Math.Min(minimum[component], local[component]);
|
||||
+ maximum[component] = Math.Max(maximum[component], local[component]);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ IEntity child = entity.GetChildren();
|
||||
+ while (child)
|
||||
+ {
|
||||
+ if (nodes.Count() >= 32 || nodes.Contains(child)) return false;
|
||||
+ nodes.Insert(child); child = child.GetSibling();
|
||||
+ }
|
||||
+ }
|
||||
+ if (!meshes || !Finite(minimum) || !Finite(maximum)) return false;
|
||||
+ for (int dimension = 0; dimension < 3; dimension++)
|
||||
+ if (maximum[dimension] <= minimum[dimension] || maximum[dimension] - minimum[dimension] > 40) return false;
|
||||
+ PrintFormat("ERR CRASH GEOMETRY: nodes=%1 meshes=%2 static=1 replicatedRoot=1 minX=%3 minY=%4 minZ=%5", nodes.Count(), meshes, minimum[0], minimum[1], minimum[2]);
|
||||
+ PrintFormat("ERR CRASH GEOMETRY: maxX=%1 maxY=%2 maxZ=%3 resource=%4", maximum[0], maximum[1], maximum[2], ERR_CrashSiteResources.WreckPrefab());
|
||||
+ return true;
|
||||
+ }
|
||||
+ static bool Run()
|
||||
+ {
|
||||
+ if (!Replication.IsServer()) return false;
|
||||
+ // At high altitude, independent of the pending crash-start setup and terrain.
|
||||
+ // This static prop is the only owned probe entity; every return after creation deletes it.
|
||||
+ IEntity wreck = ERR_Actors.Spawn(ERR_CrashSiteResources.WreckPrefab(), "1000 2500 1000");
|
||||
+ if (!wreck) return false;
|
||||
+ vector minimum, maximum;
|
||||
+ bool measured = Measure(wreck, minimum, maximum);
|
||||
+ ERR_Actors.DeleteSpawned(wreck);
|
||||
+ bool deleted = wreck == null;
|
||||
+ PrintFormat("ERR CRASH GEOMETRY CLEANUP: measured=%1 deleted=%2; no terrain placement or multiplayer visibility claim", measured, deleted);
|
||||
+ return measured && deleted;
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
--- a/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
||||
@@ -29,6 +29,7 @@
|
||||
return camps > 0 && seen.Count() == camps * 2;
|
||||
}
|
||||
|
||||
+ protected bool m_ERRTestCrashGeometry;
|
||||
protected bool m_ERRTestPatrolHQ;
|
||||
protected ref ERR_NativePatrolProbe m_ERRHQPatrolMovement;
|
||||
protected ref ERR_NativePatrolHQProbe m_ERRHQPatrolOrder;
|
||||
@@ -137,6 +138,7 @@
|
||||
m_ERRTestMortarCourier = outcome == "mortar-courier";
|
||||
m_ERRTestMortarSalvo = outcome == "mortar-salvo" || outcome == "mortar-refresh";
|
||||
m_ERRTestMortarTransfer = outcome == "mortar-transfer";
|
||||
+ m_ERRTestCrashGeometry = outcome == "crash-geometry";
|
||||
m_ERRTestPatrolHQ = outcome == "patrol-hq";
|
||||
m_ERRTestPlayerDeath = outcome == "player-death" || m_ERRTestRadioNetwork || m_ERRTestHQResponse || m_ERRTestMortar || m_ERRTestHQMemory || m_ERRTestHQBody || m_ERRTestConvoy || m_ERRTestInfantryTransfer;
|
||||
if (m_ERRTestLocalHandoff || m_ERRTestMountedAmmo || m_ERRTestAlarmHearing) m_ERRTestPlayerDeath = true;
|
||||
@@ -322,6 +324,14 @@
|
||||
protected void ERR_SmokePhase(ERR_Phase previous, ERR_Phase current)
|
||||
{
|
||||
if (m_ERRSmokeDone || !ERR_MissionRules.Terminal(current)) return;
|
||||
+ if (m_ERRTestCrashGeometry)
|
||||
+ {
|
||||
+ if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 3501, "static wreck geometry measured and probe deleted before explicit fixture reset")) return;
|
||||
+ m_ERRSmokeDone = true;
|
||||
+ GetGame().GetCallqueue().Remove(ERR_SmokeTick);
|
||||
+ Print("ERR SMOKE COMPLETE: owned static crash wreck native bounds and local cleanup; terrain placement and multiplayer unqualified");
|
||||
+ return;
|
||||
+ }
|
||||
if (m_ERRTestSupplyTravel)
|
||||
{
|
||||
if (!ERR_Check(current == ERR_Phase.DEFEAT && m_ERRSmokeStep == 3201, "production supply travel checked before explicit fixture reset")) return;
|
||||
@@ -673,6 +683,13 @@
|
||||
if (!ERR_Check(CanStartSpawnPreload() && m_ERRSpawnPreloadRequested && !m_SpawnPreload, "prisoner admitted only after enabled native spawn preload finishes")) return;
|
||||
m_ERRSmokePlayer = players[0];
|
||||
if (!ERR_CheckRoster() || !ERR_NativeContractsProbe.Run(this, m_ERRSmokePlayer) || !ERR_CheckCompanionCommands()) return;
|
||||
+ if (m_ERRTestCrashGeometry)
|
||||
+ {
|
||||
+ if (!ERR_Check(ERR_NativeCrashGeometryProbe.Run(), "owned static wreck finite aggregate bounds, static physics and local deletion")) return;
|
||||
+ m_ERRSmokeStep = 3501;
|
||||
+ Transition(ERR_Phase.DEFEAT);
|
||||
+ return;
|
||||
+ }
|
||||
if (m_ERRTestSupplyTravel) { ERR_BeginSupplyTravel(now); return; }
|
||||
if (m_ERRTestAircraftField)
|
||||
{
|
||||
--- a/tools/headless_workbench.py
|
||||
+++ b/tools/headless_workbench.py
|
||||
@@ -14,7 +14,7 @@
|
||||
p.add_argument('--external-addons', type=Path, help='Installed RHS/WCS/BMP source root; expose only audited closure in a separate Chat profile')
|
||||
p.add_argument('--compat', type=Path, required=True, help='Disposable cloned Proton compatdata directory outside Steam')
|
||||
p.add_argument('--profile', type=Path, required=True, help='Separate disposable successor Workbench profile')
|
||||
-p.add_argument('--smoke', choices=['normal-escape-route', 'escape-route', 'optional-site-skip', 'infantry-combat', 'medical-combat', 'hunter-faction', 'unconscious-camera', 'objective-map', 'town-garrisons', 'site-garrisons', 'radio-interaction', 'enemy-loadout', 'aggression', 'air-logistics', 'air-assault', 'air-recon', 'airfield-markers', 'opening-tools', 'mortar-station', 'generated-sites', 'hq-local-handoff', 'infantry-transfer', 'hq-body', 'convoy', 'supply-convoys', 'supply-travel', 'mounted-ammo', 'alarm-hearing', 'hq-memory', 'hq-awareness', 'aircraft-field', 'aircraft-route', 'native-end-active', 'native-end-preparing', 'aircraft-control', 'aircraft-cancel', 'aircraft-translate', 'map-ownership', 'mortar-refresh', 'mortar-salvo', 'mortar-courier', 'station-teardown', 'prison-breach', 'powered-flight', 'powered-translate', 'local-admission', 'mortar-expiry', 'mortar-transfer', 'mortar-fire', 'patrol-hq', 'victory', 'lost-helicopter', 'player-death', 'radio-network', 'hq-response', 'mortar-inventory', 'startup-failure', 'site-survey', 'cache-loss', 'extraction-capacity', 'early-helicopter-loss', 'extraction-startup-failure', 'extraction-boundary-failure', 'transport-loss', 'transport-survey', 'lifecycle', 'objective-ui', 'recovery', 'prisoner-kit', 'medical', 'casualty-load', 'casualty-direct', 'casualty-bench', 'casualty-remove', 'environment', 'environment-restart', 'patrols', 'radio-document-loss', 'radio-document-loss-partial', 'guard-cancel', 'casualty-service'], default='victory')
|
||||
+p.add_argument('--smoke', choices=['crash-geometry', 'normal-escape-route', 'escape-route', 'optional-site-skip', 'infantry-combat', 'medical-combat', 'hunter-faction', 'unconscious-camera', 'objective-map', 'town-garrisons', 'site-garrisons', 'radio-interaction', 'enemy-loadout', 'aggression', 'air-logistics', 'air-assault', 'air-recon', 'airfield-markers', 'opening-tools', 'mortar-station', 'generated-sites', 'hq-local-handoff', 'infantry-transfer', 'hq-body', 'convoy', 'supply-convoys', 'supply-travel', 'mounted-ammo', 'alarm-hearing', 'hq-memory', 'hq-awareness', 'aircraft-field', 'aircraft-route', 'native-end-active', 'native-end-preparing', 'aircraft-control', 'aircraft-cancel', 'aircraft-translate', 'map-ownership', 'mortar-refresh', 'mortar-salvo', 'mortar-courier', 'station-teardown', 'prison-breach', 'powered-flight', 'powered-translate', 'local-admission', 'mortar-expiry', 'mortar-transfer', 'mortar-fire', 'patrol-hq', 'victory', 'lost-helicopter', 'player-death', 'radio-network', 'hq-response', 'mortar-inventory', 'startup-failure', 'site-survey', 'cache-loss', 'extraction-capacity', 'early-helicopter-loss', 'extraction-startup-failure', 'extraction-boundary-failure', 'transport-loss', 'transport-survey', 'lifecycle', 'objective-ui', 'recovery', 'prisoner-kit', 'medical', 'casualty-load', 'casualty-direct', 'casualty-bench', 'casualty-remove', 'environment', 'environment-restart', 'patrols', 'radio-document-loss', 'radio-document-loss-partial', 'guard-cancel', 'casualty-service'], default='victory')
|
||||
p.add_argument('--trace-random-radius', action='store_true', help='Workbench-only read-only zero-radius caller traces; one normal Chat round, capped at sixteen records')
|
||||
p.add_argument('--maintenance-refuel', action='store_true', help='Opt-in normal-route check: original held Southern fuel can transfers finite fuel through its native UAZ action; one arranged tank depletion, no stock creation')
|
||||
p.add_argument('--mounted-swap-eligibility', action='store_true', help='Read-only mounted-ammo variant: one exact finite cargo/mounted magazine CanSwap call; no transfer or radio proof')
|
||||
@@ -35,6 +35,7 @@
|
||||
p.add_argument('--timeout', type=int, default=360)
|
||||
p.add_argument('--project', choices=['core', 'chat'], default='chat', help='Diagnostic fixture family (both load the combined mod)')
|
||||
a = p.parse_args()
|
||||
+if a.smoke == 'crash-geometry' and (a.project != 'chat' or a.rounds != 1 or a.timeout < 180): p.error('crash-geometry requires Chat, one round and timeout at least180 seconds')
|
||||
if a.trace_random_radius and (a.smoke != 'normal-escape-route' or a.project != 'chat' or a.rounds != 1 or a.timeout < 420): p.error('--trace-random-radius requires Chat normal-escape-route, one round and timeout at least 420 seconds')
|
||||
if a.smoke == 'objective-map' and (a.project != 'core' or a.rounds != 1): p.error('objective-map requires --project core --rounds 1')
|
||||
if a.smoke == 'unconscious-camera' and a.project != 'core': p.error('unconscious-camera requires --project core to keep the general smoke fixture inactive')
|
||||
--- a/docs/vanilla-resources.json
|
||||
+++ b/docs/vanilla-resources.json
|
||||
@@ -104,6 +104,7 @@
|
||||
"Prefabs/Props/Furniture/Table_01.et": "53506DCB398C7EBE",
|
||||
"Prefabs/Props/Military/Antennas/Antenna_FIA_02/Antenna_FIA_02_base.et": "B3949F6D215A9F78",
|
||||
"Prefabs/Props/Military/Sandbags/Sandbag_01_short_burlap.et": "CFFEB23FBEA00322",
|
||||
+ "Prefabs/Props/Wrecks/UH1H_wreck/UH1H_wreck_static.et": "74DCE1AEC6832E18",
|
||||
"Prefabs/Structures/BuildingParts/Doors/DoorSet_Base.et": "87CADB5ADC989993",
|
||||
"Prefabs/Structures/BuildingParts/Doors/Door_MetalGate_01_Short_LEFT_EXT_ST_B.et": "34B08027DBDE322A",
|
||||
"Prefabs/Structures/BuildingParts/Doors/Door_Metal_A_RIGHT_EXT_COV_B.et": "67F17696FF278AE0",
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"verdict": "verified geometry archive and measured-constants lineage; route fixture has a separate stock expectation correction proposed",
|
||||
"archive": "/home/jakub/devel/escapistsrereintroduced/docs/evidence/native-2026-10-03-crash-geometry",
|
||||
"raw": "/tmp/erri-workbench-crash-geometry-20261003-1852/logs/logs_2026-10-03_18-53-52",
|
||||
"byte_verified_files": {
|
||||
"console.log.txt": "05be9f2c953f675c3ed9a58a65bc408ac24543e3ad9708ee89a7da6f665721d1",
|
||||
"script.log.txt": "b0d7f0967f6007e4851bc20001c08760521dcbd72644f33afd792f9fcccad0dd",
|
||||
"error.log.txt": "f847b5369efae07a53cb50871806b5544bfe26755190e7d360ec532e0f6f189f",
|
||||
"rereintroduced-hq.log.txt": "5e65839cdbe62faf1dc7b5ae7f5dd9dbc09377ed8561ad8bff97297586ba318c",
|
||||
"runner.json.txt": "7194cabb905a6c3a25f501682f98d8860a3c1ff9c8b07c596f58d6601e1c9f76",
|
||||
"external-addons-inputs.json.txt": "f28aa36e1e9c8352773836551ad58e47df1703de3c742b069596b6fb622c6fa3",
|
||||
"launch-source.json": "055a468fec2907484b4efc2e98db40c14c0fdaf0f261d18ba9ab90dc6258cce4",
|
||||
"launch-source-sha256.json": "29ff23b8b3afa96f4c5508eb180baf18380504443c675a453a52e85a9869b3cb"
|
||||
},
|
||||
"source_snapshot_exact": true,
|
||||
"early_proposal_native_hashes": {
|
||||
"addons/core/Prefabs/ERR/CrashSite.et": "8d06afe6e2db8986f06a7c5d6649e52df009f9eead7345bf2b477f50a0725b3c",
|
||||
"addons/core/Prefabs/ERR/CrashSite.et.meta": "0f54fe80ed96394374c1922e1d0b05f7e0200ce5b979ff58325b033f51641f69",
|
||||
"addons/core/Prefabs/ERR/CrashWreck.et": "f5de4785c0e3cdf02f1d5372e9b01171bd5a37acb9c36aa2a94bae3f429b2272",
|
||||
"addons/core/Prefabs/ERR/CrashWreck.et.meta": "bde3299bdbbddb91d2ef471b61035b6cced29899cff4cd90c080fe584ce63f26",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_CrashSiteResources.c": "c6d51831776946dc51464a69987b0ee497eb8fd60bb071b211c658c789309309",
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashGeometryProbe.c": "7867ce1794aa0d1bbab72c32f60f5bd0c2bad4f5ff6224978c215e7828840178",
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c": "55819c6d4a94d80d0f0048ec4845fa5162111d5db723eea79fc86a1fffff1aa2"
|
||||
},
|
||||
"assertions_passed": 32,
|
||||
"smoke_completions": 1,
|
||||
"script_failures": 0,
|
||||
"engine_errors_retained": 13,
|
||||
"cleanup_confirmed": true,
|
||||
"native_scope": "one original owned wrapper, nodes1 meshes1 static1 replicatedRoot1; finite bounds, deleted1; no terrain placement or multiplayer visibility proof",
|
||||
"constants_followup_patch_sha256": "3387eb4121abda7ef81ca5be388e50d12d6ca6c91c33a21c6128aac07f017da3",
|
||||
"constants_source_live_sha256": "832aebf6e754dba54ba28b8f480180d32ced968a2d2f192424c4007a862c2b43",
|
||||
"raw_bounds": {
|
||||
"min": [
|
||||
-1.43719,
|
||||
0.512451,
|
||||
-8.79651
|
||||
],
|
||||
"max": [
|
||||
1.4325,
|
||||
3.98193,
|
||||
3.94385
|
||||
]
|
||||
},
|
||||
"stored_bounds": {
|
||||
"min": [
|
||||
-1.439,
|
||||
0.511,
|
||||
-8.798
|
||||
],
|
||||
"max": [
|
||||
1.434,
|
||||
3.983,
|
||||
3.945
|
||||
]
|
||||
},
|
||||
"rounding": "expand each direction by1mm then outward millimetre rounding",
|
||||
"review_execution": "Read-only source/archive verification only; no compiler/native run."
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_CrashSiteResources.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_CrashSiteResources.c
|
||||
@@ -5,8 +5,11 @@
|
||||
static ResourceName WreckPrefab() { return "{486DDD0B811047EE}Prefabs/ERR/CrashWreck.et"; }
|
||||
static bool Bounds(out vector minimum, out vector maximum)
|
||||
{
|
||||
- // Fail closed until the exact owned wrapper has native measured bounds.
|
||||
- minimum = vector.Zero; maximum = vector.Zero;
|
||||
- return false;
|
||||
+ // Exact owned static wrapper measured in WORKBENCH on 2026-10-03.
|
||||
+ // Native bounds: (-1.43719, 0.512451, -8.79651) to (1.4325, 3.98193, 3.94385).
|
||||
+ // Expand by 1mm then round outward to millimetres; terrain survey adds its own clearance.
|
||||
+ minimum = "-1.439 0.511 -8.798";
|
||||
+ maximum = "1.434 3.983 3.945";
|
||||
+ return true;
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"native_log": "/tmp/erri-workbench-crash-geometry-20261003-1852/logs/logs_2026-10-03_18-53-52/console.log",
|
||||
"console_sha256": "05be9f2c953f675c3ed9a58a65bc408ac24543e3ad9708ee89a7da6f665721d1",
|
||||
"runner_sha256": "7194cabb905a6c3a25f501682f98d8860a3c1ff9c8b07c596f58d6601e1c9f76",
|
||||
"launch_source_sha256": "29ff23b8b3afa96f4c5508eb180baf18380504443c675a453a52e85a9869b3cb",
|
||||
"native_result": "smoke-completed",
|
||||
"cleanup_confirmed": true,
|
||||
"measured_source": {
|
||||
"addons/core/Prefabs/ERR/CrashWreck.et": "f5de4785c0e3cdf02f1d5372e9b01171bd5a37acb9c36aa2a94bae3f429b2272",
|
||||
"addons/core/Prefabs/ERR/CrashWreck.et.meta": "bde3299bdbbddb91d2ef471b61035b6cced29899cff4cd90c080fe584ce63f26",
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashGeometryProbe.c": "7867ce1794aa0d1bbab72c32f60f5bd0c2bad4f5ff6224978c215e7828840178"
|
||||
},
|
||||
"raw_min": [
|
||||
-1.43719,
|
||||
0.512451,
|
||||
-8.79651
|
||||
],
|
||||
"raw_max": [
|
||||
1.4325,
|
||||
3.98193,
|
||||
3.94385
|
||||
],
|
||||
"outward_min": [
|
||||
-1.439,
|
||||
0.511,
|
||||
-8.798
|
||||
],
|
||||
"outward_max": [
|
||||
1.434,
|
||||
3.983,
|
||||
3.945
|
||||
],
|
||||
"rounding": "floor(rawMin*1000-1)/1000 and ceil(rawMax*1000+1)/1000",
|
||||
"derived_core_geometry": {
|
||||
"offset": [
|
||||
13.439,
|
||||
-0.511,
|
||||
0
|
||||
],
|
||||
"survey_center": [
|
||||
13.4365,
|
||||
0,
|
||||
-2.4265
|
||||
],
|
||||
"half_size": 8,
|
||||
"height": 5
|
||||
},
|
||||
"limits": "Native isolated wrapper geometry/static physics/Rpl presence/local cleanup only; no terrain placement, walkability or remote replication proof."
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
PASS: each stored bound is >=1mm outward of exact logged native scalar; derived geometry remains within core caps. No engine/compiler run.
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"files": {
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_CrashSiteResources.c": {
|
||||
"baseline_sha256": "c6d51831776946dc51464a69987b0ee497eb8fd60bb071b211c658c789309309",
|
||||
"proposal_sha256": "832aebf6e754dba54ba28b8f480180d32ced968a2d2f192424c4007a862c2b43",
|
||||
"index_sha256": null
|
||||
}
|
||||
},
|
||||
"patch_sha256": "3387eb4121abda7ef81ca5be388e50d12d6ca6c91c33a21c6128aac07f017da3"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"files": {
|
||||
"addons/core/Prefabs/ERR/CrashSite.et": {
|
||||
"baseline_sha256": null,
|
||||
"proposal_sha256": "8d06afe6e2db8986f06a7c5d6649e52df009f9eead7345bf2b477f50a0725b3c",
|
||||
"index_sha256": null
|
||||
},
|
||||
"addons/core/Prefabs/ERR/CrashSite.et.meta": {
|
||||
"baseline_sha256": null,
|
||||
"proposal_sha256": "0f54fe80ed96394374c1922e1d0b05f7e0200ce5b979ff58325b033f51641f69",
|
||||
"index_sha256": null
|
||||
},
|
||||
"addons/core/Prefabs/ERR/CrashWreck.et": {
|
||||
"baseline_sha256": null,
|
||||
"proposal_sha256": "f5de4785c0e3cdf02f1d5372e9b01171bd5a37acb9c36aa2a94bae3f429b2272",
|
||||
"index_sha256": null
|
||||
},
|
||||
"addons/core/Prefabs/ERR/CrashWreck.et.meta": {
|
||||
"baseline_sha256": null,
|
||||
"proposal_sha256": "bde3299bdbbddb91d2ef471b61035b6cced29899cff4cd90c080fe584ce63f26",
|
||||
"index_sha256": null
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_CrashSiteResources.c": {
|
||||
"baseline_sha256": null,
|
||||
"proposal_sha256": "c6d51831776946dc51464a69987b0ee497eb8fd60bb071b211c658c789309309",
|
||||
"index_sha256": null
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashGeometryProbe.c": {
|
||||
"baseline_sha256": null,
|
||||
"proposal_sha256": "7867ce1794aa0d1bbab72c32f60f5bd0c2bad4f5ff6224978c215e7828840178",
|
||||
"index_sha256": null
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c": {
|
||||
"baseline_sha256": "bc548e03f217a6f07f1d0893157281521a531eb21c54763cabba16064a91532c",
|
||||
"proposal_sha256": "55819c6d4a94d80d0f0048ec4845fa5162111d5db723eea79fc86a1fffff1aa2",
|
||||
"index_sha256": "ff651e27c4a981df66f4fc5b55aadb262df75820aef707bb68c369e548c0c3be"
|
||||
},
|
||||
"tools/headless_workbench.py": {
|
||||
"baseline_sha256": "aa971eb48206042315aa7632625d04d44ec9db82ea568a071b977118cb63361f",
|
||||
"proposal_sha256": "a5c3ec5186fa027be816405b6a7c4b3451d61025c74fd3f16dd9c88deb5201c6",
|
||||
"index_sha256": "b82da94e227a45c87b8ad74cac55d1b48dfaed55b82a66fe867ca4f0e5d22190"
|
||||
},
|
||||
"docs/vanilla-resources.json": {
|
||||
"baseline_sha256": "e10f60ce74a743b4619b0c2f2cc7fefcf09a94ab3ca1cbb332f386d6fb0da387",
|
||||
"proposal_sha256": "ec5ea933464f519eeadb416d7d7d7c0c3376da5204e928f5efff1be70fc61ce9",
|
||||
"index_sha256": "30dccbe13f1737ab832bb287cdef7f5a46ae718eafb68aa13c1c13ebdd29923b"
|
||||
}
|
||||
},
|
||||
"patch_sha256": "bb9299bc8bc95c3f63751253eba685611d152b65ce0b113f8da54e30254acc51",
|
||||
"native_status": "pending; Bounds intentionally false until measured",
|
||||
"resource_audit_sha256": "6233bc8d785dd8cbb05cec1b2ec1f27a30721f51bb3ef311057a695484987b92"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"defect": "Fixture compared authored vanilla-map placeholder to physically substituted shared field map; recursive inventory enumeration could count installed magazines as loose bag allowance.",
|
||||
"scope": "WORKBENCH fixture only, one source file; no inventory/stock/service mutation.",
|
||||
"evidence": {
|
||||
"map_override": "addons/core/Scripts/Game/ERR/30_Map/ERR_ScenarioMap.c",
|
||||
"site_substitution": "addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c:428",
|
||||
"enumeration": "ERR_Inventory.Items deduplicates identities but does not distinguish direct slots from nested weapon storage."
|
||||
},
|
||||
"proof_limit": "Exact current direct-bag prefab counts, not persisted startup identity provenance. Inherited pistol contents are excluded. Native fixture remains pending.",
|
||||
"validation": "Read-only source and API pattern inspection plus apply-check; no compiler/native during parent suite."
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
--- a/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c
|
||||
@@ -7,6 +7,19 @@
|
||||
{
|
||||
if (condition) { Print("ERR SMOKE PASS: crash start " + message); return true; }
|
||||
Print("ERR SMOKE FAIL: crash start " + message, LogLevel.ERROR); return false;
|
||||
+ }
|
||||
+ // GetItems can include magazines installed in a contained pistol. Only exact
|
||||
+ // reciprocal slots owned by this bag count toward its loose authored allowance.
|
||||
+ protected static bool DirectBagItem(IEntity item, IEntity bag)
|
||||
+ {
|
||||
+ if (!item || !bag) return false;
|
||||
+ InventoryItemComponent component = InventoryItemComponent.Cast(item.FindComponent(InventoryItemComponent));
|
||||
+ if (!component) return false;
|
||||
+ InventoryStorageSlot slot = component.GetParentSlot();
|
||||
+ if (!slot) return false;
|
||||
+ BaseInventoryStorageComponent storage = slot.GetStorage();
|
||||
+ return storage && storage.GetOwner() == bag && storage.GetSlot(slot.GetID()) == slot
|
||||
+ && slot.GetParentContainer() == storage && slot.GetAttachedEntity() == item;
|
||||
}
|
||||
static bool Run(ERR_GameMode mode, IEntity player)
|
||||
{
|
||||
@@ -39,10 +52,14 @@
|
||||
if (!Check(inventory && items.Count() > 0 && items.Count() <= 128, "finite starting stock is present")) return false;
|
||||
foreach (ERR_SiteStock stock : site.Definition.Stock)
|
||||
{
|
||||
+ // Mirror the current shared-map Scenario FieldMap override; all other
|
||||
+ // finite stock resources remain exactly as authored in the definition.
|
||||
+ ResourceName expected = stock.Prefab;
|
||||
+ if (expected == ERR_Supplies.Map()) expected = "{A46500E4A30B653B}Prefabs/Items/Equipment/ERRM_SharedFieldMap.et";
|
||||
int count;
|
||||
foreach (IEntity item : items)
|
||||
- if (item && item.GetPrefabData() && item.GetPrefabData().GetPrefabName() == stock.Prefab) count++;
|
||||
- if (!Check(count == stock.Count, "original starting stock count " + stock.Prefab)) return false;
|
||||
+ if (DirectBagItem(item, site.Container) && item.GetPrefabData() && item.GetPrefabData().GetPrefabName() == expected) count++;
|
||||
+ if (!Check(count == stock.Count, "current direct salvage stock count " + expected)) return false;
|
||||
}
|
||||
if (!Check(ERR_ObjectiveText.Description(mode).Contains("salvage"), "initial objective explains the salvage bag")) return false;
|
||||
PrintFormat("ERR CRASH START: anchor=%1 wreck=%2 halfSize=%3 clearance=%4; on-foot static aftermath, no crash flight or multiplayer proof", site.Definition.Position, wreck.GetOrigin(), halfSize, height);
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"files": {
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c": {
|
||||
"baseline_sha256": "0e2f21e93065b64dfb034df3d5aec3e8286127ff03d5094fd243b5b36508f365",
|
||||
"proposal_sha256": "d039027a462cc57d35d5e4f722e5b6b03e8f95a38fe66b19982092df983b1db0",
|
||||
"index_sha256": null
|
||||
}
|
||||
},
|
||||
"patch_sha256": "83583d38d0aad96c91f602d3f6a419f0781cf90e72631c85180ec8e91d759245"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"files": {
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c": {
|
||||
"baseline_sha256": "55819c6d4a94d80d0f0048ec4845fa5162111d5db723eea79fc86a1fffff1aa2",
|
||||
"proposal_sha256": "ce55c8be0047406e17ec4dced1912332ab4347bfa1f204921302392099a9e67b"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_NativeContractsProbe.c": {
|
||||
"baseline_sha256": "421e4b901afe6118b6bf44e8f678db8ccdf1c83b39da0cf816baa36f7275ccdd",
|
||||
"proposal_sha256": "60aa767d9455f2f4958a6a47bd68bbd8ab0466adc8f1dd9ae433c40ae96c68ff"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c": {
|
||||
"baseline_sha256": null,
|
||||
"proposal_sha256": "0e2f21e93065b64dfb034df3d5aec3e8286127ff03d5094fd243b5b36508f365"
|
||||
},
|
||||
"tools/headless_workbench.py": {
|
||||
"baseline_sha256": "a5c3ec5186fa027be816405b6a7c4b3451d61025c74fd3f16dd9c88deb5201c6",
|
||||
"proposal_sha256": "af11b29cc9f22f12e019978164fe808c9c903ea977b15a722846501a8377727f"
|
||||
},
|
||||
"tools/check.py": {
|
||||
"baseline_sha256": "fb6bf594dd6544abee60d4e172d1d28f34f223cae93678e2356156f34e653f00",
|
||||
"proposal_sha256": "2965f354c39b6dd44f9f8a0c8d923fc65056fb1464d0227adf75ad98ab707d36"
|
||||
}
|
||||
},
|
||||
"patch_sha256": "7bc6754694297ad259059cd614ccf222b29a51ce5b4e80dfa82c5ec890702fe5"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
check: /tmp/err-policy-78nohnwn/check.cpp:232: int main(): Assertion `ERR_Settings::AddedDefault("startMode")==0' failed.
|
||||
Traceback (most recent call last):
|
||||
File "/tmp/erri-crash-settings-1806/tests/test_start_settings.py", line 22, in <module>
|
||||
run(r'''
|
||||
~~~^^^^^
|
||||
#include <cassert>
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
...<49 lines>...
|
||||
}
|
||||
^
|
||||
''')
|
||||
^^^^
|
||||
File "/home/jakub/devel/escapistsrereintroduced/tests/policy_harness.py", line 14, in run
|
||||
subprocess.run([str(p/'check')],check=True)
|
||||
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/usr/lib/python3.14/subprocess.py", line 578, in run
|
||||
raise CalledProcessError(retcode, process.args,
|
||||
output=stdout, stderr=stderr)
|
||||
subprocess.CalledProcessError: Command '['/tmp/err-policy-78nohnwn/check']' died with <Signals.SIGABRT: 6>.
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c": {
|
||||
"baseline_sha256": "2951c36cf3a72ae079ab8991879b4759fae783d719c61878f1aad7126836dae6",
|
||||
"index_sha256": "20d319109cb688b3c43260c60adf52b511c51aae5861e223854f0acc6c5f637e"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c": {
|
||||
"baseline_sha256": "c3e008c8bbf538c5bca3a82a975decc7a283a38543a9d2639d90a81ce592c51e",
|
||||
"index_sha256": "8b01c7487c3f45b7f59da7447acc624a1792f660368f0c3feeaa36dd49d39124"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c": {
|
||||
"baseline_sha256": "3b96a99832ed40002598a186dd8de1d21410c2e690df37a6319fdbeeeb4eeab0",
|
||||
"index_sha256": "b190c6952a43deb70bbcbb87ccb3245377263179eb703c9148f2bd83e58144f4"
|
||||
},
|
||||
"addons/core/UI/layouts/ERR/AdminMenu.layout": {
|
||||
"baseline_sha256": "6577a8ee61db2ab1cd4e9a5a27a3c6fb5ca6ccffddd9df80577c5d7ec1e63bc0",
|
||||
"index_sha256": "1199df0d56076ec88360eea5b5a2ed18b6eac662af9a1ad59725600d997c07ad"
|
||||
},
|
||||
"tools/import_settings.py": {
|
||||
"baseline_sha256": "8b41ea8fb45e5c3840dad67f9d2494cba5dfa1e0e67d41e334fdd04e515a68a1",
|
||||
"index_sha256": "1c28b364358651056e64463db83153d08a8caaee0eaa652cec6563a7ff52a3da"
|
||||
},
|
||||
"tests/test_admin_menu.py": {
|
||||
"baseline_sha256": "53286ed86862e4b71614cb3ed687aa68893fc024cce203368bf54589ab92703b",
|
||||
"index_sha256": "624a2464d25c57f49431139ef5be772284a5fcce0d32696800127310d1d7ed2e"
|
||||
},
|
||||
"tests/test_settings_migration.py": {
|
||||
"baseline_sha256": "fabaeb631c60f4fb1d4dec4cf215a1b1e456d8f77e7e0706fe687ce6dfb4881f",
|
||||
"index_sha256": "99b0ebf0336d105d780cc97bcd12597bc13f3bbfdb3f4c31379868cb1a167abe"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveText.c": {
|
||||
"baseline_sha256": "8d75b35ab977be0cb1a2e3d3d1cb8ef875cdbfba69c35784c3d195451ef944c6",
|
||||
"index_sha256": "98f7bc6325f970f6eddb56095a667b77f29e4e6ce66c9b6b480d578542479cfd"
|
||||
},
|
||||
"tests/test_rough_intel_feedback.py": {
|
||||
"baseline_sha256": "d7395ecc498dda46e1c9a4c8fbf98a64f2bbd013de7806517fb8008756e7b40d",
|
||||
"index_sha256": "d7395ecc498dda46e1c9a4c8fbf98a64f2bbd013de7806517fb8008756e7b40d"
|
||||
},
|
||||
"tests/test_radio_waiting_text.py": {
|
||||
"baseline_sha256": "2aa54d8126b3fddae2b77d496f56d2d6e6d393c6d5124bdb5598713d9c29d629",
|
||||
"index_sha256": "2aa54d8126b3fddae2b77d496f56d2d6e6d393c6d5124bdb5598713d9c29d629"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c
|
||||
@@ -9,11 +9,12 @@
|
||||
|
||||
static array<string> Keys()
|
||||
{
|
||||
- return {"keepWeaponOnUnconscious", "reportIntervalSeconds", "supportSquadLimit", "responseRadiusMetres", "aiIntelChancePercent", "intelRevealChancePercent", "radioDefenceSeconds", "startTimeMinutes", "timeMultiplier", "startDateCode", "weatherProfile", "viewDistanceMetres", "antiAirChancePercent", "antiPersonnelMineChancePercent", "automaticEquipmentChancePercent", "automaticConvoyEnabled", "convoyCount", "heliTimerMinutes"};
|
||||
+ return {"startMode", "keepWeaponOnUnconscious", "reportIntervalSeconds", "supportSquadLimit", "responseRadiusMetres", "aiIntelChancePercent", "intelRevealChancePercent", "radioDefenceSeconds", "startTimeMinutes", "timeMultiplier", "startDateCode", "weatherProfile", "viewDistanceMetres", "antiAirChancePercent", "antiPersonnelMineChancePercent", "automaticEquipmentChancePercent", "automaticConvoyEnabled", "convoyCount", "heliTimerMinutes"};
|
||||
}
|
||||
|
||||
static bool Valid(string key, int value)
|
||||
{
|
||||
+ if (key == "startMode") return value == 0 || value == 1;
|
||||
if (key == "keepWeaponOnUnconscious") return value == 0 || value == 1;
|
||||
if (key == "heliTimerMinutes") return value >= 1 && value <= 1440;
|
||||
if (key == "convoyCount") return value >= 0 && value <= 20;
|
||||
@@ -98,6 +99,7 @@
|
||||
|
||||
static int AddedDefault(string key)
|
||||
{
|
||||
+ if (key == "startMode") return 0;
|
||||
if (key == "keepWeaponOnUnconscious") return 1;
|
||||
if (key == "heliTimerMinutes") return 15;
|
||||
if (key == "convoyCount") return 3;
|
||||
@@ -114,6 +116,7 @@
|
||||
void ERR_Settings(string path = PATH)
|
||||
{
|
||||
m_Path = path;
|
||||
+ m_Values.Set("startMode", AddedDefault("startMode"));
|
||||
m_Values.Set("keepWeaponOnUnconscious", AddedDefault("keepWeaponOnUnconscious"));
|
||||
m_Values.Set("reportIntervalSeconds", 10);
|
||||
m_Values.Set("supportSquadLimit", 4);
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c
|
||||
@@ -4,6 +4,7 @@
|
||||
{
|
||||
static string CoreSetting(string section, string option)
|
||||
{
|
||||
+ if (section == "mission" && option == "start") return "startMode";
|
||||
if (section == "mission" && option == "keepweapon") return "keepWeaponOnUnconscious";
|
||||
if (section == "mission" && option == "radio") return "radioDefenceSeconds";
|
||||
if (section == "intel" && option == "reveal") return "intelRevealChancePercent";
|
||||
@@ -11,6 +12,8 @@
|
||||
}
|
||||
static bool Selection(string key, string text, out int value)
|
||||
{
|
||||
+ if (key == "startMode" && text == "prison") { value = 0; return true; }
|
||||
+ if (key == "startMode" && text == "crash") { value = 1; return true; }
|
||||
if (text == "random" && ERR_Settings.Randomizable(key)) { value = -1; return true; }
|
||||
if ((text == "random-day" || text == "random day") && key == "startTimeMinutes") { value = -2; return true; }
|
||||
if (key == "startTimeMinutes") return ERR_TimeService.ParseClock(text, value);
|
||||
@@ -99,6 +102,20 @@
|
||||
else replies.Insert("Use /esc mission viewdistance show|set 500..10000|default. Invalid value or save failure leaves the previous setting unchanged.");
|
||||
return true;
|
||||
}
|
||||
+ protected bool StartCommand(ERR_GameMode mode, array<string> parts, array<string> replies)
|
||||
+ {
|
||||
+ if (parts.Count() < 2 || parts[0] != "mission" || parts[1] != "start") return false;
|
||||
+ if (parts.Count() == 3 && parts[2] == "show")
|
||||
+ {
|
||||
+ replies.Insert(ERR_AdminMenuFields.StartSummary(mode.Settings().Get("startMode"), mode.StartMode()));
|
||||
+ return true;
|
||||
+ }
|
||||
+ int value;
|
||||
+ if (parts.Count() == 4 && parts[2] == "set" && ERR_CommandArguments.Selection("startMode", parts[3], value) && mode.Settings().Set("startMode", value))
|
||||
+ replies.Insert(ERR_AdminMenuFields.StartSummary(value, mode.StartMode()) + ". Saved for next round; current start and players are unchanged.");
|
||||
+ else replies.Insert("Use /esc mission start show|set prison|crash (or 0|1). No random start. Invalid value or save failure leaves the previous selection unchanged.");
|
||||
+ return true;
|
||||
+ }
|
||||
protected bool TimeCommand(ERR_GameMode mode, array<string> parts, array<string> replies)
|
||||
{
|
||||
if (parts.Count() < 2 || parts[0] != "mission" || (parts[1] != "time" && parts[1] != "speed")) return false;
|
||||
@@ -154,6 +171,7 @@
|
||||
if (topic == "time" || topic == "mission")
|
||||
{
|
||||
replies.Insert("/esc mission radio show|set N|random | mission abandon");
|
||||
+ replies.Insert("/esc mission start show|set prison|crash: save the next round start; current round unchanged.");
|
||||
replies.Insert("/esc mission viewdistance show|set 500..10000|default; applies immediately after closing menus.");
|
||||
replies.Insert("/esc time show|set HH:MM|random|random-day | mission speed show|set N|random; saved changes apply next round.");
|
||||
replies.Insert("/esc mission date show|set YYYY-MM-DD|authored|random | mission weather show|set authored|clear|overcast|rain|random");
|
||||
@@ -173,6 +191,7 @@
|
||||
replies.Insert("/esc menu | status | settings | help mission|time|intel|hq|cheat|god|killais");
|
||||
replies.Insert("/esc mission abandon | mission radio show|set N|random | time show|set HH:MM|random|random-day");
|
||||
replies.Insert("/esc mission date|weather|speed show|set VALUE | mission viewdistance show|set 500..10000|default | intel reveal show|set N|help");
|
||||
+ replies.Insert("/esc mission start show|set prison|crash; next round only.");
|
||||
replies.Insert("/esc spectate next|previous; optional systems add their own command topics.");
|
||||
}
|
||||
protected bool Unavailable(array<string> parts, array<string> replies)
|
||||
@@ -212,6 +231,7 @@
|
||||
foreach (string key : ERR_Settings.Keys())
|
||||
{
|
||||
string line = key + "=" + mode.Settings().Get(key).ToString();
|
||||
+ if (key == "startMode") line = ERR_AdminMenuFields.StartSummary(mode.Settings().Get(key), mode.StartMode());
|
||||
if (key == "automaticConvoyEnabled") line += " (saved for next round; current startup unchanged)";
|
||||
replies.Insert(line);
|
||||
}
|
||||
@@ -240,6 +260,7 @@
|
||||
if (ERR_EnvironmentCommands.Execute(mode.Settings(), mode.Environment(), parts, replies)) return;
|
||||
if (ViewDistanceCommand(mode, parts, replies)) return;
|
||||
if (TimeCommand(mode, parts, replies)) return;
|
||||
+ if (StartCommand(mode, parts, replies)) return;
|
||||
if (parts.Count() == 3 || parts.Count() == 4)
|
||||
{
|
||||
string key = Setting(parts[0], parts[1]);
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c
|
||||
@@ -8,7 +8,7 @@
|
||||
{
|
||||
static array<string> Keys()
|
||||
{
|
||||
- return {"radioDefenceSeconds", "aiIntelChancePercent", "intelRevealChancePercent", "startTimeMinutes", "timeMultiplier", "startDateCode", "weatherProfile", "viewDistanceMetres", "reportIntervalSeconds", "supportSquadLimit", "responseRadiusMetres", "convoyCount", "antiAirChancePercent", "antiPersonnelMineChancePercent", "heliTimerMinutes"};
|
||||
+ return {"startMode", "radioDefenceSeconds", "aiIntelChancePercent", "intelRevealChancePercent", "startTimeMinutes", "timeMultiplier", "startDateCode", "weatherProfile", "viewDistanceMetres", "reportIntervalSeconds", "supportSquadLimit", "responseRadiusMetres", "convoyCount", "antiAirChancePercent", "antiPersonnelMineChancePercent", "heliTimerMinutes"};
|
||||
}
|
||||
static bool Available(string key, bool hq, bool intel)
|
||||
{
|
||||
@@ -30,16 +30,22 @@
|
||||
static string Display(string key, string value)
|
||||
{
|
||||
if (value == "-1" || value == "-2") return ERR_Settings.SelectionText(value.ToInt());
|
||||
+ if (key == "startMode") { if (value == "1") return "Crash"; return "Prison"; }
|
||||
if (key == "startTimeMinutes") return ERR_TimeService.Clock(value.ToInt());
|
||||
if (key == "startDateCode") return ERR_EnvironmentService.Date(value.ToInt());
|
||||
if (key == "weatherProfile") return ERR_EnvironmentService.ProfileName(value.ToInt());
|
||||
if (key == "viewDistanceMetres" && value == "0") return "default";
|
||||
return value;
|
||||
}
|
||||
+ static string StartSummary(int saved, int current)
|
||||
+ {
|
||||
+ return "Next start: " + Display("startMode", saved.ToString()) + " | Current round: " + Display("startMode", current.ToString());
|
||||
+ }
|
||||
static string Command(string key, string value)
|
||||
{
|
||||
string prefix;
|
||||
- if (key == "radioDefenceSeconds") prefix = "mission radio";
|
||||
+ if (key == "startMode") prefix = "mission start";
|
||||
+ else if (key == "radioDefenceSeconds") prefix = "mission radio";
|
||||
else if (key == "aiIntelChancePercent") prefix = "intel carrying";
|
||||
else if (key == "intelRevealChancePercent") prefix = "intel reveal";
|
||||
else if (key == "startTimeMinutes") prefix = "mission time";
|
||||
@@ -258,7 +264,8 @@
|
||||
if (!ERR_AdminMenuFields.Keys().Contains(key)) continue;
|
||||
string value = ERR_AdminMenuFields.Display(key, entry.Substring(divider + 1, entry.Length() - divider - 1));
|
||||
m_AvailableFields.Insert(key);
|
||||
- SetText("Saved_" + key, "Saved: " + value);
|
||||
+ if (key == "startMode") SetText("Saved_" + key, ERR_AdminMenuFields.StartSummary(entry.Substring(divider + 1, entry.Length() - divider - 1).ToInt(), m_Mode.StartMode()));
|
||||
+ else SetText("Saved_" + key, "Saved: " + value);
|
||||
// Existing fields retain all draft text, including a temporarily empty edit.
|
||||
if (!m_InitializedFields.Contains(key))
|
||||
{
|
||||
--- a/addons/core/UI/layouts/ERR/AdminMenu.layout
|
||||
+++ b/addons/core/UI/layouts/ERR/AdminMenu.layout
|
||||
@@ -22,10 +22,39 @@
|
||||
}
|
||||
FrameWidgetClass { Name "SettingsPage" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 0 OffsetLeft 0 PositionY 160 OffsetTop 160 SizeX 1000 OffsetRight -1000 SizeY 486 OffsetBottom -646 } {
|
||||
TextWidgetClass {
|
||||
- Name "SettingsHelp" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 6 OffsetTop 6 SizeX 936 OffsetRight -964 SizeY 50 OffsetBottom -56 }
|
||||
- Color 0.9 0.92 0.94 1 Text "Type a value or choose Random, then press Apply. Random stays saved and rolls once each round." "Font Size" 19 "Min Font Size" 19 Wrap 1
|
||||
- FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" }
|
||||
-}
|
||||
+ Name "Label_startMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 6 OffsetTop 6 SizeX 368 OffsetRight -396 SizeY 28 OffsetBottom -34 }
|
||||
+ Color 0.9 0.92 0.94 1 Text "Next start (Prison or Crash)" "Font Size" 20 "Min Font Size" 20 Wrap 1 FontProperties FontProperties {
|
||||
+ Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt"
|
||||
+ }
|
||||
+ }
|
||||
+TextWidgetClass {
|
||||
+ Name "Saved_startMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 38 OffsetTop 38 SizeX 936 OffsetRight -964 SizeY 24 OffsetBottom -62 }
|
||||
+ Color 0.9 0.92 0.94 1 Text "Waiting for saved value" "Font Size" 16 "Min Font Size" 16 Wrap 1 FontProperties FontProperties {
|
||||
+ Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt"
|
||||
+ }
|
||||
+ }
|
||||
+TextWidgetClass {
|
||||
+ Name "Help_startMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 62 OffsetTop 62 SizeX 936 OffsetRight -964 SizeY 18 OffsetBottom -80 }
|
||||
+ Color 0.72 0.81 0.87 1 Text "Crash starts on foot beside a static wreck. Save for next round; no flight or random start." "Font Size" 16 "Min Font Size" 16 Wrap 1
|
||||
+ FontProperties FontProperties { Font "{3E7733BAC8C831F6}UI/Fonts/RobotoCondensed/RobotoCondensed_Regular.fnt" }
|
||||
+}
|
||||
+
|
||||
+ButtonWidgetClass : "{DA43C77A0D1E59F8}UI/layouts/ERR/AdminValue.layout" {
|
||||
+ Name "startMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 408 OffsetLeft 408 PositionY 6 OffsetTop 6 SizeX 240 OffsetRight -648 SizeY 32 OffsetBottom -38 }
|
||||
+ components {
|
||||
+ SCR_EditBoxComponent "{547290FFBD5B33E9}" {
|
||||
+ m_sLabel ""
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ButtonWidgetClass : "{75C912A1C89BE6C2}UI/layouts/WidgetLibrary/Buttons/WLib_ButtonText.layout" {
|
||||
+ Name "Apply_startMode" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 660 OffsetLeft 660 PositionY 6 OffsetTop 6 SizeX 112 OffsetRight -772 SizeY 32 OffsetBottom -38 }
|
||||
+ components {
|
||||
+ SCR_ButtonTextComponent "{5548F0143AE99095}" {
|
||||
+ m_sText "Apply"
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
TextWidgetClass {
|
||||
Name "Label_radioDefenceSeconds" Slot FrameWidgetSlot { Anchor 0 0 0 0 PositionX 28 OffsetLeft 28 PositionY 80 OffsetTop 80 SizeX 368 OffsetRight -396 SizeY 28 OffsetBottom -108 }
|
||||
Color 0.9 0.92 0.94 1 Text "Radio transmission defence (30-1800 s)" "Font Size" 20 "Min Font Size" 20 Wrap 1 FontProperties FontProperties {
|
||||
--- a/tools/import_settings.py
|
||||
+++ b/tools/import_settings.py
|
||||
@@ -3,6 +3,7 @@
|
||||
import argparse,json,os,tempfile,sys
|
||||
from pathlib import Path
|
||||
SCHEMA={
|
||||
+ 'startMode':(0,0,1),
|
||||
'keepWeaponOnUnconscious':(1,0,1),
|
||||
'reportIntervalSeconds':(10,5,60),
|
||||
'supportSquadLimit':(4,0,8),
|
||||
--- a/tests/test_admin_menu.py
|
||||
+++ b/tests/test_admin_menu.py
|
||||
@@ -6,11 +6,11 @@
|
||||
from pathlib import Path
|
||||
BASE=Path(os.environ.get("ERR_CONVOY_SETTINGS_ROOT", Path(__file__).resolve().parents[1]))
|
||||
from policy_harness import ROOT, body, run
|
||||
-source = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c'
|
||||
-layout = ROOT / 'addons/core/UI/layouts/ERR/AdminMenu.layout'
|
||||
+source = BASE / 'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c'
|
||||
+layout = BASE / 'addons/core/UI/layouts/ERR/AdminMenu.layout'
|
||||
keys = re.findall(r'"([A-Za-z]+)"', body(source, 'static array<string> Keys('))
|
||||
settings = re.findall(r'"([A-Za-z]+)"', body(BASE / 'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c', 'static array<string> Keys('))
|
||||
-assert len(keys) == 15 and set(settings) - set(keys) == {"automaticConvoyEnabled", "keepWeaponOnUnconscious", "automaticEquipmentChancePercent"}
|
||||
+assert len(keys) == 16 and set(settings) - set(keys) == {"automaticConvoyEnabled", "keepWeaponOnUnconscious", "automaticEquipmentChancePercent"}
|
||||
assert set(keys) <= set(settings) # Every menu field must have a server setting.
|
||||
# Native layouts place child widget declarations inside an anonymous Children
|
||||
# block. A missing brace can preserve most widget names yet prevent menu load.
|
||||
@@ -47,7 +47,9 @@
|
||||
assert 'RandomDay_startTimeMinutes' in names
|
||||
assert len(names) == len(set(names)), 'Menu widget names must be unique'
|
||||
for key in keys:
|
||||
- assert all(name in names for name in (key, 'Apply_' + key, 'Saved_' + key, ('Default_' if key == 'viewDistanceMetres' else 'Random_') + key, 'Help_' + key))
|
||||
+ assert all(name in names for name in (key, 'Apply_' + key, 'Saved_' + key, 'Help_' + key))
|
||||
+ if key != 'startMode': assert ('Default_' if key == 'viewDistanceMetres' else 'Random_') + key in names
|
||||
+ else: assert 'Random_startMode' not in names
|
||||
for name in ('Close', 'SettingsPage', 'HQPage', 'JournalPage', 'JournalText', 'JournalContent', 'JournalScroll', 'PauseJournal', 'LatestJournal', 'Status'):
|
||||
assert name in names
|
||||
for name in re.findall(r'"([A-Za-z]+)"', body(source, 'override void OnMenuOpen(').split('foreach')[0]):
|
||||
@@ -93,7 +95,7 @@
|
||||
assert(Fields::FollowJournal(false,0,200,400,false));
|
||||
assert(Fields::FollowJournal(true,0,0,400,false));
|
||||
std::vector<std::pair<string,string>> cases={
|
||||
- {"radioDefenceSeconds","mission radio"},{"aiIntelChancePercent","intel carrying"},
|
||||
+ {"startMode","mission start"},{"radioDefenceSeconds","mission radio"},{"aiIntelChancePercent","intel carrying"},
|
||||
{"intelRevealChancePercent","intel reveal"},{"startTimeMinutes","mission time"},
|
||||
{"timeMultiplier","mission speed"},{"startDateCode","mission date"},
|
||||
{"weatherProfile","mission weather"},{"viewDistanceMetres","mission viewdistance"},{"reportIntervalSeconds","hq interval"},
|
||||
@@ -120,7 +122,7 @@
|
||||
for(string key:{"intelRevealChancePercent","radioDefenceSeconds","startTimeMinutes","timeMultiplier","startDateCode","weatherProfile"}) assert(Fields::Available(key,false,false));
|
||||
}
|
||||
''')
|
||||
-print('PASS: actual menu command routing covers all fifteen settings, rejects unsupported keys, gates companions, and matches unique authored widgets')
|
||||
+print('PASS: actual menu command routing covers all sixteen settings, rejects unsupported keys, gates companions, and matches unique authored widgets')
|
||||
|
||||
assert all(name in names for name in ('KeepWeaponOn', 'KeepWeaponOff', 'Saved_keepWeaponOnUnconscious'))
|
||||
click=body(source,'protected void OnButton(')
|
||||
--- a/tests/test_settings_migration.py
|
||||
+++ b/tests/test_settings_migration.py
|
||||
@@ -5,7 +5,7 @@
|
||||
spec=importlib.util.spec_from_file_location('import_settings',BASE/'tools/import_settings.py')
|
||||
m=importlib.util.module_from_spec(spec);spec.loader.exec_module(m)
|
||||
result,deferred=m.merge({'configVersion':1,'reportIntervalSeconds':20.0,'supportSquadLimit':2,'responseRadiusMetres':1500,'convoyCount':3},{'aiIntelChancePercent':0,'intelRevealChancePercent':100})
|
||||
-assert result==dict(keepWeaponOnUnconscious=1,reportIntervalSeconds=20,supportSquadLimit=2,responseRadiusMetres=1500,aiIntelChancePercent=0,intelRevealChancePercent=100,radioDefenceSeconds=180,startTimeMinutes=840,timeMultiplier=1,startDateCode=0,weatherProfile=0,viewDistanceMetres=0,automaticEquipmentChancePercent=25,antiAirChancePercent=7,antiPersonnelMineChancePercent=60,automaticConvoyEnabled=1,convoyCount=3,heliTimerMinutes=15)
|
||||
+assert result==dict(startMode=0,keepWeaponOnUnconscious=1,reportIntervalSeconds=20,supportSquadLimit=2,responseRadiusMetres=1500,aiIntelChancePercent=0,intelRevealChancePercent=100,radioDefenceSeconds=180,startTimeMinutes=840,timeMultiplier=1,startDateCode=0,weatherProfile=0,viewDistanceMetres=0,automaticEquipmentChancePercent=25,antiAirChancePercent=7,antiPersonnelMineChancePercent=60,automaticConvoyEnabled=1,convoyCount=3,heliTimerMinutes=15)
|
||||
assert deferred==[]
|
||||
for count in (0,1,3,20):
|
||||
values,notes=m.merge(ai={'convoyCount':count})
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveText.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveText.c
|
||||
@@ -11,7 +11,7 @@
|
||||
}
|
||||
static string Extraction(float radius)
|
||||
{
|
||||
- return string.Format("The map marks the initial helicopter pickup site. A prisoner must pilot the helicopter. Gather everyone you intend to rescue before flying beyond %1 kilometres from the prison: crossing that boundary ends the round for everyone. Only living prisoners aboard escape, including unconscious passengers; anyone left behind does not escape. To load an unconscious prisoner, place them on the ground beside the grounded, stationary helicopter and use 'Load casualty into extraction helicopter' on them.", radius / 1000.0);
|
||||
+ return string.Format("The map marks the initial helicopter pickup site. A prisoner must pilot the helicopter. Gather everyone you intend to rescue before flying beyond %1 kilometres from the starting area: crossing that boundary ends the round for everyone. Only living prisoners aboard escape, including unconscious passengers; anyone left behind does not escape. To load an unconscious prisoner, place them on the ground beside the grounded, stationary helicopter and use 'Load casualty into extraction helicopter' on them.", radius / 1000.0);
|
||||
}
|
||||
static string RadioFeedbackMessage(ERR_RadioFeedback feedback)
|
||||
{
|
||||
@@ -55,7 +55,9 @@
|
||||
// Scan all sites before acknowledging rough intel: an identified radio wins.
|
||||
if (roughRadio)
|
||||
return "Intel recovered: a question mark shows an approximate location, but its type is still unknown. Take a different intelligence folder into your inventory to pinpoint the radio; a folder already recovered cannot provide another clue. Try the other marked clue site if needed. A close approach with a clear view can also identify the station.";
|
||||
- return "Choose either marked clue site. Take its intelligence folders into your own inventory to reveal the station on your map. If the location is not yet identified, take another folder. Each marked site has enough folders; use the other if one is lost. If every folder is lost, a close approach with a clear view can identify the station itself. Nearby medical and guard sites can also be discovered by approaching with a clear view.";
|
||||
+ string startHint;
|
||||
+ if (mode.StartMode() == 1) startHint = "Search the salvage backpack at the crash site for weapons and a field map. ";
|
||||
+ return startHint + "Choose either marked clue site. Take its intelligence folders into your own inventory to reveal the station on your map. If the location is not yet identified, take another folder. Each marked site has enough folders; use the other if one is lost. If every folder is lost, a close approach with a clear view can identify the station itself. Nearby medical and guard sites can also be discovered by approaching with a clear view.";
|
||||
}
|
||||
if (phase == ERR_Phase.RADIO_DEFENCE)
|
||||
{
|
||||
--- a/tests/test_rough_intel_feedback.py
|
||||
+++ b/tests/test_rough_intel_feedback.py
|
||||
@@ -1,7 +1,9 @@
|
||||
"""Run actual shared objective selection and map grid methods; no native UI claim."""
|
||||
from policy_harness import ROOT, body, run
|
||||
+from pathlib import Path
|
||||
+import os
|
||||
|
||||
-source = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveText.c'
|
||||
+source = Path(os.environ.get('ERR_OBJECTIVE_TEXT_SOURCE', ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveText.c'))
|
||||
s = body(source, 'protected static string PhaseDescription(')
|
||||
s = s.replace('protected ', '').replace('ERR_GameMode mode,', 'ERR_GameMode* mode,')
|
||||
s = s.replace('ERR_Phase phase', 'int phase').replace('mode.', 'mode->')
|
||||
@@ -25,6 +27,7 @@
|
||||
namespace Math {float Ceil(float v){return std::ceil(v);}float Floor(float v){return std::floor(v);}float Round(float v){return std::round(v);}}
|
||||
struct ERR_LocationComponent {int kind,knowledge;int Kind(){return kind;}int Knowledge(){return knowledge;}};
|
||||
struct ERR_GameMode {
|
||||
+ int startMode=0;int StartMode(){return startMode;}
|
||||
int phase=ERR_Phase::RADIO_SEARCH;string error;bool occupied=false;
|
||||
std::vector<ERR_LocationComponent*> locations;
|
||||
int Phase(){return phase;}string PreparationError(){return error;}
|
||||
@@ -44,6 +47,9 @@
|
||||
mode.locations={&radio};
|
||||
string unknown=Actual::PhaseDescription(&mode,true);
|
||||
assert(has(unknown,"Choose either marked clue site")&&!has(unknown,"Intel recovered"));
|
||||
+ mode.startMode=1;string crash=Actual::PhaseDescription(&mode,true);
|
||||
+ assert(has(crash,"salvage backpack at the crash site")&&has(crash,unknown)&&!has(crash,"inside the prison"));
|
||||
+ assert(Actual::PhaseDescription(&mode,false)==crash);mode.startMode=0;
|
||||
radio.knowledge=1;
|
||||
string rough=Actual::PhaseDescription(&mode,true);
|
||||
assert(rough!=unknown&&has(rough,"Intel recovered")&&has(rough,"question mark"));
|
||||
@@ -83,3 +89,6 @@
|
||||
}
|
||||
''')
|
||||
print('PASS: actual rough-intel objective selection, exact precedence, source grid dimensions and unchanged other-phase dispatch; native UI pending')
|
||||
+
|
||||
+assert "kilometres from the starting area:" in body(source,"static string Extraction(")
|
||||
+assert "kilometres from the prison:" not in body(source,"static string Extraction(")
|
||||
--- a/tests/test_radio_waiting_text.py
|
||||
+++ b/tests/test_radio_waiting_text.py
|
||||
@@ -1,7 +1,9 @@
|
||||
"""Execute actual task/guide copy for initial waiting and subsequent radio states."""
|
||||
from policy_harness import ROOT, body, run
|
||||
+from pathlib import Path
|
||||
+import os
|
||||
|
||||
-source = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveText.c'
|
||||
+source = Path(os.environ.get('ERR_OBJECTIVE_TEXT_SOURCE', ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveText.c'))
|
||||
def translate(s):
|
||||
s = s.replace('protected ', '').replace('ERR_GameMode mode,', 'ERR_GameMode* mode,')
|
||||
s = s.replace('ERR_Phase phase', 'int phase').replace('mode.', 'mode->')
|
||||
@@ -27,6 +29,7 @@
|
||||
namespace Math {float Ceil(float n){return std::ceil(n);}}
|
||||
struct ERR_LocationComponent {int Kind(){return 0;}int Knowledge(){return 0;}};
|
||||
struct ERR_GameMode {
|
||||
+ int startMode=0;int StartMode(){return startMode;}
|
||||
int phase=ERR_Phase::RADIO_DEFENCE, feedback=ERR_RadioFeedback::WAITING, remaining=180;
|
||||
bool occupied=false;int Phase(){return phase;}string PreparationError(){return "";}
|
||||
void Locations(std::vector<ERR_LocationComponent*>& locations){locations.clear();}
|
||||
--- /dev/null
|
||||
+++ b/tests/test_start_settings.py
|
||||
@@ -0,0 +1,81 @@
|
||||
+"""Actual start setting parse/save and admin command bodies; native IO/UI are doubled.
|
||||
+Frozen-mode lifecycle itself is tested by the separate core start fixture.
|
||||
+"""
|
||||
+import os,re
|
||||
+from pathlib import Path
|
||||
+from policy_harness import ROOT,body,run
|
||||
+BASE=Path(os.environ.get('ERR_START_SETTINGS_ROOT',ROOT));CORE=BASE/'addons/core/Scripts/Game/ERR/00_Core'
|
||||
+S=Path(os.environ.get('ERR_SETTINGS_SOURCE', CORE/'ERR_Settings.c'));A=CORE/'ERR_AdminService.c';M=CORE/'ERR_AdminMenu.c'
|
||||
+def cpp(s):
|
||||
+ s=s.replace('protected ','').replace('out int ','int& ').replace('out map<string, int> values','Values& values').replace('new map<string, int>()','Values()').replace('map<string, int>','Values')
|
||||
+ s=s.replace('array<string> parts','Array<string> parts').replace('array<string> replies','Array<string>& replies').replace('array<string>','Array<string>').replace('foreach (','for (')
|
||||
+ s=s.replace('JsonLoadContext json = new JsonLoadContext();','JsonLoadContext json;').replace('JsonSaveContext json = new JsonSaveContext();','JsonSaveContext json;').replace('JsonLoadContext json,','JsonLoadContext& json,')
|
||||
+ s=s.replace('ERR_GameMode mode','Mode* mode').replace('mode.','mode->').replace('Settings().','Settings()->').replace('Math.Round','std::round')
|
||||
+ for n in ['ERR_Settings','ERR_ProfileConfig','ERR_CommandArguments','ERR_AdminMenuFields','ERR_TimeService','ERR_EnvironmentService','Replication','FileIO']:s=s.replace(n+'.',n+'::')
|
||||
+ s=s.replace('"0123456789".IndexOf','string("0123456789").IndexOf')
|
||||
+ for n in ['value','saved','current']:s=s.replace(n+'.ToString()','string(std::to_string('+n+'))')
|
||||
+ return s
|
||||
+settings='\n'.join(cpp(body(S,sig)) for sig in ['static array<string> Keys(','static bool Valid(','static bool Randomizable(','static bool ValidSelection(','static string SelectionText(','static int AddedDefault(','protected bool Read(','static bool Parse(','bool Set('])
|
||||
+args='\n'.join(cpp(body(A,sig)) for sig in ['static bool Integer(','static bool Selection('])
|
||||
+fields='\n'.join(cpp(body(M,sig)) for sig in ['static string Display(','static string StartSummary('])
|
||||
+command=cpp(body(A,'protected bool StartCommand('))
|
||||
+run(r'''
|
||||
+#include <cassert>
|
||||
+#include <string>
|
||||
+#include <vector>
|
||||
+#include <map>
|
||||
+#include <cmath>
|
||||
+#include <algorithm>
|
||||
+struct string:std::string{using std::string::string;string(std::string s):std::string(s){}bool IsEmpty(){return empty();}int Length(){return size();}int ToInt(){return std::stoi(*this);}int IndexOf(string x){auto n=find(x);return n==npos?-1:int(n);}string Substring(int a,int n){return substr(a,n);}};
|
||||
+template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}void Insert(T v){this->push_back(v);}};
|
||||
+struct Values{std::map<string,int> data;int Get(string k){return data.at(k);}void Set(string k,int v){data[k]=v;}void Remove(string k){data.erase(k);}};
|
||||
+std::map<string,std::map<string,float>> disk;bool failSave=false;
|
||||
+struct JsonLoadContext{std::map<string,float> data;bool DoesKeyExist(string k){return data.count(k);}bool ReadValue(string k,float& v){if(!data.count(k))return false;v=data[k];return true;}};
|
||||
+struct JsonSaveContext{std::map<string,float> data;void EnableTypeDiscriminator(bool){}void WriteValue(string k,int v){data[k]=v;}bool SaveToFile(string p){if(failSave)return false;disk[p]=data;return true;}};
|
||||
+namespace ERR_ProfileConfig{bool Load(string p,JsonLoadContext& j){if(!disk.count(p))return false;j.data=disk[p];return true;}bool Save(string p,JsonSaveContext&j){return j.SaveToFile(p);}bool Exists(string p){return disk.count(p);}}
|
||||
+namespace FileIO{bool CopyFile(string a,string b){if(!disk.count(a))return false;disk[b]=disk[a];return true;}void DeleteFile(string p){disk.erase(p);}}
|
||||
+namespace Replication{bool server=true;bool IsServer(){return server;}}
|
||||
+struct ERR_Settings{static constexpr auto PATH="settings";string m_Path=PATH;bool m_ReadOnly=false;Values m_Values,m_Resolved;int Get(string k){return m_Values.Get(k);}
|
||||
+'''+settings+r'''
|
||||
+};
|
||||
+namespace ERR_TimeService{bool ParseClock(string,int&){return false;}string Clock(int){return "clock";}}
|
||||
+namespace ERR_EnvironmentService{bool ParseDate(string,int&){return false;}bool ParseProfile(string,int&){return false;}string Date(int){return "date";}string ProfileName(int){return "weather";}}
|
||||
+struct ERR_CommandArguments{
|
||||
+'''+args+r'''
|
||||
+};
|
||||
+struct ERR_AdminMenuFields{
|
||||
+'''+fields+r'''
|
||||
+};
|
||||
+struct Mode{ERR_Settings* settings;int frozen;ERR_Settings*Settings(){return settings;}int StartMode(){return frozen;}};
|
||||
+struct Admin{
|
||||
+'''+command+r'''
|
||||
+};
|
||||
+int main(){
|
||||
+ assert(ERR_Settings::AddedDefault("startMode")==0);
|
||||
+ assert(!ERR_Settings::Randomizable("startMode")&&!ERR_Settings::ValidSelection("startMode",-1)&&!ERR_Settings::ValidSelection("startMode",-2));
|
||||
+ disk["old"]={{"reportIntervalSeconds",10},{"supportSquadLimit",4},{"responseRadiusMetres",2000},{"aiIntelChancePercent",60},{"intelRevealChancePercent",15},{"radioDefenceSeconds",180}};
|
||||
+ ERR_Settings settings;assert(settings.Read("old",settings.m_Values)&&settings.Get("startMode")==0);
|
||||
+ for(float bad:{-1.f,-2.f,2.f,.5f}){disk["bad"]=disk["old"];disk["bad"]["startMode"]=bad;Values ignored;assert(!settings.Read("bad",ignored));}
|
||||
+ Mode mode{&settings,0};Admin admin;Array<string> replies;
|
||||
+ assert(!admin.StartCommand(&mode,{"mission","radio","show"},replies));
|
||||
+ assert(admin.StartCommand(&mode,{"mission","start","set","crash"},replies));
|
||||
+ assert(settings.Get("startMode")==1&&mode.StartMode()==0&&disk["settings"]["startMode"]==1);
|
||||
+ assert(replies.back().find("Next start: Crash | Current round: Prison")!=string::npos);
|
||||
+ assert(replies.back().find("Saved for next round")!=string::npos);
|
||||
+ ERR_Settings restarted;assert(restarted.Read("settings",restarted.m_Values));Mode next{&restarted,restarted.Get("startMode")};assert(next.StartMode()==1);
|
||||
+ auto saved=disk["settings"];failSave=true;admin.StartCommand(&mode,{"mission","start","set","prison"},replies);assert(settings.Get("startMode")==1&&disk["settings"]==saved&&mode.StartMode()==0);failSave=false;
|
||||
+ for(string bad:{"random","random-day","2","-1","0.5","crashjunk"}){admin.StartCommand(&mode,{"mission","start","set",bad},replies);assert(settings.Get("startMode")==1&&disk["settings"]==saved);}
|
||||
+ admin.StartCommand(&mode,{"mission","start","set","prison","extra"},replies);assert(settings.Get("startMode")==1);
|
||||
+ Replication::server=false;admin.StartCommand(&mode,{"mission","start","set","prison"},replies);assert(settings.Get("startMode")==1);Replication::server=true;
|
||||
+ settings.m_ReadOnly=true;admin.StartCommand(&mode,{"mission","start","set","prison"},replies);assert(settings.Get("startMode")==1);settings.m_ReadOnly=false;
|
||||
+ admin.StartCommand(&mode,{"mission","start","set","0"},replies);assert(settings.Get("startMode")==0&&mode.StartMode()==0);
|
||||
+ admin.StartCommand(&next,{"mission","start","show"},replies);assert(replies.back()=="Next start: Crash | Current round: Crash");
|
||||
+}
|
||||
+''')
|
||||
+assert 'm_Values.Set("startMode", AddedDefault("startMode"));' in S.read_text()
|
||||
+execute=body(A,'void Execute(');assert execute.index('if (!authorized)')<execute.index('StartCommand(mode, parts, replies)')
|
||||
+assert 'StartSummary(' in body(M,'void ReceiveSnapshot(')
|
||||
+assert 'm_Mode.StartMode()' in body(M,'void ReceiveSnapshot(')
|
||||
+assert 'ERR_Settings.Randomizable(key)' in body(M,'override void OnMenuOpen(')
|
||||
+assert 'mission start show|set prison|crash' in body(A,'protected void Help(')
|
||||
+print('PASS: actual start defaults/parse/save, failure retention and authorized command wiring; current/next feedback, aliases and no random choice; native UI and core mode freezing are separate')
|
||||
@@ -0,0 +1,3 @@
|
||||
PASS: actual menu command routing covers all sixteen settings, rejects unsupported keys, gates companions, and matches unique authored widgets
|
||||
PASS: explicit weapon retention buttons use the same ready/authorized server command path
|
||||
PASS: item editor, preset controls and dynamic item-row layout are structurally valid
|
||||
@@ -0,0 +1,2 @@
|
||||
PASS: legacy values preserved, unsupported fields reported, invalid data rejected, existing files protected, runtime bounds aligned
|
||||
PASS: failed initial settings promotion leaves defaults writable after restart; prior/fallback saves survive copy, readback and mismatch faults
|
||||
@@ -0,0 +1 @@
|
||||
PASS: actual initial WAITING task/guide copy, configured duration, unchanged interruption and rounded progress; native task assertion pending
|
||||
@@ -0,0 +1 @@
|
||||
PASS: actual rough-intel objective selection, exact precedence, source grid dimensions and unchanged other-phase dispatch; native UI pending
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"files": {
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c": {
|
||||
"baseline_sha256": "2951c36cf3a72ae079ab8991879b4759fae783d719c61878f1aad7126836dae6",
|
||||
"index_sha256": "20d319109cb688b3c43260c60adf52b511c51aae5861e223854f0acc6c5f637e",
|
||||
"proposal_sha256": "47fb9c34d31bffc892b18d6d6c4e7500d10b0a681bfa73e6476a761ed3375f0d"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c": {
|
||||
"baseline_sha256": "c3e008c8bbf538c5bca3a82a975decc7a283a38543a9d2639d90a81ce592c51e",
|
||||
"index_sha256": "8b01c7487c3f45b7f59da7447acc624a1792f660368f0c3feeaa36dd49d39124",
|
||||
"proposal_sha256": "e8f778bfe56a91a1c761968261dcd7a5f5daa7f4983752d818a5443385fac049"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c": {
|
||||
"baseline_sha256": "3b96a99832ed40002598a186dd8de1d21410c2e690df37a6319fdbeeeb4eeab0",
|
||||
"index_sha256": "b190c6952a43deb70bbcbb87ccb3245377263179eb703c9148f2bd83e58144f4",
|
||||
"proposal_sha256": "8e8233a1c9000901e3a48141d59a55584099fc3b319f87c1589461b975ac9221"
|
||||
},
|
||||
"addons/core/UI/layouts/ERR/AdminMenu.layout": {
|
||||
"baseline_sha256": "6577a8ee61db2ab1cd4e9a5a27a3c6fb5ca6ccffddd9df80577c5d7ec1e63bc0",
|
||||
"index_sha256": "1199df0d56076ec88360eea5b5a2ed18b6eac662af9a1ad59725600d997c07ad",
|
||||
"proposal_sha256": "5583b018cabbebd7b4398b36bdca26c75c3437bcefed482dae9ed2a619bb7cf4"
|
||||
},
|
||||
"tools/import_settings.py": {
|
||||
"baseline_sha256": "8b41ea8fb45e5c3840dad67f9d2494cba5dfa1e0e67d41e334fdd04e515a68a1",
|
||||
"index_sha256": "1c28b364358651056e64463db83153d08a8caaee0eaa652cec6563a7ff52a3da",
|
||||
"proposal_sha256": "a35ec5adf2c177f4daf2e3be5f97131b83a9920e765ee3e2c845b0d54c00af37"
|
||||
},
|
||||
"tests/test_admin_menu.py": {
|
||||
"baseline_sha256": "53286ed86862e4b71614cb3ed687aa68893fc024cce203368bf54589ab92703b",
|
||||
"index_sha256": "624a2464d25c57f49431139ef5be772284a5fcce0d32696800127310d1d7ed2e",
|
||||
"proposal_sha256": "789f88da25bbd57bb7923065fc718f70c8a18c50681dd90079931a18993b9729"
|
||||
},
|
||||
"tests/test_settings_migration.py": {
|
||||
"baseline_sha256": "fabaeb631c60f4fb1d4dec4cf215a1b1e456d8f77e7e0706fe687ce6dfb4881f",
|
||||
"index_sha256": "99b0ebf0336d105d780cc97bcd12597bc13f3bbfdb3f4c31379868cb1a167abe",
|
||||
"proposal_sha256": "eee1f5c598f5875816d89a4bc46a9e6cc0f770557abde3d264c09dc2ded27523"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveText.c": {
|
||||
"baseline_sha256": "8d75b35ab977be0cb1a2e3d3d1cb8ef875cdbfba69c35784c3d195451ef944c6",
|
||||
"index_sha256": "98f7bc6325f970f6eddb56095a667b77f29e4e6ce66c9b6b480d578542479cfd",
|
||||
"proposal_sha256": "2e2a880e68c9384698f9df21334d27e1aceaf3b59166d00eaabb802f19f61a13"
|
||||
},
|
||||
"tests/test_rough_intel_feedback.py": {
|
||||
"baseline_sha256": "d7395ecc498dda46e1c9a4c8fbf98a64f2bbd013de7806517fb8008756e7b40d",
|
||||
"index_sha256": "d7395ecc498dda46e1c9a4c8fbf98a64f2bbd013de7806517fb8008756e7b40d",
|
||||
"proposal_sha256": "a7c5a956d65a1a4d4f4aca6ddb47ba07fe70d07e2f0f99030058ba67e9246422"
|
||||
},
|
||||
"tests/test_radio_waiting_text.py": {
|
||||
"baseline_sha256": "2aa54d8126b3fddae2b77d496f56d2d6e6d393c6d5124bdb5598713d9c29d629",
|
||||
"index_sha256": "2aa54d8126b3fddae2b77d496f56d2d6e6d393c6d5124bdb5598713d9c29d629",
|
||||
"proposal_sha256": "2acd7ebf18766c8436b998b57f06fcf07ec9e42a28b686e0bd95ede570a9a5d9"
|
||||
},
|
||||
"tests/test_start_settings.py": {
|
||||
"baseline_sha256": null,
|
||||
"index_sha256": null,
|
||||
"proposal_sha256": "8b4dcc9e786c5fc00a1e88f1c364fd8e9a1bf8f6fa73f1d5aebbaeb5da444cd7"
|
||||
}
|
||||
},
|
||||
"patch_sha256": "7b0af4235f773ae035ea9b27eec2e9f2d3afbd6ddb8ac51554fa6331c9cbeefc",
|
||||
"test_results_sha256": "2eb3091075ddccbc823513b78d6a816fab9277af94c464a892fbf0b2527760f6",
|
||||
"logs": {
|
||||
"baseline-result.log": "a3c8410c52f4ae8be664790dc9c84a5646c5fce0ff518566d88f858797f0e1fe",
|
||||
"start-result.log": "fe0f4af1afd506238e36606bcad6d3cbe264fe9f662d0aab883416f169f31000",
|
||||
"radio-result.log": "b8ad2d5ff62ab9bf44bef345f6f7ac36b52eee1ffed656ed6067f4b996066b21",
|
||||
"rough-result.log": "3496e5f3a9644b630a6e1de0b6cca5dd9b5b86718369e206fa672d999df2bd7c",
|
||||
"migration-result.log": "f1e1880620c44a4f750b4634b157af8a53702757f849668d0fb8b4b587d18287",
|
||||
"menu-green.log": "a9419fa2984d3398e3293e66d291b83b3cdd9703962f8151e52b6dc58e61da03",
|
||||
"start-green.log": "fe0f4af1afd506238e36606bcad6d3cbe264fe9f662d0aab883416f169f31000"
|
||||
},
|
||||
"new_test_registration": "tests/test_start_settings.py",
|
||||
"baseline_guarded": true
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
PASS: actual start defaults/parse/save, failure retention and authorized command wiring; current/next feedback, aliases and no random choice; native UI and core mode freezing are separate
|
||||
@@ -0,0 +1 @@
|
||||
PASS: actual start defaults/parse/save, failure retention and authorized command wiring; current/next feedback, aliases and no random choice; native UI and core mode freezing are separate
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"proposed": {
|
||||
"test_start_settings.py": 0,
|
||||
"test_admin_menu.py": 0,
|
||||
"test_settings_migration.py": 0,
|
||||
"test_rough_intel_feedback.py": 0,
|
||||
"test_radio_waiting_text.py": 0
|
||||
},
|
||||
"baseline_start_settings": {
|
||||
"exit": 1,
|
||||
"result": "Compiled then SIGABRT at AddedDefault(startMode)==0 against exact baseline Settings with proposed UI/command surface; not a compile-only absence failure."
|
||||
},
|
||||
"scope": "Actual settings parser/transaction and StartCommand/Display bodies. Native file IO, resource/UI and frozen mode boundary doubled; actual runtime freeze belongs to core proposal.",
|
||||
"native_or_live_writes": false,
|
||||
"compiler_work_finished": true
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
--- a/tests/test_hq_convoy_dispatch.py
|
||||
+++ b/tests/test_hq_convoy_dispatch.py
|
||||
@@ -9,7 +9,7 @@
|
||||
def cpp(s):
|
||||
for old,new in [('protected ',''),('override ',''),('null','nullptr'),('Replication.','Replication::'),
|
||||
('ERR_GameMode.','ERR_GameMode::'),('ERR_ConvoyRoadPlan.','ERR_ConvoyRoadPlan::'),
|
||||
- ('ERR_Settings.','ERR_Settings::'),('ERR_TimeService.','ERR_TimeService::'),('ERR_EnvironmentService.','ERR_EnvironmentService::'),('Math.','Math::'),('array<string>','Array<string>&')]:s=s.replace(old,new)
|
||||
+ ('ERR_AdminMenuFields.','ERR_AdminMenuFields::'),('ERR_Settings.','ERR_Settings::'),('ERR_TimeService.','ERR_TimeService::'),('ERR_EnvironmentService.','ERR_EnvironmentService::'),('Math.','Math::'),('array<string>','Array<string>&')]:s=s.replace(old,new)
|
||||
for typ in ('ERR_GameMode','ERR_ConvoyReceipt','ERR_ConvoyTask','ERR_SiteRuntime','ERR_HQUnit','ERR_AdminProvider'):
|
||||
s=re.sub(r'\b'+typ+r' (?=\w)',typ+'* ',s)
|
||||
for var in ('m_SupplyConvoys','m_ConvoyStartup','m_Mode','m_Convoys','m_ConvoyPool','m_ConvoyTask','m_HQ','site','unit','receipt','mode','provider'):
|
||||
@@ -87,6 +87,8 @@
|
||||
if(key=="automaticConvoyEnabled"){automatic=value;return true;}
|
||||
assert(key=="antiAirChancePercent");stinger=value;return true;}
|
||||
};
|
||||
+// Settings listing is outside these convoy assertions (Keys is empty); its actual formatter is covered by test_start_settings.
|
||||
+struct ERR_AdminMenuFields{static string StartSummary(int,int){return "start summary";}};
|
||||
// Date/time branches are unrelated to these commands and deliberately refuse.
|
||||
struct ERR_TimeService{static bool ParseClock(string,int&){return false;}};
|
||||
struct ERR_EnvironmentService{static bool ParseDate(string,int&){return false;}static bool ParseProfile(string,int&){return false;}};
|
||||
@@ -98,7 +100,7 @@
|
||||
struct Sites sites;ERR_Settings settings;bool sitesReady=true;
|
||||
static ERR_GameMode* Get(){return current;}bool Active(){return active;}Ledger* Forces(){return &ledger;}
|
||||
struct Sites* Sites(){return sitesReady?&sites:nullptr;}ERR_Settings* Settings(){return settingsReady?&settings:nullptr;}
|
||||
- string Status(){return "mission";}bool AbandonRound(){return false;}
|
||||
+ int StartMode(){return 0;}string Status(){return "mission";}bool AbandonRound(){return false;}
|
||||
};
|
||||
struct Clock{float GetWorldTime(){return 123000;}Clock* GetWorld(){return this;}}clock_;
|
||||
Clock* GetGame(){return &clock_;}
|
||||
@@ -0,0 +1 @@
|
||||
PASS: actual authenticated convoy dispatch, active/ready admission gates, canonical receipt, safe unconsumed preflight retry, pool refusal, retained partial failure and consumed no-retry
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"complete": true,
|
||||
"scope": "Read-only route proposal/API review, plus separate tests-only adapter followup. No compiler or native run after parent serialization notice.",
|
||||
"source_hashes": {
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c": "d039027a462cc57d35d5e4f722e5b6b03e8f95a38fe66b19982092df983b1db0",
|
||||
"addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c": "ce55c8be0047406e17ec4dced1912332ab4347bfa1f204921302392099a9e67b",
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_NativeContractsProbe.c": "60aa767d9455f2f4958a6a47bd68bbd8ab0466adc8f1dd9ae433c40ae96c68ff",
|
||||
"addons/core/Scripts/Game/ERR/30_Map/ERR_ScenarioMap.c": "75fa1d742129ef7f33c005cd48f56db7f49ee7bde3c5428532b0b501b032b0a3"
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"status": "corrected",
|
||||
"detail": "Authored vanilla map is replaced by current ScenarioMap FieldMap; followup expectation matches exact active owned resource. Direct reciprocal bag slot filter counts loose authored stock and excludes nested gun magazines."
|
||||
}
|
||||
],
|
||||
"branch_review": "Default prison route retained. Crash starts in RADIO_SEARCH, validates canonical conscious on-foot original actor, owned static replicated wreck and bounded measured geometry, then uses ordinary stock/radio/extraction route. Contracts expected objective matches frozen mode.",
|
||||
"api_review": "CompartmentAccessComponent.IsInCompartment is installed generated native API. GetBounds and Physics.IsDynamic match successfully executed geometry witness. Native stock slot methods match established reciprocal custody patterns.",
|
||||
"limits": [
|
||||
"No claim of full crash native success; parent run is pending.",
|
||||
"Shared map fixture expectation is pinned to current ScenarioMap override; future overrides require adapting diagnostic.",
|
||||
"No multiplayer, flight, pathing or collision guarantee is inferred."
|
||||
],
|
||||
"adapter_manifest_sha256": "ab2364c9e3139125b1d8bb0fdfde8d2c51908d0bbdb433dcecfd0b033bfc45d0"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"files": {
|
||||
"tests/test_hq_convoy_dispatch.py": {
|
||||
"baseline_sha256": "945a3cba06694608b4880408a13447ebbbf812d400fba3af5b7a57cb006a1f6d",
|
||||
"proposed_sha256": "eab5cbc72fa6efcf4702acc4f2d2165c99b37da97c648d3c3b489234f375ecd4"
|
||||
}
|
||||
},
|
||||
"patch_sha256": "cad9cacc06b7ce730cd581ed2a8eddfb7ed83dc682daece37686f7fda200d310",
|
||||
"green_log_sha256": "9ef0c0bc476587c61a60336fb57dd110e9fc14babe9c3b608b6fdc87b3c10c43",
|
||||
"focused_exit_code": 0,
|
||||
"scope": "Tests only. Namespace translation, current-mode getter double and unrelated settings formatter double. Existing assertions and extracted production bodies unchanged.",
|
||||
"scan": "Other Execute-body users test_start_settings, test_spectator_guidance, test_intel_admin, test_convoy_auto_settings, test_admin_providers, test_view_distance, test_ai_stinger_admin do not compile affected listing prefix.",
|
||||
"baseline_failure": "Parent preliminary full suite at /tmp/erri-crash-root-1852/full-suite.log retained; failure was missing C++ doubles for newly introduced API, not a production regression."
|
||||
}
|
||||
Reference in New Issue
Block a user