40 lines
2.6 KiB
Python
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/ai/Scripts/Game/ERR/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')
|