"""Execute production claim/retirement and per-update scheduling with engine doubles.""" import re from policy_harness import ROOT, body, run p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_GarageVehicles.c' def convert(s): s=s.replace('protected ','').replace('null','nullptr').replace('foreach (','for (') s=s.replace('array','Array').replace('array','Array').replace('array','Array') s=s.replace('Array observers,','Array& observers,').replace('Array actors,','Array& actors,') for cls in ['ERR_ParkedVehicle','SCR_GarbageSystem','IEntity','BaseCompartmentSlot']: s=re.sub(r'\b'+cls+r' (\w+)',cls+r'* \1',s) for cls in ['ERR_CivilianTrafficRules','ERR_ConvoyRules','ERR_Actors','Replication','SCR_GarbageSystem']: s=s.replace(cls+'.',cls+'::') for name in ['parked','seat','m_Mode','garbage','Site','Entity']: s=s.replace(name+'.',name+'->') s=s.replace('vector.Distance','Geometry::Distance') s=s.replace('m_Parked[i].','m_Parked[i]->') return s methods=convert('\n'.join(body(p,x) for x in ['protected bool InUse(', 'protected void Claim(', 'void PlayerEntered(', 'protected void Maintain(', 'protected void Step('])) run(r''' #include #include #include struct Vec{float x=0,z=0;}; namespace Geometry{float Distance(Vec a,Vec b){return std::hypot(a.x-b.x,a.z-b.z);}} templatestruct Array:std::vector{using std::vector::vector;int Count(){return this->size();}bool IsEmpty(){return this->empty();}void Remove(int i){this->erase(this->begin()+i);}void Clear(){this->clear();}}; struct IEntity{Vec origin;bool player=false,hidden=true,deleted=false,seatsKnown=true;IEntity* occupant=nullptr;Vec GetOrigin(){return origin;}Vec GetYawPitchRoll(){return {};}}; struct BaseCompartmentSlot{IEntity* occupant=nullptr;IEntity* GetOccupant(){return occupant;}}; namespace Replication{bool authority=true;bool IsServer(){return authority;}} namespace ERR_Actors{bool Player(IEntity* e){return e&&e->player;}void DeleteSpawned(IEntity* e){assert(!e->occupant);e->deleted=true;}} namespace ERR_ConvoyRules{ bool PartOf(IEntity* e,IEntity* root){return e==root;} bool CollectSeats(IEntity* e,Array& a){static BaseCompartmentSlot seat;seat.occupant=e->occupant;a.push_back(&seat);return e->seatsKnown;} } namespace ERR_CivilianTrafficRules{ bool Far(Vec p,Array& o,float distance){for(auto q:o)if(Geometry::Distance(p,q)=0&&now-since>=60000;} } struct SCR_GarbageSystem{static SCR_GarbageSystem* GetByEntityWorld(IEntity*){static SCR_GarbageSystem g;return &g;}void UpdateBlacklist(IEntity*,bool){}}; struct SiteData{bool Consumed=false;}; struct ERR_ParkedVehicle{IEntity* Entity=nullptr;SiteData* Site=nullptr;Vec Origin;float HiddenSince=-1;}; struct Mode{int owned=0;void Own(IEntity*){owned++;}}; struct Service{ Mode mode;Mode* m_Mode=&mode;bool m_Stopped=false,running=true,known=true; int m_Claimed=0,m_MaintainCursor=0,m_Work=0,m_Pending=0,m_CleanupRadius=1400; float clock=0,m_NextStep=0;int discovers=0,plans=0,pending=0,hiddenCalls=0; Array m_Parked;Array views;Array actors; bool Running(){return running;}float Now(){return clock;} bool Observers(Array& o,Array& a){o=views;a=actors;return known;} bool Hidden(Vec,Vec,Array& a,IEntity* e){hiddenCalls++;return e->hidden;} void Discover(Array&,float){discovers++;}void Plan(Array&,Array&,float){plans++;} void Pending(Array&,Array&){pending++;} ''' + methods.replace('m_Pending = nullptr','m_Pending = 0') + r''' }; int main(){ Array far={{2000,0}},near={{100,0}};Array actors; IEntity car,player;player.player=true;SiteData site;ERR_ParkedVehicle record;record.Entity=&car;record.Site=&site; Service s;s.m_Parked={&record}; s.Maintain(far,actors,100,true);assert(record.HiddenSince==100&&!car.deleted); s.Maintain(far,actors,60099,true);assert(!car.deleted); s.Maintain(near,actors,60100,true);assert(record.HiddenSince<0&&!car.deleted); s.Maintain(far,actors,70000,true);car.hidden=false;s.Maintain(far,actors,140000,true);assert(!car.deleted&&record.HiddenSince<0); car.hidden=true;s.Maintain(far,actors,150000,true);s.Maintain(far,actors,220000,false);assert(!car.deleted&&record.HiddenSince<0); s.Maintain(far,actors,230000,true);s.Maintain(far,actors,290000,true);assert(car.deleted&&s.m_Parked.empty()&&!site.Consumed); car.deleted=false;s.m_Parked={&record};s.PlayerEntered(&player,&car);assert(site.Consumed&&s.m_Claimed==1&&s.m_Parked.empty()&&s.mode.owned==1); s.PlayerEntered(&player,&car);s.Maintain(far,actors,500000,true);assert(s.m_Claimed==1&&!car.deleted); SiteData used;record.Site=&used;s.m_Parked={&record};car.origin={4,0};s.Maintain(far,actors,600000,true);assert(used.Consumed&&!car.deleted&&s.m_Parked.empty()); SiteData occupied;record.Site=&occupied;car.origin={0,0};car.occupant=&player;s.m_Parked={&record};s.Maintain(far,actors,700000,true);assert(occupied.Consumed&&!car.deleted);car.occupant=nullptr; Service tick;tick.Step();assert(tick.discovers==1&&tick.plans==0);tick.Step();assert(tick.discovers==1); // no same-frame catch-up tick.clock=250;tick.Step();assert(tick.plans==1);tick.clock=500;tick.Step();assert(tick.discovers==1&&tick.plans==1); tick.m_Pending=1;tick.clock=750;tick.Step();assert(tick.pending==1&&tick.plans==1&&tick.discovers==1); tick.known=false;tick.clock=1000;record.HiddenSince=100;tick.m_Parked={&record};tick.Step();assert(tick.m_Pending==0&&record.HiddenSince<0&&tick.pending==1); tick.m_Stopped=true;tick.clock=1250;tick.Step();assert(tick.plans==1&&tick.discovers==1); Service client;Replication::authority=false;client.Step();assert(client.discovers==0&&client.plans==0); } ''') print('PASS: permanent entry/movement/occupancy claims; far hidden grace cleanup; proximity/visibility/unknown-view resets; one staged operation per update, no same-frame catch-up, stop and client guards') # The current round takes one snapshot of the saved menu values. No polling # should silently apply next-round changes or restart disabled/client services. start=body(p,'void Start(').replace('Replication.', 'Replication::').replace('Math.Max', 'std::max') start=start.replace('m_Mode.Settings().Get(', 'settings.Get(').replace('m_Bikes.Find()', 'bikeLookups++') start=start.replace('GetGame().GetCallqueue().CallLater(Step, 250, true)', 'queueCalls++') run(r''' #include #include #include #include namespace Replication{bool authority=true;bool IsServer(){return authority;}} struct Settings{std::map values={{"garageVehicleCount",16},{"garageChancePercent",70},{"garageRadiusMetres",1000},{"garageSpawnIntervalSeconds",5}};int Get(std::string k){return values.at(k);}}; struct Service{ Settings settings;bool m_Started=false,m_Stopped=false; int m_Requested=0,m_GarageChance=0,m_SpawnRadius=0,m_SpawnInterval=0,m_CleanupRadius=0,bikeLookups=0,queueCalls=0; void Stop(){m_Stopped=true;} ''' + start + r''' }; int main(){ Service normal;normal.Start();assert(normal.m_Requested==16&&normal.m_GarageChance==70&&normal.m_SpawnRadius==1000&&normal.m_SpawnInterval==5000&&normal.m_CleanupRadius==1400&&normal.queueCalls==1); normal.settings.values["garageRadiusMetres"]=1500;normal.settings.values["garageSpawnIntervalSeconds"]=60;normal.Start();assert(normal.m_SpawnRadius==1000&&normal.m_SpawnInterval==5000&&normal.queueCalls==1); Service custom;custom.settings.values={{"garageVehicleCount",24},{"garageChancePercent",100},{"garageRadiusMetres",1500},{"garageSpawnIntervalSeconds",60}};custom.Start();assert(custom.m_Requested==24&&custom.m_GarageChance==100&&custom.m_SpawnRadius==1500&&custom.m_SpawnInterval==60000&&custom.m_CleanupRadius==1900); for(auto key:{"garageVehicleCount","garageChancePercent"}){Service disabled;disabled.settings.values[key]=0;disabled.Start();assert(disabled.m_Stopped&&disabled.queueCalls==0&&disabled.bikeLookups==0);} Service small;small.settings.values["garageRadiusMetres"]=250;small.Start();assert(small.m_CleanupRadius==1400); Service stopped;stopped.m_Stopped=true;stopped.Start();assert(stopped.queueCalls==0); Service client;Replication::authority=false;client.Start();assert(!client.m_Started&&client.queueCalls==0&&client.bikeLookups==0); } ''') print('PASS: saved garage menu settings configure the round once; unit conversion and cleanup radius scale correctly; count/chance zero disable startup; clients and stopped rounds do no work')