Capture current mission, AI, map and administration development

Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
This commit is contained in:
2026-10-13 22:52:53 +02:00
parent a951a96edc
commit 6a667d8deb
8104 changed files with 2124945 additions and 2061 deletions
+24 -3
View File
@@ -4,21 +4,24 @@ from policy_harness import ROOT, body, run
MODE = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c'
SPAWN = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnLogic.c'
def cpp(s):
# Test mission scheduling inside the existing performance wrapper.
s=s.replace('ServerTickMeasured(', 'ServerTick(').replace('System.', 'System::').replace('ERR_PerfMetric.', 'ERR_PerfMetric::').replace('int perfStamp;', 'int perfStamp=0;')
s=s.replace('ERR_HQ.Event','ERR_HQ::Event').replace('protected ', '').replace('Replication.IsServer()', 'server').replace('Replication.BumpMe()', '(void)0')
s=s.replace('array<int> connected = {};','std::vector<int> connected;').replace('connected.IsEmpty()', 'connected.empty()')
s=s.replace('foreach (int id : connected)', 'for (int id : connected)')
s=s.replace('ERR_PlayerLife life', 'Life* life').replace('SCR_PlayerController controller', 'Controller* controller').replace('PlayerController controller', 'Controller* controller')
s=s.replace('SCR_PlayerController.Cast(', 'Controller::Cast(').replace('ERR_Phase.DEFEAT','5').replace('ERR_Phase.RADIO_SEARCH','2')
for v in ('m_Roster','controller','life','m_Command','m_Extraction','m_RadioDefence','m_Recovery','GetGame()','GetWorld()','GetPlayerManager()'):
for v in ('m_Performance','m_Roster','controller','life','m_Command','m_CivilianTraffic','m_Extraction','m_RadioDefence','m_Recovery','GetGame()','GetWorld()','GetPlayerManager()'):
s=s.replace(v+'.', v+'->')
return s
methods='\n'.join(cpp(body(MODE,x)) for x in ('void InitialAdmissionStarted(', 'void InitialAdmissionExhausted(', 'protected bool InitialAdmissionsExhausted(', 'protected void ServerTick('))
methods='\n'.join(cpp(body(MODE,x)) for x in ('void InitialAdmissionStarted(', 'void InitialAdmissionExhausted(', 'protected bool InitialAdmissionsExhausted(', 'protected void ServerTickMeasured('))
run(r'''
#include <cassert>
#include <map>
#include <vector>
#include <string>
bool server=true;
template<class... T>void PrintFormat(const char*,T...){}
struct Controller {void* actor=nullptr;void* GetControlledEntity(){return actor;}static Controller* Cast(Controller* c){return c;}void ERR_UpdateObserverServer(){}};
struct Life {bool Connected=true,UsedLife=false;void* Actor=nullptr;};
struct Roster {std::map<int,Life> lives;bool survivor=false;Life* Get(int id){auto i=lives.find(id);return i==lives.end()?nullptr:&i->second;}bool HasSurvivor(){return survivor;}};
@@ -28,11 +31,15 @@ struct World {float now=0;float GetWorldTime(){return now;}} world;
struct ERR_HQ {static void Event(std::string,std::string){}};
struct Service {bool defeat=false;bool DefeatDue(float){return defeat;}void Tick(float=0){}void Maintain(float){}void Invoke(float){}};
struct Exhausted {std::map<int,Controller*> values;void Remove(int id){values.erase(id);}void Set(int id,Controller* c){values[id]=c;}bool Contains(int id){return values.count(id);}Controller* Get(int id){return values.at(id);}};
namespace System {int GetTickCount(){return 0;}}
namespace ERR_PerfMetric {enum {MAINTENANCE,CIVILIANS,FORCES,OBSERVERS,HQ_TICK,LISTENERS};}
struct Performance {int Mark(int,int stamp){return stamp;}void Stop(int){}};
struct Mode {
Performance* m_Performance=nullptr;
void TickForces(float){}
bool m_StartedPlayers=false;int m_Phase=1;float m_NoSurvivorsSince=-1;std::string m_EndReason;
Exhausted m_ExhaustedInitialAdmissions;Roster roster;Roster* m_Roster=&roster;
Service service,m_OnTick;Service *m_Extraction=&service,*m_RadioDefence=&service,*m_Recovery=&service,*m_Command=&service;
Service service,m_OnTick;Service *m_Extraction=&service,*m_RadioDefence=&service,*m_Recovery=&service,*m_Command=&service,*m_CivilianTraffic=nullptr;
World* GetWorld(){return &world;}bool Active(){return m_Phase>0&&m_Phase<5;}void Transition(int p){m_Phase=p;}bool RefreshRadioFeedback(){return false;}
'''+methods+r'''
};
@@ -68,6 +75,20 @@ int main(){
if(fault==0){server=false;}if(fault==1){f.m.m_Phase=0;}if(fault==2){f.m.m_Phase=5;}
if(fault==3){f.m.m_StartedPlayers=true;}if(fault==4){game.players.connected[1]=&f.second;}if(fault==5){f.m.roster.lives.clear();}
f.exhaust();assert(f.m.m_ExhaustedInitialAdmissions.values.empty());}
// Empty server must retire a played round after the last reserved body expires.
{Fixture f;f.m.m_StartedPlayers=true;f.m.roster.lives[1].UsedLife=true;
game.players.connected.clear();f.m.roster.survivor=true;
f.tick(900000);assert(f.m.Active()&&f.m.m_NoSurvivorsSince==-1);
f.m.roster.survivor=false;f.tick(901000);assert(f.m.m_NoSurvivorsSince==901000);
f.tick(930999);assert(f.m.Active());f.tick(931000);
assert(!f.m.Active()&&f.m.m_EndReason=="No surviving prisoners remain.");}
// A new empty round waits indefinitely; it must not restart in a loop.
{Fixture f;game.players.connected.clear();f.tick(0);f.tick(36000000);
assert(f.m.Active()&&f.m.m_NoSurvivorsSince==-1);}
// A valid reservation/recovered survivor cancels a pending empty-server loss.
{Fixture f;f.m.m_StartedPlayers=true;game.players.connected.clear();f.tick(0);
f.m.roster.survivor=true;f.tick(29999);f.tick(60000);
assert(f.m.Active()&&f.m.m_NoSurvivorsSince==-1);}
// Existing actual first spawn changes participation; normal death grace is unchanged.
{Fixture f;f.exhaust();f.m.InitialAdmissionStarted(1);f.m.m_StartedPlayers=true;f.m.roster.lives[1].UsedLife=true;f.m.roster.survivor=true;
f.tick(30000);assert(f.m.m_NoSurvivorsSince==-1&&f.m.Active());f.m.roster.survivor=false;f.tick(31000);f.tick(61000);