62 lines
5.8 KiB
Python
62 lines
5.8 KiB
Python
"""Execute actual medicine allowance/insertion coordinator with native inventory adapters."""
|
|
import re
|
|
from policy_harness import ROOT, run
|
|
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyMedicine.c'
|
|
s=p.read_text();s=s[s.index('class ERR_EnemyMedicine'):]
|
|
s=re.sub(r'//[^\n]*','',s).replace('protected ','').replace('ref ','').replace('class ERR_EnemyMedicine','struct ERR_EnemyMedicine')
|
|
s=s.replace('array<IEntity>', 'Array<IEntity*>').replace('foreach (','for (').replace('ResourceName','string')
|
|
s=s.replace('InventoryStorageManagerComponent.Cast(actor.FindComponent(InventoryStorageManagerComponent))','actor->inventory').replace('BaseInventoryStorageComponent.Cast(item.FindComponent(BaseInventoryStorageComponent))','item->bag').replace('ERR_HQ.Cast(mode.Command())','mode->Command()')
|
|
for cls in ('IEntity','ERR_GameMode','SCR_AIGroup','InventoryStorageManagerComponent','BaseInventoryStorageComponent','ERR_HQ'):
|
|
s=re.sub(r'\b'+cls+r' (\w+)',cls+r'* \1',s)
|
|
s=s.replace('ERR_EnemyEquipmentCallback m_Operation','ERR_EnemyEquipmentCallback* m_Operation')
|
|
for obj in ('actor','existing','item','mode','inventory','m_Operation','hq'):
|
|
s=s.replace(obj+'.',obj+'->')
|
|
s=s.replace('GetPrefabData().','GetPrefabData()->').replace('Hunters().','Hunters()->')
|
|
for ns in ('ERR_EnemyEquipmentRules','ERR_EnemyMedicalCatalog','ERR_HQ','Math','EStoragePurpose','string'):
|
|
s=s.replace(ns+'.',ns+'::')
|
|
s=s.replace('string::Format(', 'Format(').replace('null','nullptr')
|
|
s=re.sub(r'\b(bool|int|float|\w+\*) (\w+);',r'\1 \2 {};',s).replace('\n}\n','\n};\n')
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
struct string:std::string {using std::string::string;string(const std::string& s):std::string(s){}bool Contains(string x){return find(x)!=npos;}void ToLower(){std::transform(begin(),end(),begin(),::tolower);}};
|
|
template<class...T>string Format(string,T...){return "event";}
|
|
template<class T>struct Array:std::vector<T>{int Count(){return this->size();}};
|
|
struct Prefab{string path;string GetPrefabName(){return path;}};
|
|
struct BaseInventoryStorageComponent{};
|
|
struct InventoryStorageManagerComponent;
|
|
struct IEntity{Prefab prefab;bool owned=true;InventoryStorageManagerComponent* inventory=nullptr;BaseInventoryStorageComponent* bag=nullptr;Prefab* GetPrefabData(){return &prefab;}int GetOrigin(){return 0;}};
|
|
struct SCR_AIGroup{};
|
|
struct ERR_EnemyEquipmentCallback{bool Finished=false,Succeeded=false;};
|
|
namespace EStoragePurpose{enum{PURPOSE_DEPOSIT};}
|
|
struct InventoryStorageManagerComponent{Array<IEntity*> items;int attempts=0,accepted=0;bool fullBag=false,full=false,async=false;ERR_EnemyEquipmentCallback* pending=nullptr;
|
|
void GetItems(Array<IEntity*>& out){out=items;}
|
|
bool TrySpawnPrefabToStorage(string prefab,BaseInventoryStorageComponent* bag,int,int,ERR_EnemyEquipmentCallback* callback){attempts++;if(full||(bag&&fullBag))return false;accepted++;auto* item=new IEntity;item->prefab.path=prefab;items.push_back(item);pending=callback;if(!async){callback->Finished=true;callback->Succeeded=true;}return true;}
|
|
};
|
|
struct Hunters{bool Contains(SCR_AIGroup*){return false;}};
|
|
struct ERR_HQ{Hunters hunters;Hunters* Hunters(){return &hunters;}static void Event(string,string){}};
|
|
struct ERR_GameMode{ERR_HQ hq;ERR_HQ* Command(){return &hq;}};
|
|
namespace ERR_EnemyEquipmentRules {bool Eligible(ERR_GameMode*,SCR_AIGroup*,IEntity* a){return a&&a->owned;}}
|
|
namespace ERR_EnemyMedicalCatalog {const string EPI="epi",MORPHINE="morphine";bool Medic(string p){return p.Contains("medic");}bool Specialist(string p){return p.Contains("_sf");}}
|
|
namespace Math{int RandomInt(int,int){return 0;}}
|
|
'''.replace('Hunters hunters;Hunters* Hunters()', 'struct Hunters hunters;struct Hunters* Hunters()')+s+r'''
|
|
int main(){ERR_GameMode mode;SCR_AIGroup group;IEntity actor;InventoryStorageManagerComponent inventory;actor.inventory=&inventory;actor.prefab.path="_sf_medic";
|
|
IEntity backpack;backpack.prefab.path="backpack";BaseInventoryStorageComponent bag;backpack.bag=&bag;inventory.items.push_back(&backpack);
|
|
IEntity authored;authored.prefab.path="morphine";inventory.items.push_back(&authored);
|
|
ERR_EnemyMedicine grant;inventory.fullBag=true;for(int i=0;i<20;i++)grant.Check(&mode,&group,&actor);
|
|
assert(grant.m_Done&&grant.m_Issued==11&&inventory.accepted==11&&inventory.attempts==22); // six epi plus five missing morphine; refused bag falls back once
|
|
int attempts=inventory.attempts;inventory.items.clear();for(int i=0;i<5;i++)grant.Check(&mode,&group,&actor);assert(inventory.attempts==attempts); // no refill after loot
|
|
InventoryStorageManagerComponent blocked;actor.inventory=&blocked;blocked.async=true;ERR_EnemyMedicine pending;for(int i=0;i<35;i++)pending.Check(&mode,&group,&actor);assert(pending.m_Done&&blocked.accepted==1); // pending operation quarantined, never duplicated
|
|
InventoryStorageManagerComponent unavailable;actor.inventory=&unavailable;unavailable.full=true;ERR_EnemyMedicine noSpace;noSpace.Check(&mode,&group,&actor);assert(noSpace.m_Done&&unavailable.accepted==0);
|
|
InventoryStorageManagerComponent specialStock;actor.inventory=&specialStock;actor.prefab.path="soldier_sf";
|
|
ERR_EnemyMedicine special;for(int i=0;i<8;i++)special.Check(&mode,&group,&actor);
|
|
assert(special.m_Done&&specialStock.accepted==4);int epi=0,morphine=0;
|
|
for(auto* item:specialStock.items){epi+=item->prefab.path=="epi";morphine+=item->prefab.path=="morphine";}
|
|
assert(epi==2&&morphine==2); // Every special-forces soldier has two finite injectors.
|
|
actor.owned=false;ERR_EnemyMedicine captured;captured.Check(&mode,&group,&actor);assert(!captured.m_Started);captured.Stop();actor.owned=true;captured.Check(&mode,&group,&actor);assert(!captured.m_Started);
|
|
}
|
|
''')
|
|
print('PASS: actual finite medicine grants, authored stock deduction, full-backpack refusal/pouch fallback, no loot replenishment, unresolved-operation quarantine and ownership/stop guards')
|