Files
EscapistsReintroduced/tests/test_infantry_resupply_waypoints.py
T
jakub cab998fb64 Combine Workshop addon and fix prison startup
Merge owned systems into one addon while preserving resource identities. Gate player admission on the replicated prison scene, restore the original framed door, and hold enemy AI until escape. Correct scenario branding and author metadata, include publishing assets, and retain regression and native verification evidence.
2026-09-20 16:42:52 +02:00

40 lines
2.6 KiB
Python

"""Actual rendezvous waypoint geometry and native order insertion; no navigation proof."""
from pathlib import Path
import os
from policy_harness import ROOT,body,run
P=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c'))
s=body(P,'protected bool Waypoints()').replace('protected ','')
for name in ('AIWaypoint','ERR_Actors','ERR_Resources'):s=s.replace(name+'.',name+'::')
for name in ('m_MoveWaypoint','m_HoldWaypoint','m_Recipient'):s=s.replace(name+'.',name+'->')
s=s.replace('Group.', 'Group->')
run(r'''
#include <cassert>
#include <vector>
#include <cmath>
struct Vec{float x,y,z;};
struct AIWaypoint{float radius=0;int kind;Vec position;void SetCompletionRadius(float r){radius=r;}static AIWaypoint* Cast(AIWaypoint* p){return p;}};
struct ERR_Resources{static int MoveWaypoint(){return 1;}static int DefendWaypoint(){return 2;}};
struct ERR_Actors{static inline int reject=0;static inline std::vector<AIWaypoint*>spawned;
static Vec Ground(Vec p){p.y=2;return p;}
static AIWaypoint* Spawn(int kind,Vec p){if(reject==kind)return nullptr;auto w=new AIWaypoint{0,kind,p};spawned.push_back(w);return w;}};
struct Group{std::vector<AIWaypoint*>order;int activated=0;void AddWaypointAt(AIWaypoint* w,int index){assert(index==0);order.insert(order.begin(),w);}void ActivateAI(){activated++;}};
struct Unit{struct Group* Group;};
struct Service{AIWaypoint* m_MoveWaypoint=nullptr;AIWaypoint* m_HoldWaypoint=nullptr;Unit* m_Recipient;Vec m_Rendezvous;
'''+s+r'''
};
int main(){
Group group;Unit unit{&group};Service service;service.m_Recipient=&unit;service.m_Rendezvous={13,8,5};
assert(service.Waypoints()&&group.activated==1&&group.order.size()==2);
assert(group.order[0]==service.m_MoveWaypoint&&group.order[1]==service.m_HoldWaypoint);
assert(group.order[0]->kind==1&&group.order[1]->kind==2);
for(auto* w:group.order){assert(w->position.x==13&&w->position.y==2&&w->position.z==5&&w->radius==0.5f);}
// A radius of 2 admitted a flat approach point 5m from the report center; 0.5 removes that allowance.
const float reportX=10;const float oldArrivalX=service.m_Rendezvous.x+2;
assert(oldArrivalX-reportX>4&&service.m_Rendezvous.x+service.m_MoveWaypoint->radius-reportX<4);
// Failed partial construction never inserts either waypoint or activates the group.
for(int failed:{1,2}){ERR_Actors::reject=failed;Group refused;Unit u{&refused};Service bad;bad.m_Recipient=&u;bad.m_Rendezvous={13,8,5};
assert(!bad.Waypoints()&&refused.order.empty()&&refused.activated==0);}
}
''')
print('PASS: actual report-derived waypoint insertion/order and tighter positive radii; no formation navigation claim')