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

129 lines
23 KiB
Python

"""Execute actual gate observer bodies; fake only native boundaries, no engine claim."""
import re
from policy_harness import ROOT, body, run
P=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_OrdinaryGateObserver.c'
def cpp(s):
s=s.replace('protected ', '').replace('out bool held', 'bool& held').replace('out float ', 'float& ').replace('out bool ', 'bool& ')
types=('ERR_GameMode','BaseWorld','PlayerController','IEntity','ERR_PlayerLife','PlayerManager','BaseUserAction','ERR_UnlockPrisonAction','UserActionContext')
for typ in types:s=re.sub(r'\b'+typ+r' (\w+)',typ+r'* \1',s)
s=s.replace('array<BaseUserAction>', 'Array<BaseUserAction*>').replace('array<bool>', 'Array<bool>')
s=s.replace('foreach (BaseUserAction* action : actions)', 'for (BaseUserAction* action : actions)')
s=s.replace('int matches;', 'int matches=0;')
for typ in ('BaseActionsManagerComponent','BaseDoorComponent','SCR_InteractionHandlerComponent'):
s=s.replace('FindComponent('+typ+')', 'FindComponent('+typ+'Key)')
s=s.replace(typ+'.Cast(', 'static_cast<'+typ+'*>(')
s=s.replace('ERR_UnlockPrisonAction.Cast(', 'dynamic_cast<ERR_UnlockPrisonAction*>(')
for name in ('mode','world','controller','actor','players','action','candidate','expected','context','m_Mode','m_World','m_Controller','m_Actor','m_Life','m_Gate','m_Manager','m_Lock','m_Context','m_Door','m_Handler','s_Request'):
s=s.replace(name+'.',name+'->')
for scope in ('System','Replication','RplSession','RplMode','ERR_Phase','ERR_GameMode','ERR_Actors','ERR_OrdinaryInputObserverRules','CompartmentAccessComponent'):
s=s.replace(scope+'.',scope+'::')
for getter in ('GetGame','Players','PrisonEscape','GetInputManager','GetMenuManager'):
s=s.replace(getter+'().',getter+'()->')
s=s.replace('nonce.Length()', 'int(nonce.size())').replace('allowed.Contains(nonce[i])', '(allowed.find(nonce[i]) != string::npos)')
return s.replace('null','nullptr').replace('string.Format(', 'Format(')
accessor=cpp(body(P,'bool ERR_GateReadProgress('))
shared='\n'.join(cpp(body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_OrdinaryInputObserver.c', signature)) for signature in ('static bool Nonce(', 'static bool HeldScope(', 'static bool PhaseAllowed('))
methods='\n'.join(cpp(body(P,s)) for s in ('protected static bool Enabled(', 'static void Sample(', 'protected bool BindGate(', 'protected bool Context(', 'protected void Cancel(', 'protected bool CachedPermission(', 'protected static bool FiniteVector(', 'protected static string ChoiceIdentity(', 'protected void ObserveChoices(', 'protected void Observe('))
run(r'''
#include <cassert>
#include <cmath>
#include <limits>
#include <map>
#include <string>
#include <vector>
using string=std::string;using UUID=string;
template<class T> struct Array:std::vector<T> {using std::vector<T>::vector;int Count(){return this->size();}};
struct vector {float v[3]={0,0,0};float& operator[](int i){return v[i];}float Length(){return std::sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);}vector operator/(float n){return {{v[0]/n,v[1]/n,v[2]/n}};}};
vector Vector(float x,float y,float z){return {{x,y,z}};}
enum {BaseActionsManagerComponentKey,BaseDoorComponentKey,SCR_InteractionHandlerComponentKey};
struct BaseWorld{};
struct IEntity {BaseWorld* world=nullptr;bool living=true,vehicle=false;void* components[3]={};vector origin=Vector(6090,210,7158);BaseWorld* GetWorld(){return world;}void* FindComponent(int key){return components[key];}vector forward=Vector(0,0,1.5);vector GetOrigin(){return origin;}void GetTransform(vector out[4]){out[2]=forward;out[3]=origin;}};
struct NativeType {string name;string ToString(){return name;}};
struct BaseUserAction {string className="BaseUserAction";NativeType Type(){return {className};}virtual ~BaseUserAction()=default;IEntity* owner=nullptr;int id=4;float duration=4;IEntity* GetOwner(){return owner;}int GetActionID(){return id;}float GetActionDuration(){return duration;}};
struct ERR_UnlockPrisonAction:BaseUserAction{};
struct UserActionContext {Array<BaseUserAction*> actions;vector origin=Vector(6092,212,7154);float radius=2;void GetActionsList(Array<BaseUserAction*>& out){out=actions;}vector GetOrigin(){return origin;}float GetRadius(){return radius;}};
struct BaseActionsManagerComponent {UserActionContext* context=nullptr;BaseUserAction* action=nullptr;UserActionContext* GetContext(string){return context;}BaseUserAction* FindAction(int id){return action&&action->id==id?action:nullptr;}};
struct BaseDoorComponent {float state=0,control=0;float GetNormalizedDoorState(){return state;}float GetControlValue(){return control;}};
struct SCR_InteractionHandlerComponent {BaseUserAction* selected=nullptr;UserActionContext* current=nullptr;BaseUserAction* m_pLastUserAction=nullptr;UserActionContext* m_pLastContext=nullptr;float m_fCurrentProgress=0;bool m_bIsPerforming=false;IEntity* actor=nullptr;Array<BaseUserAction*> filtered;Array<bool> permitted;
BaseUserAction* GetSelectedAction(){return selected;}UserActionContext* GetCurrentContext(){return current;}IEntity* GetControlledEntity(){return actor;}void GetFilteredActions(Array<BaseUserAction*>& actions,Array<bool>& allowed){actions=filtered;allowed=permitted;}
'''+accessor+r'''
};
struct PlayerController:IEntity {int id=1;IEntity* actor=nullptr;int GetPlayerId(){return id;}IEntity* GetControlledEntity(){return actor;}};
struct PlayerManager {PlayerController* controller=nullptr;IEntity* actor=nullptr;PlayerController* GetPlayerController(int){return controller;}IEntity* GetPlayerControlledEntity(int){return actor;}};
struct ERR_PlayerLife {UUID AccountId="original-account";};
struct Roster {ERR_PlayerLife* life=nullptr;IEntity* actor=nullptr;ERR_PlayerLife* CurrentActor(IEntity* value){return value==actor?life:nullptr;}};
struct Prison {IEntity* gate=nullptr;bool registered=true,lost=false;bool Registered(){return registered;}bool GateLost(){return lost;}IEntity* Gate(){return gate;}};
namespace ERR_Phase {enum {PRISON=1,RADIO_SEARCH=2,EXTRACTION=4};}
struct ERR_GameMode {static ERR_GameMode* current;bool active=true;int phase=ERR_Phase::PRISON;BaseWorld* world=nullptr;Roster* roster=nullptr;Prison* prison=nullptr;static ERR_GameMode* Get(){return current;}bool Active(){return active;}int Phase(){return phase;}BaseWorld* GetWorld(){return world;}Roster* Players(){return roster;}Prison* PrisonEscape(){return prison;}vector prisonPosition=Vector(6090,210,7160);vector PrisonPosition(){return prisonPosition;}};ERR_GameMode* ERR_GameMode::current=nullptr;
struct InputManager {float pressed=0;ERR_GameMode* changeDuringRead=nullptr;float GetActionValue(string name){assert(name=="PerformAction");if(changeDuringRead)changeDuringRead->active=false;return pressed;}};
struct MenuManager {bool open=false;void* GetTopMenu(){return open?this:nullptr;}};
struct Game {BaseWorld* world=nullptr;PlayerController* controller=nullptr;PlayerManager* players=nullptr;InputManager* input=nullptr;MenuManager* menus=nullptr;BaseWorld* GetWorld(){return world;}PlayerController* GetPlayerController(){return controller;}PlayerManager* GetPlayerManager(){return players;}InputManager* GetInputManager(){return input;}MenuManager* GetMenuManager(){return menus;}} game;Game* activeGame=&game;Game* GetGame(){return activeGame;}
namespace System {bool console=false;std::map<string,string> cli;bool IsConsoleApp(){return console;}bool GetCLIParam(string key,string& value){if(!cli.count(key))return false;value=cli[key];return true;}}
namespace Replication {bool server=true;bool IsServer(){return server;}}
namespace RplMode {enum {None,Listen,Dedicated};}namespace RplSession {int mode=RplMode::None;int Mode(){return mode;}}
struct ERR_OrdinaryInputObserverRules {
'''+shared+r'''
};
namespace ERR_Actors {bool CanFight(IEntity* actor){return actor&&actor->living;}}
namespace CompartmentAccessComponent {IEntity* GetVehicleIn(IEntity* actor){return actor->vehicle?actor:nullptr;}}
int headers=0,samples=0,geometries=0,cancels=0,choices=0;string lastChoice;string reason;bool lastSelected=false,lastContext=false,lastPermitted=false,lastBound=false,lastPerforming=false;float lastProgress=0;int lastPhase=0;
string Format(string,int phase,bool selected,bool context,bool permitted,bool bound,bool performing,float progress,float duration,float pressed){assert(duration==4);lastPhase=phase;lastSelected=selected;lastContext=context;lastPermitted=permitted;lastBound=bound;lastPerforming=performing;lastProgress=progress;return "SAMPLE";}
string Format(string,string name,int id){return name+":"+std::to_string(id);}
string Format(string,int index,string identity,int permission){return std::to_string(index)+"="+identity+":"+std::to_string(permission);}
string Format(string,string selected,bool context,int count,int permissions,int shown,bool truncated,string ordered){return "selected="+selected+" context="+std::to_string(context)+" actions="+std::to_string(count)+" permissions="+std::to_string(permissions)+" shown="+std::to_string(shown)+" truncated="+std::to_string(truncated)+" ordered=["+ordered+"]";}
vector lastPrison,lastGate,lastForward;
string Format(string,vector,vector,float,float,float,vector prison,vector gate,vector forward){lastPrison=prison;lastGate=gate;lastForward=forward;return "GEOMETRY";}
void PrintFormat(string,string,int,int){headers++;}
void PrintFormat(string format,string,int,int,string value){if(format.find("ERR GATE CHOICE")!=string::npos){choices++;lastChoice=value;}else if(format.find("CANCELLED")!=string::npos){cancels++;reason=value;}else if(value=="SAMPLE")samples++;else if(value=="GEOMETRY")geometries++;else assert(false);}
class ERR_OrdinaryGateObserver {public:
static ERR_OrdinaryGateObserver* s_Request;static bool s_Attempted;
ERR_GameMode* m_Mode=nullptr;BaseWorld* m_World=nullptr;PlayerController* m_Controller=nullptr;IEntity* m_Actor=nullptr;ERR_PlayerLife* m_Life=nullptr;UUID m_Account;IEntity* m_Gate=nullptr;BaseActionsManagerComponent* m_Manager=nullptr;ERR_UnlockPrisonAction* m_Lock=nullptr;UserActionContext* m_Context=nullptr;BaseDoorComponent* m_Door=nullptr;SCR_InteractionHandlerComponent* m_Handler=nullptr;
string m_Nonce;int m_Start=0,m_Previous=0,m_Index=0;bool m_Stopped=false,m_HeldAction=false;int m_ObservedPhase=-1;
'''+methods+r'''
};
ERR_OrdinaryGateObserver* ERR_OrdinaryGateObserver::s_Request=nullptr;bool ERR_OrdinaryGateObserver::s_Attempted=false;
struct Fixture {BaseWorld world,otherWorld;ERR_GameMode mode;IEntity actor,otherActor,gate,otherGate;PlayerController controller,otherController;PlayerManager players;Roster roster;ERR_PlayerLife life,otherLife;Prison prison;InputManager input;MenuManager menus;BaseActionsManagerComponent manager,otherManager;BaseDoorComponent door,otherDoor;UserActionContext context,otherContext;SCR_InteractionHandlerComponent handler,otherHandler;ERR_UnlockPrisonAction lock,otherLock;BaseUserAction foreignAction;
Fixture(){delete ERR_OrdinaryGateObserver::s_Request;ERR_OrdinaryGateObserver::s_Request=nullptr;ERR_OrdinaryGateObserver::s_Attempted=false;headers=samples=geometries=cancels=choices=0;lastChoice="";reason="";System::console=false;System::cli={{"errOrdinaryScenario","core"},{"errOrdinaryInputObserve","Run42"},{"errOrdinaryGateObserve","Run42"}};Replication::server=true;RplSession::mode=RplMode::None;activeGame=&game;ERR_GameMode::current=&mode;mode.world=&world;mode.roster=&roster;mode.prison=&prison;actor.world=gate.world=&world;controller.actor=&actor;controller.components[SCR_InteractionHandlerComponentKey]=&handler;players.controller=&controller;players.actor=&actor;roster.actor=&actor;roster.life=&life;prison.gate=&gate;gate.components[BaseActionsManagerComponentKey]=&manager;gate.components[BaseDoorComponentKey]=&door;manager.context=&context;manager.action=&lock;lock.owner=&gate;lock.className="ERR_UnlockPrisonAction";context.actions={&lock};handler.actor=&actor;handler.selected=handler.m_pLastUserAction=&lock;handler.current=handler.m_pLastContext=&context;handler.filtered={&lock};handler.permitted={true};game={&world,&controller,&players,&input,&menus};}
void sample(int index=1,int now=1100){ERR_OrdinaryGateObserver::Sample(&mode,&world,&controller,&actor,"Run42",1000,index,now);}
};
int main(){
// Held mode changes only admissible phase, never the original pins or clock.
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();auto p=ERR_OrdinaryGateObserver::s_Request;assert(p&&p->m_HeldAction&&p->m_ObservedPhase==ERR_Phase::PRISON);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(2,1200);f.sample(3,1300);assert(samples==3&&!cancels&&p->m_Start==1000&&p->m_ObservedPhase==ERR_Phase::RADIO_SEARCH);f.mode.phase=ERR_Phase::PRISON;f.sample(4,1400);assert(samples==3&&cancels==1);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(5,1500);assert(samples==3&&cancels==1);}
for(int fault=0;fault<5;fault++){Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; if(fault==0)System::cli["errOrdinaryHeldAction"]="foreign";if(fault==1)System::cli.erase("errOrdinaryLookObserve");if(fault==2)System::cli["errOrdinaryLookObserve"]="foreign";if(fault==3)f.mode.phase=ERR_Phase::RADIO_SEARCH;if(fault==4)System::cli["errOrdinaryHeldAction"]="";f.sample();assert(!samples);f.mode.phase=ERR_Phase::PRISON;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample(2,1200);assert(!samples);}
for(int fault=0;fault<8;fault++){Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(2,1200);assert(samples==2&&!cancels);if(fault==0)System::cli.erase("errOrdinaryHeldAction");if(fault==1)System::cli["errOrdinaryLookObserve"]="foreign";if(fault==2)f.actor.vehicle=true;if(fault==3)f.menus.open=true;if(fault==4)f.life.AccountId="replacement";if(fault==5)f.mode.phase=ERR_Phase::EXTRACTION;if(fault==6)f.players.actor=nullptr;if(fault==7)game.world=nullptr;f.sample(3,1300);assert(samples==2&&cancels==1);}
{Fixture f;f.sample();System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample(2,1200);assert(samples==1&&cancels==1);}
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(2,45999);assert(samples==2);f.sample(3,46000);assert(samples==2&&cancels==1);}
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(451,1200);assert(samples==1&&cancels==1);}
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42"; f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.door.control=1;f.door.state=.4;f.context.origin=Vector(6091,212,7155);f.gate.forward=Vector(1,0,0);f.handler.selected=nullptr;f.handler.current=nullptr;f.sample(2,1200);assert(samples==2&&geometries==2&&!cancels&&!lastSelected&&!lastBound&&lastPhase==ERR_Phase::RADIO_SEARCH);f.manager.context=&f.otherContext;f.sample(3,1300);assert(samples==2&&cancels==1);}
// Legacy gate-only observation retains its prior permitted phase reversal.
{Fixture f;f.sample();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(2,1200);f.mode.phase=ERR_Phase::PRISON;f.sample(3,1300);assert(samples==3&&!cancels);}
// Diagnostics are an independent opt-in beneath the same validated observer.
{Fixture f;f.sample();assert(choices==0);System::cli["errOrdinaryGateChoices"]="foreign";f.sample(2,1200);assert(choices==0&&samples==2);}
// A disabled stock door can be selected while the exact lock is cached available.
{Fixture f;System::cli["errOrdinaryGateChoices"]="Run42";f.foreignAction.className="ERR_PrisonDoorAction";f.foreignAction.id=7;f.handler.filtered={&f.foreignAction,&f.lock};f.handler.permitted={false,true};f.handler.selected=&f.foreignAction;f.sample();assert(choices==1&&samples==1&&geometries==1);assert(!lastSelected&&lastContext&&lastPermitted);assert(lastChoice=="selected=ERR_PrisonDoorAction:7 context=1 actions=2 permissions=2 shown=2 truncated=0 ordered=[0=ERR_PrisonDoorAction:7:0,1=ERR_UnlockPrisonAction:4:1]");assert(f.handler.selected==&f.foreignAction&&f.handler.filtered[0]==&f.foreignAction);}
// Preserve native ordering and missing cached data without guessing authority.
{Fixture f;System::cli["errOrdinaryGateChoices"]="Run42";f.handler.selected=nullptr;f.handler.current=&f.otherContext;f.handler.filtered={nullptr,&f.lock};f.handler.permitted={false};f.sample();assert(choices==1&&!lastSelected&&!lastContext);assert(lastChoice=="selected=none:-1 context=0 actions=2 permissions=1 shown=2 truncated=0 ordered=[0=none:-1:0,1=ERR_UnlockPrisonAction:4:-1]");}
{Fixture f;System::cli["errOrdinaryGateChoices"]="Run42";f.handler.filtered.clear();f.handler.permitted.clear();for(int i=0;i<12;i++){f.handler.filtered.push_back(&f.lock);f.handler.permitted.push_back(true);}f.sample();assert(choices==1);assert(lastChoice.find("actions=12 permissions=12 shown=8 truncated=1")!=string::npos);assert(lastChoice.find("7=ERR_UnlockPrisonAction:4:1")!=string::npos&&lastChoice.find("8=ERR_")==string::npos);f.prison.gate=&f.otherGate;f.sample(2,1200);assert(choices==1&&cancels==1);}
// Direct diagnostic entry cannot bypass a stopped or replaced original binding.
{Fixture f;f.sample();System::cli["errOrdinaryGateChoices"]="Run42";auto request=ERR_OrdinaryGateObserver::s_Request;request->m_Stopped=true;request->ObserveChoices(2,1200);assert(choices==0);request->m_Stopped=false;f.roster.life=&f.otherLife;request->ObserveChoices(2,1200);assert(choices==0);}
{Fixture f;f.handler.m_bIsPerforming=true;f.handler.m_fCurrentProgress=2.25;f.input.pressed=1;f.sample();assert(headers==1&&samples==1&&geometries==1&&!cancels);assert(lastSelected&&lastContext&&lastPermitted&&lastBound&&lastPerforming&&lastProgress==2.25f);assert(lastPrison[2]==7160&&lastGate[2]==7158&&lastForward[2]==1);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.handler.m_bIsPerforming=false;f.handler.m_fCurrentProgress=0;f.door.control=1;f.sample(2,1200);assert(samples==2&&headers==1&&!cancels&&lastPhase==ERR_Phase::RADIO_SEARCH);}
// Actual accessor never attributes accumulated progress from another selection/context.
for(int fault=0;fault<5;fault++){Fixture f;f.handler.m_bIsPerforming=true;f.handler.m_fCurrentProgress=3;BaseUserAction* expected=&f.lock;UserActionContext* ctx=&f.context;if(fault==0)expected=nullptr;if(fault==1)f.handler.selected=&f.foreignAction;if(fault==2)f.handler.current=&f.otherContext;if(fault==3)f.handler.m_pLastUserAction=&f.foreignAction;if(fault==4)f.handler.m_pLastContext=&f.otherContext;float progress=99;bool performing=true;assert(!f.handler.ERR_GateReadProgress(expected,ctx,progress,performing));assert(progress==0&&!performing);}
{Fixture f;f.handler.selected=&f.foreignAction;f.handler.m_fCurrentProgress=3;f.handler.m_bIsPerforming=true;f.sample();assert(samples==1&&!lastSelected&&!lastBound&&!lastPerforming&&lastProgress==0);}
// Cached flags cannot become positive via a missing/mismatched native array.
for(int fault=0;fault<4;fault++){Fixture f;if(fault==0)f.handler.filtered.clear();if(fault==1)f.handler.permitted.clear();if(fault==2)f.handler.filtered={&f.foreignAction};if(fault==3)f.handler.permitted={false};f.sample();assert(samples==1&&!lastPermitted);}
for(int fault=0;fault<8;fault++){Fixture f;if(fault==0)System::cli.erase("errOrdinaryGateObserve");if(fault==1)System::cli["errOrdinaryGateObserve"]="foreign";if(fault==2)System::cli["errOrdinaryInputObserve"]="foreign";if(fault==3)System::console=true;if(fault==4)Replication::server=false;if(fault==5)RplSession::mode=RplMode::Listen;if(fault==6)System::cli["errOrdinaryScenario"]="other";if(fault==7)RplSession::mode=RplMode::Dedicated;f.sample();assert(!samples&&!cancels&&!ERR_OrdinaryGateObserver::s_Attempted);}
// Registration cannot recover after initial absent/ambiguous/native-mismatched gate.
for(int fault=0;fault<8;fault++){Fixture f;if(fault==0)f.prison.registered=false;if(fault==1)f.prison.lost=true;if(fault==2)f.prison.gate=nullptr;if(fault==3)f.context.actions.clear();if(fault==4){f.otherLock.owner=&f.gate;f.context.actions.push_back(&f.otherLock);}if(fault==5)f.lock.owner=&f.otherGate;if(fault==6)f.lock.duration=3;if(fault==7)f.manager.action=&f.foreignAction;f.sample();assert(!samples&&cancels==1&&reason=="original-prison-lock-unavailable");f.prison.registered=true;f.prison.lost=false;f.prison.gate=&f.gate;f.context.actions={&f.lock};f.lock.owner=&f.gate;f.lock.duration=4;f.manager.action=&f.lock;f.sample(2,1200);assert(!samples&&cancels==1);}
for(int fault=0;fault<26;fault++){Fixture f;f.sample();if(fault==0)game.controller=&f.otherController;if(fault==1)f.controller.actor=&f.otherActor;if(fault==2)f.handler.actor=&f.otherActor;if(fault==3)f.players.actor=&f.otherActor;if(fault==4)f.players.controller=&f.otherController;if(fault==5)f.life.AccountId="replacement";if(fault==6)f.roster.life=&f.otherLife;if(fault==7)f.actor.world=&f.otherWorld;if(fault==8)f.gate.world=&f.otherWorld;if(fault==9)f.mode.active=false;if(fault==10)f.mode.phase=ERR_Phase::EXTRACTION;if(fault==11)f.actor.living=false;if(fault==12)f.actor.vehicle=true;if(fault==13)activeGame=nullptr;if(fault==14)f.menus.open=true;if(fault==15)f.prison.registered=false;if(fault==16)f.prison.gate=&f.otherGate;if(fault==17)f.prison.lost=true;if(fault==18)f.gate.components[BaseActionsManagerComponentKey]=&f.otherManager;if(fault==19)f.gate.components[BaseDoorComponentKey]=&f.otherDoor;if(fault==20)f.controller.components[SCR_InteractionHandlerComponentKey]=&f.otherHandler;if(fault==21)f.manager.context=&f.otherContext;if(fault==22)f.manager.action=&f.otherLock;if(fault==23)f.lock.owner=&f.otherGate;if(fault==24)f.lock.duration=5;if(fault==25)f.controller.id=0;f.sample(2,1200);assert(samples==1&&cancels==1&&reason=="native-player-or-prison-context-lost");f.sample(3,1300);assert(cancels==1);}
{Fixture f;f.input.changeDuringRead=&f.mode;f.sample();assert(!samples&&!headers&&cancels==1);}
for(int fault=0;fault<5;fault++){Fixture f;f.sample();int index=2,now=1200;if(fault==0)index=1;if(fault==1)index=3;if(fault==2)index=451;if(fault==3)now=1099;if(fault==4)now=46000;f.sample(index,now);assert(samples==1&&cancels==1&&reason=="sample-or-clock-bound");}
for(int fault=0;fault<9;fault++){Fixture f;if(fault==0)f.input.pressed=std::numeric_limits<float>::quiet_NaN();if(fault==1)f.handler.m_fCurrentProgress=-1;if(fault==2)f.door.state=2;if(fault==3)f.door.control=std::numeric_limits<float>::infinity();if(fault==4)f.context.radius=0;if(fault==5)f.actor.origin[0]=std::numeric_limits<float>::infinity();if(fault==6)f.mode.prisonPosition[1]=std::numeric_limits<float>::quiet_NaN();if(fault==7)f.gate.origin[0]=std::numeric_limits<float>::infinity();if(fault==8)f.gate.forward=Vector(0,0,0);f.sample();assert(!samples&&cancels==1&&reason=="invalid-native-action-sample");}
{Fixture f;System::cli["errOrdinaryScenario"]="chat";f.sample();System::cli.erase("errOrdinaryGateObserve");f.sample(2,1200);assert(cancels==1);System::cli["errOrdinaryGateObserve"]="Run42";f.sample(3,1300);assert(samples==1&&cancels==1);}
{Fixture f;f.sample();ERR_OrdinaryGateObserver::Sample(&f.mode,&f.otherWorld,&f.controller,&f.actor,"Run42",1000,2,1200);assert(cancels==1&&reason=="original-binding-changed");}
}
''')
print('PASS: actual gate observer binds native registered action/context and current life, reads accumulated progress, refuses stale bindings and never revives outside original bounds')