Add typed field-flight prototype and preserve native qualification failures
This commit is contained in:
@@ -2,12 +2,12 @@
|
||||
from policy_harness import ROOT, body, run
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/ERR_OrdinaryInputObserver.c'
|
||||
def cpp(s):
|
||||
s=s.replace('protected ', '').replace('out string nonce','string& nonce')
|
||||
s=s.replace('protected ', '').replace('out bool held', 'bool& held').replace('out string nonce','string& nonce')
|
||||
for t in ('ERR_GameMode','PlayerController','IEntity','ERR_PlayerLife','ERR_OrdinaryInputObserver','PlayerManager','SCR_InventoryMenuUI','Widget'):
|
||||
s=s.replace(t+' mode',t+'* mode').replace(t+' controller',t+'* controller').replace(t+' actor',t+'* actor').replace(t+' life',t+'* life').replace(t+' request',t+'* request').replace(t+' current',t+'* current').replace(t+' manager',t+'* manager').replace(t+' menu',t+'* menu').replace(t+' root',t+'* root').replace(t+' expectedMenu',t+'* expectedMenu').replace(t+' expectedRoot',t+'* expectedRoot').replace(t+' overlay',t+'* overlay')
|
||||
for v in ('mode','controller','actor','request','life','current','manager','menu','root','m_Mode','m_World','m_Controller','m_Actor','m_Character','m_Menu','s_Request','expectedMenu','expectedRoot','m_CaptureMenu','m_CaptureRoot','overlay','m_aHitZonePoints'):
|
||||
s=s.replace(v+'.',v+'->')
|
||||
for scope in ('System','Replication','ERR_Phase','ERR_GameMode','ERR_Actors','SCR_InventoryMenuUI','ERR_OrdinaryInputObserverRules','ERR_OrdinaryLookObserver','ERR_OrdinaryGateObserver','vector','Math'):
|
||||
for scope in ('System','Replication','RplSession','RplMode','CompartmentAccessComponent','ERR_Phase','ERR_GameMode','ERR_Actors','SCR_InventoryMenuUI','ERR_OrdinaryInputObserverRules','ERR_OrdinaryLookObserver','ERR_OrdinaryGateObserver','vector','Math'):
|
||||
s=s.replace(scope+'.',scope+'::')
|
||||
s=s.replace('GetGame().','GetGame()->').replace('GetPlayerManager().','GetPlayerManager()->').replace('GetInputManager().','GetInputManager()->').replace('GetMenuManager().','GetMenuManager()->').replace('GetCallqueue().','GetCallqueue()->').replace('Players().','Players()->')
|
||||
s=s.replace('CharacterControllerComponent.Cast(actor->FindComponent(CharacterControllerComponent))','actor->FindComponent(0)').replace('FindComponent(CharacterControllerComponent)','FindComponent(0)')
|
||||
@@ -17,9 +17,10 @@ def cpp(s):
|
||||
s=s.replace('string.Format', 'Format').replace('Widget* overlay;', 'Widget* overlay=null;')
|
||||
s=s.replace('null','nullptr').replace('bool open;', 'bool open = false;')
|
||||
s=s.replace('nonce.Length()', 'int(nonce.size())').replace('allowed.Contains(nonce[i])', '(allowed.find(nonce[i]) != string::npos)')
|
||||
s=s.replace('nonce.Length()', 'int(nonce.size())').replace('allowed.Contains(nonce[i])', '(allowed.find(nonce[i]) != string::npos)')
|
||||
return s
|
||||
state=cpp(body(P,'string ERR_InputObserverInventoryState('))
|
||||
rules='\n'.join(cpp(body(P,x)) for x in ('static bool Nonce(', 'static bool Within(', 'static bool Stationary('))
|
||||
rules='\n'.join(cpp(body(P,x)) for x in ('static bool Nonce(', 'static bool HeldScope(', 'static bool PhaseAllowed(', 'static bool Within(', 'static bool Stationary('))
|
||||
methods='\n'.join(cpp(body(P,x)) for x in ('protected static bool Enabled(', 'static void Queue(', 'protected bool Valid(', 'protected void Record(', 'protected void CancelCapture(', 'protected void Capture(', 'protected void CaptureLater(', 'protected void Observe(', 'protected void Sample(', 'protected void End(', 'void Cancel(', 'static void ClearWorld('))
|
||||
run(r'''
|
||||
#include <cassert>
|
||||
@@ -33,10 +34,12 @@ struct vector {float x=0,y=0,z=0;float Length(){return std::sqrt(x*x+y*y+z*z);}s
|
||||
namespace Math {float AbsFloat(float x){return std::abs(x);}}
|
||||
namespace System {bool console=false;int now=0;std::map<string,string> cli;std::vector<string> shots;bool IsConsoleApp(){return console;}int GetTickCount(){return now;}bool GetCLIParam(string key,string& value){if(!cli.count(key))return false;value=cli[key];return true;}void MakeScreenshot(string path){shots.push_back(path);}}
|
||||
namespace Replication {bool server=true;bool IsServer(){return server;}}
|
||||
namespace ERR_Phase {enum {PRISON,PREPARING,DEFEAT};}
|
||||
namespace ERR_Phase {enum {PREPARING=0,PRISON=1,RADIO_SEARCH=2,DEFEAT=6};}
|
||||
namespace RplMode {enum {None,Listen,Dedicated};}namespace RplSession {int mode=RplMode::None;int Mode(){return mode;}}
|
||||
struct BaseWorld {float time=0;float GetWorldTime(){return time;}};
|
||||
struct CharacterControllerComponent {bool unconscious=false,disabled=false;vector input,velocity;bool IsUnconscious(){return unconscious;}bool GetDisableMovementControls(){return disabled;}vector GetMovementInput(){return input;}vector GetVelocity(){return velocity;}};
|
||||
struct IEntity {BaseWorld* world=nullptr;CharacterControllerComponent* component=nullptr;bool conscious=true;vector origin;BaseWorld* GetWorld(){return world;}CharacterControllerComponent* FindComponent(int){return component;}vector GetOrigin(){return origin;}};
|
||||
struct IEntity {BaseWorld* world=nullptr;CharacterControllerComponent* component=nullptr;bool conscious=true,vehicle=false;vector origin;BaseWorld* GetWorld(){return world;}CharacterControllerComponent* FindComponent(int){return component;}vector GetOrigin(){return origin;}};
|
||||
namespace CompartmentAccessComponent {IEntity* GetVehicleIn(IEntity* actor){return actor->vehicle?actor:nullptr;}}
|
||||
namespace ERR_Actors {bool CanFight(IEntity* actor){return actor&&actor->conscious;}}
|
||||
struct PlayerController {int id=1;IEntity* actor=nullptr;int GetPlayerId(){return id;}IEntity* GetControlledEntity(){return actor;}};
|
||||
struct ERR_PlayerLife {UUID AccountId="private-account";};
|
||||
@@ -75,14 +78,14 @@ struct ERR_OrdinaryGateObserver {
|
||||
struct ERR_OrdinaryInputObserver {
|
||||
static ERR_OrdinaryInputObserver* s_Request;static bool s_Attempted;
|
||||
ERR_GameMode* m_Mode=nullptr;BaseWorld* m_World=nullptr;PlayerController* m_Controller=nullptr;IEntity* m_Actor=nullptr;CharacterControllerComponent* m_Character=nullptr;ERR_PlayerLife* m_Life=nullptr;
|
||||
UUID m_Account;int m_PlayerId=0;string m_Nonce;bool m_Screenshots=false,m_Finished=false,m_Ready=false,m_Opened=false,m_Closed=false;SCR_InventoryMenuUI* m_Menu=nullptr;
|
||||
UUID m_Account;int m_PlayerId=0;string m_Nonce;bool m_HeldAction=false;int m_ObservedPhase=-1;bool m_Screenshots=false,m_Finished=false,m_Ready=false,m_Opened=false,m_Closed=false;SCR_InventoryMenuUI* m_Menu=nullptr;
|
||||
string m_CaptureSuffix;SCR_InventoryMenuUI* m_CaptureMenu=nullptr;Widget* m_CaptureRoot=nullptr;int m_CaptureDue=0,m_CaptureExpires=0,m_CaptureLoadedAt=-1,m_InventoryStateLines=0;bool m_BaselineCaptureQueued=false,m_OpenCaptureQueued=false,m_ClosedCaptureQueued=false;
|
||||
int m_Start=0,m_Previous=0,m_Samples=0,m_BaselineSince=-1;vector m_BaselineOrigin;float m_LastWorldTime=0;
|
||||
'''+methods+r'''
|
||||
};
|
||||
ERR_OrdinaryInputObserver* ERR_OrdinaryInputObserver::s_Request=nullptr;bool ERR_OrdinaryInputObserver::s_Attempted=false;
|
||||
struct Fixture {ERR_GameMode mode;BaseWorld world;PlayerController controller;IEntity actor;CharacterControllerComponent character;ERR_PlayerLife life;Widget widget;SCR_InventoryMenuUI menu;
|
||||
Fixture(){game={};System::cli={{"errOrdinaryScenario","core"},{"errOrdinaryInputObserve","Run42"},{"errOrdinaryInputScreenshots","1"}};System::now=0;System::console=false;System::shots.clear();Replication::server=true;events.clear();inventoryStates.clear();inventoryReasons.clear();samples=0;ERR_OrdinaryInputObserver::s_Request=nullptr;ERR_OrdinaryInputObserver::s_Attempted=false;SCR_InventoryMenuUI::current=nullptr;ERR_GameMode::current=&mode;mode.world=&world;mode.roster.actor=&actor;mode.roster.life=&life;actor.world=&world;actor.component=&character;controller.actor=&actor;game.world=&world;game.controller=&controller;game.manager.controller=&controller;game.manager.actor=&actor;menu.character=&character;menu.root=&widget;}
|
||||
Fixture(){game={};System::cli={{"errOrdinaryScenario","core"},{"errOrdinaryInputObserve","Run42"},{"errOrdinaryInputScreenshots","1"}};System::now=0;System::console=false;System::shots.clear();Replication::server=true;RplSession::mode=RplMode::None;events.clear();inventoryStates.clear();inventoryReasons.clear();samples=0;ERR_OrdinaryInputObserver::s_Request=nullptr;ERR_OrdinaryInputObserver::s_Attempted=false;SCR_InventoryMenuUI::current=nullptr;ERR_GameMode::current=&mode;mode.world=&world;mode.roster.actor=&actor;mode.roster.life=&life;actor.world=&world;actor.component=&character;controller.actor=&actor;game.world=&world;game.controller=&controller;game.manager.controller=&controller;game.manager.actor=&actor;menu.character=&character;menu.root=&widget;}
|
||||
ERR_OrdinaryInputObserver* queue(){ERR_OrdinaryInputObserver::Queue(&mode,&controller,&actor);return ERR_OrdinaryInputObserver::s_Request;}
|
||||
void sample(int ms){System::now=ms;world.time=ms;ERR_OrdinaryInputObserver::s_Request->Sample();}
|
||||
void capture(int ms){System::now=ms;world.time=ms;ERR_OrdinaryInputObserver::s_Request->CaptureLater();}
|
||||
@@ -92,6 +95,38 @@ struct Fixture {ERR_GameMode mode;BaseWorld world;PlayerController controller;IE
|
||||
};
|
||||
int count(string value){int n=0;for(auto event:events)if(event==value)n++;return n;}
|
||||
int main(){
|
||||
|
||||
// Execute the actual shared option/phase rules and actual queued lifecycle.
|
||||
for(int fault=0;fault<9;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)System::cli.erase("errOrdinaryGateObserve");
|
||||
if(fault==4)System::cli["errOrdinaryGateObserve"]="foreign";
|
||||
if(fault==5)f.mode.phase=ERR_Phase::RADIO_SEARCH;
|
||||
if(fault==6)RplSession::mode=RplMode::Listen;
|
||||
if(fault==7)RplSession::mode=RplMode::Dedicated;
|
||||
if(fault==8)System::cli["errOrdinaryHeldAction"]="";
|
||||
assert(!f.queue()&&game.queue.queued==0);assert(ERR_OrdinaryInputObserver::s_Attempted==(fault==5));
|
||||
if(fault==5){f.mode.phase=ERR_Phase::PRISON;assert(!f.queue());}}
|
||||
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42";
|
||||
auto p=f.queue();assert(p&&p->m_HeldAction&&p->m_ObservedPhase==ERR_Phase::PRISON);f.sample(100);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(200);f.sample(300);assert(samples==3&&!p->m_Finished&&p->m_ObservedPhase==ERR_Phase::RADIO_SEARCH&&p->m_Start==0);
|
||||
f.mode.phase=ERR_Phase::PRISON;f.sample(400);assert(samples==3&&p->m_Finished);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(500);assert(samples==3);ERR_OrdinaryInputObserver::ClearWorld();assert(!f.queue());}
|
||||
for(int fault=0;fault<10;fault++){Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42";auto p=f.queue();f.sample(100);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(200);
|
||||
if(fault==0)System::cli.erase("errOrdinaryHeldAction");
|
||||
if(fault==1)System::cli["errOrdinaryGateObserve"]="foreign";
|
||||
if(fault==2)f.open();
|
||||
if(fault==3)f.actor.vehicle=true;
|
||||
if(fault==4)f.life.AccountId="replacement";
|
||||
if(fault==5)f.mode.phase=ERR_Phase::DEFEAT;
|
||||
if(fault==6)f.character.unconscious=true;
|
||||
if(fault==7)game.world=nullptr;
|
||||
if(fault==8)game.manager.actor=nullptr;
|
||||
if(fault==9)p->m_Samples=450;
|
||||
f.sample(300);assert(p->m_Finished&&samples==2);}
|
||||
{Fixture f;auto p=f.queue();f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(100);assert(p->m_Finished&&samples==0);}
|
||||
{Fixture f;auto p=f.queue();System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42";f.sample(100);assert(p->m_Finished&&samples==0);}
|
||||
{Fixture f;System::cli["errOrdinaryHeldAction"]="Run42";System::cli["errOrdinaryLookObserve"]="Run42";System::cli["errOrdinaryGateObserve"]="Run42";auto p=f.queue();f.sample(100);f.mode.phase=ERR_Phase::RADIO_SEARCH;f.sample(44999);assert(samples==2&&p->m_Start==0);f.sample(45000);assert(samples==2&&p->m_Finished);}
|
||||
assert(ERR_OrdinaryInputObserverRules::Nonce("aZ09"));for(string n:std::vector<string>{"","../bad","a-b","a_b","line\n","a b","$logs:x",string(33,'x')})assert(!ERR_OrdinaryInputObserverRules::Nonce(n));
|
||||
assert(ERR_OrdinaryInputObserverRules::Within(0,44900,44999,449));assert(!ERR_OrdinaryInputObserverRules::Within(0,44900,45000,449));assert(!ERR_OrdinaryInputObserverRules::Within(0,100,99,2));assert(!ERR_OrdinaryInputObserverRules::Within(0,1,2,450));
|
||||
for(int fault=0;fault<6;fault++){Fixture f;
|
||||
|
||||
Reference in New Issue
Block a user