Capture current mission, AI, map and administration development

Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
This commit is contained in:
2026-10-13 22:52:53 +02:00
parent a951a96edc
commit 6a667d8deb
8104 changed files with 2124945 additions and 2061 deletions
@@ -0,0 +1,104 @@
#!/usr/bin/env python3
"""Execute production bounded radio graph and hop-delivery state machine."""
from pathlib import Path
import os, re, subprocess, tempfile
ROOT=Path(__file__).resolve().parents[1]
source=Path(os.environ.get('ERR_NETWORK_SOURCE', ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQNetwork.c')).read_text()
def extract(signature):
a=source.index(signature);b=source.index('{',a);end=b+1;depth=1
while depth:depth+=(source[end]=='{')-(source[end]=='}');end+=1
return source[a:end]
def trans(s):
s=re.sub(r'//[^\n]*','',s).replace('protected ','').replace('null','nullptr')
s=s.replace('string.Format','Format').replace('string ', 'std::string ')
s=s.replace('Math.Round(distance).ToString()', 'std::to_string(int(distance))')
s=re.sub(r'\b(\w+)\.ToString\(\)',r'std::to_string(\1)',s)
for name in ['Math','vector','ERR_HQLocalHandoff']:s=s.replace(name+'.',name+'::')
for typ in ['IEntity','SCR_AIGroup','ERR_HQRoute','ERR_HQRadioNode','ERR_HQJournal']:
s=re.sub(r'\b'+typ+r' (\w+)',typ+r'* \1',s)
s=s.replace('array<int> queue = {}','Arr<int> queue').replace('array<int> cell','Arr<int>* cell').replace('array<int> neighbors','Arr<int>* neighbors')
s=s.replace('cell = {};','cell = new Arr<int>();')
s=re.sub(r'foreach\s*\(int (\w+) : neighbors\)',r'for (auto \1 : *neighbors)',s)
for name in ['carrier','caller','node','route','journal','cell']:
s=s.replace(name+'.',name+'->')
s=re.sub(r'(Nodes|m_Nodes)\[([^\]]+)\]\.',r'\1[\2]->',s)
s=s.replace('Carrier.GetOrigin()', 'Carrier->GetOrigin()')
s=re.sub(r'\b(int|float|bool) (\w+);',r'\1 \2{};',s)
return s
headers=r'''
#include <cassert>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <iostream>
struct vector{float v[3]{};float operator[](int i)const{return v[i];}static float DistanceXZ(vector a,vector b){return std::hypot(a[0]-b[0],a[2]-b[2]);}};
vector V(float x,float z=0){return {{x,0,z}};}
namespace Math{int Floor(float x){return std::floor(x);}}
std::string Format(const char*,int x,int z){return std::to_string(x)+":"+std::to_string(z);}
template<class T>struct Arr:std::vector<T>{int Count(){return this->size();}bool IsEmpty(){return this->empty();}void Clear(){this->clear();}void Insert(T x){this->push_back(x);}void InsertAt(T x,int i){this->insert(this->begin()+i,x);}};
template<class K,class V>struct Map:std::map<K,V>{void Clear(){this->clear();}bool Contains(K k){return this->count(k);}bool Find(K k,V& v){if(!Contains(k))return false;v=this->at(k);return true;}V Get(K k){if(!Contains(k))return {};return this->at(k);}void Insert(K k,V v){(*this)[k]=v;}};
struct SCR_AIGroup{bool enemy=true;};struct IEntity{vector pos;bool alive=true;int radio=1;bool captured=false;vector GetOrigin(){return pos;}};
struct ERR_HQRadioNode{IEntity* Carrier{};SCR_AIGroup* Group{};int UnitId{},Capability{};bool Valid(bool manpack=false){return Carrier&&Carrier->alive&&!Carrier->captured&&Carrier->radio>=(manpack?2:1);}std::string Label(){return "unit "+std::to_string(UnitId);}};
struct ERR_HQJournal{Arr<std::string> events;void Write(std::string kind,std::string text,int){events.Insert(kind+" "+text);}};
'''
headers+='struct ERR_HQStatusSampler{};struct ERR_HQLocalHandoff{static bool Valid(SCR_AIGroup*,ERR_HQStatusSampler*,IEntity*,ERR_HQRadioNode*){return true;}};\n'
routefields='SCR_AIGroup* LocalSource=nullptr;IEntity* LocalWitness=nullptr;ERR_HQStatusSampler* LocalRoster=nullptr;Arr<ERR_HQRadioNode*> Nodes;bool Downlink{},Sending{},Failed{},Originated{};int Cursor{},MessageId{};float Due{},StartedAt=-1,OriginDue=-1;vector SentFrom;std::string Payload;'
networkfields='int m_LocalChecks=0;Arr<ERR_HQRadioNode*> m_Nodes;Arr<int> m_Parents,m_Depths;Map<IEntity*,int> m_Indices;Map<std::string,Arr<int>*> m_Cells;bool Overflow{};'
route='struct ERR_HQRoute{'+routefields+'\n'+'\n'.join(trans(extract(x)) for x in ['int Advance(', 'protected string SenderLabel(', 'protected int Fail('])+'};\n'
network='struct Network{'+networkfields+'\n'+'\n'.join(trans(extract(x)) for x in ['void Clear(', 'protected string Cell(', 'void Add(', 'void Build(', 'ERR_HQRoute Route('])+'};\n'
tests=r'''
int main(){
Network network;SCR_AIGroup group;IEntity c[5];for(int i=0;i<5;i++)c[i].pos=V(i*500);
c[0].radio=2;for(int i=0;i<5;i++)network.Add(&c[i],&group,37+i,c[i].radio);network.Build();
assert(network.Route(&c[0])->Nodes.Count()==1);assert(network.Route(&c[3])->Nodes.Count()==4);assert(!network.Route(&c[4]));
ERR_HQJournal journal;auto up=network.Route(&c[2]);assert(up->Nodes.Count()==3);
assert(up->Advance(0,&journal)==0);assert(!up->Sending&&!up->Originated&&up->OriginDue==3000);
assert(journal.events.Count()==1&&journal.events.back().find("CALL ")==0);
assert(up->Advance(2999,&journal)==0);assert(journal.events.Count()==1);
assert(up->Advance(3000,&journal)==0);assert(up->Sending&&up->Originated&&up->Due==5000);
assert(up->Advance(5000,&journal)==0);
c[2].alive=false;assert(up->Advance(7000,&journal)==0);c[0].alive=false;assert(up->Advance(9000,&journal)==-1);
assert(journal.events.back().find("LOST")!=std::string::npos); // final transmission needs its live sender
for(auto& carrier:c)carrier.alive=true;
auto good=network.Route(&c[2]);assert(good->Advance(0,&journal)==0);assert(good->Advance(3000,&journal)==0);assert(good->Advance(5000,&journal)==0);
c[2].alive=false;assert(good->Advance(7000,&journal)==0);assert(good->Advance(9000,&journal)==1);
assert(journal.events.back().find("HQ received")!=std::string::npos); // a completed earlier hop survives its sender
auto severed=network.Route(&c[0]);assert(severed->Advance(0,&journal)==0);assert(severed->Advance(3000,&journal)==0);c[0].radio=0;assert(severed->Advance(5000,&journal)==-1);c[0].radio=2;
for(auto& carrier:c)carrier.alive=true;
auto lost=network.Route(&c[2]);assert(lost->Advance(0,&journal)==0);assert(lost->Advance(3000,&journal)==0);c[1].radio=0;assert(lost->Advance(5000,&journal)==-1);assert(lost->Advance(7000,&journal)==-1);
c[1].radio=1;auto moving=network.Route(&c[2]);moving->Advance(0,&journal);moving->Advance(3000,&journal);c[1].pos=V(499);assert(moving->Advance(5000,&journal)==-1);c[1].pos=V(500);
// No originating transmission may survive radio loss, death/incapacitation, or capture during the hold.
for(int reason=0;reason<3;reason++){
auto interrupted=network.Route(&c[0]);ERR_HQJournal calls;assert(interrupted->Advance(10000,&calls)==0);
if(reason==0)c[0].radio=1;
if(reason==1)c[0].alive=false;
if(reason==2)c[0].captured=true;
assert(interrupted->Advance(11500,&calls)==-1);assert(!interrupted->Sending&&!interrupted->Originated);
assert(calls.events.Count()==2&&calls.events[0].find("CALL ")==0&&calls.events[1].find("LOST ")==0);
c[0].radio=2;c[0].alive=true;c[0].captured=false;
assert(interrupted->Advance(15000,&calls)==-1);assert(calls.events.Count()==2);
}
auto direct=network.Route(&c[0]);ERR_HQJournal directLog;
assert(direct->Advance(0,&directLog)==0);assert(direct->Advance(2999,&directLog)==0);
assert(direct->Advance(3000,&directLog)==0);assert(direct->Advance(4999,&directLog)==0);assert(direct->Advance(5000,&directLog)==1);
assert(directLog.events.Count()==4); // CALL, CALL COMPLETE, TRANSMIT, RECEIVE exactly once.
ERR_HQRoute empty;assert(empty.Advance(0,&journal)==-1);assert(!empty.Originated&&!empty.Sending);
int beforeDown=journal.events.Count();auto down=network.Route(&c[2],true);assert(down->Nodes[0]->Carrier==&c[0]);assert(down->Advance(0,&journal)==0);
assert(down->Advance(2000,&journal)==0);assert(down->Advance(4000,&journal)==0);assert(down->Advance(6000,&journal)==1);
assert(!down->Originated&&down->OriginDue==-1);for(int j=beforeDown;j<journal.events.Count();j++)assert(journal.events[j].find("CALL")!=0);
auto captured=network.Route(&c[2],true);captured->Advance(0,&journal);c[0].captured=true;assert(captured->Advance(2000,&journal)==-1);c[0].captured=false;
auto timeout=network.Route(&c[2]);timeout->Advance(0,&journal);assert(timeout->Advance(30001,&journal)==-1);
Network disconnected;disconnected.Add(&c[1],&group,1,1);disconnected.Build();assert(!disconnected.Route(&c[1]));
Network boundary;c[1].pos=V(501);boundary.Add(&c[0],&group,1,2);boundary.Add(&c[1],&group,2,1);boundary.Build();assert(!boundary.Route(&c[1]));
network.Clear();assert(!network.Route(&c[0]));
Network crowded;std::vector<IEntity> many(2050);for(auto& carrier:many){carrier.radio=2;crowded.Add(&carrier,&group,1,2);}assert(crowded.Overflow&&crowded.m_Nodes.Count()==2048);
crowded.Build();assert(crowded.Overflow); // bounded dense graph work
std::cout<<"PASS: real-carrier shortest-hop paths, 500m boundary, three-hop cap, no-manpack failure, three-second originating-call interruption, unchanged downlink hop timing, completed-hop survival, interrupted final uplink, radio loss, capture, motion, timeout, reset and network bounds\n";
}
'''
with tempfile.TemporaryDirectory(prefix='eai-hq-network-') as tmp:
cpp=Path(tmp)/'test.cpp';exe=Path(tmp)/'test';cpp.write_text(headers+route+network+tests)
subprocess.run(['g++','-std=c++17','-Wall','-Wextra',str(cpp),'-o',str(exe)],check=True)
subprocess.run([str(exe)],check=True)
@@ -0,0 +1,148 @@
"""Actual finite mine transaction/callback and shared reservation; native boundaries doubled."""
from pathlib import Path
import os,re
from policy_harness import ROOT,body,run
P=Path(os.environ.get('ERR_MINE_TRANSFER_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryMineTransfer.c'))
s=P.read_text()
for forbidden in ('GetItem(', 'TrySpawn', 'SetAmmoCount', 'ActivateTrigger(', 'DeleteEntity', 'SetOrigin'):
assert forbidden not in s
assert s.count('TryMoveItemToStorage(')==1
assert s.index('m_Reservation.Commit()')<s.index('m_Submitted = true;')<s.index('TryMoveItemToStorage(')
reservation=(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_FiniteMagazineReservation.c').read_text()
stored=body(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryAmmoTransfer.c',' static bool StoredUnder(')
def cpp(s):
s=re.sub(r'//[^\n]*','',s).replace('protected ','').replace('override ','').replace('ref ','').replace('class ','struct ').replace('foreach (','for (').replace('array<','Array<').replace('null','nullptr')
s=s.replace('out IEntity found','IEntity& found').replace('ERR_HQ.Cast(m_Mode.Command())','m_Mode.Command()')
s=s.replace('void ERR_InfantryMineTransfer(', 'ERR_InfantryMineTransfer(').replace('void ERR_FiniteMagazineReservation(', 'ERR_FiniteMagazineReservation(')
for typ in ('InventoryStorageManagerComponent','InventoryItemComponent','SCR_AIVehicleUsageComponent','SCR_PressureTriggerComponent'):
s=re.sub(typ+r'\.Cast\((\w+)\.FindComponent\('+typ+r'\)\)',r'\1.'+{'InventoryStorageManagerComponent':'inventory','InventoryItemComponent':'item','SCR_AIVehicleUsageComponent':'usage','SCR_PressureTriggerComponent':'trigger'}[typ],s)
for typ,field in [('InventoryStorageManagerComponent','inventory'),('SCR_AntiPersonnelMineCollisionHandlerComponent','collision'),('SCR_PressureTriggerComponent','trigger'),('DamageManagerComponent','damage')]:
s=re.sub(r'(\w+)\.FindComponent\('+typ+r'\)',r'\1.'+field,s)
for typ in ('ERR_HQ','ERR_GameMode','ERR_ForceRecord','ERR_HQStatusSampler','InventoryStorageManagerComponent','InventoryItemComponent','InventoryStorageSlot','BaseInventoryStorageComponent','SCR_AIVehicleUsageComponent','SCR_PressureTriggerComponent','SCR_AIGroupUtilityComponent','Physics','ERR_InfantryMineTransfer','ERR_InfantryMineCallback','ERR_FiniteMagazineReservation'):
s=re.sub(r'\b'+typ+r' (?=\w)',typ+'* ',s)
s=s.replace('Array<BaseInventoryStorageComponent>','Array<BaseInventoryStorageComponent*>').replace('Array<IEntity> attempted','Array<IEntity>* attempted')
for field in ('m_Original','m_Spent'):
s=s.replace('Array<IEntity> '+field,'Array<IEntity>* '+field).replace(field+'.',field+'->')
s=s.replace('Array<IEntity> original, Array<IEntity> spent','Array<IEntity>* original, Array<IEntity>* spent')
for ns in ('Replication','SCR_Global','ERR_GameMode','ERR_Actors','ERR_EnemyEquipmentRules','ERR_ConvoyRules','SCR_FactionManager','CompartmentAccessComponent','ERR_InfantryAmmoTransfer','ERR_InfantryAmmoAccess','ERR_ForceRules','ERR_EnemyLoadoutCatalog','ERR_InfantryAmmoTransferState','EStoragePurpose'):
s=s.replace(ns+'.',ns+'::')
for var in ('hq','m_Mine','exactMine','mode','donorVehicle','recipientActor','originalRoster','usage','item','actor','group','inventory','carried','trigger','m_Mode','m_Donor','m_DonorGroup','m_Recipient','m_RecipientGroup','m_Roster','m_DonorRecord','m_RecipientRecord','m_Source','m_Destination','m_Reservation','m_Callback','m_FromSlot','m_FromStorage','m_Storage','slot','storage','utility','physics','Transfer','entity'):
s=re.sub(r'\b'+var+r'\.',var+'->',s)
for call in ('Forces()','GetPilotCompartmentSlot()','GetPrefabData()','GetParentSlot()'):
s=s.replace(call+'.',call+'->')
s=s.replace('m_VehicleMgr.','m_VehicleMgr->')
s=re.sub(r'\b(bool|int|IEntity) (\w+);',r'\1 \2{};',s)
s=re.sub(r'^( \w+\*) (\w+);',r'\1 \2=nullptr;',s,flags=re.M)
return s.replace('\n}\n','\n};\n')
run(r'''
#include <cassert>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#include <functional>
using string=std::string;
template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}void Insert(T v){this->push_back(v);}bool Contains(T v){return std::find(this->begin(),this->end(),v)!=this->end();}void RemoveItem(T v){auto i=std::find(this->begin(),this->end(),v);if(i!=this->end())this->erase(i);}};
struct Entity;struct Group;using IEntity=Entity*;using Vehicle=Entity*;using SCR_AIGroup=Group*;
struct Vector{float n=0;float Length(){return n;}};
struct Physics{Vector speed,angular;Vector GetVelocity(){return speed;}Vector GetAngularVelocity(){return angular;}};
struct BaseInventoryStorageComponent{IEntity owner=nullptr;IEntity GetOwner(){return owner;}};
struct InventoryStorageSlot{IEntity attached=nullptr;BaseInventoryStorageComponent*storage=nullptr;IEntity GetAttachedEntity(){return attached;}BaseInventoryStorageComponent*GetStorage(){return storage;}};
struct InventoryItemComponent{InventoryStorageSlot*slot=nullptr;InventoryStorageSlot*GetParentSlot(){return slot;}};
struct SCR_PressureTriggerComponent{bool active=false,initial=false;bool IsActivated(){return active;}bool IsActivatedByDefault(){return initial;}};
struct Prefab{string name="PMN4";string GetPrefabName(){return name;}};
struct Seat{IEntity occupant=nullptr;IEntity GetOccupant(){return occupant;}};
struct SCR_AIVehicleUsageComponent{Seat*seat=nullptr;Seat*GetPilotCompartmentSlot(){return seat;}};
struct InventoryStorageManagerComponent;
struct Entity{InventoryStorageManagerComponent*inventory=nullptr;InventoryItemComponent*item=nullptr;SCR_PressureTriggerComponent*trigger=nullptr;SCR_AIVehicleUsageComponent*usage=nullptr;Prefab*prefab=nullptr;Physics*physics=nullptr;IEntity vehicle=nullptr,parent=nullptr;SCR_AIGroup group=nullptr;int faction=1;bool alive=true,fit=true,player=false,collision=true,damage=true;
Prefab*GetPrefabData(){return prefab;}Physics*GetPhysics(){return physics;}IEntity GetParent(){return parent;}};
struct VehicleManager{bool found=true;bool FindVehicle(IEntity){return found;}};
struct SCR_AIGroupUtilityComponent{bool military=true;VehicleManager*m_VehicleMgr=nullptr;bool IsMilitary(){return military;}};
struct Group{bool slave=false;int players=0,faction=1;SCR_AIGroupUtilityComponent*utility=nullptr;bool IsSlave(){return slave;}int GetPlayerCount(bool){return players;}int GetFaction(){return faction;}SCR_AIGroupUtilityComponent*GetGroupUtilityComponent(){return utility;}};
struct ERR_ForceRecord{SCR_AIGroup Group=nullptr;bool Physical=true,Eliminated=false;};
struct Ledger{SCR_AIGroup donor=nullptr,recipient=nullptr;ERR_ForceRecord*d=nullptr,*r=nullptr;ERR_ForceRecord*FindGroup(SCR_AIGroup g){return g==donor?d:g==recipient?r:nullptr;}};
struct ERR_HQ{bool designated=true;bool MineSupplyReady(SCR_AIGroup,IEntity,bool replacement=false){return !replacement||designated;}};
struct ERR_GameMode{ERR_HQ hq;bool command=true;ERR_HQ*Command(){return command?&hq:nullptr;}inline static ERR_GameMode*current=nullptr;bool active=true;Ledger*ledger=nullptr;static ERR_GameMode*Get(){return current;}bool Active(){return active;}Ledger*Forces(){return ledger;}int EnemyFaction(){return 1;}};
struct ERR_HQStatusSampler{SCR_AIGroup group=nullptr;IEntity actor=nullptr;bool valid=true;int strength=1;bool OwnsRoster(SCR_AIGroup g){return g==group;}int InitialStrength(){return strength;}IEntity InitialMember(int i){return i==0?actor:nullptr;}bool CanAttribute(int i,IEntity a,bool){return valid&&i==0&&a==actor;}};
struct Replication{inline static bool server=true;static bool IsServer(){return server;}};
struct SCR_Global{inline static bool edit=false;static bool IsEditMode(){return edit;}};
struct ERR_Actors{static bool Alive(IEntity e){return e&&e->damage&&e->alive;}static bool CanFight(IEntity e){return Alive(e)&&e->fit;}static bool Player(IEntity e){return e&&e->player;}static SCR_AIGroup Group(IEntity e){return e?e->group:nullptr;}};
struct ERR_EnemyEquipmentRules{static bool Eligible(ERR_GameMode*,SCR_AIGroup g,IEntity e){return g&&!g->slave&&!g->players&&g->faction==1&&ERR_Actors::CanFight(e)&&!e->player&&e->group==g;}};
struct SCR_FactionManager{static int SGetFaction(IEntity e){return e?e->faction:0;}};
struct CompartmentAccessComponent{static IEntity GetVehicleIn(IEntity e){return e?e->vehicle:nullptr;}};
struct ERR_ConvoyRules{inline static bool captured=false;static bool Captured(IEntity,SCR_AIGroup){return captured;}static bool PartOf(IEntity e,IEntity root){return e&&e==root;}};
struct ERR_InfantryAmmoAccess{inline static bool clear=true;static bool Clear(IEntity,IEntity){return clear;}};
struct ERR_ForceRules{static bool Finite(float n){return std::isfinite(n);}};
struct ERR_EnemyLoadoutCatalog{inline static string MINE="PMN4";};
struct EStoragePurpose{static const int PURPOSE_DEPOSIT=1;};
enum ERR_InfantryAmmoTransferState{FAILED=-1,PENDING,SUCCEEDED};
struct ScriptedInventoryOperationCallback{virtual ~ScriptedInventoryOperationCallback()=default;virtual void OnComplete(){}virtual void OnAllComplete(){}virtual void OnFailed(){}virtual void OnAllFailed(){}};
struct InventoryStorageManagerComponent{IEntity owner=nullptr;Array<IEntity>items;Array<BaseInventoryStorageComponent*>storages;BaseInventoryStorageComponent*destination=nullptr;bool capacity=true,accept=true;int calls=0;ScriptedInventoryOperationCallback*last=nullptr;std::function<void()>effect;
IEntity GetOwner(){return owner;}void GetItems(Array<IEntity>&a,int=0){a=items;}void GetStorages(Array<BaseInventoryStorageComponent*>&a,int){a=storages;}BaseInventoryStorageComponent*FindStorageForItem(IEntity,int){return destination;}
bool CanMoveItemToStorage(IEntity,BaseInventoryStorageComponent*,int){return capacity;}
bool TryMoveItemToStorage(IEntity,BaseInventoryStorageComponent*,int,ScriptedInventoryOperationCallback*cb){calls++;last=cb;if(effect)effect();return accept;}};
struct ERR_InfantryAmmoTransfer{
'''+cpp(stored)+r'''
};
'''+cpp(reservation)+r'''
struct ERR_InfantryMineTransfer;
struct ERR_InfantryMineCallback : ScriptedInventoryOperationCallback{ERR_InfantryMineTransfer*Transfer=nullptr;void OnComplete();void OnAllComplete();void OnFailed();void OnAllFailed();};
'''+cpp(s[s.index('class ERR_InfantryMineTransfer\n'):])+r'''
'''+''.join(cpp(body(P,'protected override void '+method+'(')).replace('void '+method+'(', 'void ERR_InfantryMineCallback::'+method+'(') for method in ('OnComplete','OnAllComplete','OnFailed','OnAllFailed'))+r'''
struct Fixture{ERR_GameMode mode;Ledger ledger;Group donorGroup,recipientGroup;ERR_ForceRecord donorRecord,recipientRecord;Entity truck,driver,actor,incoming,original,extra;InventoryStorageManagerComponent source,destination;BaseInventoryStorageComponent sourceStorage,destStorage;InventoryStorageSlot from,to,ownSlot,extraSlot;InventoryItemComponent inItem,ownItem,extraItem;Prefab prefab;SCR_PressureTriggerComponent inTrigger,ownTrigger,extraTrigger;SCR_AIVehicleUsageComponent usage;Seat seat;Physics physics;VehicleManager vehicleMgr;SCR_AIGroupUtilityComponent utility;ERR_HQStatusSampler roster;Array<IEntity>stock,spent;ERR_FiniteMagazineReservation reservation;
Fixture():reservation(&stock,&spent,&incoming){Replication::server=true;SCR_Global::edit=false;ERR_ConvoyRules::captured=false;ERR_InfantryAmmoAccess::clear=true;ERR_GameMode::current=&mode;mode.ledger=&ledger;
ledger.donor=&donorGroup;ledger.recipient=&recipientGroup;ledger.d=&donorRecord;ledger.r=&recipientRecord;donorRecord.Group=&donorGroup;recipientRecord.Group=&recipientGroup;
truck.inventory=&source;actor.inventory=&destination;truck.physics=&physics;truck.usage=&usage;usage.seat=&seat;seat.occupant=&driver;driver.vehicle=&truck;driver.group=&donorGroup;actor.group=&recipientGroup;donorGroup.utility=&utility;utility.m_VehicleMgr=&vehicleMgr;
source.owner=&truck;destination.owner=&actor;sourceStorage.owner=&truck;destStorage.owner=&actor;source.storages={&sourceStorage};destination.storages={&destStorage};destination.destination=&destStorage;
from.storage=&sourceStorage;from.attached=&incoming;to.storage=&destStorage;ownSlot.storage=&destStorage;ownSlot.attached=&original;extraSlot.storage=&destStorage;extraSlot.attached=&extra;
incoming.prefab=&prefab;incoming.trigger=&inTrigger;incoming.item=&inItem;inItem.slot=&from;original.prefab=&prefab;original.trigger=&ownTrigger;original.item=&ownItem;ownItem.slot=&ownSlot;extra.prefab=&prefab;extra.trigger=&extraTrigger;extra.item=&extraItem;extraItem.slot=&extraSlot;
source.items={&incoming};destination.items={&original};roster.group=&recipientGroup;roster.actor=&actor;stock={&incoming};assert(reservation.Reserve());}
ERR_InfantryMineTransfer Job(bool empty=false){return ERR_InfantryMineTransfer(&mode,&truck,&donorGroup,&actor,&recipientGroup,&incoming,&reservation,&roster,0,empty);}
void Move(){source.items.clear();destination.items.Insert(&incoming);from.attached=nullptr;to.attached=&incoming;inItem.slot=&to;}
};
int main(){
// Authoritative designation plus an inspected empty inventory permits exactly one finite replacement.
{Fixture f;f.destination.items.clear();auto t=f.Job(true);assert(t.Tick(0)==PENDING&&t.Submitted());f.Move();f.source.last->OnComplete();assert(t.Tick(1)==SUCCEEDED&&f.destination.items.Count()==1&&f.source.calls==1);}
for(int k=0;k<7;k++){Fixture f;f.destination.items.clear();
if(k==0)f.mode.hq.designated=false;if(k==1)f.destination.items.Insert(nullptr);if(k==2)f.destination.items.Insert(&f.original);if(k==3)f.destination.owner=&f.extra;if(k==4)f.destination.items.resize(129,&f.original);if(k==5){f.original.damage=false;f.destination.items.Insert(&f.original);}if(k==6)f.mode.command=false;
auto t=f.Job(true);assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.source.calls==0);}
// Empty/one mode never switches after dispatch; a foreign new mine or revoked entitlement aborts and retains uncertainty.
for(int k=0;k<2;k++){Fixture f;f.destination.items.clear();auto t=f.Job(true);t.Tick(0);if(k==0)f.destination.items.Insert(&f.original);if(k==1){f.mode.hq.designated=false;}assert(t.Tick(1)==FAILED&&t.Unresolved()&&f.source.calls==1);f.Move();f.source.last->OnComplete();assert(!t.Unresolved()&&t.Tick(2)==FAILED);}
{Fixture f;f.destination.items.clear();auto t=f.Job(true);t.Tick(0);t.Stop();f.Move();f.source.last->OnComplete();assert(!t.Unresolved()&&t.Tick(1)==FAILED&&f.source.calls==1&&!f.reservation.ReleaseUnsubmitted());}
{Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING&&t.Submitted()&&t.Unresolved()&&f.source.calls==1);assert(f.reservation.CommittedFor(&f.incoming)&&!f.reservation.ReleaseUnsubmitted());
f.source.last->OnComplete();assert(t.Tick(1)==PENDING&&t.Unresolved());f.Move();assert(t.Tick(2)==SUCCEEDED&&!t.Unresolved());assert(f.destination.items.Count()==2);t.Tick(3);assert(f.source.calls==1);}
// Partially constructed contexts never bind later or reach native mutation.
for(int k=0;k<10;k++){Fixture f;
if(k==4)f.mode.ledger=nullptr;if(k==5)f.ledger.d=nullptr;if(k==6)f.ledger.r=nullptr;if(k==7)f.seat.occupant=nullptr;
ERR_InfantryMineTransfer t(k==0?nullptr:&f.mode,k==1?nullptr:&f.truck,&f.donorGroup,k==2?nullptr:&f.actor,&f.recipientGroup,k==8?nullptr:&f.incoming,&f.reservation,k==3?nullptr:&f.roster,k==9?1:0);
assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.source.calls==0);}
// No entitlement for zero/two carriers, uncertain inventory, or replaced original mine.
for(int k=0;k<8;k++){Fixture f;if(k==0)f.destination.items.clear();if(k==1)f.destination.items.Insert(&f.extra);if(k==2)f.ownTrigger.active=true;if(k==3)f.ownTrigger.initial=true;if(k==4)f.ownItem.slot=nullptr;if(k==5)f.ownSlot.attached=&f.extra;if(k==6)f.destination.items.Insert(nullptr);if(k==7)f.destination.items.resize(129,&f.original);
auto t=f.Job();assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.source.calls==0&&f.reservation.ReleaseUnsubmitted());}
{Fixture f;auto t=f.Job();f.destination.items={&f.extra};assert(t.Tick(0)==FAILED&&f.source.calls==0);}
{Fixture f;f.extra.damage=false;f.destination.items.Insert(&f.extra);assert(!ERR_InfantryMineTransfer::Carrier(&f.actor,&f.recipientGroup));auto t=f.Job();assert(t.Tick(0)==FAILED&&f.source.calls==0);}
// Duplicates in native enumeration are one item, not a second entitlement.
{Fixture f;f.destination.items.Insert(&f.original);assert(ERR_InfantryMineTransfer::Carrier(&f.actor,&f.recipientGroup)==&f.original);}
// Atomic shared claim before native request, including synchronous callback and false return.
{Fixture f;f.source.accept=false;f.source.effect=[&]{assert(f.reservation.CommittedFor(&f.incoming)&&!f.reservation.ReleaseUnsubmitted());f.Move();f.source.last->OnComplete();};auto t=f.Job();assert(t.Tick(0)==SUCCEEDED&&!t.Unresolved()&&f.source.calls==1);}
{Fixture f;ERR_FiniteMagazineReservation rival(&f.stock,&f.spent,&f.incoming);assert(!rival.Reserve());auto t=f.Job();assert(t.Tick(0)==PENDING&&f.spent.Count()==1);}
{Fixture f;f.reservation.ReleaseUnsubmitted();auto t=f.Job();assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.source.calls==0);}
{Fixture f;f.source.accept=false;auto t=f.Job();assert(t.Tick(0)==FAILED&&t.Submitted()&&t.Unresolved());f.source.last->OnFailed();assert(!t.Unresolved()&&!f.reservation.ReleaseUnsubmitted());t.Tick(1);assert(f.source.calls==1);}
// Failure cannot release partial movement; late success is not permission to retry.
{Fixture f;auto t=f.Job();t.Tick(0);f.inItem.slot=&f.to;f.source.last->OnFailed();assert(t.Tick(1)==FAILED&&t.Unresolved());f.source.last->OnComplete();assert(t.Unresolved()&&f.source.calls==1);}
{Fixture f;auto t=f.Job();t.Tick(0);t.Stop();f.mode.active=false;f.Move();f.source.last->OnComplete();assert(!t.Unresolved()&&t.Tick(1)==FAILED&&f.source.calls==1);}
{Fixture f;auto t=f.Job();t.Tick(0);assert(t.Tick(8000)==FAILED&&t.Unresolved());f.Move();f.source.last->OnComplete();assert(!t.Unresolved()&&t.Tick(8001)==FAILED&&f.source.calls==1);}
{Fixture f;auto t=f.Job();t.Tick(10);assert(t.Tick(9)==FAILED&&t.Unresolved()&&f.source.calls==1);}
// Only deletion, not damage/capture, settles an unknown one-item movement.
{Fixture f;auto t=f.Job();t.Tick(0);t.m_Mine=nullptr;f.reservation.m_Item=nullptr;f.stock[0]=nullptr;f.spent[0]=nullptr;assert(t.Tick(1)==FAILED&&!t.Unresolved());f.source.last->OnComplete();assert(t.Tick(2)==FAILED&&!f.reservation.ReleaseUnsubmitted()&&f.spent.Count()==1);}
for(int k=0;k<3;k++){Fixture f;auto t=f.Job();t.Tick(0);if(k==0)f.incoming.alive=false;if(k==1)f.actor.player=true;if(k==2){ERR_ConvoyRules::captured=true;}assert(t.Tick(1)==FAILED&&t.Unresolved()&&f.source.calls==1);}
// Original actor/ledger/driver/managers/capacity/reach/stock all remain required.
for(int k=0;k<25;k++){Fixture f;auto t=f.Job();ERR_ForceRecord replacement;InventoryStorageManagerComponent changed;
switch(k){case 0:Replication::server=false;break;case 1:SCR_Global::edit=true;break;case 2:f.mode.active=false;break;case 3:ERR_GameMode::current=nullptr;break;case 4:f.roster.valid=false;break;case 5:f.roster.actor=&f.extra;break;case 6:f.roster.strength=2;break;case 7:f.actor.fit=false;break;case 8:f.actor.player=true;break;case 9:f.actor.vehicle=&f.truck;break;case 10:f.ledger.r=&replacement;break;case 11:f.donorRecord.Eliminated=true;break;case 12:f.vehicleMgr.found=false;break;case 13:f.seat.occupant=&f.extra;break;case 14:f.truck.inventory=&changed;break;case 15:f.actor.inventory=&changed;break;case 16:f.physics.speed.n=1;break;case 17:f.physics.angular.n=1;break;case 18:ERR_InfantryAmmoAccess::clear=false;break;case 19:f.source.capacity=false;break;case 20:f.destination.destination=nullptr;break;case 21:f.inTrigger.active=true;break;case 22:f.from.attached=&f.extra;break;case 23:f.source.items.clear();break;case 24:f.destination.items.Insert(&f.incoming);break;}
assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.source.calls==0);}
// Ownership lost after submission remains quarantined until exact physical proof.
{Fixture f;auto t=f.Job();t.Tick(0);f.roster.valid=false;assert(t.Tick(1)==FAILED&&t.Unresolved());f.Move();f.source.last->OnComplete();assert(!t.Unresolved()&&t.Tick(2)==FAILED);}
}
'''.replace(';if(', ';\n if('))
print('PASS: actual finite PMN4 designated-zero/one entitlement, pinned original ownership, shared commit, physical custody, callback quarantine/deletion and no retry')
@@ -0,0 +1,174 @@
"""Execute the exact original truck-to-courier pickup; no engine coverage claim."""
import os,re
from pathlib import Path
from policy_harness import ROOT,run
from test_finite_magazine_reservation import translated_reservation
p=Path(os.environ.get('ERR_MOUNTED_PICKUP_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_MountedAmmoPickup.c'))
s=p.read_text()
for forbidden in ('TrySpawn','SetAmmoCount','SetOrigin','SetTransform','DeleteEntity','TrySwap','TryInsert','TryRemove','PerformAction'):
assert forbidden not in s,forbidden
assert s.count('TryMoveItemToStorage(')==1
assert s.index('m_Reservation.Commit()') < s.index('TryMoveItemToStorage(')
code=s[s.index('class ERR_MountedAmmoPickup\n'):]
code=re.sub(r'//[^\n]*','',code).replace('protected ','').replace('notnull ','').replace('ref ','').replace('class ','struct ')
code=code.replace('void ERR_MountedAmmoPickup(','ERR_MountedAmmoPickup(')
code=code.replace('array<','Array<').replace('null','nullptr')
# Only engine component lookup/casts are doubled; all transaction methods execute.
cast_types={'InventoryItemComponent':'item','BaseMagazineComponent':'magazine','InventoryStorageManagerComponent':'inventory'}
for kind,field in cast_types.items():
code=re.sub(kind+r'\.Cast\(([^;\n]*?)\.FindComponent\('+kind+r'\)\)',lambda m:m[1]+'.'+field,code)
code=code.replace('WeaponSlotComponent.Cast(m_WeaponSlot.GetParentContainer())','dynamic_cast<Mount*>(m_WeaponSlot.GetParentContainer())')
code=code.replace('ERR_HQ.Cast(m_Mode.Command())','m_Mode.Command()').replace('ChimeraCharacter.Cast(m_Worker)','m_Worker')
for name in ('ERR_GameMode','ERR_MountedAmmoTransferState','ERR_ForceRules','ERR_Actors','ERR_ConvoyRules','ERR_EnemyEquipmentRules','ERR_InfantryAmmoTransfer','Replication','SCR_Global','CompartmentAccessComponent','EMuzzleType','EStoragePurpose','vector','TraceFlags','ERR_InfantryAmmoAccess'):
code=code.replace(name+'.',name+'::')
for name in ('m_Mode','mode','task','originalRoster','m_Task','m_Receipt','m_Donor','m_Target','m_Truck','m_Root','m_DonorRecord','m_TargetRecord','m_Roster','m_Weapon','m_WeaponSlot','m_Muzzle','m_Loaded','m_Incoming','m_Mount','m_FromStorage','m_ToStorage','m_OldMagazine','m_NewMagazine','m_Carried','m_TruckInventory','m_Reservation','m_Callback','m_Worker','gunItem','loadedItem','incomingItem','gun','item','hq','vehicle','entity','slot','inventory','magazine','character','trace','m_FromSlot','m_ToSlot','m_Destination','owner','storage'):
code=re.sub(r'\b'+name+r'\.',name+'->',code)
code=code.replace(').',' )->')
# Physics/vector return values, unlike components, are not pointers.
code=code.replace('GetVelocity( )->Length()', 'GetVelocity().Length()').replace('GetAngularVelocity( )->Length()', 'GetAngularVelocity().Length()')
code=code.replace('ERR_FiniteMagazineReservation m_Reservation','ERR_FiniteMagazineReservation* m_Reservation').replace('ERR_FiniteMagazineReservation pickupReservation','ERR_FiniteMagazineReservation* pickupReservation')
code=code.replace('ERR_MountedPickupCallback m_Callback','ERR_MountedPickupCallback* m_Callback')
code=code.replace('TraceParam trace = new TraceParam()', 'TraceParam* trace = new TraceParam()')
code=code.replace('TraceMove(trace, AccessFilter)', 'TraceMove(trace, [this](IEntity e){return AccessFilter(e);})')
code=re.sub(r'\b(bool|int|IEntity|Vehicle|ERR_GameMode|ERR_ConvoyTask|ERR_ConvoyReceipt|ERR_ConvoyVehicle|SCR_AIGroup|ERR_ForceRecord|ERR_HQStatusSampler|BaseWeaponComponent|WeaponSlotComponent|InventoryStorageSlot|BaseMuzzleComponent|BaseMagazineComponent|BaseInventoryStorageComponent|InventoryStorageManagerComponent|ERR_FiniteMagazineReservation\*|ERR_MountedPickupCallback\*) (\w+);',r'\1 \2{};',code)
code=code.replace('\n}\n','\n};\n')
callbacks=[]
for name in ('OnComplete','OnAllComplete','OnFailed','OnAllFailed'):
m=re.search('protected override void '+name+r'\(\) (\{[^\n]+\})',s)
callbacks.append('void ERR_MountedPickupCallback::'+name+'() '+m[1].replace('Transfer.','Transfer->'))
pre=r'''
#include <cassert>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <limits>
using string=std::string;
template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}bool Contains(T x){return std::find(this->begin(),this->end(),x)!=this->end();}void Insert(T x){this->push_back(x);}void RemoveItem(T x){this->erase(std::remove(this->begin(),this->end(),x),this->end());}};
struct vector{float x=0,y=0,z=0;float Length(){return std::sqrt(x*x+y*y+z*z);}static float Distance(vector a,vector b){return vector{a.x-b.x,a.y-b.y,a.z-b.z}.Length();}};
struct Entity;struct Group;struct Mode;struct Task;struct Receipt;struct ConvoyVehicle;struct Record;struct Roster;struct Weapon;struct Mount;struct Slot;struct Muzzle;struct Magazine;struct Storage;struct Inventory;struct HQ;
using IEntity=Entity*;using Vehicle=Entity*;using ChimeraCharacter=Entity*;using SCR_AIGroup=Group*;using ERR_GameMode=Mode*;using ERR_ConvoyTask=Task*;using ERR_ConvoyReceipt=Receipt*;using ERR_ConvoyVehicle=ConvoyVehicle*;using ERR_ForceRecord=Record*;using ERR_HQStatusSampler=Roster*;using BaseWeaponComponent=Weapon*;using WeaponSlotComponent=Mount*;using InventoryStorageSlot=Slot*;using BaseMuzzleComponent=Muzzle*;using BaseMagazineComponent=Magazine*;using BaseInventoryStorageComponent=Storage*;using InventoryStorageManagerComponent=Inventory*;using ERR_HQ=HQ*;
struct Component{virtual ~Component()=default;};
struct Item{Slot*slot=nullptr;Slot*GetParentSlot(){return slot;}};using InventoryItemComponent=Item*;
struct Physics{vector velocity,angular;vector GetVelocity(){return velocity;}vector GetAngularVelocity(){return angular;}};
struct Entity{Entity*parent=nullptr;bool alive=true,eligible=true,awake=true;IEntity seated=nullptr;Item*item=nullptr;Magazine*magazine=nullptr;Inventory*inventory=nullptr;Physics*physics=nullptr;vector position;Physics*GetPhysics(){return physics;}vector GetOrigin(){return position;}vector AimingPosition(){return position;}};
struct Slot{Storage*storage=nullptr;Component*container=nullptr;IEntity attached=nullptr;bool locked=false;vector point{1,0,0};Storage*GetStorage(){return storage;}Component*GetParentContainer(){return container;}IEntity GetAttachedEntity(){return attached;}bool IsLocked(){return locked;}void GetWorldTransform(vector mat[4]){mat[3]=point;}};
struct Storage{IEntity owner=nullptr;IEntity GetOwner(){return owner;}};
struct Well{int type=1;int Type(){return type;}bool IsInherited(int t){return t==type;}};
struct Magazine{IEntity owner=nullptr;Well*well=nullptr;int rounds=100,capacity=100;bool used=false;IEntity GetOwner(){return owner;}Well*GetMagazineWell(){return well;}int GetAmmoCount(){return rounds;}int GetMaxAmmoCount(){return capacity;}bool IsUsed(){return used;}};
struct Muzzle:Component{IEntity owner=nullptr;Magazine*mag=nullptr;Well*well=nullptr;int kind=0;IEntity GetOwner(){return owner;}Magazine*GetMagazine(){return mag;}Well*GetMagazineWell(){return well;}int GetMuzzleType(){return kind;}};
struct Weapon{IEntity owner=nullptr;Array<Muzzle*>muzzles;IEntity GetOwner(){return owner;}void GetMuzzlesList(Array<Muzzle*>&a){a=muzzles;}};
struct Mount:Component{IEntity owner=nullptr;IEntity gun=nullptr;Slot*slot=nullptr;IEntity GetOwner(){return owner;}IEntity GetWeaponEntity(){return gun;}Slot*GetSlotInfo(){return slot;}};
struct Group{};
struct Record{string Id;};
struct Ledger{SCR_AIGroup donor=nullptr,target=nullptr;Record*d=nullptr,*t=nullptr;Record*FindGroup(SCR_AIGroup g){return g==donor?d:g==target?t:nullptr;}};
struct HQ{bool valid=true;bool ValidateBoundVehicle(SCR_AIGroup g,IEntity e){return valid&&g&&e;}};
struct Mode{inline static Mode*current=nullptr;bool active=true;Ledger*ledger=nullptr;HQ*hq=nullptr;static Mode*Get(){return current;}bool Active(){return active;}Ledger*Forces(){return ledger;}HQ*Command(){return hq;}};
struct Receipt{bool Consumed=true;Array<string>Records;};
struct ConvoyVehicle{int Index=0;IEntity Entity=nullptr;SCR_AIGroup Group=nullptr;bool Released=false,Registered=true,crew=true,Arrived=false;IEntity Driver=nullptr;Array<IEntity>Members;bool CrewValid(ERR_GameMode){return crew;}};
struct Task{bool Ready=true,Stopped=false;ERR_ConvoyReceipt Receipt=nullptr;Array<ERR_ConvoyVehicle>Vehicles;};
struct Roster{SCR_AIGroup group=nullptr;IEntity root=nullptr,worker=nullptr;bool valid=true;IEntity InitialMember(int slot){return slot==1?worker:nullptr;}bool OwnsRoster(SCR_AIGroup g){return valid&&g==group;}bool ValidateBoundVehicle(IEntity e){return valid&&e==root;}bool CanAttribute(int slot,IEntity e,bool observe){assert(!observe);return valid&&slot==1&&e==worker;}};
struct Replication{inline static bool server=true;static bool IsServer(){return server;}};struct SCR_Global{inline static bool editor=false;static bool IsEditMode(){return editor;}};
struct ERR_Actors{static bool Alive(IEntity e){return e&&e->alive;}static bool CanFight(IEntity e){return e&&e->alive&&e->awake;}};
struct ERR_ConvoyRules{static bool PartOf(IEntity e,IEntity root){for(int i=0;e&&i<32;i++,e=e->parent)if(e==root)return true;return false;}};
struct ERR_InfantryAmmoTransfer{static bool StoredUnder(IEntity e,IEntity root){return ERR_ConvoyRules::PartOf(e,root);}};
struct ERR_EnemyEquipmentRules{static bool Eligible(ERR_GameMode m,SCR_AIGroup g,IEntity e){return m&&g&&e&&e->eligible;}};
struct CompartmentAccessComponent{static IEntity GetVehicleIn(IEntity e){return e?e->seated:nullptr;}};
struct ERR_ForceRules{static bool Finite(float x){return std::isfinite(x);}static bool FiniteVector(vector v){return Finite(v.x)&&Finite(v.y)&&Finite(v.z);}};
struct EMuzzleType{static const int MT_BaseMuzzle=0;};struct EStoragePurpose{static const int PURPOSE_DEPOSIT=1;};
struct TraceParam{vector Start,End;int Flags=0,LayerMask=0;};struct TraceFlags{static const int WORLD=1,ENTS=2;};const int TRACE_LAYER_CAMERA=4;
struct World{float fraction=1;Array<IEntity>blockers;int calls=0;float TraceMove(TraceParam*t,std::function<bool(IEntity)>filter){assert(t->Flags==3&&t->LayerMask==4);calls++;for(auto*e:blockers)if(filter(e))return 0;return fraction;}};
struct Game{World*world=nullptr;World*GetWorld(){return world;}};Game*game=nullptr;Game*GetGame(){return game;}
struct ScriptedInventoryOperationCallback{virtual void OnComplete(){}virtual void OnAllComplete(){}virtual void OnFailed(){}virtual void OnAllFailed(){}virtual ~ScriptedInventoryOperationCallback()=default;};
struct ERR_MountedAmmoPickup;
struct ERR_MountedPickupCallback:ScriptedInventoryOperationCallback{ERR_MountedAmmoPickup*Transfer=nullptr;void OnComplete()override;void OnAllComplete()override;void OnFailed()override;void OnAllFailed()override;};
struct Inventory{IEntity owner=nullptr;Array<IEntity>items;Array<Storage*>storages;Storage*selected=nullptr;bool allow=true,accept=true;int queries=0,calls=0,ack=0;ScriptedInventoryOperationCallback*last=nullptr;std::function<void()>effect;
IEntity GetOwner(){return owner;}void GetItems(Array<IEntity>&a,int p){assert(p==1);a=items;}void GetStorages(Array<Storage*>&a,int p){assert(p==1);a=storages;}
Storage*FindStorageForItem(IEntity,int p){assert(p==1);return selected;}
bool CanMoveItemToStorage(IEntity a,Storage*b,int slot){assert(a&&b&&slot==-1);queries++;return allow;}
bool TryMoveItemToStorage(IEntity a,Storage*b,int slot,ScriptedInventoryOperationCallback*cb){assert(a&&b&&slot==-1);calls++;last=cb;if(effect)effect();if(ack==1)cb->OnComplete();if(ack==-1)cb->OnFailed();return accept;}
bool CanSwapItemStorages(IEntity a,IEntity b){assert(a&&b&&a!=b);queries++;return allow;}
bool TrySwapItemStorages(IEntity a,IEntity b,ScriptedInventoryOperationCallback*cb){assert(a&&b&&a!=b);calls++;last=cb;if(effect)effect();if(ack==1)cb->OnComplete();if(ack==-1)cb->OnFailed();return accept;}};
enum ERR_MountedAmmoTransferState{FAILED=-1,PENDING,SUCCEEDED};
struct ERR_InfantryAmmoAccess{inline static bool clear=true;static bool Clear(Vehicle v,IEntity e){return v&&e&&clear;}};
'''
code=code.replace('ERR_GameMode::Get()', 'Mode::Get()')
main=r'''
struct Fixture{
Mode mode;Ledger ledger;HQ hq;Group dg,tg;Record dr{"donor"},tr{"target"};Receipt receipt;Task task;ConvoyVehicle donor,target;Roster roster;
Entity truck,root,worker,driver,targetDriver,gun,loaded,incoming,foreign;Physics dp,tp;Item gunItem,oldItem,newItem;Slot weaponSlot,fromSlot,toSlot,carrySlot;Storage truckStorage,carryStorage,gunStorage;Inventory carried,truckInventory;
Well well;Weapon weapon;Mount mount;Muzzle muzzle;Magazine oldMag,newMag;Array<IEntity>stock,spent;ERR_FiniteMagazineReservation reservation;
Fixture():reservation(&stock,&spent,&incoming){Mode::current=&mode;mode.ledger=&ledger;mode.hq=&hq;ledger.donor=&dg;ledger.target=&tg;ledger.d=&dr;ledger.t=&tr;
receipt.Records={"target","donor","2","3","4","5"};task.Receipt=&receipt;task.Vehicles.resize(6,nullptr);task.Vehicles[0]=&target;task.Vehicles[1]=&donor;
donor.Index=1;donor.Entity=&truck;donor.Group=&dg;donor.Driver=&driver;target.Entity=&root;target.Group=&tg;target.Driver=&targetDriver;target.Members={&worker,&targetDriver};truck.physics=&dp;root.physics=&tp;
roster.group=&tg;roster.root=&root;roster.worker=&worker;gun.parent=&root;loaded.parent=&gun;gun.item=&gunItem;loaded.item=&oldItem;incoming.item=&newItem;
gunItem.slot=&weaponSlot;oldItem.slot=&toSlot;newItem.slot=&fromSlot;weaponSlot.attached=&gun;weaponSlot.container=&mount;mount.slot=&weaponSlot;mount.gun=&gun;mount.owner=&root;
weapon.owner=&gun;weapon.muzzles={&muzzle};muzzle.owner=&gun;muzzle.mag=&oldMag;muzzle.well=&well;oldMag.owner=&loaded;oldMag.rounds=25;oldMag.used=true;newMag.owner=&incoming;oldMag.well=&well;newMag.well=&well;
loaded.magazine=&oldMag;incoming.magazine=&newMag;toSlot.attached=&loaded;toSlot.container=&muzzle;toSlot.storage=&gunStorage;gunStorage.owner=&gun;
fromSlot.attached=&incoming;fromSlot.storage=&truckStorage;truckStorage.owner=&truck;carrySlot.storage=&carryStorage;carryStorage.owner=&worker;
carried.owner=&worker;carried.storages={&carryStorage};carried.selected=&carryStorage;worker.inventory=&carried;
truckInventory.owner=&truck;truckInventory.items={&incoming};truckInventory.storages={&truckStorage};truck.inventory=&truckInventory;stock={&incoming};assert(reservation.Reserve());ERR_InfantryAmmoAccess::clear=true;}
ERR_MountedAmmoPickup Job(){return ERR_MountedAmmoPickup(&mode,&task,0,&roster,1,&weapon,&muzzle,&loaded,&incoming,&reservation);}
void Move(){fromSlot.attached=nullptr;carrySlot.attached=&incoming;newItem.slot=&carrySlot;truckInventory.items.clear();carried.items={&incoming};}
};
int main(){
// No personal firearm exists in the fixture: compatibility is the pinned mounted muzzle.
{Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING&&t.Submitted()&&t.Unresolved());assert(f.truckInventory.calls==1&&f.reservation.CommittedFor(&f.incoming));
f.truckInventory.last->OnComplete();assert(t.Tick(1)==PENDING&&t.Unresolved());f.Move();assert(t.Tick(2)==SUCCEEDED&&!t.Unresolved());
assert(t.Tick(9000)==SUCCEEDED&&f.truckInventory.calls==1&&f.spent.Count()==1&&f.oldMag.rounds==25&&f.newMag.rounds==100);}
{Fixture f;auto t=f.Job();t.Tick(0);f.Move();assert(t.Tick(1)==PENDING);f.truckInventory.last->OnAllComplete();assert(t.Tick(2)==SUCCEEDED);}
// Authored cargo access can be reachable beyond four metres from the vehicle origin.
{Fixture f;f.worker.position={-1,0,5};auto t=f.Job();assert(t.Tick(0)==PENDING&&t.Submitted());}
// A valid original convoy remains serviceable at a stationary route endpoint.
{Fixture f;f.donor.Arrived=true;f.target.Arrived=true;auto t=f.Job();assert(t.Tick(0)==PENDING&&t.Submitted());}
// The shared reservation is irrevocable before entering a synchronously-calling engine.
{Fixture f;f.truckInventory.accept=false;f.truckInventory.ack=1;f.truckInventory.effect=[&]{assert(f.reservation.CommittedFor(&f.incoming));assert(!f.reservation.ReleaseUnsubmitted());f.Move();};auto t=f.Job();assert(t.Tick(0)==SUCCEEDED&&!t.Unresolved());}
{Fixture f;auto a=f.Job();auto b=f.Job();assert(a.Tick(0)==PENDING&&b.Tick(0)==FAILED&&!b.Submitted()&&f.truckInventory.calls==1);}
{Fixture f;f.truckInventory.accept=false;auto t=f.Job();assert(t.Tick(0)==FAILED&&t.Submitted()&&t.Unresolved()&&!f.reservation.ReleaseUnsubmitted());f.truckInventory.last->OnFailed();assert(!t.Unresolved());assert(t.Tick(1)==FAILED&&f.truckInventory.calls==1);}
// Failure beats success; partial movement remains quarantined even after failure callback.
{Fixture f;auto t=f.Job();t.Tick(0);f.truckInventory.last->OnComplete();f.truckInventory.last->OnFailed();assert(t.Tick(1)==FAILED&&!t.Unresolved());f.truckInventory.last->OnAllComplete();assert(t.Tick(2)==FAILED);}
{Fixture f;auto t=f.Job();t.Tick(0);f.newItem.slot=&f.carrySlot;f.truckInventory.last->OnFailed();assert(t.Tick(1)==FAILED&&t.Unresolved());}
{Fixture f;auto t=f.Job();t.Stop();assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.truckInventory.calls==0&&f.reservation.ReleaseUnsubmitted());}
{Fixture f;auto t=f.Job();t.Tick(0);t.Stop();f.mode.active=false;f.Move();f.truckInventory.last->OnComplete();assert(!t.Unresolved()&&t.Tick(1)==FAILED&&f.truckInventory.calls==1);}
{Fixture f;auto t=f.Job();t.Tick(0);assert(t.Tick(8000)==FAILED&&t.Unresolved()&&f.truckInventory.calls==1);}
{Fixture f;auto t=f.Job();t.Tick(10);assert(t.Tick(9)==FAILED&&t.Unresolved()&&f.truckInventory.calls==1);}
// Native deletion clears the weak exact identity: no item can arrive later.
// Retain the spent slot, do not count delivery, and never retry on late callbacks.
{Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING&&t.Unresolved());
t.m_Incoming=nullptr;f.reservation.m_Item=nullptr;f.stock[0]=nullptr;f.spent[0]=nullptr;
f.fromSlot.attached=nullptr;f.truckInventory.items.clear();
assert(t.Tick(1)==FAILED&&!t.Unresolved()&&f.spent.Count()==1&&!f.reservation.ReleaseUnsubmitted());
f.truckInventory.last->OnComplete();f.truckInventory.last->OnFailed();
assert(t.Tick(2)==FAILED&&!t.Unresolved()&&f.truckInventory.calls==1&&f.spent.Count()==1);}
// Damage, worker loss, source capture and a moved-but-existing item remain uncertain.
for(int k=0;k<4;k++){Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING);
if(k==0){f.incoming.alive=false;}if(k==1){t.m_Worker=nullptr;}
if(k==2){f.donor.Released=true;}if(k==3){f.truckInventory.items.clear();f.newItem.slot=nullptr;}
t.Stop();assert(t.Unresolved()&&t.Tick(1)==FAILED&&f.truckInventory.calls==1);}
// Original identity, carried capacity and source access losses fail before any submission.
for(int k=0;k<43;k++){Fixture f;auto t=f.Job();
switch(k){case 0:f.task.Stopped=true;break;case 1:f.task.Ready=false;break;case 2:f.donor.Released=true;break;case 3:f.target.Released=true;break;
case 4:f.receipt.Consumed=false;break;case 5:f.roster.valid=false;break;case 6:f.worker.seated=&f.root;break;case 7:f.worker.awake=false;break;
case 8:f.worker.eligible=false;break;case 9:f.hq.valid=false;break;case 10:f.dp.velocity.x=.3;break;case 11:f.tp.angular.x=.2;break;
case 12:f.target.crew=false;break;case 13:f.mount.gun=&f.foreign;break;case 14:f.muzzle.mag=nullptr;break;case 15:f.fromSlot.locked=true;break;
case 16:f.oldItem.slot=nullptr;break;case 17:f.newMag.used=true;break;case 18:f.oldMag.rounds=26;break;case 19:f.newMag.rounds=25;break;
case 20:f.newMag.capacity=0;break;case 21:f.oldMag.rounds=-1;break;case 22:f.newMag.rounds=101;break;case 23:f.truckInventory.allow=false;break;
case 24:f.truckInventory.items.clear();break;case 25:f.truckInventory.items.resize(129,&f.foreign);break;case 26:f.carried.storages.resize(65,&f.gunStorage);break;
case 27:f.gunStorage.owner=&f.foreign;break;case 28:f.fromSlot.storage=&f.gunStorage;break;case 29:f.task.Vehicles[0]=&f.donor;break;
case 30:f.worker.inventory=&f.truckInventory;break;case 31:f.weapon.muzzles.resize(9,&f.muzzle);break;case 32:f.ledger.t=&f.dr;break;case 33:f.target.Members.clear();break;
case 34:f.carried.selected=nullptr;break;case 35:ERR_InfantryAmmoAccess::clear=false;break;case 36:f.donor.Registered=false;break;
case 37:f.donor.Driver=&f.foreign;break;case 38:f.target.Driver=&f.foreign;break;case 39:f.target.Registered=false;break;
case 40:f.carried.items={&f.incoming};break;case 41:f.carried.selected=&f.gunStorage;break;case 42:f.toSlot.locked=true;break;}
assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.truckInventory.calls==0&&f.spent.Count()==1&&f.reservation.ReleaseUnsubmitted());}
// Loss while pending is terminal; a late exact receipt settles quarantine without resuming.
for(int k=0;k<5;k++){Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING);switch(k){case 0:f.task.Stopped=true;break;case 1:f.roster.valid=false;break;case 2:f.mode.active=false;break;case 3:f.target.Driver=&f.foreign;break;case 4:f.muzzle.mag=nullptr;break;}
assert(t.Tick(1)==FAILED&&t.Unresolved());f.Move();f.truckInventory.last->OnComplete();assert(!t.Unresolved()&&t.Tick(2)==FAILED&&f.truckInventory.calls==1);}
// Invalid construction cannot reach inventory mutation.
for(int k=0;k<9;k++){Fixture f;switch(k){case 0:f.donor.Entity=nullptr;break;case 1:f.target.Entity=nullptr;break;case 2:f.task.Vehicles[1]=nullptr;break;case 3:f.task.Vehicles[0]=nullptr;break;
case 4:f.roster.worker=nullptr;break;case 5:f.gun.item=nullptr;break;case 6:f.incoming.item=nullptr;break;case 7:f.loaded.item=nullptr;break;case 8:f.target.Driver=&f.worker;break;}
auto t=f.Job();assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.truckInventory.calls==0);}
}
'''
run(pre+translated_reservation()+code+'\n'+'\n'.join(callbacks)+main)
print('PASS: actual mounted pickup, exact finite ownership, pre-submission commit, physical custody, bounded callback and quarantine lifecycle; no native coverage claim')
@@ -0,0 +1,184 @@
"""Execute the proposed exact carried-to-mounted swap; no engine coverage claim."""
import os,re
from pathlib import Path
from policy_harness import ROOT,run
from test_finite_magazine_reservation import translated_reservation
p=Path(os.environ.get('ERR_MOUNTED_TRANSFER_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_MountedAmmoTransfer.c'))
s=p.read_text()
for forbidden in ('TrySpawn','SetAmmoCount','SetOrigin','SetTransform','DeleteEntity','TryMove','TryInsert','TryRemove','PerformAction'):
assert forbidden not in s,forbidden
assert s.count('TrySwapItemStorages(')==1
code=s[s.index('class ERR_MountedAmmoTransfer\n'):]
code=re.sub(r'//[^\n]*','',code).replace('protected ','').replace('notnull ','').replace('ref ','').replace('class ','struct ')
code=code.replace('void ERR_MountedAmmoTransfer(','ERR_MountedAmmoTransfer(')
code=code.replace('array<','Array<').replace('null','nullptr')
# Only engine component lookup/casts are doubled; all transaction methods execute.
cast_types={'InventoryItemComponent':'item','BaseMagazineComponent':'magazine','InventoryStorageManagerComponent':'inventory'}
for kind,field in cast_types.items():
code=re.sub(kind+r'\.Cast\(([^;\n]*?)\.FindComponent\('+kind+r'\)\)',lambda m:m[1]+'.'+field,code)
code=code.replace('WeaponSlotComponent.Cast(m_WeaponSlot.GetParentContainer())','dynamic_cast<Mount*>(m_WeaponSlot.GetParentContainer())')
code=code.replace('ERR_HQ.Cast(m_Mode.Command())','m_Mode.Command()').replace('ChimeraCharacter.Cast(m_Worker)','m_Worker')
for name in ('ERR_GameMode','ERR_MountedAmmoTransferState','ERR_ForceRules','ERR_Actors','ERR_ConvoyRules','ERR_EnemyEquipmentRules','ERR_InfantryAmmoTransfer','Replication','SCR_Global','CompartmentAccessComponent','EMuzzleType','EStoragePurpose','vector','TraceFlags'):
code=code.replace(name+'.',name+'::')
for name in ('m_Mode','mode','task','originalRoster','m_Task','m_Receipt','m_Donor','m_Target','m_Truck','m_Root','m_DonorRecord','m_TargetRecord','m_Roster','m_Weapon','m_WeaponSlot','m_Muzzle','m_Loaded','m_Incoming','m_Mount','m_FromStorage','m_ToStorage','m_OldMagazine','m_NewMagazine','m_Carried','m_TruckInventory','m_Reservation','m_Callback','m_Worker','gunItem','loadedItem','incomingItem','gun','item','hq','vehicle','entity','slot','inventory','magazine','character','trace','m_FromSlot','m_ToSlot'):
code=re.sub(r'\b'+name+r'\.',name+'->',code)
code=code.replace(').',' )->')
# Physics/vector return values, unlike components, are not pointers.
code=code.replace('GetVelocity( )->Length()', 'GetVelocity().Length()').replace('GetAngularVelocity( )->Length()', 'GetAngularVelocity().Length()')
code=code.replace('ERR_FiniteMagazineReservation m_Reservation','ERR_FiniteMagazineReservation* m_Reservation').replace('ERR_FiniteMagazineReservation committedPickup','ERR_FiniteMagazineReservation* committedPickup')
code=code.replace('ERR_MountedAmmoCallback m_Callback','ERR_MountedAmmoCallback* m_Callback')
code=code.replace('TraceParam trace = new TraceParam()', 'TraceParam* trace = new TraceParam()')
code=code.replace('TraceMove(trace, AccessFilter)', 'TraceMove(trace, [this](IEntity e){return AccessFilter(e);})')
code=re.sub(r'\b(bool|int|IEntity|Vehicle|ERR_GameMode|ERR_ConvoyTask|ERR_ConvoyReceipt|ERR_ConvoyVehicle|SCR_AIGroup|ERR_ForceRecord|ERR_HQStatusSampler|BaseWeaponComponent|WeaponSlotComponent|InventoryStorageSlot|BaseMuzzleComponent|BaseMagazineComponent|BaseInventoryStorageComponent|InventoryStorageManagerComponent|ERR_FiniteMagazineReservation\*|ERR_MountedAmmoCallback\*) (\w+);',r'\1 \2{};',code)
code=code.replace('\n}\n','\n};\n')
callbacks=[]
for name in ('OnComplete','OnAllComplete','OnFailed','OnAllFailed'):
m=re.search('protected override void '+name+r'\(\) (\{[^\n]+\})',s)
callbacks.append('void ERR_MountedAmmoCallback::'+name+'() '+m[1].replace('Transfer.','Transfer->'))
pre=r'''
#include <cassert>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <limits>
using string=std::string;
template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}bool Contains(T x){return std::find(this->begin(),this->end(),x)!=this->end();}void Insert(T x){this->push_back(x);}void RemoveItem(T x){this->erase(std::remove(this->begin(),this->end(),x),this->end());}};
struct vector{float x=0,y=0,z=0;float Length(){return std::sqrt(x*x+y*y+z*z);}static float Distance(vector a,vector b){return vector{a.x-b.x,a.y-b.y,a.z-b.z}.Length();}};
struct Entity;struct Group;struct Mode;struct Task;struct Receipt;struct ConvoyVehicle;struct Record;struct Roster;struct Weapon;struct Mount;struct Slot;struct Muzzle;struct Magazine;struct Storage;struct Inventory;struct HQ;
using IEntity=Entity*;using Vehicle=Entity*;using ChimeraCharacter=Entity*;using SCR_AIGroup=Group*;using ERR_GameMode=Mode*;using ERR_ConvoyTask=Task*;using ERR_ConvoyReceipt=Receipt*;using ERR_ConvoyVehicle=ConvoyVehicle*;using ERR_ForceRecord=Record*;using ERR_HQStatusSampler=Roster*;using BaseWeaponComponent=Weapon*;using WeaponSlotComponent=Mount*;using InventoryStorageSlot=Slot*;using BaseMuzzleComponent=Muzzle*;using BaseMagazineComponent=Magazine*;using BaseInventoryStorageComponent=Storage*;using InventoryStorageManagerComponent=Inventory*;using ERR_HQ=HQ*;
struct Component{virtual ~Component()=default;};
struct Item{Slot*slot=nullptr;Slot*GetParentSlot(){return slot;}};using InventoryItemComponent=Item*;
struct Physics{vector velocity,angular;vector GetVelocity(){return velocity;}vector GetAngularVelocity(){return angular;}};
struct Entity{Entity*parent=nullptr;bool alive=true,eligible=true,awake=true;IEntity seated=nullptr;Item*item=nullptr;Magazine*magazine=nullptr;Inventory*inventory=nullptr;Physics*physics=nullptr;vector position;Physics*GetPhysics(){return physics;}vector AimingPosition(){return position;}};
struct Slot{Storage*storage=nullptr;Component*container=nullptr;IEntity attached=nullptr;bool locked=false;vector point{1,0,0};Storage*GetStorage(){return storage;}Component*GetParentContainer(){return container;}IEntity GetAttachedEntity(){return attached;}bool IsLocked(){return locked;}void GetWorldTransform(vector mat[4]){mat[3]=point;}};
struct Storage{IEntity owner=nullptr;IEntity GetOwner(){return owner;}};
struct Well{int type=1;int Type(){return type;}bool IsInherited(int t){return t==type;}};
struct Magazine{IEntity owner=nullptr;Well*well=nullptr;int rounds=100,capacity=100;bool used=false;IEntity GetOwner(){return owner;}Well*GetMagazineWell(){return well;}int GetAmmoCount(){return rounds;}int GetMaxAmmoCount(){return capacity;}bool IsUsed(){return used;}};
struct Muzzle:Component{IEntity owner=nullptr;Magazine*mag=nullptr;Well*well=nullptr;int kind=0;IEntity GetOwner(){return owner;}Magazine*GetMagazine(){return mag;}Well*GetMagazineWell(){return well;}int GetMuzzleType(){return kind;}};
struct Weapon{IEntity owner=nullptr;Array<Muzzle*>muzzles;IEntity GetOwner(){return owner;}void GetMuzzlesList(Array<Muzzle*>&a){a=muzzles;}};
struct Mount:Component{IEntity owner=nullptr;IEntity gun=nullptr;Slot*slot=nullptr;IEntity GetOwner(){return owner;}IEntity GetWeaponEntity(){return gun;}Slot*GetSlotInfo(){return slot;}};
struct Group{};
struct Record{string Id;};
struct Ledger{SCR_AIGroup donor=nullptr,target=nullptr;Record*d=nullptr,*t=nullptr;Record*FindGroup(SCR_AIGroup g){return g==donor?d:g==target?t:nullptr;}};
struct HQ{bool valid=true;bool ValidateBoundVehicle(SCR_AIGroup g,IEntity e){return valid&&g&&e;}};
struct Mode{inline static Mode*current=nullptr;bool active=true;Ledger*ledger=nullptr;HQ*hq=nullptr;static Mode*Get(){return current;}bool Active(){return active;}Ledger*Forces(){return ledger;}HQ*Command(){return hq;}};
struct Receipt{bool Consumed=true;Array<string>Records;};
struct ConvoyVehicle{int Index=0;IEntity Entity=nullptr;SCR_AIGroup Group=nullptr;bool Released=false,Registered=true,crew=true;Array<IEntity>Members;bool CrewValid(ERR_GameMode){return crew;}};
struct Task{bool Ready=true,Stopped=false;ERR_ConvoyReceipt Receipt=nullptr;Array<ERR_ConvoyVehicle>Vehicles;};
struct Roster{SCR_AIGroup group=nullptr;IEntity root=nullptr,worker=nullptr;bool valid=true;IEntity InitialMember(int slot){return slot==1?worker:nullptr;}bool OwnsRoster(SCR_AIGroup g){return valid&&g==group;}bool ValidateBoundVehicle(IEntity e){return valid&&e==root;}bool CanAttribute(int slot,IEntity e,bool observe){assert(!observe);return valid&&slot==1&&e==worker;}};
struct Replication{inline static bool server=true;static bool IsServer(){return server;}};struct SCR_Global{inline static bool editor=false;static bool IsEditMode(){return editor;}};
struct ERR_Actors{static bool Alive(IEntity e){return e&&e->alive;}static bool CanFight(IEntity e){return e&&e->alive&&e->awake;}};
struct ERR_ConvoyRules{static bool PartOf(IEntity e,IEntity root){for(int i=0;e&&i<32;i++,e=e->parent)if(e==root)return true;return false;}};
struct ERR_InfantryAmmoTransfer{static bool StoredUnder(IEntity e,IEntity root){return ERR_ConvoyRules::PartOf(e,root);}};
struct ERR_EnemyEquipmentRules{static bool Eligible(ERR_GameMode m,SCR_AIGroup g,IEntity e){return m&&g&&e&&e->eligible;}};
struct CompartmentAccessComponent{static IEntity GetVehicleIn(IEntity e){return e?e->seated:nullptr;}};
struct ERR_ForceRules{static bool Finite(float x){return std::isfinite(x);}static bool FiniteVector(vector v){return Finite(v.x)&&Finite(v.y)&&Finite(v.z);}};
struct EMuzzleType{static const int MT_BaseMuzzle=0;};struct EStoragePurpose{static const int PURPOSE_DEPOSIT=1;};
struct TraceParam{vector Start,End;int Flags=0,LayerMask=0;};struct TraceFlags{static const int WORLD=1,ENTS=2;};const int TRACE_LAYER_CAMERA=4;
struct World{float fraction=1;Array<IEntity>blockers;int calls=0;float TraceMove(TraceParam*t,std::function<bool(IEntity)>filter){assert(t->Flags==3&&t->LayerMask==4);calls++;for(auto*e:blockers)if(filter(e))return 0;return fraction;}};
struct Game{World*world=nullptr;World*GetWorld(){return world;}};Game*game=nullptr;Game*GetGame(){return game;}
struct ScriptedInventoryOperationCallback{virtual void OnComplete(){}virtual void OnAllComplete(){}virtual void OnFailed(){}virtual void OnAllFailed(){}virtual ~ScriptedInventoryOperationCallback()=default;};
struct ERR_MountedAmmoTransfer;
struct ERR_MountedAmmoCallback:ScriptedInventoryOperationCallback{ERR_MountedAmmoTransfer*Transfer=nullptr;void OnComplete()override;void OnAllComplete()override;void OnFailed()override;void OnAllFailed()override;};
struct Inventory{IEntity owner=nullptr;Array<IEntity>items;Array<Storage*>storages;bool allow=true,accept=true;int queries=0,calls=0,ack=0;ScriptedInventoryOperationCallback*last=nullptr;std::function<void()>effect;
IEntity GetOwner(){return owner;}void GetItems(Array<IEntity>&a,int p){assert(p==1);a=items;}void GetStorages(Array<Storage*>&a,int p){assert(p==1);a=storages;}
bool CanSwapItemStorages(IEntity a,IEntity b){assert(a&&b&&a!=b);queries++;return allow;}
bool TrySwapItemStorages(IEntity a,IEntity b,ScriptedInventoryOperationCallback*cb){assert(a&&b&&a!=b);calls++;last=cb;if(effect)effect();if(ack==1)cb->OnComplete();if(ack==-1)cb->OnFailed();return accept;}};
enum ERR_MountedAmmoTransferState{FAILED=-1,PENDING,SUCCEEDED};
'''
# ERR_GameMode aliases are pointer types; the static call uses the doubled class.
code=code.replace('ERR_GameMode::Get()', 'Mode::Get()')
main=r'''
struct Fixture{
Mode mode;Ledger ledger;HQ hq;Group dg,tg;Record dr{"donor"},tr{"target"};Receipt receipt;Task task;ConvoyVehicle donor,target;Roster roster;
Entity truck,root,worker,gun,loaded,incoming,foreign;Physics dp,tp;Item gunItem,oldItem,newItem;Slot weaponSlot,fromSlot,toSlot;Storage carryStorage,gunStorage;Inventory carried,truckInventory;
Well well;Weapon weapon;Mount mount;Muzzle muzzle;Magazine oldMag,newMag;Array<IEntity>stock,spent;ERR_FiniteMagazineReservation reservation;World world;Game game_;
Fixture():reservation(&stock,&spent,&incoming){Mode::current=&mode;mode.ledger=&ledger;mode.hq=&hq;ledger.donor=&dg;ledger.target=&tg;ledger.d=&dr;ledger.t=&tr;
receipt.Records={"target","donor","2","3","4","5"};task.Receipt=&receipt;task.Vehicles.resize(6,nullptr);task.Vehicles[0]=&target;task.Vehicles[1]=&donor;
donor.Index=1;donor.Entity=&truck;donor.Group=&dg;target.Entity=&root;target.Group=&tg;target.Members={&worker};truck.physics=&dp;root.physics=&tp;
roster.group=&tg;roster.root=&root;roster.worker=&worker;gun.parent=&root;loaded.parent=&gun;gun.item=&gunItem;loaded.item=&oldItem;incoming.item=&newItem;
gunItem.slot=&weaponSlot;oldItem.slot=&toSlot;newItem.slot=&fromSlot;weaponSlot.attached=&gun;weaponSlot.container=&mount;mount.slot=&weaponSlot;mount.gun=&gun;mount.owner=&root;
weapon.owner=&gun;weapon.muzzles={&muzzle};muzzle.owner=&gun;muzzle.mag=&oldMag;muzzle.well=&well;oldMag.owner=&loaded;oldMag.rounds=25;oldMag.used=true;newMag.owner=&incoming;oldMag.well=&well;newMag.well=&well;
loaded.magazine=&oldMag;incoming.magazine=&newMag;toSlot.attached=&loaded;toSlot.container=&muzzle;toSlot.storage=&gunStorage;gunStorage.owner=&gun;
fromSlot.attached=&incoming;fromSlot.storage=&carryStorage;carryStorage.owner=&worker;carried.owner=&worker;carried.items={&incoming};carried.storages={&carryStorage};worker.inventory=&carried;
truckInventory.owner=&truck;truck.inventory=&truckInventory;stock={&incoming};assert(reservation.Reserve()&&reservation.Commit());game_.world=&world;game=&game_;}
ERR_MountedAmmoTransfer Job(){return ERR_MountedAmmoTransfer(&mode,&task,0,&roster,1,&weapon,&muzzle,&loaded,&incoming,&reservation);}
void Swap(){fromSlot.attached=&loaded;toSlot.attached=&incoming;oldItem.slot=&fromSlot;newItem.slot=&toSlot;muzzle.mag=&newMag;carried.items={&loaded};}
};
int main(){
{Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING&&t.Submitted()&&t.Unresolved());assert(f.carried.calls==1);
f.carried.last->OnComplete();assert(t.Tick(1)==PENDING&&t.Unresolved());f.Swap();assert(t.Tick(2)==SUCCEEDED&&!t.Unresolved());
assert(t.Tick(9000)==SUCCEEDED&&f.carried.calls==1&&f.spent.Count()==1&&f.oldMag.rounds==25&&f.newMag.rounds==100);}
{Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING);f.Swap();assert(t.Tick(1)==PENDING);f.carried.last->OnAllComplete();assert(t.Tick(2)==SUCCEEDED);}
// Inline success plus false native return is still accepted when exact proof agrees.
{Fixture f;f.carried.accept=false;f.carried.ack=1;f.carried.effect=[&]{f.Swap();};auto t=f.Job();assert(t.Tick(0)==SUCCEEDED&&!t.Unresolved()&&f.carried.calls==1);}
// Two transactions sharing a committed pickup can never submit two native swaps.
{Fixture f;auto a=f.Job();auto b=f.Job();assert(a.Tick(0)==PENDING&&b.Tick(0)==FAILED&&!b.Submitted()&&f.carried.calls==1);}
// No callback, even on false native return, is conservatively quarantined.
{Fixture f;f.carried.accept=false;auto t=f.Job();assert(t.Tick(0)==FAILED&&t.Submitted()&&t.Unresolved());f.carried.last->OnFailed();assert(!t.Unresolved());assert(t.Tick(1)==FAILED&&f.carried.calls==1);}
{Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING);f.carried.last->OnComplete();f.carried.last->OnFailed();assert(t.Tick(1)==FAILED&&!t.Unresolved());f.carried.last->OnAllComplete();assert(t.Tick(2)==FAILED);}
// A partial native failure cannot free target slots or either magazine identity.
{Fixture f;auto t=f.Job();t.Tick(0);f.newItem.slot=&f.toSlot;f.toSlot.attached=&f.incoming;f.carried.last->OnFailed();assert(t.Tick(1)==FAILED&&t.Unresolved());}
// Stop never launches/replays; late exact completion resolves quarantine only.
{Fixture f;auto t=f.Job();t.Stop();assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.carried.calls==0&&f.spent.Count()==1);}
{Fixture f;auto t=f.Job();t.Tick(0);t.Stop();f.mode.active=false;f.Swap();f.carried.last->OnComplete();assert(!t.Unresolved()&&t.Tick(1)==FAILED&&f.carried.calls==1);}
{Fixture f;auto t=f.Job();t.Tick(0);assert(t.Tick(8000)==FAILED&&t.Unresolved()&&f.carried.calls==1);}
{Fixture f;auto t=f.Job();t.Tick(10);assert(t.Tick(9)==FAILED&&f.carried.calls==1);}
// A swap retains quarantine while either exact exchange identity survives.
for(int side=0;side<2;side++){Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING&&t.Unresolved());
if(side==0)t.m_Incoming=nullptr;else t.m_Loaded=nullptr;
t.Stop();assert(t.Unresolved()&&t.Tick(1)==FAILED&&f.carried.calls==1);
f.carried.last->OnComplete();assert(t.Unresolved());
t.m_Incoming=nullptr;t.m_Loaded=nullptr;f.reservation.m_Item=nullptr;f.stock[0]=nullptr;f.spent[0]=nullptr;
assert(!t.Unresolved()&&!f.reservation.ReleaseUnsubmitted()&&f.spent.Count()==1);
f.carried.last->OnFailed();assert(t.Tick(2)==FAILED&&!t.Unresolved()&&f.carried.calls==1);}
{Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING);f.incoming.alive=false;f.loaded.alive=false;
t.Stop();assert(t.Unresolved()&&f.carried.calls==1);}
// Physical target changes, outgoing capacity/content guards, source inventory bounds.
for(int k=0;k<34;k++){Fixture f;auto t=f.Job();
switch(k){case 0:f.task.Stopped=true;break;case 1:f.task.Ready=false;break;case 2:f.donor.Released=true;break;case 3:f.target.Released=true;break;
case 4:f.receipt.Consumed=false;break;case 5:f.roster.valid=false;break;case 6:f.worker.seated=&f.root;break;case 7:f.worker.awake=false;break;
case 8:f.worker.eligible=false;break;case 9:f.hq.valid=false;break;case 10:f.dp.velocity.x=0.3;break;case 11:f.tp.angular.x=0.2;break;
case 12:f.target.crew=false;break;case 13:f.mount.gun=&f.foreign;break;case 14:f.muzzle.mag=nullptr;break;case 15:f.fromSlot.locked=true;break;
case 16:f.toSlot.locked=true;break;case 17:f.newMag.used=true;break;case 18:f.oldMag.rounds=26;break;case 19:f.newMag.rounds=25;break;
case 20:f.newMag.capacity=0;break;case 21:f.oldMag.rounds=-1;break;case 22:f.newMag.rounds=101;break;case 23:f.carried.allow=false;break;
case 24:f.truckInventory.items={&f.incoming};break;case 25:f.carried.items.resize(129,&f.foreign);break;case 26:f.carried.storages.resize(65,&f.gunStorage);break;
case 27:f.gunStorage.owner=&f.foreign;break;case 28:f.fromSlot.storage=&f.gunStorage;break;case 29:f.task.Vehicles[0]=&f.donor;break;
case 30:f.worker.inventory=&f.truckInventory;break;case 31:f.weapon.muzzles.resize(9,&f.muzzle);break;case 32:f.ledger.t=&f.dr;break;case 33:f.target.Members.clear();break;}
assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.carried.calls==0&&f.spent.Count()==1);}
// Partial constructor state fails closed before native inventory access.
for(int k=0;k<9;k++){Fixture f;
switch(k){case 0:f.donor.Entity=nullptr;break;case 1:f.target.Entity=nullptr;break;case 2:f.donor.Group=nullptr;break;
case 3:f.target.Group=nullptr;break;case 4:f.task.Vehicles[1]=nullptr;break;case 5:f.task.Vehicles[0]=nullptr;break;
case 6:f.roster.worker=nullptr;break;case 7:f.incoming.item=nullptr;break;case 8:f.gun.item=nullptr;break;}
auto t=f.Job();assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.carried.calls==0);}
// A released handle cannot authorize even when another handle reclaims its exact item.
{Fixture f;Array<IEntity> stock{&f.incoming},spent;ERR_FiniteMagazineReservation released(&stock,&spent,&f.incoming);
assert(released.Reserve()&&released.ReleaseUnsubmitted());ERR_FiniteMagazineReservation other(&stock,&spent,&f.incoming);
assert(other.Reserve()&&other.Commit());auto t=ERR_MountedAmmoTransfer(&f.mode,&f.task,0,&f.roster,1,&f.weapon,&f.muzzle,&f.loaded,&f.incoming,&released);
assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.carried.calls==0);}
// Truck is stationary but need not be beside the mount during the carried leg.
{Fixture f;f.truck.position={35,0,0};auto t=f.Job();assert(t.Tick(0)==PENDING&&f.carried.calls==1);}
// Context loss after accepted operation is terminal while exact late proof can settle quarantine.
for(int k=0;k<5;k++){Fixture f;auto t=f.Job();t.Tick(0);switch(k){case 0:f.target.Released=true;break;case 1:f.donor.Released=true;break;
case 2:f.roster.valid=false;break;case 3:f.worker.awake=false;break;case 4:f.task.Stopped=true;break;}
assert(t.Tick(1)==FAILED&&t.Unresolved());f.Swap();f.carried.last->OnComplete();assert(!t.Unresolved()&&t.Tick(2)==FAILED&&f.carried.calls==1);}
// Existing reservation has already spent the pickup. Released/foreign/duplicate handles fail.
{Fixture f;assert(f.reservation.CommittedFor(&f.incoming)&&!f.reservation.CommittedFor(&f.loaded));assert(!f.reservation.ReleaseUnsubmitted());}
{Fixture f;Array<IEntity> stock{&f.loaded},spent;ERR_FiniteMagazineReservation r(&stock,&spent,&f.loaded);assert(r.Reserve()&&r.ReleaseUnsubmitted());
ERR_FiniteMagazineReservation next(&stock,&spent,&f.loaded);assert(next.Reserve()&&next.Commit());assert(!r.CommittedFor(&f.loaded)&&!r.ClaimMountedSwap(&f.loaded));}
// Authored slot reach executes real distance/trace logic, retaining vehicle hull occlusion.
for(int k=0;k<7;k++){Fixture f;auto t=f.Job();switch(k){case 0:f.toSlot.point.x=4.01;break;case 1:f.toSlot.point.x=0.01;break;
case 2:f.toSlot.point.x=std::numeric_limits<float>::quiet_NaN();break;case 3:f.worker.position.x=std::numeric_limits<float>::infinity();break;
case 4:f.world.blockers={&f.root};break;case 5:f.world.blockers={&f.foreign};break;case 6:f.world.fraction=0.5;break;}
assert(t.Tick(0)==FAILED&&!t.Submitted());}
{Fixture f;f.world.blockers={&f.worker,&f.gun,&f.loaded};f.toSlot.point.x=4;auto t=f.Job();assert(t.Tick(0)==PENDING&&f.world.calls==1);}
// Invalid clock/server/editor guards never consume the second-leg claim.
for(int k=0;k<4;k++){Fixture f;auto t=f.Job();if(k==0)Replication::server=false;if(k==1)SCR_Global::editor=true;
assert(t.Tick(k==2?-1:k==3?std::numeric_limits<float>::quiet_NaN():0)==FAILED&&!t.Submitted());Replication::server=true;SCR_Global::editor=false;}
}
'''
run(pre+translated_reservation()+code+'\n'+'\n'.join(callbacks)+main)
print('PASS: actual carried-mounted swap, shared committed claim, physical slot reach, exact two-way proof, uncertainty and terminal cleanup')