from policy_harness import ROOT,body,run p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HunterCombat.c' s=body(p,'static bool Recent(').replace('EAITargetInfoCategory.','EAITargetInfoCategory::') run('''#include namespace EAITargetInfoCategory {enum {UNKNOWN,DESTROYED,DISARMED,LOST,DETECTED,IDENTIFIED};} '''+s+''' int main(){for(int c=0;c<6;c++){bool threat=c==4||c==5;assert(Recent(c,0)==threat);assert(Recent(c,15)==threat);assert(!Recent(c,-1));assert(!Recent(c,15.001f));}} ''') print('PASS: only recent native detected/identified threats suspend hunter travel; stale/disarmed/destroyed contacts cannot strand patrols') # Execute the actual state transition and owned-order cleanup with native perception doubled. s=body(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HunterService.c','protected void UpdateCombat(') s=s.replace('protected ','').replace('ERR_HunterVehicle unit','Unit* unit').replace('unit.','unit->').replace('ERR_HunterCombat.Active','Active').replace('ERR_HQ.Event','Event').replace('null','nullptr') run('''#include #include struct Group{bool contact=false;}; bool Active(Group* g){return g&&g->contact;} int messages=0;void Event(std::string,std::string){messages++;} struct Unit{bool Registered=true,CombatHeld=false;Group* Group=nullptr;float CombatQuietUntil=0,NextOrder=100;void* Downlink=nullptr;void CancelHQDownlink(){Downlink=nullptr;}std::string Source="test";int clears=0;void ClearOrder(){clears++;}}; '''.replace('Group* Group','struct Group* Group')+s+''' int main(){Group group;Unit u;u.Group=&group;u.Downlink=&group;UpdateCombat(&u,1000);assert(!u.CombatHeld&&u.clears==0&&u.Downlink); group.contact=true;UpdateCombat(&u,2000);assert(u.CombatHeld&&u.clears==1&&!u.Downlink&&u.CombatQuietUntil==17000); UpdateCombat(&u,5000);assert(u.clears==1&&u.CombatQuietUntil==20000&&messages==1); group.contact=false;UpdateCombat(&u,19999);assert(u.CombatHeld);UpdateCombat(&u,20000);assert(!u.CombatHeld&&u.NextOrder==0&&messages==2); Unit pending;pending.Group=&group;pending.Registered=false;group.contact=true;UpdateCombat(&pending,100);assert(!pending.CombatHeld&&pending.clears==0); } ''') print('PASS: actual hunter combat transition cancels only its travel once, holds through renewed contact and resumes after quiet; unregistered startup preserved')