Files
jakub fda19a5200 Complete roadblocks in background and fix session regressions
Continue safe roadblock placement after admission and prison unlock, build posts incrementally, and clean up incomplete transactions. Add bounded stuck-patrol dismount recovery, defer deployment initialization during terrain takeover, reset deferred site search timing on first player arrival, and fix atlas page serialization and terrain resource lookup.

Validation: 30 native Everon posts with 120 living guards after unlock; seven affected regression suites pass; two final restart smoke rounds complete with 21 assertions and no script/runtime failures. Existing dependency asset errors remain.
2026-10-14 19:48:29 +02:00

50 lines
3.1 KiB
Python

"""Execute road suitability/spacing and validate admin/settings integration."""
from policy_harness import ROOT, body, run
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_Roadblocks.c'
code=body(p,'static int SearchMilliseconds(')+'\n'+body(p,'static int SearchAttempts(')+'\n'+body(p,'static bool Road(')+'\n'+body(p,'static bool Spaced(')
code=code.replace('array<vector> used','Array<Vec>* used').replace('vector ', 'Vec ').replace('foreach (','for (').replace(' : used)', ' : *used)').replace('vector.DistanceXZ','Vec::DistanceXZ').replace('ERR_ForceRules.FiniteVector','Finite').replace('ERR_ForceRules.Finite','std::isfinite').replace('Math.AbsFloat','std::abs').replace('Math.Clamp','std::clamp')
run(r'''
#include <algorithm>
#include <cassert>
#include <cmath>
#include <limits>
#include <vector>
struct Vec{float x,y,z;static float DistanceXZ(Vec a,Vec b){return std::hypot(a.x-b.x,a.z-b.z);}};
bool Finite(Vec v){return std::isfinite(v.x)&&std::isfinite(v.y)&&std::isfinite(v.z);}
template<class T>using Array=std::vector<T>;
'''+code+r'''
int main(){
assert(SearchMilliseconds()==12000 && SearchAttempts()==300);
float nan=std::numeric_limits<float>::quiet_NaN();
assert(Road(4,40,2)&&Road(16,100,-2));
assert(!Road(3.9,100,0)&&!Road(17,100,0)&&!Road(6,39,0));
assert(!Road(6,100,2.1)&&!Road(6,100,-2.1)); // elevated bridge/underpass
assert(!Road(nan,100,0)&&!Road(6,nan,0)&&!Road(6,100,nan));
Array<Vec> used;Vec prison{0,0,0};
assert(Spaced({700,50,0},&used,prison,3000));
assert(!Spaced({699,0,0},&used,prison,3000));
assert(!Spaced({2800,0,0},&used,prison,3000));
used.push_back({1300,100,0});
assert(Spaced({700,0,0},&used,prison,3000));
assert(!Spaced({701,0,0},&used,prison,3000));
assert(!Spaced({nan,0,0},&used,prison,3000));
assert(!Spaced({700,0,0},nullptr,prison,3000));
assert(!Spaced({700,0,0},&used,prison,nan));
}
''')
settings=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c'
assert '"roadblockCount"' in body(settings,'static array<string> Keys(')
# Execute actual settings branches, not a duplicated policy.
import re
valid=re.search(r'if \(key == "roadblockCount"\) return ([^;]+);',body(settings,'static bool Valid('))[1]
default=re.search(r'if \(key == "roadblockCount"\) return ([^;]+);',body(settings,'static int AddedDefault('))[1]
run('#include <cassert>\nbool valid(int value){return '+valid+';}\nint main(){assert(!valid(-1)&&valid(0)&&valid(4)&&valid(12)&&valid(13)&&valid(30)&&!valid(31));assert('+default+'==4);}')
s=p.read_text()
assert s.index('m_Mode.Forces().Register(')<s.index('m_Mode.RegisterGroup(m_BuildGroup)')
assert 'm_Groups.Insert(m_BuildGroup)' in s and 'm_Mode.Own(ownedEntity)' in s
assert 'm_Attempts >= ERR_RoadblockRules.SearchAttempts()' in s and '>= ERR_RoadblockRules.SearchMilliseconds()' in s and 'm_Ready) return ERR_PrepareResult.READY' in s
assert 'if (m_Target == 0) return Finish("disabled")' in s
assert 'm_Positions.Count() >= m_Target' in s
assert 'roadblockCount' not in body(settings,'static bool Randomizable(')
print('PASS: road width/bridge/length checks, prison and post spacing, setting bounds/default, finite startup and owned HQ admission')