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 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 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")