"""Execute actual scoped skill and finite native-equipment policy with API doubles.""" import os,re from pathlib import Path from policy_harness import ROOT,run source=Path(os.environ.get('ERR_EQUIPMENT_SOURCE',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_EnemyEquipment.c'))).read_text() code=source[:source.index('class ERR_EnemyEquipmentGroup')] code=re.sub(r'//[^\n]*','',code) code=code.replace('modded class SCR_AICombatComponent','struct SCR_AICombatComponent : NativeCombat') code=code.replace('class ERR_EnemyEquipmentCallback : ScriptedInventoryOperationCallback','struct ERR_EnemyEquipmentCallback') code=code.replace('class ERR_EnemyEquipmentRules','struct ERR_EnemyEquipmentRules').replace('class ERR_EnemyEquipmentEntry','struct ERR_EnemyEquipmentEntry') code=code.replace('protected ','').replace('override ','').replace('ref ','') code=code.replace('static const ResourceName','static constexpr const char*').replace('static const int','static constexpr int') code=code.replace('string result','std::string result').replace('array','std::vector') code=code.replace('BaseWeaponManagerComponent.Cast(Actor.FindComponent(BaseWeaponManagerComponent))','Actor->weapons') code=code.replace('InventoryStorageManagerComponent.Cast(Actor.FindComponent(InventoryStorageManagerComponent))','Actor->inventory') for cls in ('ERR_GameMode','SCR_AIGroup','SCR_AIGroupUtilityComponent','IEntity','SCR_AICombatComponent','ERR_EnemyEquipmentCallback','ERR_EnemyOptics','BaseWeaponManagerComponent','InventoryStorageManagerComponent'): code=re.sub(r'\b'+cls+r' ([a-zA-Z_]\w*)',cls+r'* \1',code) for obj in ('mode','group','utility','Actor','Group','Combat','Optics','Operation','item','weapons','inventory'): code=code.replace(obj+'.',obj+'->') for cls in ('Replication','SCR_Global','ERR_GameMode','ERR_Actors','ERR_EnemyEquipmentRules','EAISkill','ERR_HQ','Math','EStoragePurpose'): code=code.replace(cls+'.',cls+'::') code=code.replace('GetPrefabData().','GetPrefabData()->').replace('Settings().','Settings()->').replace('foreach (','for (').replace('null','nullptr').replace('super.','NativeCombat::') code=code.replace('new ERR_EnemyEquipmentCallback()','NewOperation()') code=re.sub(r'\b(bool|int|EAISkill|[A-Za-z_]\w*\*) ([A-Za-z_]\w*);',r'\1 \2 {};',code) code=code.replace('\n}\n','\n};\n') # Forward factory declaration permits bounded managed operation storage below. code=code.replace('struct ERR_EnemyEquipmentEntry','ERR_EnemyEquipmentCallback* NewOperation();\nstruct ERR_EnemyEquipmentEntry') run(r''' #include #include #include #include enum class EAISkill {ROOKIE,REGULAR,EXPERT,CYLON}; namespace Replication {bool server=true;bool IsServer(){return server;}} namespace SCR_Global {bool editor=false;bool IsEditMode(){return editor;}} namespace EStoragePurpose {constexpr int PURPOSE_WEAPON_PROXY=7;} namespace ERR_HQ {void Event(std::string,std::string){}} struct SCR_AIGroupUtilityComponent {bool military=true;bool IsMilitary(){return military;}}; struct SCR_AIGroup { SCR_AIGroupUtilityComponent utility;int players=0,faction=1;bool ready=true; SCR_AIGroupUtilityComponent* GetGroupUtilityComponent(){return ready?&utility:nullptr;} int GetPlayerCount(bool){return players;}int GetFaction(){return faction;} }; struct Settings {int oneIn=15;int Get(std::string key){assert(key=="stingerChanceOneIn");return oneIn;}}; struct ERR_GameMode { static inline ERR_GameMode* current=nullptr;bool active=true;struct Settings values; static ERR_GameMode* Get(){return current;}bool Active(){return active;}int EnemyFaction(){return 1;} struct Settings* Settings(){return &values;} }; namespace Math {int draw=0,calls=0;int RandomInt(int lo,int hi){assert(lo==0&&hi>0);calls++;return draw;}} struct Prefab {std::string name;std::string GetPrefabName(){return name;}}; struct ERR_EnemyEquipmentCallback; struct InventoryStorageManagerComponent { bool accept=true;int requests=0;ERR_EnemyEquipmentCallback* callback=nullptr; bool TrySpawnPrefabToStorage(const char* prefab,void* target,int slot,int purpose,ERR_EnemyEquipmentCallback* op){assert(std::string(prefab).find("3DF204EEE0534EF2")!=std::string::npos);assert(!target&&slot==-1&&purpose==7);requests++;callback=op;return accept;} }; struct IEntity; struct BaseWeaponManagerComponent {std::vector items;void GetWeaponsList(std::vector& out){out=items;}}; struct IEntity { bool player=false,alive=true;SCR_AIGroup* group=nullptr;Prefab* prefab=nullptr; BaseWeaponManagerComponent* weapons=nullptr;InventoryStorageManagerComponent* inventory=nullptr; Prefab* GetPrefabData(){return prefab;} }; namespace ERR_Actors {bool CanFight(IEntity* actor){return actor->alive;}bool Player(IEntity* actor){return actor->player;}SCR_AIGroup* Group(IEntity* actor){return actor->group;}} struct NativeCombat { IEntity* owner=nullptr;EAISkill skill=EAISkill::REGULAR; IEntity* GetOwner(){return owner;}EAISkill GetAISkill(){return skill;} virtual void SetAISkill(EAISkill value){skill=value;}virtual void ResetAISkill(){skill=EAISkill::ROOKIE;} }; struct ERR_EnemyOptics{int stops=0;void Stop(){stops++;}}; ''' + code + r''' std::vector> operations; ERR_EnemyEquipmentCallback* NewOperation(){operations.emplace_back(new ERR_EnemyEquipmentCallback());return operations.back().get();} struct Soldier { SCR_AIGroup group;BaseWeaponManagerComponent weapons;InventoryStorageManagerComponent inventory;IEntity actor;SCR_AICombatComponent combat;ERR_EnemyOptics optics; Soldier(){actor.group=&group;actor.weapons=&weapons;actor.inventory=&inventory;combat.owner=&actor;} ERR_EnemyEquipmentEntry Entry(){ERR_EnemyEquipmentEntry e;e.Actor=&actor;e.Group=&group;e.Combat=&combat;e.Optics=&optics;return e;} }; int main(){ ERR_GameMode mode;ERR_GameMode::current=&mode; // One draw per exact actor; accepted insertion cannot be retried, even after timeout. for(int draw=0;draw<15;draw++){ Math::draw=draw;Math::calls=0;Soldier soldier;auto job=soldier.Entry(); for(int n=0;n<20;n++){job.Check(&mode);} assert(job.Complete&&Math::calls==1&&soldier.inventory.requests==(draw==0?1:0)); } Math::draw=0;mode.values.oneIn=0;Soldier off;auto disabled=off.Entry();Math::calls=0; assert(disabled.Check(&mode)&&Math::calls==0&&off.inventory.requests==0); mode.values.oneIn=1; Soldier success;auto finished=success.Entry();assert(!finished.Check(&mode)); success.inventory.callback->OnComplete();success.inventory.callback->OnAllFailed(); assert(finished.Check(&mode)&&success.inventory.requests==1&&success.inventory.callback->Succeeded); // A completed then removed launcher is never replenished. for(int n=0;n<10;n++){finished.Check(&mode);}assert(success.inventory.requests==1); Soldier rejected;rejected.inventory.accept=false;auto retries=rejected.Entry(); for(int n=0;n<10;n++){retries.Check(&mode);}assert(rejected.inventory.requests==4&&retries.Complete); Soldier failed;auto again=failed.Entry();again.Check(&mode);failed.inventory.callback->OnFailed();again.Check(&mode);assert(failed.inventory.requests==2); for(int n=0;n<10;n++){again.Check(&mode);}assert(failed.inventory.requests==2); Soldier changed;auto captured=changed.Entry();captured.Check(&mode);changed.actor.player=true;assert(captured.Check(&mode));changed.actor.player=false; for(int n=0;n<10;n++){captured.Check(&mode);}assert(changed.inventory.requests==1); Soldier absent;absent.actor.inventory=nullptr;auto missing=absent.Entry();for(int n=0;n<8;n++){missing.Check(&mode);}assert(missing.Complete&&absent.inventory.requests==0); Soldier equipped;Prefab prefab;prefab.name=ERR_EnemyEquipmentEntry::LAUNCHER;IEntity item;item.prefab=&prefab;equipped.weapons.items.push_back(&item);auto existing=equipped.Entry();assert(existing.Check(&mode)&&equipped.inventory.requests==0); // The exact same eligibility policy protects skill binding and item submission. for(int variant=0;variant<9;variant++){ Soldier soldier;ERR_GameMode other;auto job=soldier.Entry();Math::calls=0; if(variant==0)Replication::server=false; if(variant==1)SCR_Global::editor=true; if(variant==2)mode.active=false; if(variant==3)ERR_GameMode::current=&other; if(variant==4)soldier.actor.player=true; if(variant==5)soldier.actor.alive=false; if(variant==6)soldier.group.players=1; if(variant==7)soldier.group.faction=2; if(variant==8)soldier.group.utility.military=false; assert(job.Check(&mode)&&Math::calls==0&&soldier.inventory.requests==0); soldier.combat.ERR_BindEnemySkill(&mode,&soldier.group);assert(soldier.combat.GetAISkill()==EAISkill::REGULAR); Replication::server=true;SCR_Global::editor=false;mode.active=true;ERR_GameMode::current=&mode; } Soldier skill;skill.combat.ERR_BindEnemySkill(&mode,&skill.group);assert(skill.combat.GetAISkill()==EAISkill::EXPERT); skill.combat.SetAISkill(EAISkill::ROOKIE);assert(skill.combat.GetAISkill()==EAISkill::EXPERT); skill.combat.ResetAISkill();assert(skill.combat.GetAISkill()==EAISkill::EXPERT); skill.combat.SetAISkill(EAISkill::CYLON);assert(skill.combat.GetAISkill()==EAISkill::CYLON); skill.combat.ERR_BindEnemySkill(&mode,&skill.group);skill.combat.ERR_ReleaseEnemySkill(&mode);assert(skill.combat.GetAISkill()==EAISkill::REGULAR); skill.combat.SetAISkill(EAISkill::ROOKIE);assert(skill.combat.GetAISkill()==EAISkill::ROOKIE); Soldier moved;SCR_AIGroup replacement;moved.combat.ERR_BindEnemySkill(&mode,&moved.group);moved.actor.group=&replacement; moved.combat.SetAISkill(EAISkill::ROOKIE);assert(moved.combat.GetAISkill()==EAISkill::ROOKIE); Soldier stopped;auto terminal=stopped.Entry();terminal.Check(&mode);terminal.Stop(&mode);assert(stopped.optics.stops==1);stopped.inventory.callback->OnComplete(); for(int n=0;n<10;n++){terminal.Check(&mode);}assert(stopped.inventory.requests==1&&terminal.Complete); } ''') print('PASS: actual enemy eligibility, scoped native skill floor/reset/restoration, one-roll inventory issuance, completion/failure, timeout quarantine, actor capture and terminal stop; native inventory runtime unproven') 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_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('Optics.Check','Optics->Check') for cls in ('Replication','ERR_GameMode','ERR_EnemyEquipmentRules'):coordinator=coordinator.replace(cls+'.',cls+'::') 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 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;}}; struct SCR_AICombatComponent{int binds=0;void ERR_BindEnemySkill(ERR_GameMode*,SCR_AIGroup*){binds++;}}; struct IEntity{SCR_AICombatComponent* combat=nullptr;bool eligible=true;}; struct AIAgent{IEntity* actor=nullptr;IEntity* GetControlledEntity(){return actor;}}; struct SCR_AIGroup{Array agents;void GetAgents(Array& out){out=agents;}}; namespace ERR_EnemyEquipmentRules{bool Eligible(ERR_GameMode*,SCR_AIGroup*,IEntity* actor){return actor&&actor->eligible;}} 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_EnemyEquipmentEntry{ 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); auto entry=service.m_Entries[0];assert(entry->Optics&&entry->Optics->actor==&soldier&&entry->Optics->group==&group); assert(entry->Complete&&entry->Optics->checks==1); // Stinger is already complete; optics has its own startup completion. service.Tick(3001);assert(entry->checks==1&&entry->Optics->checks==1); service.Tick(6000);assert(entry->checks==2&&entry->Optics->checks==2&&combat.binds==1); 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); 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<140;i++){bounded.RegisterGroup(new SCR_AIGroup());}assert(bounded.m_Groups.Count()==128); 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); 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 128-group bound')