Files
EscapistsReintroduced/tests/test_native_infantry_fixture_lifecycle.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

50 lines
4.3 KiB
Python

"""Actual fixture recipient/Stop methods with native boundaries doubled."""
import os,re,sys
from pathlib import Path
REPO=Path(os.environ.get('ERR_REPO','/home/jakub/devel/escapistsrereintroduced'))
sys.path.insert(0,str(REPO/'tests'))
from policy_harness import body,run
P=Path(os.environ.get('ERR_INFANTRY_PROBE_SOURCE',REPO/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeInfantryTransferProbe.c'))
s='\n'.join(body(P,x) for x in ('protected bool RecipientOwned()','void Stop()'))
s=s.replace('protected ','').replace('ERR_EnemyEquipmentRules.','Rules::').replace('CompartmentAccessComponent.','Compartment::')
for v in ('m_Unit','m_Mode','m_Actor','m_Move','m_HQ','m_Truck'):s=s.replace(v+'.',v+'->')
s=s.replace('StatusSampler.','StatusSampler->')
run(r'''
#include <cassert>
#include <vector>
struct Mode{bool active=true;static inline Mode* current=nullptr;};
struct Group{};
struct Actor{bool player=false,alive=true,seated=false;Group* group=nullptr;int moved=0,last=-1;void SetOrigin(int p){moved++;last=p;}};
struct Sampler{Group* group;int strength=1;bool released=false;std::vector<Actor*> original;bool OwnsRoster(Group* g){return g==group;}int InitialStrength(){return strength;}Actor* InitialMember(int i){return i<(int)original.size()?original[i]:nullptr;}bool CanAttribute(int,Actor*){return !released;}};
struct Unit{struct Group* Group;Sampler* StatusSampler;};
struct Rules{static inline bool server=true;static bool Eligible(Mode* mode,Group* group,Actor* actor){return server&&mode&&mode==Mode::current&&mode->active&&actor&&actor->alive&&!actor->player&&actor->group==group;}};
struct Compartment{static bool GetVehicleIn(Actor* a){return a->seated;}};
struct HQ{int token=200001,calls=0;int LogisticsToken(Group*){return token;}void ReleaseLogistics(Group*,int own){calls++;if(token==own)token=0;}};
struct Truck{int SupplyToken=200001;bool SupplyHeld=true;};
struct Move{int stops=0;bool unresolved=false;void Stop(){stops++;}bool Unresolved(){return unresolved;}};
struct Probe{static constexpr int TOKEN=200001;Mode* m_Mode;Unit* m_Unit;Actor* m_Actor;Move* m_Move=nullptr;HQ* m_HQ;Truck* m_Truck;bool m_Stopped=false,m_Positioned=true;int m_OriginalPosition=45;
METHODS
};
struct F{Mode mode;Group group;Actor actor;Sampler sampler;Unit unit;HQ hq;Truck truck;Probe probe;F():sampler{&group,1,false,{&actor}},unit{&group,&sampler},probe{&mode,&unit,&actor,nullptr,&hq,&truck}{Mode::current=&mode;actor.group=&group;}};
int main(){
{F f;assert(f.probe.RecipientOwned());f.actor.player=true;assert(!f.probe.RecipientOwned());f.probe.Stop();assert(f.actor.moved==0&&f.hq.token==0&&f.truck.SupplyToken==0);}
{F f;f.probe.Stop();assert(f.actor.moved==1&&f.actor.last==45&&!f.truck.SupplyHeld&&f.hq.calls==1);f.probe.Stop();assert(f.actor.moved==1&&f.hq.calls==1);}
{F f;Move move;move.unresolved=true;f.probe.m_Move=&move;f.probe.Stop();assert(move.stops==1&&f.actor.moved==0&&f.probe.m_Move==&move&&f.hq.token==0);}
{F f;Move move;f.probe.m_Move=&move;f.probe.Stop();assert(move.stops==1&&f.actor.moved==1);}
{F f;f.hq.token=55;f.truck.SupplyToken=55;f.probe.Stop();assert(f.hq.token==55&&f.truck.SupplyToken==55&&f.truck.SupplyHeld&&f.actor.moved==0);}
{F f;f.sampler.released=true;assert(!f.probe.RecipientOwned());f.probe.Stop();assert(f.actor.moved==0);}
{F f;f.actor.seated=true;f.probe.Stop();assert(f.actor.moved==0);}
{F f;Group foreign;f.actor.group=&foreign;f.probe.Stop();assert(f.actor.moved==0);}
{F f;Mode::current=nullptr;f.probe.Stop();assert(f.actor.moved==0);}
{F f;f.probe.m_Mode=nullptr;Mode::current=nullptr;f.probe.Stop();assert(f.actor.moved==0);}
{F f;f.mode.active=false;f.probe.Stop();assert(f.actor.moved==0);}
{F f;Rules::server=false;f.probe.Stop();assert(f.actor.moved==0);Rules::server=true;}
{F f;f.sampler.strength=33;assert(!f.probe.RecipientOwned());f.sampler.strength=0;assert(!f.probe.RecipientOwned());f.sampler.strength=1;f.sampler.original.clear();assert(!f.probe.RecipientOwned());}
}
'''.replace('METHODS',s))
place=body(P,'protected int Place(float now)')
assert place.index('if (!RecipientOwned()) return -1;')<place.index('m_Actor.SetOrigin(')
tick=body(P,'int Tick(ERR_HQ hq, float now)')
assert '&& RecipientOwned() && hq.LogisticsToken(m_Unit.Group) == TOKEN' in tick
print('PASS: actual fixture current/original recipient ownership, unresolved transfer cleanup, exact-token release and idempotent Stop')