Files
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

103 lines
6.5 KiB
Python

"""Execute production view-distance policy, local ownership and command bodies.
Native rendering and replication require separate engine validation.
"""
import re
from policy_harness import ROOT, body, run
core = ROOT/'addons/core/Scripts/Game/ERR/00_Core'
service = core/'ERR_ViewDistance.c'
admin = core/'ERR_AdminService.c'
settings = core/'ERR_Settings.c'
def cpp(s):
s = s.replace('protected ', '').replace('out int ', 'int& ')
for name in ('Math', 'System', 'ERR_Settings', 'ERR_CommandArguments', 'ERR_TimeService', 'ERR_EnvironmentService', 'ERR_AdminMenuFields'):
s = s.replace(name + '.', name + '::')
s = s.replace('GetGame().', 'GetGame()->').replace('mode.Settings().', 'mode.Settings()->')
s = s.replace('GetGame()->GetViewDistanceServerLimit().ToString()', 'std::to_string(GetGame()->GetViewDistanceServerLimit())')
s = s.replace('mode.Settings()->Get("viewDistanceMetres").ToString()', 'std::to_string(mode.Settings()->Get("viewDistanceMetres"))')
s = s.replace('value.ToString()', 'std::to_string(value)')
s = s.replace('"0123456789".IndexOf(', 'string("0123456789").IndexOf(')
return s.replace('array<string>', 'Strings').replace('ERR_GameMode mode', 'ERR_GameMode& mode').replace('Strings replies', 'Strings& replies')
methods = '\n'.join(cpp(body(service, sig)) for sig in ('static int ServerDistance(', 'static float LocalDistance(', 'void Apply(', 'void Restore('))
run(r'''
#include <cassert>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
struct string : std::string {
using std::string::string; string(std::string s):std::string(s){}
bool IsEmpty(){return empty();} int Length(){return size();}
string Substring(int a,int b){return substr(a,b);} int ToInt(){return std::stoi(*this);}
int IndexOf(string s){auto n=find(s);return n==npos?-1:int(n);}
};
struct Strings:std::vector<string> {using vector::vector;int Count(){return size();}void Insert(string s){push_back(s);}};
namespace Math {float Min(float a,float b){return std::min(a,b);}float Max(float a,float b){return std::max(a,b);}float AbsFloat(float f){return std::abs(f);}}
namespace System {bool dedicated=false;bool IsConsoleApp(){return dedicated;}}
struct Game {float current=1600,minimum=500,maximum=10000,limit=5000;int writes=0;
float GetViewDistance(){return current;}float GetMinimumViewDistance(){return minimum;}
float GetMaximumViewDistance(){return maximum;}float GetViewDistanceServerLimit(){return limit;}
void SetViewDistance(float v){current=v;++writes;}} game;
Game* live=&game;Game* GetGame(){return live;}
struct Distance {float m_Original=-1,m_Applied=-1;
''' + methods + r'''
};
struct ERR_Settings {
''' + cpp(body(settings,'static bool Valid(')) + cpp(body(settings,'static int AddedDefault(')) + cpp(body(settings,'static bool Randomizable(')) + r'''
int saved=0;bool fail=false;int Get(string key){return saved;}bool Set(string key,int value){if(fail||!Valid(key,value))return false;saved=value;return true;}
};
struct ERR_TimeService {static bool ParseClock(string,int&){return false;}};
struct ERR_EnvironmentService {static bool ParseDate(string,int&){return false;}static bool ParseProfile(string,int&){return false;}};
struct ERR_CommandArguments {
''' + cpp(body(admin,'static bool Integer(')) + cpp(body(admin,'static bool Selection(')) + r'''
};
struct ERR_AdminMenuFields {static string Display(string,string value){return value;}};
struct ERR_GameMode {ERR_Settings storage;int published=0;ERR_Settings* Settings(){return &storage;}void PublishViewDistance(){++published;}};
struct Admin {
''' + cpp(body(admin,'protected bool ViewDistanceCommand(')) + r'''
};
int main(){
assert(ERR_Settings::AddedDefault("viewDistanceMetres")==0);
assert(!ERR_Settings::Randomizable("viewDistanceMetres"));
for(int v:{-2,-1,1,499,10001})assert(!ERR_Settings::Valid("viewDistanceMetres",v));
for(int v:{0,500,2500,10000})assert(ERR_Settings::Valid("viewDistanceMetres",v));
assert(Distance::ServerDistance(0,1600)==0);
assert(Distance::ServerDistance(5000,1600)==1600);
assert(Distance::ServerDistance(3000,0)==3000);
assert(Distance::LocalDistance(3000,500,2500,5000)==2500);
assert(Distance::LocalDistance(3000,500,10000,1600)==1600);
assert(Distance::LocalDistance(500,1000,10000,800)==800);
Distance local;local.Apply(0);assert(game.writes==0);
local.Apply(3000);assert(game.current==3000&&game.writes==1);
local.Apply(3000);assert(game.writes==1);
local.Apply(6000);assert(game.current==5000);
local.Apply(0);assert(game.current==1600);
local.Apply(2500);game.current=900;local.Restore();assert(game.current==900); // another camera owner wins
local.Apply(3500);local.Restore();assert(game.current==900); // new override captures fresh baseline
System::dedicated=true;local.Apply(3000);assert(game.current==900);System::dedicated=false;
live=nullptr;local.Apply(3000);local.Restore();live=&game;
Admin admin;ERR_GameMode mode;Strings replies;
assert(!admin.ViewDistanceCommand(mode,{"mission","weather","show"},replies));
assert(admin.ViewDistanceCommand(mode,{"mission","viewdistance","set","3000"},replies));
assert(mode.storage.saved==3000&&mode.published==1);
mode.storage.fail=true;admin.ViewDistanceCommand(mode,{"mission","viewdistance","set","4000"},replies);
assert(mode.storage.saved==3000&&mode.published==1);mode.storage.fail=false;
for(string v:{"-1","random","499","10001","1.5","2500junk","9999999"}){
admin.ViewDistanceCommand(mode,{"mission","viewdistance","set",v},replies);
assert(mode.storage.saved==3000&&mode.published==1);
}
admin.ViewDistanceCommand(mode,{"mission","viewdistance","show"},replies);assert(mode.published==1);
admin.ViewDistanceCommand(mode,{"mission","viewdistance","set","default"},replies);
assert(mode.storage.saved==0&&mode.published==2);
}
''')
# Lifecycle wiring: callback + periodic application cover JIP and native menu resets.
mode=(core/'ERR_GameMode.c').read_text()
assert '[RplProp(onRplName: "ApplyLocalViewDistance")]' in mode
assert 'CallLater(ApplyLocalViewDistance, 1000, true)' in body(core/'ERR_GameMode.c','protected override void EOnInit(')
assert 'GetTopMenu()) return;' in body(core/'ERR_GameMode.c','protected void ApplyLocalViewDistance(')
for sig in ('protected override void OnGameModeEnd(', 'protected void StopServices('):
assert 'StopLocalViewDistance();' in body(core/'ERR_GameMode.c',sig)
execute=body(admin,'void Execute(')
assert execute.index('if (!authorized)') < execute.index('ViewDistanceCommand(')
print('PASS: view-distance bounds, default, save failures, command parsing, temporary ownership, server/platform limits and lifecycle wiring')