Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
46 lines
7.4 KiB
Python
46 lines
7.4 KiB
Python
"""Execute full captured footprint class with explicit native bounds/hierarchy doubles."""
|
|
from pathlib import Path
|
|
import os,re
|
|
from policy_harness import ROOT,run
|
|
p=Path(os.environ.get('ERR_INTERCEPT_FOOTPRINT_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InterceptVehicleFootprint.c'))
|
|
s=p.read_text();assert 'private float m_Radius;' in s and 'private IEntity m_Root;' in s
|
|
s=re.sub(r'//[^\n]*','',s).replace('class ERR_InterceptVehicleFootprint','struct ERR_InterceptVehicleFootprint').replace('private ','').replace('protected ','').replace('ref ','')
|
|
s=s.replace('ChimeraCharacter.Cast(entity) != null','entity->character').replace('CompartmentAccessComponent.Cast(entity.FindComponent(CompartmentAccessComponent))','entity->access').replace('InventoryItemComponent.Cast(entity.FindComponent(InventoryItemComponent))','entity->item')
|
|
s=s.replace('array<IEntity>','Array<IEntity*>').replace('Array<IEntity*> nodes,','Array<IEntity*>& nodes,').replace('foreach (','for (').replace('out float','float&').replace('vector minimum, maximum;','vector minimum{}, maximum{};').replace('float radius, low, high;','float radius=0,low=0,high=0;')
|
|
for cls in ['IEntity','ERR_InterceptVehicleFootprint','CompartmentAccessComponent','InventoryItemComponent','InventoryStorageSlot','BaseInventoryStorageComponent']:
|
|
s=re.sub(r'\b'+cls+r' (\w+)',cls+r'* \1',s)
|
|
for n in ['root','entity','child','item','slot','storage','access','footprint']:s=s.replace(n+'.',n+'->')
|
|
s=s.replace('m_Nodes[0]','m_Nodes[0]').replace('GetCompartment().','GetCompartment()->')
|
|
for n in ['ERR_ForceRules','Math','EStoragePurpose']:s=s.replace(n+'.',n+'::')
|
|
s=s.replace('null','nullptr').replace('\n}\n','\n};\n');s=re.sub(r'\b(float|int|bool) (\w+);',r'\1 \2{};',s)
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <cmath>
|
|
#include <algorithm>
|
|
#include <vector>
|
|
struct vector{float x=0,y=0,z=0;float&operator[](int n){return n==0?x:n==1?y:z;}vector operator+(vector b)const{return{x+b.x,y+b.y,z+b.z};}vector operator-(vector b)const{return{x-b.x,y-b.y,z-b.z};}};
|
|
vector Vector(float x,float y,float z){return{x,y,z};}
|
|
namespace Math{float Sqrt(float n){return std::sqrt(n);}float Min(float a,float b){return std::min(a,b);}float Max(float a,float b){return std::max(a,b);}}
|
|
namespace ERR_ForceRules{bool Finite(float n){return std::isfinite(n);}bool FiniteVector(vector v){return Finite(v.x)&&Finite(v.y)&&Finite(v.z);}}
|
|
template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}bool IsEmpty(){return this->empty();}void Insert(T v){this->push_back(v);}bool Contains(T v){return std::find(this->begin(),this->end(),v)!=this->end();}explicit operator bool(){return true;}};
|
|
struct IEntity;struct Seat{IEntity*occupant=nullptr;IEntity*GetOccupant(){return occupant;}};
|
|
struct CompartmentAccessComponent{bool inside=true;IEntity*owner=nullptr;Seat*seat=nullptr;bool IsInCompartment(){return inside;}IEntity*GetVehicleCompartmentManagerOwner(){return owner;}Seat*GetCompartment(){return seat;}};
|
|
struct InventoryStorageSlot;
|
|
struct BaseInventoryStorageComponent{InventoryStorageSlot*current=nullptr;InventoryStorageSlot*GetSlot(int id){return id==0?current:nullptr;}IEntity*owner=nullptr;int purpose=1;IEntity*GetOwner(){return owner;}int GetPurpose(){return purpose;}};
|
|
struct InventoryStorageSlot{int GetID(){return 0;}BaseInventoryStorageComponent*storage=nullptr;void*container=nullptr;IEntity*attached=nullptr;BaseInventoryStorageComponent*GetStorage(){return storage;}void*GetParentContainer(){return container;}IEntity*GetAttachedEntity(){return attached;}};
|
|
struct InventoryItemComponent{InventoryStorageSlot*slot=nullptr;InventoryStorageSlot*GetParentSlot(){return slot;}};
|
|
namespace EStoragePurpose{constexpr int PURPOSE_UNSET=0,PURPOSE_DEPOSIT=1,PURPOSE_ANY=127;}
|
|
struct IEntity{IEntity*child=nullptr,*sibling=nullptr,*parent=nullptr;InventoryItemComponent*item=nullptr;CompartmentAccessComponent*access=nullptr;bool character=false,geometry=true;vector lo={-1,-.5,-2},hi={1,2,2},origin={100,10,100};float yaw=0;int reads=0;bool GetVObject(){return geometry;}IEntity*GetChildren(){return child;}IEntity*GetSibling(){return sibling;}IEntity*GetParent(){return parent;}void GetBounds(vector&a,vector&b){reads++;a=lo;b=hi;}vector CoordToParent(vector v){return origin+Vector(v.x*std::cos(yaw)+v.z*std::sin(yaw),v.y,-v.x*std::sin(yaw)+v.z*std::cos(yaw));}vector CoordToLocal(vector v){v=v-origin;return{v.x*std::cos(yaw)-v.z*std::sin(yaw),v.y,v.x*std::sin(yaw)+v.z*std::cos(yaw)};}};
|
|
''' + s + r'''
|
|
int main(){using F=ERR_InterceptVehicleFootprint;IEntity root;auto f=F::Capture(&root);assert(f&&f->Valid()&&f->Matches(&root));assert(std::abs(f->Radius()-(std::sqrt(5.f)+.5f))<.001);assert(std::abs(f->Height()-3.5)<.001);IEntity foreign;assert(!f->Matches(&foreign));float radius=f->Radius();root.origin={-700,33,900};root.yaw=.7;assert(f->Matches(&root)&&f->Radius()==radius);
|
|
for(int bad=0;bad<6;bad++){IEntity e;if(bad==0)e.geometry=false;if(bad==1)e.lo.x=NAN;if(bad==2)e.hi.x=e.lo.x;if(bad==3)e.hi.z=41;if(bad==4)e.origin.x=NAN;if(bad==5)e.hi.y=16;assert(!F::Capture(&e));}assert(!F::Capture(nullptr));
|
|
IEntity hull,attachment;hull.child=&attachment;attachment.parent=&hull;attachment.lo={-.5,0,-.5};attachment.hi={.5,.5,.5};f=F::Capture(&hull);assert(f&&f->Matches(&hull));attachment.yaw=.8;assert(f->Matches(&hull));attachment.hi.z=9;assert(!f->Matches(&hull));attachment.hi.z=.5;attachment.origin.y=20;assert(!f->Matches(&hull));attachment.origin.y=10;IEntity replacement;hull.child=&replacement;assert(!f->Matches(&hull));hull.child=&attachment;attachment.sibling=&replacement;assert(!f->Matches(&hull));attachment.sibling=nullptr;
|
|
// Seated body is measured, but a huge carried inventory child is not traversed.
|
|
IEntity body,carried;Seat seat;CompartmentAccessComponent access;hull.child=&body;body.parent=&hull;body.character=true;body.lo={-.4,0,-.4};body.hi={.4,1.5,.4};body.access=&access;access.owner=&hull;access.seat=&seat;seat.occupant=&body;body.child=&carried;carried.hi.z=999;f=F::Capture(&hull);assert(f&&f->Matches(&hull)&&carried.reads==0);access.inside=false;assert(!f->Matches(&hull));access.inside=true;seat.occupant=&foreign;assert(!F::Capture(&hull));seat.occupant=&body;access.owner=&foreign;assert(!F::Capture(&hull));
|
|
// Only exact reciprocal in-root deposit cargo is skipped; unknown/foreign is not.
|
|
IEntity cargo;InventoryItemComponent item;InventoryStorageSlot slot;BaseInventoryStorageComponent storage;hull.child=&cargo;cargo.parent=&hull;cargo.hi.z=999;cargo.item=&item;item.slot=&slot;slot.storage=&storage;slot.container=&storage;slot.attached=&cargo;storage.owner=&hull;storage.current=&slot;f=F::Capture(&hull);assert(f&&f->Matches(&hull)&&cargo.reads==0);storage.current=nullptr;assert(!F::Capture(&hull)&&!f->Matches(&hull));InventoryStorageSlot otherSlot;storage.current=&otherSlot;assert(!F::Capture(&hull)&&!f->Matches(&hull));storage.current=&slot;assert(f->Matches(&hull));slot.attached=&foreign;assert(!F::Capture(&hull));slot.attached=&cargo;storage.purpose=127;assert(!F::Capture(&hull));storage.purpose=1;storage.owner=&foreign;assert(!F::Capture(&hull));
|
|
IEntity nodes[129];for(int i=0;i<128;i++){nodes[i].child=&nodes[i+1];nodes[i+1].parent=&nodes[i];}assert(!F::Capture(&nodes[0]));nodes[127].child=nullptr;f=F::Capture(&nodes[0]);assert(f&&f->Matches(&nodes[0]));nodes[127].child=&nodes[0];assert(!F::Capture(&nodes[0]));
|
|
}
|
|
''')
|
|
print('PASS: actual immutable measured footprint/root/attachment matching, bounds/transforms, moving geometry, seated-body and cargo reciprocity, finite hierarchy caps; native geometry doubled')
|