"""Execute actual aim-equivalence and renewal control flow with synthetic API data. No fake native ballistic result is represented as a measured firing result. """ import re from policy_harness import ROOT, body, run r=ROOT/'addons/ai/Scripts/Game/ERR' solution=r/'ERR_MortarAimSolution.c'; firing=r/'ERR_MortarFiring.c' eq=body(solution,'static bool Equivalent(').replace('vector.Distance','vector::Distance').replace('Math.AbsFloat','std::fabs') matches=body(solution,'bool Matches(').replace('ERR_MortarBattery battery','ERR_MortarBattery* battery').replace('ERR_HQReport report','ERR_HQReport* report').replace('battery.','battery->') fresh=body(r/'ERR_MortarPrediction.c','static bool Fresh(').replace('ERR_HQReport report','ERR_HQReport* report').replace('report.','report->') renew=body(firing,'bool ERR_RevalidateAim(') for typ in ['ERR_MortarBattery','ERR_MortarSystem','ERR_HQReport','ERR_MortarAimSolution']: renew=re.sub(r'\b'+typ+r' (battery|system|report|commanded|updated)\b',typ+r'* \1',renew) renew=renew.replace('IEntity gun;','IEntity gun=nullptr;').replace('ResourceName ammo;','std::string ammo;') for name in ['battery','system','report','commanded','updated']:renew=renew.replace(name+'.',name+'->') for name in ['ERR_MortarBattery','ERR_MortarAimRules','ERR_MortarPrediction']:renew=renew.replace(name+'.',name+'::') # Native trace formatting is deliberately inert. Authorization branches remain # the production method body, and every solver invocation is counted below. renew=re.sub(r', string\.Format\([^\n]*\)\);',');',renew) run('''#include #include #include #include struct vector {float x=0,y=0,z=0; static float Distance(vector a,vector b){return std::sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));}}; using IEntity=void*; struct ERR_HQReport {IEntity Target=this;bool Distress=false;float ObservedAt=0;std::string TravelMode="foot";}; struct ERR_MortarPrediction {static constexpr float MAX_REPORT_AGE_MS=60000; '''+fresh+'''}; struct ERR_MortarAimRules { '''+eq+'''}; struct Node;struct ERR_MortarAimSolution; struct ERR_MortarBattery {static inline std::string SHELL="nativeHE";IEntity Gun=this;ERR_MortarAimSolution* AimSolution=nullptr;Node* AimSolver=nullptr;int OrderId=1,OrderShots=0;float AimedAt=1000,AimValidatedAt=1000; void Trace(const char*,const char*){}}; struct ERR_MortarAimSolution {IEntity Gun=nullptr;ERR_HQReport* Report=nullptr;int OrderId=1,Shot=0,Charge=0;vector GunOrigin{},Impact{500,0,0},AimTarget{500,500,0};float FlightTime=30; '''+matches+'''}; struct ERR_MortarSystem {int rejects=0;bool Withhold(ERR_MortarBattery*,const char*){rejects++;return false;}const char* ContactFailure(ERR_MortarBattery*){return "stale";}}; struct Node { static constexpr int PORT_ARTILLERY_ENTITY=1,PORT_AMMO_PREFAB=2; IEntity portGun=nullptr;std::string portAmmo=ERR_MortarBattery::SHELL;ERR_MortarAimSolution* calculated=nullptr;int solves=0; void GetVariableIn(int,IEntity& out){out=portGun;}void GetVariableIn(int,std::string& out){out=portAmmo;} ERR_MortarAimSolution* ERR_Solve(ERR_MortarBattery*,ERR_MortarSystem* system,ERR_HQReport*,float){solves++;if(!calculated)system->rejects++;return calculated;} '''+renew+'''}; struct Fixture { ERR_MortarBattery battery;ERR_HQReport report;ERR_MortarAimSolution original,next;ERR_MortarSystem system;Node node; Fixture(){original.Gun=battery.Gun;original.Report=&report;next=original;battery.AimSolution=&original;battery.AimSolver=&node;node.portGun=battery.Gun;node.calculated=&next;} bool attempt(float now=25000){return node.ERR_RevalidateAim(&battery,&system,&report,now);} }; int main(){ Fixture stable; assert(stable.attempt()); assert(stable.node.solves==1&&stable.battery.AimedAt==1000&&stable.battery.AimValidatedAt==25000); assert(stable.report.ObservedAt==0&&stable.battery.AimSolution==&stable.original); assert(stable.attempt(45000)&&stable.node.solves==2); // fresh recomputation every renewal assert(!stable.attempt(60001)&&stable.node.solves==2&&stable.battery.AimedAt==1000&&stable.battery.AimValidatedAt==45000); // observation never renewed Fixture limit;assert(limit.attempt(60000)); Fixture future;future.report.ObservedAt=26000;assert(!future.attempt()&&future.node.solves==0); Fixture gone;gone.battery.AimSolver=nullptr;assert(!gone.attempt()&&gone.node.solves==0); Fixture wrongGun;wrongGun.node.portGun=&wrongGun.report;assert(!wrongGun.attempt()&&wrongGun.node.solves==0); Fixture wrongAmmo;wrongAmmo.node.portAmmo="other";assert(!wrongAmmo.attempt()&&wrongAmmo.node.solves==0); Fixture newReport;ERR_HQReport different;newReport.original.Report=&different;assert(!newReport.attempt()&&newReport.node.solves==0); Fixture nextOrder;nextOrder.battery.OrderId++;assert(!nextOrder.attempt()&&nextOrder.node.solves==0); Fixture nextShot;nextShot.battery.OrderShots++;assert(!nextShot.attempt()&&nextShot.node.solves==0); Fixture solverFail;solverFail.node.calculated=nullptr;assert(!solverFail.attempt()&&solverFail.battery.AimedAt==1000); Fixture charge;charge.next.Charge++;assert(!charge.attempt()&&charge.battery.AimedAt==1000); Fixture gunMove;gunMove.next.GunOrigin.y=.051f;assert(!gunMove.attempt()); Fixture impactMove;impactMove.next.Impact.y=.101f;assert(!impactMove.attempt()); Fixture aimMove;aimMove.next.AimTarget.y+=.101f;assert(!aimMove.attempt()); Fixture flight;flight.next.FlightTime+=.051f;assert(!flight.attempt()); Fixture invalid;invalid.next.FlightTime=std::numeric_limits::quiet_NaN();assert(!invalid.attempt()); Fixture slowDrift;slowDrift.next.Impact.x+=.06f;assert(slowDrift.attempt()); slowDrift.next.Impact.x+=.06f;assert(!slowDrift.attempt(35000)); // compare original, not last accepted approximation assert(slowDrift.battery.AimSolution==&slowDrift.original&&slowDrift.original.Impact.x==500); } ''') # The tested renewal is used at both existing pre-shot and physical-transfer # gates; it may neither emit a replacement barrel command nor change a report. source=firing.read_text();system=(r/'ERR_MortarSystem.c').read_text() assert source.count('system.AllowShot(battery)')==2 assert 'SetVariableOut' not in body(firing,'bool ERR_RevalidateAim(') assert 'ObservedAt =' not in source assert 'now - battery.AimValidatedAt > 10000' in system assert 'battery.AimSolver.ERR_RevalidateAim(battery, this, report, now)' in system assert source.count('BallisticTable.GetAimHeightOfProjectileAltitudeFromSource(')==1 assert 'GetAmmoInitialSpeedCoefficients(ammo, coefficients)' in body(firing,'protected ERR_MortarAimSolution ERR_Solve(') print('PASS: actual aim renewal requires fresh same-report solve and original-command equivalence; native firing untested')