Files
EscapistsReintroduced/tests/test_enemy_medicine.py
T

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')