Add configurable nearby garage vehicles and fix roadblocks and fuel pumps; record Workshop 0.0.131
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
"""Execute the shipped checkpoint layout across road widths and rotations."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_Roadblocks.c'
|
||||
s='\n'.join(body(p,x) for x in ('protected void Layout(', 'protected void AddProp('))
|
||||
s='\n'.join(body(p,x) for x in ('protected void Layout(', 'protected void AddProp(', 'protected vector GuardPosition('))
|
||||
s=s.replace('protected ', '').replace('out ', '').replace('array<ref ERR_RoadblockProp> covers', 'Array<Prop*>& covers')
|
||||
s=s.replace('ResourceName ', 'string ').replace('vector ', 'Vec ').replace('ERR_Actors.Ground','Ground').replace('new ERR_RoadblockProp','new Prop')
|
||||
shoulder = re.search(r'm_Shoulder = ([^;]+);', body(p, 'protected bool Candidate('))[1]
|
||||
shoulder = shoulder.replace('road.GetWidth()', 'width').replace('Math.Max', 'std::max')
|
||||
run(r'''
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
@@ -27,24 +30,28 @@ int main(){
|
||||
for(double width:{4.,6.,10.,16.})for(int degrees=0;degrees<360;degrees+=15){
|
||||
Checkpoint l;double angle=degrees*3.141592653589793/180;
|
||||
l.m_Forward={std::sin(angle),0,std::cos(angle)};l.m_Right={std::cos(angle),0,-std::sin(angle)};
|
||||
l.m_Shoulder=std::max(width*.5+1.5,4.);Array<Prop*>props;l.Layout(props);assert(props.size()==18);
|
||||
l.m_Shoulder='''+shoulder+r''';Array<Prop*>props;l.Layout(props);assert(props.size()==8);
|
||||
std::map<string,int>counts;std::vector<double>barriers;
|
||||
for(auto*p:props){counts[p->Prefab]++;
|
||||
Vec delta=p->Position-l.m_Centre;double across=dot(delta,l.m_Right),along=dot(delta,l.m_Forward);
|
||||
// Whole footprints (not just origins) preserve a four-metre straight passage.
|
||||
double reach=std::abs(dot(p->Right,l.m_Right))*p->HalfWidth+std::abs(dot(p->Forward,l.m_Right))*p->HalfDepth;
|
||||
assert(std::abs(across)-reach>=2.-1e-8);
|
||||
// Bound the compact footprint, including both road shoulders.
|
||||
assert(std::abs(across)+reach <= std::max(width*.5+1.2,4.5)+1e-6);
|
||||
double depth=std::abs(dot(p->Right,l.m_Forward))*p->HalfWidth+std::abs(dot(p->Forward,l.m_Forward))*p->HalfDepth;
|
||||
assert(std::abs(along)+depth <= 8.9+1e-6);
|
||||
if(p->Prefab=="barrier")barriers.push_back(along);
|
||||
if(p->Prefab=="sign")assert(dot(p->Forward,l.m_Forward)*along>0); // both approaches face outward
|
||||
// Guard starting volumes cannot intersect any prop in the planned post.
|
||||
for(int side:{-1,1})for(int row:{-1,1}){
|
||||
Vec guard=l.m_Centre+l.m_Right*(side*(l.m_Shoulder+2.5))+l.m_Forward*(side*(row-1.5));
|
||||
Vec guard=l.GuardPosition(side,row);
|
||||
Vec rel=guard-p->Position;
|
||||
assert(std::abs(dot(rel,p->Right))>p->HalfWidth+.6 || std::abs(dot(rel,p->Forward))>p->HalfDepth+.6);
|
||||
}
|
||||
}
|
||||
assert(counts["cover"]==8&&counts["barrier"]==4&&counts["obstacle"]==2&&counts["sign"]==2&&counts["table"]==1&&counts["shelter"]==1);
|
||||
assert(barriers.size()==4&&std::abs(barriers[0]-barriers[2])>15.9);
|
||||
assert(counts["cover"]==4&&counts["barrier"]==2&&counts["sign"]==2&&counts.size()==3);
|
||||
assert(barriers.size()==2&&std::abs(barriers[0]-barriers[1])>11.9);
|
||||
// No physical prop footprint intersects another (separating axes).
|
||||
for(size_t i=0;i<props.size();i++)for(size_t j=i+1;j<props.size();j++){
|
||||
auto*a=props[i];auto*b=props[j];bool separate=false;
|
||||
|
||||
Reference in New Issue
Block a user