"""Actual mine top-up selector plus the real shared finite reservation; native leaf is doubled.""" import os,re from pathlib import Path from policy_harness import ROOT,body,run from test_finite_magazine_reservation import translated_reservation p=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c')) s=body(p,'protected void TransferMine(').replace('protected ','').replace('null','nullptr') s=s.replace('ERR_InfantryMineTransfer.', 'ERR_InfantryMineTransfer::').replace('ERR_Actors.', 'ERR_Actors::').replace('vector.DistanceXZ','Vec::DistanceXZ') s=s.replace('foreach (IEntity mine : m_MineStock)','for (IEntity mine : m_MineStock)') s=s.replace('ERR_FiniteMagazineReservation reservation', 'ERR_FiniteMagazineReservation* reservation').replace('new ERR_FiniteMagazineReservation(m_MineStock, m_Spent, mine)', 'new ERR_FiniteMagazineReservation(&m_MineStock, &m_Spent, mine)') for x in ['m_MineMove','m_Recipient','m_Truck','m_HQ','actor','m_Receiving','reservation']:s=s.replace(x+'.',x+'->') for x in ['StatusSampler','Entity']:s=s.replace(x+'.',x+'->') run(r''' #include #include #include #include #include using string=std::string; struct Vec{float x=0;static float DistanceXZ(Vec a,Vec b){return std::abs(a.x-b.x);}}; struct Group{};struct Mode{};struct Entity{bool ready=false,fight=true,owned=true,grant=true,designated=false;int mines=1;Vec pos;Vec GetOrigin(){return pos;}};using IEntity=Entity*; templatestruct Array:std::vector{using std::vector::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){this->erase(std::remove(this->begin(),this->end(),v),this->end());}}; '''+translated_reservation()+r''' struct Sampler{Arrayoriginal;int InitialStrength(){return original.Count();}IEntity InitialMember(int i){return original[i];}bool CanAttribute(int i,IEntity x,bool){return i>=0&&iowned;}}; struct Unit{struct Group*Group;Sampler*StatusSampler;};struct Truck{IEntity Entity;struct Group*Group;}; struct HQ{bool MineSupplyReady(Group*,IEntity x,bool replacement=false){return x&&x->grant&&(!replacement||x->designated);}}; struct ERR_Actors{static bool CanFight(IEntity x){return x&&x->fight;}}; struct ERR_InfantryMineTransfer{ static inline bool accept=true;static inline int made=0;IEntity item,actor;ERR_FiniteMagazineReservation*r;bool submitted=false;int result=0; ERR_InfantryMineTransfer(Mode*,IEntity,Group*,IEntity a,Group*,IEntity i,ERR_FiniteMagazineReservation*q,Sampler*,int,bool empty=false):item(i),actor(a),r(q){assert(a->mines==(empty?0:1));made++;} static bool ReadyMine(IEntity x){return x&&x->ready;} static int CarriedCount(IEntity x,Group*,IEntity& found){found=x;return x?x->mines:-1;} static IEntity Carrier(IEntity x,Group*){return x&&x->mines==1?x:nullptr;} int Tick(float){if(accept&&!submitted){assert(r->Commit());submitted=true;}return result;} bool Submitted(){return submitted;} }; struct Service{ HQ*m_HQ;Mode*m_Mode;Unit*m_Recipient;Truck*m_Truck;IEntity m_Receiving=nullptr;bool m_EmptyMineReplacement=false;int m_MineRecipientSlot=-1,m_MinesDelivered=0,finishes=0;ERR_InfantryMineTransfer*m_MineMove=nullptr; Arraym_Members,m_MineStock,m_Spent,cargo; bool Contains(IEntity,IEntity x){return cargo.Contains(x);}void Finish(string){finishes++;} '''+s+r''' }; struct Fixture{HQ h;Mode mode;Group g,d;Entity actor,other,truck,mine,second;Sampler sampler;Unit unit;Truck donor;Service s; Fixture():sampler{{&actor,&other}},unit{&g,&sampler},donor{&truck,&d}{mine.ready=second.ready=true;s.m_HQ=&h;s.m_Mode=&mode;s.m_Recipient=&unit;s.m_Truck=&donor;s.m_Members={&actor,&other};s.m_MineStock={&mine,&second};s.cargo=s.m_MineStock;ERR_InfantryMineTransfer::accept=true;} }; int main(){ {Fixture f;f.actor.mines=0;f.actor.designated=true;f.s.TransferMine(0);assert(f.s.m_MineMove&&f.s.m_MineMove->actor==&f.actor&&f.s.m_EmptyMineReplacement&&f.s.m_Spent.Count()==1);} {Fixture f;f.actor.mines=-1;f.actor.designated=true;f.other.mines=0;f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.empty());} {Fixture f;f.actor.mines=0;f.actor.designated=true;ERR_InfantryMineTransfer::accept=false;f.s.TransferMine(0);assert(f.s.m_Receiving==&f.actor&&f.s.m_EmptyMineReplacement);f.actor.mines=1;ERR_InfantryMineTransfer::accept=true;f.s.TransferMine(1);assert(!f.s.m_MineMove&&f.s.finishes==1&&f.s.m_Spent.empty());} // Never grant mines to undesignated zero/two-mine members or to unsettled initial grants. for(int refusal=0;refusal<6;refusal++){Fixture f;f.other.mines=0; if(refusal==0)f.actor.mines=0;if(refusal==1)f.actor.mines=2;if(refusal==2)f.actor.grant=false;if(refusal==3)f.actor.owned=false;if(refusal==4)f.actor.pos.x=5;if(refusal==5)f.actor.fight=false; f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.empty()&&!f.s.m_Receiving);} // One exact finite original identity and the same shared spent list. {Fixture f;f.s.TransferMine(0);auto*leaf=f.s.m_MineMove;assert(leaf&&leaf->actor==&f.actor&&leaf->item==&f.mine&&f.s.m_Spent.Count()==1&&f.s.m_Spent[0]==&f.mine); f.s.TransferMine(1000);assert(f.s.m_MineMove==leaf&&f.s.m_Spent.Count()==1);leaf->result=1;f.s.TransferMine(2000);assert(!f.s.m_MineMove&&f.s.m_MinesDelivered==1&&f.s.finishes==1&&f.s.m_Spent.Count()==1);} // Preflight refusal may release only before native submission, keeping actor pinned. {Fixture f;ERR_InfantryMineTransfer::accept=false;f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.empty()&&f.s.m_Receiving==&f.actor); f.actor.mines=0;ERR_InfantryMineTransfer::accept=true;f.s.TransferMine(1000);assert(!f.s.m_MineMove&&f.s.finishes==1&&f.s.m_Spent.empty());} {Fixture f;ERR_InfantryMineTransfer::accept=false;f.s.TransferMine(0);f.actor.grant=false;ERR_InfantryMineTransfer::accept=true;f.s.TransferMine(1000);assert(!f.s.m_MineMove&&f.s.m_Spent.empty());} // Captured/absent original or already-spent cargo is unavailable; no substitute. {Fixture f;f.s.cargo.clear();f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.empty());} {Fixture f;f.s.m_Spent=f.s.m_MineStock;f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.Count()==2);} {Fixture f;for(int i=0;i<96;i++)f.s.m_Spent.Insert(&f.truck);f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.Count()==96);} // Failure delegates cleanup while retaining the submitted leaf and spent item. {Fixture f;f.s.TransferMine(0);auto*leaf=f.s.m_MineMove;leaf->result=-1;f.s.TransferMine(1000);assert(f.s.m_MineMove==leaf&&f.s.finishes==1&&f.s.m_Spent.Count()==1);} } '''.replace('if(refusal==0)f.actor.mines=0;if(refusal==1)f.actor.mines=2;if(refusal==2)f.actor.grant=false;if(refusal==3)f.actor.owned=false;if(refusal==4)f.actor.pos.x=5;if(refusal==5)f.actor.fight=false;', 'if(refusal==0){f.actor.mines=0;}if(refusal==1){f.actor.mines=2;}if(refusal==2){f.actor.grant=false;}if(refusal==3){f.actor.owned=false;}if(refusal==4){f.actor.pos.x=5;}if(refusal==5){f.actor.fight=false;}')) print('PASS: actual designated zero/one original carrier selection, settled startup, shared finite claims, no refund after submission') h=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c')) w=body(h,'bool MineSupplyReady(').replace('SCR_AIGroup group','Group* group').replace('Replication.','Replication::').replace('m_Equipment.','m_Equipment->') run(r''' #include struct Group{};struct Item{};using IEntity=Item*; struct Equipment{bool ready=false,designated=false;Group*group=nullptr;IEntity actor=nullptr;bool MineSupplyReady(Group*g,IEntity a,bool replacement=false){return ready&&g==group&&a==actor&&(!replacement||designated);}}; struct Replication{static inline bool server=true;static bool IsServer(){return server;}}; struct HQ{Equipment*m_Equipment=nullptr;bool active=true;bool MissionActive(){return active;} '''+w+r'''}; int main(){Group group,other;Item actor;Equipment e;e.group=&group;e.actor=&actor;HQ h;assert(!h.MineSupplyReady(&group,&actor));h.m_Equipment=&e;assert(!h.MineSupplyReady(&group,&actor));e.ready=true;assert(h.MineSupplyReady(&group,&actor));assert(!h.MineSupplyReady(&group,&actor,true));e.designated=true;assert(h.MineSupplyReady(&group,&actor,true));assert(!h.MineSupplyReady(&other,&actor,true));assert(!h.MineSupplyReady(&other,&actor));h.active=false;assert(!h.MineSupplyReady(&group,&actor));h.active=true;Replication::server=false;assert(!h.MineSupplyReady(&group,&actor));} ''') print('PASS: actual HQ startup grant readiness forwarding is authoritative and fail-closed')