"""Execute actual finite equipment coordinator; individual grant policies have separate tests.""" import os,re from pathlib import Path from policy_harness import ROOT,run source=Path(os.environ.get('ERR_EQUIPMENT_SOURCE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyEquipment.c'))).read_text() coordinator=source[source.index('class ERR_EnemyEquipmentGroup'):] coordinator=re.sub(r'//[^\n]*','',coordinator).replace('protected ','').replace('ref ','').replace('class ','struct ') coordinator=coordinator.replace('array','Array').replace('array','Array').replace('array','Array') coordinator=coordinator.replace('SCR_AICombatComponent.Cast(actor.FindComponent(SCR_AICombatComponent))','actor->combat').replace('SCR_AICombatComponent.Cast(entry.Actor.FindComponent(SCR_AICombatComponent))','entry->Actor->combat') for cls in ('ERR_GameMode','SCR_AIGroup','ERR_EnemyRadio','ERR_EnemyEquipmentGroup','ERR_EnemyEquipmentEntry','IEntity','AIAgent'): coordinator=re.sub(r'\b'+cls+r' ([a-zA-Z_]\w*)',cls+r'* \1',coordinator) for obj in ('m_Mode','existing','state','group','agent','entry','actor'): coordinator=coordinator.replace(obj+'.',obj+'->') coordinator=coordinator.replace('Group.GetAgents','Group->GetAgents').replace('Combat.ERR_','Combat->ERR_').replace('Mines.ReadyForResupply','Mines->ReadyForResupply').replace('Optics.Check','Optics->Check').replace('Radio.Check','Radio->Check').replace('Radio.Stop','Radio->Stop').replace('Radio.Register','Radio->Register') for cls in ('Replication','ERR_GameMode','ERR_EnemyEquipmentRules','ERR_EquipmentLog'):coordinator=coordinator.replace(cls+'.',cls+'::') coordinator=coordinator.replace('string.Format', 'Format') coordinator=coordinator.replace('void ERR_EnemyEquipment(', 'ERR_EnemyEquipment(') coordinator=coordinator.replace('GetGame().GetWorld().GetWorldTime()','worldTime').replace('foreach (','for (').replace('null','nullptr') coordinator=re.sub(r'\b(bool|int|float|[A-Za-z_]\w*\*) ([A-Za-z_]\w*);',r'\1 \2 {};',coordinator).replace('\n}\n','\n};\n') run(r''' #include #include #include #include using string=std::string; templatestring Format(string,T...){return "";} float worldTime=0; namespace Replication {bool IsServer(){return true;}} template struct Array:std::vector{int Count(){return this->size();}void Insert(T value){this->push_back(value);}void Clear(){this->clear();}}; struct SCR_AIGroup; struct ERR_GameMode{static inline ERR_GameMode* current=nullptr;bool active=true;bool Active(){return active;}static ERR_GameMode* Get(){return current;}}; namespace ERR_EquipmentLog{void Round(ERR_GameMode*){}void Write(string,string){}} struct SCR_AICombatComponent{int binds=0,refreshes=0;void ERR_BindEnemySkill(ERR_GameMode*,SCR_AIGroup*){binds++;}void ERR_RefreshEnemySkill(){refreshes++;}}; struct IEntity{SCR_AICombatComponent* combat=nullptr;bool eligible=true,unconscious=false;}; struct AIAgent{IEntity* actor=nullptr;IEntity* GetControlledEntity(){return actor;}}; struct SCR_AIGroup{Array agents;void GetAgents(Array& out){out=agents;}}; namespace ERR_EnemyEquipmentRules{bool Owned(ERR_GameMode*,SCR_AIGroup*,IEntity* actor){return actor&&actor->eligible;}bool Eligible(ERR_GameMode* m,SCR_AIGroup* g,IEntity* actor){return Owned(m,g,actor)&&!actor->unconscious;}} struct ERR_EnemyOptics{ IEntity* actor;SCR_AIGroup* group;int checks=0,stops=0; ERR_EnemyOptics(IEntity* a,SCR_AIGroup* g):actor(a),group(g){} void Check(ERR_GameMode*){checks++;}void Stop(){stops++;} }; struct ERR_EnemyRadio{ERR_EnemyRadio(SCR_AIGroup*,int){}void Register(IEntity*){}void Check(ERR_GameMode*){}void Stop(){}}; struct MineGrant{bool settled=false,designated=false;bool ReadyForResupply(bool replacement=false){return settled&&(!replacement||designated);}}; struct AutoGrant{void Bind(IEntity*,SCR_AIGroup*){}}; struct ERR_EnemyEquipmentEntry{AutoGrant Automatic; MineGrant* Mines=nullptr; ERR_EnemyOptics* Optics=nullptr;bool Complete=false; IEntity* Actor=nullptr;SCR_AIGroup* Group=nullptr;SCR_AICombatComponent* Combat=nullptr;bool Released=false;int SkillChecks=0,checks=0,stops=0; void Check(ERR_GameMode*){checks++;Complete=true;}void Stop(ERR_GameMode*){stops++;Released=true;if(Optics)Optics->Stop();Combat=nullptr;} }; ''' + coordinator + r''' int main(){ ERR_GameMode mode;ERR_GameMode::current=&mode;ERR_EnemyEquipment service(&mode); SCR_AIGroup group;IEntity soldier;SCR_AICombatComponent combat;soldier.combat=&combat;AIAgent agent;agent.actor=&soldier;group.agents.Insert(&agent); service.RegisterGroup(&group);service.RegisterGroup(&group);assert(service.m_Groups.Count()==1); service.Tick(0);assert(service.m_Entries.Count()==0);service.Tick(3000);assert(service.m_Entries.Count()==1&&combat.binds==1&&combat.refreshes==1); auto entry=service.m_Entries[0];assert(entry->Optics&&entry->Optics->actor==&soldier&&entry->Optics->group==&group); assert(entry->Complete&&entry->Optics->checks==1&&combat.refreshes==1); // Stinger is already complete; optics has its own startup completion. MineGrant grant;entry->Mines=&grant;IEntity foreign;SCR_AIGroup otherGroup; assert(!service.MineSupplyReady(&group,&soldier));grant.settled=true; assert(service.MineSupplyReady(&group,&soldier));assert(!service.MineSupplyReady(&group,&soldier,true));grant.designated=true;assert(service.MineSupplyReady(&group,&soldier,true));assert(!service.MineSupplyReady(&otherGroup,&soldier,true));assert(!service.MineSupplyReady(&otherGroup,&soldier));assert(!service.MineSupplyReady(&group,&foreign)); soldier.eligible=false;assert(!service.MineSupplyReady(&group,&soldier));soldier.eligible=true; entry->Released=true;assert(!service.MineSupplyReady(&group,&soldier));assert(!service.MineSupplyReady(&group,&soldier,true));entry->Released=false; entry->Mines=nullptr;assert(!service.MineSupplyReady(&group,&soldier));entry->Mines=&grant; service.m_Stopped=true;assert(!service.MineSupplyReady(&group,&soldier));service.m_Stopped=false; service.m_Entries.resize(2049,nullptr);assert(!service.MineSupplyReady(&group,&soldier));service.m_Entries.resize(1); service.Tick(3001);assert(entry->checks==1&&entry->Optics->checks==1&&combat.refreshes==1); service.Tick(6000);assert(entry->checks==2&&entry->Optics->checks==2&&combat.binds==1&&combat.refreshes==2); service.UnregisterGroup(&group);service.Tick(9000);assert(service.m_Entries[0]->Released&&service.m_Entries[0]->checks==2&&entry->Optics->checks==2&&entry->Optics->stops==1); service.RegisterGroup(&group);service.Tick(12000);assert(service.m_Entries.Count()==1&&combat.binds==1&&combat.refreshes==2); service.Stop();service.RegisterGroup(&group);service.Tick(50000);assert(service.m_Groups.Count()==0&&service.m_Stopped); ERR_EnemyEquipment delayed(&mode);SCR_AIGroup late;delayed.RegisterGroup(&late);delayed.Tick(3000);late.agents.Insert(&agent);delayed.Tick(6000);assert(delayed.m_Entries.Count()==1); ERR_EnemyEquipment expired(&mode);SCR_AIGroup empty;expired.RegisterGroup(&empty);for(int i=1;i<=6;i++){expired.Tick(i*3000);}empty.agents.Insert(&agent);expired.Tick(21000);assert(expired.m_Entries.Count()==0); ERR_EnemyEquipment bounded(&mode);for(int i=0;i<270;i++){bounded.RegisterGroup(new SCR_AIGroup());}assert(bounded.m_Groups.Count()==256); ERR_EnemyEquipment incomplete(&mode);SCR_AIGroup unresolved;IEntity body;AIAgent bodyAgent;bodyAgent.actor=&body;unresolved.agents.Insert(&bodyAgent);incomplete.RegisterGroup(&unresolved); for(int i=1;i<=12;i++){incomplete.Tick(i*3000);}assert(incomplete.m_Entries.Count()==1&&incomplete.m_Entries[0]->SkillChecks==5); auto incompleteOptics=incomplete.m_Entries[0]->Optics;int checksBeforeStop=incompleteOptics->checks; incomplete.Stop();incomplete.Tick(60000);assert(incompleteOptics->stops==1&&incompleteOptics->checks==checksBeforeStop); // Temporary incapacitation preserves the same finite entry and its skill binding. ERR_EnemyEquipment recovery(&mode);SCR_AIGroup recoveringGroup;IEntity recovering;SCR_AICombatComponent recoveredCombat; recovering.combat=&recoveredCombat;AIAgent recoveringAgent;recoveringAgent.actor=&recovering;recoveringGroup.agents.Insert(&recoveringAgent); recovery.RegisterGroup(&recoveringGroup);recovery.Tick(3000);auto retained=recovery.m_Entries[0]; recovering.unconscious=true;recovery.Tick(6000);assert(!retained->Released&&retained->stops==0&&retained->checks==1&&recoveredCombat.refreshes==1); recovering.unconscious=false;recovery.Tick(9000);assert(recovery.m_Entries.Count()==1&&recovery.m_Entries[0]==retained&&recoveredCombat.binds==1&&recoveredCombat.refreshes==2&&retained->checks==2); ERR_EnemyEquipment capture(&mode);SCR_AIGroup capturedGroup;IEntity capturedBody;AIAgent capturedAgent;capturedAgent.actor=&capturedBody; capturedGroup.agents.Insert(&capturedAgent);capture.RegisterGroup(&capturedGroup);capture.Tick(3000); auto capturedOptics=capture.m_Entries[0]->Optics;capturedBody.eligible=false;capture.Tick(6000); assert(capturedOptics->checks==1&&capturedOptics->stops==1&&capture.m_Entries[0]->Released); capturedBody.eligible=true;capture.Tick(9000);assert(capturedOptics->checks==1); } ''') print('PASS: actual equipment coordinator registration dedupe, startup delay, five member scans, finite component retries, unregister/stop terminal behavior and 256-group bound')