Files
EscapistsReintroduced/tests/test_native_maintenance_stock.py
T
jakub cab998fb64 Combine Workshop addon and fix prison startup
Merge owned systems into one addon while preserving resource identities. Gate player admission on the replicated prison scene, restore the original framed door, and hold enemy AI until escape. Correct scenario branding and author metadata, include publishing assets, and retain regression and native verification evidence.
2026-09-20 16:42:52 +02:00

71 lines
5.5 KiB
Python

"""Execute actual read-only native-stock fixture checks with deterministic component adapters."""
from pathlib import Path
import os,re
from policy_harness import ROOT,body,run
P=Path(os.environ.get('ERR_NATIVE_TRANSPORT_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_NativeTransportProbe.c'))
method=body(P,'protected bool MaintenanceStock(')
for forbidden in ('SetFuel','SetResource','Consume','Spawn(','TryMove','GetInVehicle','SetHealth','EnableDamage'):
assert forbidden not in method,forbidden
s=method.replace('protected ','').replace('array<','Array<').replace('foreach (','for (').replace('null','nullptr').replace('ResourceName','string')
s=s.replace('InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(m_Site.Container.FindComponent(InventoryStorageManagerComponent));','Inventory* inventory = m_Site->Container->inventory;')
s=s.replace('SCR_ResourceComponent resource = SCR_ResourceComponent.Cast(item.FindComponent(SCR_ResourceComponent));','Resource* resource = item->resource;')
s=s.replace('SCR_FuelManagerComponent fuel = SCR_FuelManagerComponent.Cast(item.FindComponent(SCR_FuelManagerComponent));','Fuel* fuel = item->fuel;')
s=s.replace('SCR_ResourceContainer supplies;','Supply* supplies = nullptr;').replace('int kits, cans;','int kits=0, cans=0;')
for var in ('m_Site','m_Mode','item','resource','supplies','fuel'):s=re.sub(r'\b'+var+r'\.',var+'->',s)
s=s.replace('Sites().','Sites()->').replace('GetPrefabData().','GetPrefabData()->')
for ns in ('ERR_Inventory','Math','EResourceType'):s=s.replace(ns+'.',ns+'::')
run(r'''
#include <cassert>
#include <cmath>
#include <vector>
#include <string>
#include <algorithm>
using string=std::string;
template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}};
struct Item;using IEntity=Item*;
struct Inventory{Array<IEntity>items;};
struct Supply{float amount=20,capacity=20;float GetResourceValue(){return amount;}float GetMaxResourceValue(){return capacity;}};
struct Resource{Supply* supply=nullptr;Supply* GetContainer(int){return supply;}};
struct Fuel{float litres=5,capacity=20;float GetTotalFuel(){return litres;}float GetTotalMaxFuel(){return capacity;}};
struct Prefab{string name;string GetPrefabName(){return name;}};
struct Item{Prefab* prefab=nullptr;Inventory* inventory=nullptr;Resource* resource=nullptr;Fuel* fuel=nullptr;bool owned=true;Prefab* GetPrefabData(){return prefab;}};
struct Site{IEntity Container=nullptr;};struct Sites{bool Owns(IEntity item){return item&&item->owned;}};
struct Mode{struct Sites sites;struct Sites* Sites(){return &sites;}};
struct ERR_Inventory{static void Items(Inventory* inv,Array<IEntity>& items){for(auto item:inv->items)if(item&&std::find(items.begin(),items.end(),item)==items.end())items.push_back(item);}};
namespace Math{float AbsFloat(float x){return std::fabs(x);}}namespace EResourceType{enum{SUPPLIES};}
template<class...T>void PrintFormat(const char*,T...){}
struct Probe{Mode* m_Mode;Site* m_Site;int checks=0;bool Check(bool valid,string){checks++;return valid;}
'''+s+r'''
};
int main(){
Mode mode;Site site;Probe p{&mode,&site};Item container,kit,can1,can2;Inventory inventory;
Prefab kitPrefab{"{C09C7C97EFA34909}Prefabs/ERR/Items/EmergencyRepairKit.et"};
Prefab canPrefab{"{12D5AD21E383B768}Prefabs/Items/Fuel/Jerrycan_01/Jerrycan_01_item.et"};
Supply supplies;Resource resource{&supplies};Fuel fuel1,fuel2;
site.Container=&container;container.inventory=&inventory;kit.prefab=&kitPrefab;kit.resource=&resource;
can1.prefab=&canPrefab;can1.fuel=&fuel1;can2.prefab=&canPrefab;can2.fuel=&fuel2;
inventory.items={&kit,&can1,&can2};assert(p.MaintenanceStock());
assert(supplies.amount==20&&fuel1.litres==5&&fuel2.litres==5); // inspection made no changes
inventory.items.push_back(&can1);assert(p.MaintenanceStock()); // duplicate inventory enumeration is not extra stock
inventory.items={&kit,&can1};assert(!p.MaintenanceStock());inventory.items={&kit,&can1,&can2};
Item extraKit=kit;inventory.items.push_back(&extraKit);assert(!p.MaintenanceStock());inventory.items.pop_back();
kit.owned=false;assert(!p.MaintenanceStock());kit.owned=true;
can2.owned=false;assert(!p.MaintenanceStock());can2.owned=true;
kit.resource=nullptr;assert(!p.MaintenanceStock());kit.resource=&resource;
resource.supply=nullptr;assert(!p.MaintenanceStock());resource.supply=&supplies;
can2.fuel=nullptr;assert(!p.MaintenanceStock());can2.fuel=&fuel2;
for(float invalid:{0.f,19.f,21.f,NAN}){supplies.amount=invalid;assert(!p.MaintenanceStock());}supplies.amount=20;
supplies.capacity=100;assert(!p.MaintenanceStock());supplies.capacity=20;
for(float invalid:{0.f,4.f,6.f,NAN}){fuel2.litres=invalid;assert(!p.MaintenanceStock());}fuel2.litres=5;
fuel1.capacity=5;assert(!p.MaintenanceStock());fuel1.capacity=20;
string original=kitPrefab.name;kitPrefab.name="unrelated";assert(!p.MaintenanceStock());kitPrefab.name=original;
std::vector<Item> unrelated(129);for(auto& item:unrelated)inventory.items.push_back(&item);assert(!p.MaintenanceStock());inventory.items={&kit,&can1,&can2};
container.owned=false;assert(!p.MaintenanceStock());container.owned=true;
container.inventory=nullptr;assert(!p.MaintenanceStock());container.inventory=&inventory;
assert(p.MaintenanceStock());
}
''')
tick=body(P,'int Tick(')
assert tick.index('if (!MaintenanceStock()) return -1;') < tick.index('IEntity driver = Character(0)')
print('PASS: actual maintenance native-stock check rejects missing/duplicate/wrong-identity/unowned/depleted/malformed stock and is read-only; native runtime not executed')