Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
28 lines
2.3 KiB
Python
28 lines
2.3 KiB
Python
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 <cassert>
|
|
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 <cassert>
|
|
#include <string>
|
|
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')
|