Files
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

52 lines
6.5 KiB
Python

from pathlib import Path
root=Path('/home/jakub/devel/escapistsrereintroduced'); out=Path('/tmp/erri-mounted-intercept-rules-1247/tests/test_hq_mounted_intercept.py')
old=(root/'tests/test_hq_road_intercept.py').read_text(); prefix=old[:old.index("run(r'''")]; cpp=old[old.index("run(r'''")+8:old.index("''' + s + r'''")]
prefix=prefix.replace('ERR_ROAD_INTERCEPT_SOURCE','ERR_MOUNTED_INTERCEPT_SOURCE').replace("'ERR_HQRoadIntercept.c'","'ERR_HQMountedIntercept.c'",1)
prefix=prefix.replace("source=p.read_text()","source=p.read_text()\nbase=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQRoadIntercept.c'\nsource='class ERR_HQRoadIntercept\\n{\\n'+'\\n'.join(body(base,x) for x in ('static bool Eligible(', 'static bool Unreserved(', 'static bool Better('))+'\\n}\\n'+source")
prefix=prefix.replace(".replace('class ERR_HQRoadIntercept','struct ERR_HQRoadIntercept')", ".replace('class ERR_HQRoadIntercept','struct ERR_HQRoadIntercept').replace('class ERR_HQMountedInterceptRules','struct ERR_HQMountedInterceptRules').replace('class ERR_ConvoyInterceptOrder','struct ERR_ConvoyInterceptOrder')")
prefix=prefix.replace("('ERR_HQBelief','SCR_AIWorld','BaseRoad','TraceBox')", "('ERR_HQBelief','SCR_AIWorld','BaseRoad','TraceBox','SCR_AIGroup','ERR_ConvoyInterceptOrder','ERR_SettlementSafety','ERR_ConvoyPlacement')")
prefix=prefix.replace("('belief','world','road','body')", "('belief','world','road','body','order','settlements','placement')")
prefix=prefix.replace("'Replication')", "'Replication','ERR_HQRoadIntercept')")
prefix=prefix.replace("s=s.replace('null','nullptr')", "s=s.replace('null','nullptr').replace('string SourceId','std::string SourceId').replace('.IsEmpty()', '.empty()')")
prefix=prefix.replace("r'\\1 \\2{};',s)", "r'\\1 \\2{};',s).replace('float score, heading;', 'float score=0, heading=0;')")
cpp=cpp.replace('struct Math{','struct SCR_AIGroup{};\nstruct Math{static constexpr float RAD2DEG=57.2957795131f;static float Atan2(float x,float y){return std::atan2(x,y);}')
cpp=cpp.replace('int SampleCount=2,MessageId=1;', 'int SampleCount=2,MessageId=1,BeliefId=3,BeliefRevision=2;vector Position={1000,10,1000};')
cpp=cpp.replace('float width=4;', 'float width=6;').replace('{900,10,1060},{1100,10,1060}', '{900,10,1300},{1100,10,1300}')
cpp+='''
struct ERR_SettlementSafety{static inline bool clear=true;static inline int calls=0;bool OutsideSettlements(vector){calls++;return clear;}};
struct ERR_ConvoyPlacement{static inline bool clear=true;static inline int calls=0;static inline float heading=0;bool Clear(vector p,float h){calls++;heading=h;assert(p.y==10);return clear;}};
'''
main=r'''
int main(){
using Rules=ERR_HQMountedInterceptRules;ERR_HQBelief belief;SCR_AIGroup group;
assert(Rules::Eligible(&belief,10000));
ERR_ConvoyInterceptOrder order;order.Token=400001;order.Group=&group;order.SourceId="original-convoy";order.VehicleIndex=0;order.Position={1000,10,1300};order.IssuedAt=8000;order.ExpiresAt=125000;order.ObservedAt=5000;order.BeliefId=3;order.BeliefRevision=2;order.ReportId=1;
vector frozen=order.Position;assert(Rules::Current(&order,&belief,10000));belief.PredictedPosition={1050,10,1000};assert(Rules::Current(&order,&belief,11000)&&order.Position==frozen);belief.PredictedPosition={1000,10,1000};
for(int fault=0;fault<21;fault++){auto b=belief;auto o=order;float now=10000;
if(fault==0)o.Token=400000;if(fault==1)o.Token=400257;if(fault==2)o.Group=nullptr;if(fault==3)o.SourceId="";
if(fault==4)o.VehicleIndex=1;if(fault==5)o.BeliefId++;if(fault==6)o.BeliefRevision++;if(fault==7)o.ReportId++;if(fault==8)o.ObservedAt++;
if(fault==9)o.IssuedAt=6000;if(fault==10)o.IssuedAt=11000;if(fault==11)o.ExpiresAt=125001;if(fault==12)o.ExpiresAt=10000;
if(fault==13)o.IssuedAt=NAN;if(fault==14)o.Position.x=NAN;if(fault==15)b.HasVelocity=false;if(fault==16)b.SampleCount=1;
if(fault==17)b.LastDeliveredAt=10001;if(fault==18)b.TravelMode="aircraft";if(fault==19)now=38001;if(fault==20)b.ObservedAt=-1;
assert(!Rules::Current(&o,&b,now));}
order.VehicleIndex=3;assert(Rules::Current(&order,&belief,38000));order.VehicleIndex=5;assert(Rules::Current(&order,&belief,38000));
assert(!Rules::Eligible(&belief,50001));assert(!Rules::Eligible(nullptr,10000));
Array<vector> reserved;vector result;BaseRoad road;game.ai.manager.roads={&road};
assert(Rules::Select(&belief,10000,reserved,result)&&result==vector(1000,10,1300));assert(ERR_ConvoyPlacement::calls==1&&ERR_SettlementSafety::calls==1);assert(std::abs(ERR_ConvoyPlacement::heading-90)<.001);
road.width=5.99;assert(!Rules::Select(&belief,10000,reserved,result)&&result==vector::Zero);road.width=6;
int placementCalls=ERR_ConvoyPlacement::calls;ERR_SettlementSafety::clear=false;assert(!Rules::Select(&belief,10000,reserved,result)&&result==vector::Zero&&ERR_ConvoyPlacement::calls==placementCalls);ERR_SettlementSafety::clear=true;
ERR_ConvoyPlacement::clear=false;assert(!Rules::Select(&belief,10000,reserved,result)&&result==vector::Zero);ERR_ConvoyPlacement::clear=true;
road.points={{900,20,1300},{1100,20,1300}};placementCalls=ERR_ConvoyPlacement::calls;assert(!Rules::Select(&belief,10000,reserved,result)&&ERR_ConvoyPlacement::calls==placementCalls);road.points={{900,10,1300},{1100,10,1300}};
reserved.Insert({1000,10,1300});assert(!Rules::Select(&belief,10000,reserved,result));reserved.clear();
game.ai.manager.roads.resize(129,&road);assert(!Rules::Select(&belief,10000,reserved,result));game.ai.manager.roads={&road};
auto unknown=belief;unknown.HasVelocity=false;int queries=game.ai.manager.queries;assert(!Rules::Select(&unknown,10000,reserved,result)&&game.ai.manager.queries==queries);
Replication::server=false;assert(!Rules::Select(&belief,10000,reserved,result)&&game.ai.manager.queries==queries);Replication::server=true;
float score,heading;assert(Rules::FromPolyline({{900,10,1300},{1100,10,1300}},belief.Position,belief.Velocity,{1000,10,1350},reserved,result,score,heading)&&result.z==1300);
assert(!Rules::Ahead(belief.Position,belief.Velocity,{1000,10,1299}));assert(!Rules::Ahead(belief.Position,belief.Velocity,{1000,10,1901}));
Array<vector> oversized(1025,{1000,10,1300});assert(!Rules::FromPolyline(oversized,belief.Position,belief.Velocity,{1000,10,1350},reserved,result,score,heading));
}
'''
# Independent sequential condition bodies should not trigger C++ misleading-indentation diagnostics.
main=main.replace(';if(', ';\n if(')
out.write_text(prefix+"run(r'''"+cpp+"''' + s + r'''"+main+"''')\nprint('PASS: actual mounted intercept eligibility/order chronology, fixed destinations, native road selection bounds, width, segment heading, clearance and settlement delegation; no native driving claim')\n")