"""Run the production radio gate, folder recovery and evidence targeting bodies. Native inventory/discovery calls are explicit doubles; the retained Workbench fixture separately exercises real inventory, world observation and tuning. """ import re from policy_harness import ROOT, body, run core = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_DiscoveryService.c' evidence = ROOT/'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelEvidence.c' def cpp(s): s=s.replace('protected ', '').replace('foreach (', 'for (').replace('null', 'nullptr') s=s.replace('ERR_DocumentComponent.Cast(folder.FindComponent(ERR_DocumentComponent))','folder->document') s=s.replace('InventoryStorageManagerComponent.Cast(player.FindComponent(InventoryStorageManagerComponent))','player->inventory') s=s.replace('set available = new set();','Set available;').replace('set identified = new set();','Set identified;') s=s.replace('array', 'Array').replace('array','Array') for t in ('ERR_GameMode','ERR_LocationComponent','ERR_SiteService','ERR_SiteRuntime','ERR_DocumentComponent','InventoryStorageManagerComponent','ERR_IssuedIntel','ERR_BodyEvidence'): s=re.sub(r'\b'+t+r' (\w+)',t+r'* \1',s) s=s.replace('ERR_SiteRuntime* site;', 'ERR_SiteRuntime* site=nullptr;').replace('bool redirectRadio;', 'bool redirectRadio=false;').replace('bool changed;', 'bool changed=false;').replace('int assigned;', 'int assigned=0;') for n in ('Replication','ERR_LocationKind','ERR_Actors','SCR_FactionManager','ERR_GameMode','Math'): s=s.replace(n+'.', n+'::') for n in ('m_Mode','mode','location','target','chosen','sites','site','document','player','record','issued'): s=re.sub(r'\b'+n+r'\.', n+'->',s) for n in ('Settings','Sites','Players','MineIntel','Evidence','Discovery','Get','GetPlayerManager'): s=s.replace(n+'().',n+'()->') s=s.replace('site->Definition.', 'site->Definition->').replace('GetGame().','GetGame()->').replace('GetRandomElement().','GetRandomElement()->') s=s.replace('void ERR_DiscoveryService(', 'Service(') return s.replace('target->IsEmpty()', 'target.IsEmpty()') gate='\n'.join(body(core,sig) for sig in ('void ERR_DiscoveryService(', 'protected bool CountsForRadioIntel(', 'protected void RefreshRadioIntel(', 'bool RadioIntelAllowed()', 'bool MarkSpent(', 'protected void Recover(')) ev='\n'.join(body(evidence,sig) for sig in ('protected string NextTarget(', 'string Target(', 'void Retarget(')) run(r''' #include #include #include #include #include #include struct string:std::string{using std::string::string;using std::string::operator=;string(std::string s):std::string(s){}bool IsEmpty(){return empty();}}; templatestruct Array:std::vector{using std::vector::vector;void Insert(T x){this->push_back(x);}void Clear(){this->clear();}int Count(){return this->size();}bool IsEmpty(){return this->empty();}bool Contains(T x){return std::find(this->begin(),this->end(),x)!=this->end();}T GetRandomElement(){return this->front();}}; templatestruct Set:std::set{void Insert(T x){this->insert(x);}int Count(){return this->size();}bool Contains(T x){return this->count(x);}}; templatestruct Map:std::map{bool Find(K k,V& v){auto i=this->find(k);if(i==this->end())return false;v=i->second;return true;}void Set(K k,V v){(*this)[k]=v;}}; namespace Replication{bool server=true;bool IsServer(){return server;}} namespace Math{int Min(int a,int b){return std::min(a,b);}int RandomInt(int,int){return 99;}} namespace ERR_LocationKind{enum{PRISON,RADIO,EXTRACTION,OUTPOST,DEPOT,MORTAR,HOSPITAL};} struct ERR_LocationComponent{string id;int kind=ERR_LocationKind::OUTPOST,knowledge=0;bool prepared=true;string Id(){return id;}int Kind(){return kind;}int Knowledge(){return knowledge;}bool Prepared(){return prepared;}bool Discover(int roll,int chance){if(!prepared||knowledge>=2)return false;knowledge=knowledge==1||rollsites;ERR_SiteRuntime*Find(string id){return sites.count(id)?sites[id]:nullptr;}}; struct ERR_DocumentComponent{string target;string TargetId(){return target;}}; struct Entity;using IEntity=Entity*; struct InventoryStorageManagerComponent{Arrayfolders;}; struct Entity{bool alive=true,current=true;int faction=1;InventoryStorageManagerComponent*inventory=nullptr;ERR_DocumentComponent*document=nullptr;}; namespace ERR_Actors{bool Alive(IEntity p){return p&&p->alive;}} namespace SCR_FactionManager{int SGetFaction(IEntity p){return p->faction;}} struct Roster{bool CurrentActor(IEntity p){return p&&p->current;}}; struct Settings{int required=5,chance=100;int Get(string key){assert(key=="radioIntelSiteCount");return required;}int Runtime(string){return chance;}}; struct Mines{bool Recover(IEntity,IEntity){return false;}}; struct PM{int GetPlayerIdFromControlledEntity(IEntity){return 1;}}; struct Game{PM pm;PM*GetPlayerManager(){return ±}}game;Game*GetGame(){return &game;} void PrintFormat(string,int,string,int){} struct ERR_IssuedIntel{IEntity Folder=nullptr;string SiteId;}; struct ERR_BodyEvidence{ArrayIssued;bool Searched=false;}; struct Service;struct Evidence; struct ERR_GameMode{inline static ERR_GameMode*current=nullptr;struct Settings settings;struct Evidence*evidence=nullptr;Service*discovery=nullptr;ERR_SiteService sites;Roster roster;Mines mines;Arraylocations;bool active=true,preparing=false;int waiting=0,exhausted=0; static ERR_GameMode*Get(){return current;}struct Settings*Settings(){return &settings;}struct Evidence*Evidence(){return evidence;}Service*Discovery(){return discovery;}ERR_SiteService*Sites(){return &sites;}Roster*Players(){return &roster;}Mines*MineIntel(){return &mines;}int PlayerFaction(){return 1;}bool Active(){return active;}bool WorldPreparing(){return preparing;}void Locations(Array&out){out=locations;}void ERR_RadioIntelWaiting(){waiting++;}void ERR_IntelExhausted(bool){exhausted++;} }; struct Evidence{Arraym_Roster;Mapm_TargetAssignments;bool m_Stopped=false;string NextTarget();string Target(IEntity);void Retarget(IEntity,string);}; struct Service{ERR_GameMode*m_Mode;int m_RadioIntelRequired=0,m_RadioIntelIdentified=0;bool m_RadioIntelFinalized=false,m_RadioIntelUnlocked=false,m_Stopped=false;Setm_Spent;float m_CleanupNow=0;int cleanups=0;void QueueCleanup(IEntity,float){cleanups++;}void Folders(InventoryStorageManagerComponent*i,Array&out){out=i->folders;} '''+cpp(gate)+r''' }; '''+cpp(ev).replace('string NextTarget(', 'string Evidence::NextTarget(').replace('string Target(', 'string Evidence::Target(').replace('void Retarget(', 'void Evidence::Retarget(')+r''' struct Fixture{ERR_GameMode mode;Evidence evidence;Service service;ERR_LocationComponent sites[9];Definition automatic;ERR_SiteRuntime autoSite;Entity player,folder;InventoryStorageManagerComponent inv;ERR_DocumentComponent doc;ERR_IssuedIntel issued;ERR_BodyEvidence record; Fixture():service(&mode){ERR_GameMode::current=&mode;Replication::server=true;mode.discovery=&service;mode.evidence=&evidence;player.inventory=&inv;inv.folders={&folder}; for(int i=0;i<9;i++){sites[i].id="site-"+std::to_string(i);mode.locations.Insert(&sites[i]);} sites[0].kind=ERR_LocationKind::RADIO;sites[1].kind=ERR_LocationKind::PRISON;sites[2].kind=ERR_LocationKind::EXTRACTION; automatic.RevealOnEscape=true;autoSite.Definition=&automatic;mode.sites.sites[sites[3].id]=&autoSite; } void SealRadio(){issued.Folder=&folder;issued.SiteId=sites[0].id;record.Issued={&issued};evidence.m_Roster={&record};} void FixedRadio(){doc.target=sites[0].id;folder.document=&doc;} void Identify(int count){for(int i=4;i<4+count;i++)sites[i].knowledge=2;} }; int main(){ // Default boundary, exclusions and unique IDs (including duplicate observations). {Fixture f;for(int i=0;i<4;i++)f.sites[i].knowledge=2;f.Identify(4);f.sites[8].knowledge=1; f.mode.locations.Insert(&f.sites[4]);f.mode.locations.Insert(nullptr); assert(!f.service.RadioIntelAllowed()&&f.service.m_RadioIntelIdentified==4&&f.service.m_RadioIntelRequired==5); f.sites[8].knowledge=2;assert(f.service.RadioIntelAllowed());f.mode.locations.Clear();assert(f.service.RadioIntelAllowed());} // Setting edits are next-round only; fresh service snapshots the saved value. {Fixture f;f.mode.settings.required=0;assert(!f.service.RadioIntelAllowed());Service next(&f.mode);assert(next.RadioIntelAllowed());} // Preparation never lowers the requirement; completed sparse world caps it once. {Fixture f;f.mode.locations={&f.sites[4],&f.sites[5]};f.mode.preparing=true;f.Identify(2); assert(!f.service.RadioIntelAllowed()&&f.service.m_RadioIntelRequired==5);f.mode.preparing=false;assert(f.service.RadioIntelAllowed()&&f.service.m_RadioIntelRequired==2);} {Fixture f;f.mode.locations.Clear();f.mode.active=false;assert(!f.service.RadioIntelAllowed());f.mode.active=true;assert(f.service.RadioIntelAllowed()&&f.service.m_RadioIntelRequired==0);} // Unprepared sites cannot contribute knowledge or increase the final cap. {Fixture f;f.sites[8].prepared=false;f.Identify(4);assert(f.service.RadioIntelAllowed()&&f.service.m_RadioIntelRequired==4);} // Ordinary initial assignments and unsealed recovery both avoid radios. {Fixture f;assert(f.evidence.NextTarget()!=f.sites[0].id);f.service.Recover(&f.player);assert(f.sites[0].knowledge==0&&f.service.m_Spent.Contains(&f.folder)&&f.service.cleanups==1);} // Sealed radio folders redirect, including searched bodies; existing report // snapshots stay detached. Updated evidence remains after ordinary cleanup. {Fixture f;f.SealRadio();f.record.Searched=true;string queued=f.evidence.Target(&f.folder);f.service.Recover(&f.player); assert(queued==f.sites[0].id&&f.evidence.Target(&f.folder)!=queued&&f.sites[0].knowledge==0); assert(f.evidence.Target(&f.folder)==f.sites[3].id&&f.evidence.m_TargetAssignments[f.sites[3].id]==1);} // A fixed document stays unspent through four sites and processes automatically // on the next ordinary inventory scan after the fifth becomes fully known. {Fixture f;f.FixedRadio();f.Identify(4);f.service.Recover(&f.player);f.service.Recover(&f.player); assert(f.service.m_Spent.empty()&&f.service.cleanups==0&&f.sites[0].knowledge==0); f.sites[8].knowledge=2;f.service.Recover(&f.player);assert(f.service.m_Spent.Contains(&f.folder)&&f.sites[0].knowledge==2&&f.service.cleanups==0);} // If there are no alternatives yet, keep ordinary folders and issued targets. {Fixture f;f.SealRadio();f.mode.preparing=true;f.mode.locations={&f.sites[0]};f.service.Recover(&f.player); assert(f.service.m_Spent.empty()&&f.service.cleanups==0&&f.mode.exhausted==0&&f.evidence.Target(&f.folder)==f.sites[0].id); assert(f.evidence.NextTarget().IsEmpty());} // A redirected rough clue counts only on full identification, never on reuse. {Fixture f;f.SealRadio();f.mode.settings.chance=0;f.sites[3].knowledge=2;f.service.Recover(&f.player); assert(f.sites[4].knowledge==1&&f.evidence.Target(&f.folder)==f.sites[4].id);f.service.Recover(&f.player);assert(f.sites[4].knowledge==1);} // Stopped/client/wrong-owner inventory recovery preserves the authorization gate. for(int fault=0;fault<4;fault++){Fixture f;if(fault==0)Replication::server=false;if(fault==1)f.service.m_Stopped=true;if(fault==2)f.player.current=false;if(fault==3)f.player.faction=2;f.service.Recover(&f.player);assert(f.service.m_Spent.empty());} } ''') print('PASS: radio intel boundary, exclusions, preparation cap, next-round configuration, sticky unlock, redirection/evidence, fixed retention, automatic recovery and lifecycle guards')