Files
EscapistsReintroduced/tests/test_body_recovery_selection.py
T
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
3.0 KiB
Python

"""Execute production idle-team selection with explicit radio/status boundaries."""
import re
from policy_harness import ROOT, body, run
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_BodyRecovery.c'
s=body(p,'SCR_AIGroup RecoveryTeam(')
s=s.replace('SCR_AIGroup RecoveryTeam','Group* RecoveryTeam').replace('array<SCR_AIGroup> blocked','Array<Group*>* blocked')
s=s.replace('ERR_HQUnit best;', 'Unit* best=nullptr;').replace('ERR_HQUnit unit : m_Units','Unit* unit : m_Units').replace('ERR_HQWatchEntry status','Status* status')
s=s.replace('foreach (','for (').replace('null','nullptr').replace('nullptrptr','nullptr')
for name in ('unit','status','best','blocked'):s=s.replace(name+'.',name+'->')
s=s.replace('vector.DistanceXZ','vector::DistanceXZ').replace('ERR_InfantryResupplyRules.Fresh','Rules::Fresh')
run(r'''
#include <cassert>
#include <vector>
#include <cmath>
#include <algorithm>
struct vector{float x=0;static float DistanceXZ(vector a,vector b){return std::abs(a.x-b.x);}};
struct Group{};
template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;bool Contains(T t){return std::find(this->begin(),this->end(),t)!=this->end();}};
struct Status{vector Position;bool fresh=true;};
struct Unit{struct Group* Group=nullptr;bool eligible=true,HomeGuard=false,Assignment=false,PendingTask=false,PendingOrder=false,Downlink=false,fighting=false,Radio=true;int ForceSourceId=0;bool Eligible(void*){return eligible;}};
struct Watch{Status entries[3];Status* Find(int i){return &entries[i];}};
struct Network{bool available=true;bool Route(bool,bool){return available;}};
struct Rules{static bool Fresh(Status*s,float){return s&&s->fresh;}};
struct HQ{Array<Unit*> m_Units;Watch m_Watch;Network m_Network;void* m_Mode=nullptr;bool Fighting(Unit*u){return u->fighting;}
'''+s+r'''
};
int main(){
Group a,b;Unit first,second;first.Group=&a;second.Group=&b;second.ForceSourceId=1;
HQ h;h.m_Units={&first,&second};h.m_Watch.entries[0].Position.x=100;h.m_Watch.entries[1].Position.x=200;
assert(h.RecoveryTeam({},nullptr,1000)==&a);
Array<Group*> blocked{&a};assert(h.RecoveryTeam({},&blocked,1000)==&b);
blocked.push_back(&b);assert(!h.RecoveryTeam({},&blocked,1000));
h.m_Units={&first};
for(int fault=0;fault<10;fault++){
Unit clean=first;first=Unit{};first.Group=&a;
if(fault==0)first.eligible=false;
if(fault==1)first.HomeGuard=true;
if(fault==2)first.Assignment=true;
if(fault==3)first.PendingTask=true;
if(fault==4)first.PendingOrder=true;
if(fault==5)first.Downlink=true;
if(fault==6)first.fighting=true;
if(fault==7)first.Radio=false;
if(fault==8)h.m_Watch.entries[0].fresh=false;
if(fault==9)h.m_Network.available=false;
assert(!h.RecoveryTeam({},nullptr,1000));first=clean;h.m_Watch.entries[0].fresh=true;h.m_Network.available=true;
}
h.m_Watch.entries[0].Position.x=5000;assert(!h.RecoveryTeam({},nullptr,1000));
}
''')
print('PASS: nearest reported idle team, blocked teams, guards, active/pending orders, combat, radio routes, stale status and distance limit')