62 lines
3.7 KiB
Python
62 lines
3.7 KiB
Python
"""Exercise production placement vetoes for players, spectators and editor cameras."""
|
|
import re
|
|
from policy_harness import ROOT, body, run
|
|
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_GarageVehicles.c'
|
|
s=body(p,'protected bool Observers(').replace('protected ','').replace('array<vector>', 'Array<Vec>').replace('array<IEntity>', 'Array<IEntity*>').replace('array<int> ids = {};','std::vector<int> ids;').replace('foreach (int id : ids)','for (int id : ids)').replace('null','nullptr')
|
|
s=s.replace('Array<Vec> positions','Array<Vec>& positions').replace('Array<IEntity*> actors','Array<IEntity*>& actors')
|
|
s=s.replace('ERR_ForceRules.', 'ERR_ForceRules::').replace('ERR_ObserverReason.NONE','ERR_ObserverReason::NONE')
|
|
for cls in ['SCR_PlayerController','SCR_EditorManagerEntity','SCR_EditorManagerCore','IEntity']:
|
|
s=s.replace(cls+'.',cls+'::')
|
|
s=re.sub(r'\b'+cls+r' (\w+)',cls+r'* \1',s)
|
|
s=s.replace('SCR_EditorManagerCore::GetInstance(SCR_EditorManagerCore)','SCR_EditorManagerCore::GetInstance()')
|
|
s=s.replace('SCR_EditorManagerEntity* editor;', 'SCR_EditorManagerEntity* editor = nullptr;')
|
|
for prefix in ['GetGame()','GetPlayerManager()','controller','body','watched','editors','editor']:
|
|
s=s.replace(prefix+'.',prefix+'->')
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <cmath>
|
|
#include <vector>
|
|
struct Vec{float x=0,z=0;};
|
|
template<class T>struct Array:std::vector<T>{void Clear(){this->clear();}void Insert(T t){this->push_back(t);}};
|
|
namespace ERR_ForceRules{bool FiniteVector(Vec v){return std::isfinite(v.x)&&std::isfinite(v.z);}}
|
|
namespace Geometry{float DistanceXZ(Vec a, Vec b){return std::hypot(a.x-b.x,a.z-b.z);}}
|
|
namespace ERR_ObserverReason{const int NONE=0;}
|
|
struct IEntity{Vec p;Vec GetOrigin(){return p;}};
|
|
struct SCR_PlayerController{
|
|
IEntity* body=nullptr;IEntity* watched=nullptr;int state=0;
|
|
IEntity* GetControlledEntity(){return body;}IEntity* ERR_ObservedEntity(){return watched;}int ERR_ObserverState(){return state;}
|
|
static SCR_PlayerController* Cast(SCR_PlayerController* p){return p;}
|
|
};
|
|
struct SCR_EditorManagerEntity{bool opened=false;bool IsOpened(){return opened;}};
|
|
SCR_EditorManagerEntity editor;
|
|
struct SCR_EditorManagerCore{
|
|
static SCR_EditorManagerCore* GetInstance(){static SCR_EditorManagerCore c;return &c;}
|
|
static SCR_EditorManagerCore* Cast(SCR_EditorManagerCore* p){return p;}
|
|
SCR_EditorManagerEntity* GetEditorManager(int){return &editor;}
|
|
};
|
|
struct Manager{
|
|
std::vector<SCR_PlayerController*> clients;
|
|
void GetPlayers(std::vector<int>& ids){for(unsigned i=0;i<clients.size();i++)ids.push_back(i);}
|
|
SCR_PlayerController* GetPlayerController(int id){return clients[id];}
|
|
};
|
|
struct Game{Manager players;Manager* GetPlayerManager(){return &players;}} game;
|
|
Game* GetGame(){return &game;}
|
|
''' + s + r'''
|
|
int main(){
|
|
Array<Vec> positions;Array<IEntity*> actors;
|
|
assert(Observers(positions,actors)&&positions.empty());
|
|
game.players.clients={nullptr};assert(!Observers(positions,actors));
|
|
SCR_PlayerController c;game.players.clients={&c};assert(!Observers(positions,actors));
|
|
IEntity player{{10,0}}, watched{{500,0}};c.body=&player;
|
|
assert(Observers(positions,actors)&&positions.size()==1&&actors[0]==&player);
|
|
editor.opened=true;assert(!Observers(positions,actors));editor.opened=false;
|
|
c.state=1;assert(!Observers(positions,actors));c.watched=&watched;
|
|
assert(Observers(positions,actors)&&positions.size()==2&&actors[1]==&watched);
|
|
c.body=nullptr;assert(Observers(positions,actors)&&positions.size()==1&&actors[0]==&watched);
|
|
watched.p={NAN,0};assert(!Observers(positions,actors));watched.p={500,0};
|
|
c.state=0;assert(!Observers(positions,actors));
|
|
|
|
}
|
|
''')
|
|
print('PASS: bodies and spectator targets are collected; unknown, nonfinite and editor views veto spawning/cleanup; no connected players yields an empty known view')
|