"""Run production generic placement scheduling with clock/terrain adapters.""" from policy_harness import ROOT, body, run base = ROOT/'addons/core/Scripts/Game/ERR/00_Core' s = '\n'.join(body(base/'ERR_GeneratedSites.c', signature) for signature in ('static bool StartupSite(', 'void StartupOnly(', 'bool StartupReady(', 'protected bool SkipOptional(')) + '\n' + body(base/'ERR_TerrainSites.c', 'override ERR_PrepareResult Tick(') + '\n' + body(base/'ERR_TerrainSites.c', 'protected bool PrepareAirports(') + '\n' + '\n'.join(body(base/'ERR_TerrainSites.c', sig) for sig in ('static int SearchAttempts(', 'static int SearchMilliseconds(', 'protected void ExpandExtractionSearch(')) for before, after in [('override ', ''), ('protected ', ''), ('ref ERR_SiteDefinition retained','Site* retained'), ('ERR_SiteDefinition site','Site* site'), ('foreach (', 'for ('), ('site.', 'site->'), ('retained.','retained->'), ('m_Definition.', 'm_Definition->'), ('m_Airports.', 'm_Airports->'), ('System.GetTickCount','Clock::Now'), ('Replication.IsServer','Server'), ('Math.RandomFloat','RandomFloat'), ('ERR_PrepareResult.','Result::'), ('ERR_LocationKind.','Kind::')]: s=s.replace(before, after) s=s.replace('float heading = m_CandidateHeading, floor;', 'float heading = m_CandidateHeading, floor=0;') run(r''' #include #include #include #include using string=std::string; struct vector{float a[3];float& operator[](int i){return a[i];}};vector Vector(float x,float y,float z){return {{x,y,z}};} namespace Result{enum Value{FAILED=-1,PENDING,READY};}using ERR_PrepareResult=Result::Value; namespace Clock{int now=0,step=1;int Now(){int value=now;now+=step;return value;}} bool Server(){return true;}int randomCalls=0;float RandomFloat(float a,float b){randomCalls++;return (a+b)/2;} templatevoid PrintFormat(T...){} void Print(string){} namespace Kind{enum{PRISON,RADIO,EXTRACTION,OUTPOST,DEPOT,MORTAR,HOSPITAL};} struct Site{int Kind=Kind::PRISON;string Label="Test site",Id="test";vector Position=Vector(11,0,22);float Heading=0;bool PlacementResolved=false,RequireAirfield=true,RandomClear=false;}; templatestruct Array:std::vector{using std::vector::operator=;bool IsEmpty(){return this->empty();}int Count(){return this->size();}int Find(T v){auto i=std::find(this->begin(),this->end(),v);return i==this->end()?-1:i-this->begin();}void Remove(int i){this->erase(this->begin()+i);}void InsertAt(T v,int i){this->insert(this->begin()+i,v);}}; struct Definition{bool TerrainGenerated=true;Array Sites;Site* required=nullptr;bool valid=true;bool Valid(){return valid&&(!required||Sites.Find(required)>=0);}}; struct Airports{Array m_Positions;Airports(){m_Positions.push_back(Vector(0,0,0));}bool complete=true;int updates=0,cost=0,finishAfter=0;void Update(){updates++;Clock::now+=cost;if(finishAfter&&updates>=finishAfter)complete=true;}bool Complete(){return complete;}}; struct Scheduler{ void RecordRejection(string){}void ReportSearch(Site*,string){}void ReportProgress(Site*){}void ClearDiagnostics(){}string RejectionSummary(){return "terrain";} Airports airports;Airports* m_Airports=&airports;bool m_AirportsReady=true; Definition definition;Definition* m_Definition=&definition;Array m_Pending; ERR_PrepareResult m_Result=Result::PENDING;string m_Error; bool m_StartupOnly=false; bool m_Started=true,m_HaveCandidate=false,m_WaitingNav=false; vector m_Low=Vector(1000,0,-5000),m_High=Vector(9000,0,3000),m_Candidate; int m_GeometryRejected=0,m_NavigationRejected=0,m_PadRejected=0; float m_CandidateHeading=0;int m_CandidateBegan=0,m_Index=0,m_Attempts=0,m_Began=0; bool clear=true,separated=true;int waiting=0,surveys=0; vector SamplePosition(Site*){return Vector(RandomFloat(m_Low[0]+60,m_High[0]-60),0,RandomFloat(m_Low[2]+60,m_High[2]-60));} bool Separated(Site*,vector,bool){return separated;} bool Survey(Site*,vector,float,float& floor){surveys++;floor=42;if(waiting){waiting--;m_WaitingNav=true;return false;}return clear;} '''+s+r''' }; int main(){ // Cheap airport tiles batch; native-query time and count both bound a slice. {Clock::now=0;Clock::step=0;Scheduler s;s.m_AirportsReady=false;s.airports.complete=false; assert(!s.PrepareAirports()&&s.airports.updates==8);assert(!s.PrepareAirports()&&s.airports.updates==16);} {Clock::now=0;Scheduler s;s.m_AirportsReady=false;s.airports.complete=false;s.airports.cost=7; assert(!s.PrepareAirports()&&s.airports.updates==1);} {Clock::now=0;Scheduler s;s.m_AirportsReady=false;s.airports.complete=false;s.airports.finishAfter=3; assert(s.PrepareAirports()&&s.airports.updates==3);assert(s.PrepareAirports()&&s.airports.updates==3);} Clock::step=1; {Clock::now=0;Scheduler s;Site extraction,prison,radio;extraction.Kind=Kind::EXTRACTION;radio.Kind=Kind::RADIO; s.definition.Sites={&extraction,&prison,&radio};s.m_Pending={&extraction,&prison,&radio};s.StartupOnly(true); while(!s.StartupReady()) assert(s.Tick()==Result::PENDING); assert(extraction.PlacementResolved&&prison.PlacementResolved&&!radio.PlacementResolved);int calls=s.surveys; Clock::now=60000;assert(s.Tick()==Result::PENDING&&s.surveys==calls);s.StartupOnly(false); while(s.Tick()==Result::PENDING){}assert(radio.PlacementResolved&&s.m_Result==Result::READY);} {Scheduler s;s.m_Started=false;assert(s.Tick()==Result::FAILED);} {Scheduler s;assert(s.Tick()==Result::READY);} // Airport discovery yields without spending placement budget, then enables bounded clear-ground extraction. {Clock::now=0;Scheduler s;s.m_AirportsReady=false;s.airports.complete=false;assert(s.Tick()==Result::PENDING&&s.surveys==0);s.airports.complete=true;s.airports.m_Positions.clear();Site extraction;extraction.Kind=Kind::EXTRACTION;s.m_Pending={&extraction};while(s.Tick()==Result::PENDING){}assert(s.m_Result==Result::READY&&!extraction.RequireAirfield&&extraction.PlacementResolved&&extraction.Label=="Extraction landing zone");} {Clock::now=40000;Scheduler s;s.m_AirportsReady=false;Site a;s.m_Pending={&a};while(s.Tick()==Result::PENDING){}assert(s.m_Result==Result::READY&&a.PlacementResolved&&s.airports.updates==1);} // Recognized airports retain their airfield requirement. {Clock::now=0;Scheduler s;s.m_AirportsReady=false;Site extraction;extraction.Kind=Kind::EXTRACTION;s.m_Pending={&extraction};while(s.Tick()==Result::PENDING){}assert(s.m_Result==Result::READY&&extraction.RequireAirfield);} // Off-origin bounds are sampled; authored Everon positions cannot be retained. {Clock::now=0;Scheduler s;Site a,b;s.m_Pending={&a,&b};s.definition.Sites={&a,&b};while(s.Tick()==Result::PENDING){}assert(s.m_Result==Result::READY&&a.PlacementResolved&&b.PlacementResolved);assert(a.Position[0]==5000&&a.Position[2]==-1000&&a.Position[1]>42);int calls=s.surveys;assert(s.Tick()==Result::READY&&s.surveys==calls);} // Pending navigation keeps the SAME candidate and yields before spinning or resampling. {Clock::now=0;randomCalls=0;Scheduler s;Site a;s.m_Pending={&a};s.waiting=2; assert(s.Tick()==Result::PENDING&&!a.PlacementResolved&&s.surveys==1);assert(randomCalls==3&&s.m_Attempts==1); assert(s.Tick()==Result::PENDING&&s.surveys==2&&randomCalls==3); while(s.Tick()==Result::PENDING){}assert(s.m_Result==Result::READY&&randomCalls==3&&a.PlacementResolved);} // A streaming timeout releases the candidate, but never accepts unloaded geometry. {Clock::now=0;Scheduler s;Site a;s.m_Pending={&a};s.waiting=100; assert(s.Tick()==Result::PENDING&&s.m_Attempts==1);Clock::now=5001;s.Tick();assert(!a.PlacementResolved&&s.m_Attempts>=2);} // The former ceiling no longer ends a difficult prison search. {Clock::now=30001;Scheduler s;Site a;s.m_Pending={&a};s.definition.Sites={&a};s.m_Attempts=12000; while(s.Tick()==Result::PENDING){}assert(s.m_Result==Result::READY&&a.PlacementResolved);} // A recognized but unusable airport broadens once, preserving the total clock // and attempt counter and discarding any pending airport/navmesh candidate. for(int byTime:{0,1}){ Clock::now=byTime?30001:1;Scheduler s;Site a;a.Kind=Kind::EXTRACTION; s.m_Pending={&a};s.definition.Sites={&a};s.m_Attempts=byTime?2:12000;s.m_HaveCandidate=true; int attempts=s.m_Attempts;s.ExpandExtractionSearch(&a); assert(!a.RequireAirfield&&!s.m_HaveCandidate&&s.m_Began==0&&s.m_Attempts==attempts&&a.Label=="Extraction landing zone"); s.m_HaveCandidate=true;s.ExpandExtractionSearch(&a);assert(s.m_HaveCandidate); // one transition only while(s.Tick()==Result::PENDING){}assert(s.m_Result==Result::READY&&a.PlacementResolved);} {Clock::now=29990;Scheduler s;Site a;a.Kind=Kind::EXTRACTION;s.m_Attempts=11999; s.ExpandExtractionSearch(&a);assert(a.RequireAirfield);} // An exhausted budget rejects every mandatory kind WITHOUT trying the authored fallback. for(int kind:{Kind::PRISON,Kind::RADIO,Kind::EXTRACTION,Kind::MORTAR}){ Clock::now=0;Scheduler s;Site a;a.Kind=kind;s.m_Pending={&a};s.definition.Sites={&a};s.m_Attempts=48000; assert(s.Tick()==Result::FAILED&&!a.PlacementResolved&&s.surveys==0&&a.Position[0]==11&&!s.m_Error.empty());} {Clock::now=120001;Scheduler s;Site a;s.m_Pending={&a};assert(s.Tick()==Result::FAILED&&s.surveys==0);} // Optional sites can be removed only while preserving minimum objective/intel validity. for(int kind:{Kind::OUTPOST,Kind::HOSPITAL,Kind::DEPOT}){ Clock::now=0;Scheduler s;Site a,b;a.Kind=kind;s.m_Pending={&a,&b};s.definition.Sites={&a,&b};s.m_Attempts=48000; while(s.Tick()==Result::PENDING){}assert(s.m_Result==Result::READY&&!a.PlacementResolved&&b.PlacementResolved&&s.definition.Sites.Count()==1);} {Clock::now=0;Scheduler s;Site a;a.Kind=Kind::DEPOT;s.m_Pending={&a};s.definition.Sites={&a};s.definition.required=&a;s.m_Attempts=48000; assert(s.Tick()==Result::FAILED&&s.definition.Sites.Count()==1);} {Clock::now=0;Scheduler s;s.definition.valid=false;assert(s.Tick()==Result::FAILED);} } ''') print('PASS: terrain placement samples world bounds, retains streaming candidates, bounds waits/work, rejects foreign fallbacks, preserves objectives/intel and validates completion') # Execute the actual native-navigation decision with static/streaming adapters. nav = body(base/'ERR_TerrainSites.c', 'protected bool Navigable(') nav = nav.replace('protected ', '').replace('NavmeshWorldComponent mesh', 'Mesh* mesh').replace('mesh.', 'mesh->') run(r''' #include #include struct vector{}; struct Mesh{bool loaded=true,loadable=false,reachable=false;int requests=0,queries=0;bool IsTileLoaded(vector){return loaded;}bool LoadTileIn(vector){requests++;return loadable;}bool GetReachablePoint(vector,int,vector&){queries++;return reachable;}} mesh; struct World{bool available=true;Mesh* GetNavmeshWorldComponent(const char*){return available?&mesh:nullptr;}} world; struct Game{World& GetAIWorld(){return world;}} game; Game& GetGame(){return game;} struct Survey{std::string m_NavigationReason;bool m_WaitingNav=false; '''+nav+r''' }; int main(){ Survey s;world.available=false;assert(!s.Navigable({}));world.available=true; mesh.reachable=true;assert(s.Navigable({})&&mesh.queries==1&&mesh.requests==0); // Static, non-streaming mesh. mesh.reachable=false;assert(!s.Navigable({})); mesh.loaded=false;assert(!s.Navigable({})&&!s.m_WaitingNav&&mesh.requests==1); // Missing tile. mesh.loadable=true;assert(!s.Navigable({})&&s.m_WaitingNav&&mesh.requests==2); // Accepted streaming request. mesh.loaded=true;mesh.reachable=true;assert(s.Navigable({})&&mesh.requests==2); } ''') print('PASS: actual navigation readiness supports static meshes, yields only for loadable streaming tiles and refuses unreachable positions') # Execute sampling and clearance selection: an empty airport list must never be # indexed, and generic helicopter pads retain geometry/nav/physical validation. placement = body(base/'ERR_TerrainSites.c', 'static bool Bounds(') + '\n' + body(base/'ERR_TerrainSites.c', 'static float PrisonAirportBuffer(') + '\n' + body(base/'ERR_TerrainSites.c', 'protected vector SamplePosition(') + '\n' + body(base/'ERR_TerrainSites.c', 'protected bool Survey(') for before, after in [ ('protected ', ''), ('ERR_SiteDefinition site', 'Site* site'), ('site.', 'site->'), ('out float floor', 'float& floor'), ('m_Airports.', 'm_Airports->'), ('Math.', 'Math::'), ('ERR_LocationKind.', 'Kind::'), ('ERR_Actors.', 'ERR_Actors::'), ('ERR_CampTerrain.', 'ERR_CampTerrain::'), ('ERR_AirfieldPlacement.', 'ERR_AirfieldPlacement::'), ('ERR_RescueLanding.', 'ERR_RescueLanding::')]: placement = placement.replace(before, after) run(r''' #include #include #include #include struct vector {float a[3];float& operator[](int i){return a[i];}}; vector Vector(float x,float y,float z){return {{x,y,z}};} vector operator+(vector a,vector b){return Vector(a[0]+b[0],a[1]+b[1],a[2]+b[2]);} namespace Kind {enum {PRISON,EXTRACTION};} struct Site {int Kind=Kind::EXTRACTION,ResponseCount=0;bool RequireAirfield=false,Guarded=false;vector GuardOffset{},ResponseOffset{};}; namespace Math { int indexed=0;const float PI2=6.283185; float RandomFloat(float a,float b){return (a+b)/2;} int RandomInt(int a,int b){assert(b>a);indexed++;return a;} float Min(float a,float b){return ahi?hi:v);} float Cos(float a){return std::cos(a);}float Sin(float a){return std::sin(a);} } namespace ERR_Actors {vector Ground(vector p){return p;}} namespace ERR_CampTerrain {vector Rotate(vector p,float){return p;}} namespace ERR_AirfieldPlacement { bool airfield=false,ground=true;int airportChecks=0,groundChecks=0; bool Clear(vector){airportChecks++;return airfield;} bool ClearGround(vector){groundChecks++;return ground;} } namespace ERR_RescueLanding {bool fits=true;int checks=0;bool Fits(vector){checks++;return fits;}} templatestruct Array:std::vector{bool IsEmpty(){return this->empty();}int Count(){return this->size();}}; struct Airports {Array m_Positions;}; struct Terrain { std::string Rejection(){return "terrain";} bool geometry=true,flat=true;float airportBuffer=0; bool Site(::Site*,vector,float,float& floor,float buffer){airportBuffer=buffer;floor=42;return geometry;} bool Clear(vector,float,float,float,float&){return flat;} }; struct Placement { std::string m_NavigationReason="navigation";void RecordRejection(std::string){} Airports airports;Airports* m_Airports=&airports;Terrain m_Terrain; vector m_Low=Vector(1000,0,-5000),m_High=Vector(9000,0,3000); int m_GeometryRejected=0,m_NavigationRejected=0,m_PadRejected=0; bool nav=true;bool Navigable(vector){return nav;} ''' + placement + r''' }; int main(){ Placement s;Site site;float floor=0; assert(s.Bounds(Vector(-500,0,-500),Vector(500,0,500))); assert(!s.Bounds(Vector(0,0,0),Vector(999,0,2000))); assert(!s.Bounds(Vector(0,0,0),Vector(2000,0,999))); assert(!s.Bounds(Vector(0,0,0),Vector(100001,0,2000))); assert(s.PrisonAirportBuffer(Vector(0,0,0),Vector(2000,0,2000))==300); assert(s.PrisonAirportBuffer(Vector(-100,0,-100),Vector(900,0,900))==200); assert(s.PrisonAirportBuffer(Vector(0,0,0),Vector(20000,0,20000))==1500); assert(s.PrisonAirportBuffer(Vector(0,0,0),Vector(2000,0,20000))==300); auto p=s.SamplePosition(&site);assert(p[0]==5000&&p[2]==-1000&&Math::indexed==0); s.airports.m_Positions.push_back(Vector(2000,0,3000));site.RequireAirfield=true; p=s.SamplePosition(&site);assert(Math::indexed==1&&std::abs(p[0]-1775)<.01&&std::abs(p[2]-3000)<.01); site.Kind=Kind::PRISON;p=s.SamplePosition(&site);assert(p[0]==5000&&p[2]==-1000&&Math::indexed==1); site.Kind=Kind::EXTRACTION;site.RequireAirfield=false; p=s.SamplePosition(&site);assert(p[0]==5000&&p[2]==-1000&&Math::indexed==1); assert(s.Survey(&site,p,0,floor)&&floor==42);assert(ERR_AirfieldPlacement::groundChecks==1&&ERR_AirfieldPlacement::airportChecks==0&&s.m_Terrain.airportBuffer==1200); ERR_AirfieldPlacement::ground=false;assert(!s.Survey(&site,p,0,floor)&&s.m_PadRejected==1); site.RequireAirfield=true;ERR_AirfieldPlacement::ground=true; assert(!s.Survey(&site,p,0,floor));assert(ERR_AirfieldPlacement::airportChecks==1&&ERR_AirfieldPlacement::groundChecks==2); ERR_AirfieldPlacement::airfield=true;assert(s.Survey(&site,p,0,floor)); site.RequireAirfield=false;s.m_Terrain.flat=false;assert(!s.Survey(&site,p,0,floor)); s.m_Terrain.flat=true;s.nav=false;assert(!s.Survey(&site,p,0,floor)&&s.m_NavigationRejected==1); s.nav=true;s.m_Terrain.geometry=false;assert(!s.Survey(&site,p,0,floor)&&s.m_GeometryRejected==1); assert(ERR_AirfieldPlacement::groundChecks==2&&ERR_AirfieldPlacement::airportChecks==2); // A suitable primary pad must not commit an extraction that cannot fit its fleet. s.m_Terrain.geometry=true;ERR_RescueLanding::fits=false; int rejected=s.m_PadRejected;assert(!s.Survey(&site,p,0,floor)&&s.m_PadRejected==rejected+1); ERR_RescueLanding::fits=true;assert(s.Survey(&site,p,0,floor)); site.Kind=Kind::PRISON;ERR_RescueLanding::fits=false;int fleetChecks=ERR_RescueLanding::checks; assert(s.Survey(&site,p,0,floor)&&ERR_RescueLanding::checks==fleetChecks); } ''') print('PASS: real sampling handles absent airports and extraction clearance preserves geometry/navigation/flatness while selecting the correct aircraft survey')