Files
EscapistsReintroduced/docs/evidence/crash-start-2026-10-03/final-source/tests/test_terrain_editor.py
T
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

61 lines
2.9 KiB
Python

"""Execute the production editor handover; engine delivery is checked separately."""
from policy_harness import ROOT, body, run
core = ROOT / 'addons/core/Scripts/Game/ERR/00_Core'
method = body(core / 'ERR_TerrainTakeoverManagers.c', 'void ERR_SetTerrainModeEvents(')
method = (method.replace('SCR_BaseGameMode mode', 'SCR_BaseGameMode* mode')
.replace('mode.', 'mode->').replace('Replication.', 'Replication::'))
run(r'''
#include <cassert>
#include <vector>
#include <algorithm>
namespace Replication {bool server=true; bool IsServer(){return server;}}
void Print(const char*){}
enum {OnPlayerRegistered=1,OnPlayerDisconnected,OnPlayerSpawn,OnPlayerKilled,OnPlayerDeleted,OnPlayerRoleChange};
struct Invoker {
std::vector<int> callbacks{99};
void Remove(int cb){callbacks.erase(std::remove(callbacks.begin(),callbacks.end(),cb),callbacks.end());}
void Insert(int cb){callbacks.push_back(cb);}
int Count(int cb){return std::count(callbacks.begin(),callbacks.end(),cb);}
};
struct SCR_BaseGameMode {
Invoker events[6];
Invoker& GetOnPlayerRegistered(){return events[0];}
Invoker& GetOnPostCompPlayerDisconnected(){return events[1];}
Invoker& GetOnPlayerSpawned(){return events[2];}
Invoker& GetOnPlayerKilled(){return events[3];}
Invoker& GetOnPlayerDeleted(){return events[4];}
Invoker& GetOnPlayerRoleChange(){return events[5];}
};
''' + method + r'''
void check(SCR_BaseGameMode& mode,int expected){
for(int i=0;i<6;i++){
assert(mode.events[i].Count(i+1)==expected);
assert(mode.events[i].Count(99)==1); // Preserve unrelated systems' listeners.
}
}
int main(){
SCR_BaseGameMode original,replacement;
ERR_SetTerrainModeEvents(nullptr,true);
ERR_SetTerrainModeEvents(&original,true);check(original,1);
ERR_SetTerrainModeEvents(&original,false);check(original,0);
ERR_SetTerrainModeEvents(&replacement,true);check(replacement,1);
ERR_SetTerrainModeEvents(&replacement,true);check(replacement,1);
Replication::server=false;
ERR_SetTerrainModeEvents(&replacement,false);check(replacement,1);
ERR_SetTerrainModeEvents(&original,true);check(original,0);
Replication::server=true;
ERR_SetTerrainModeEvents(&replacement,false);check(replacement,0);
ERR_SetTerrainModeEvents(&replacement,false);check(replacement,0);
ERR_SetTerrainModeEvents(&replacement,true);check(replacement,1);
}
''')
# Subscription transfer must precede deleting the old owner and replaying held admissions.
takeover = core / 'ERR_TerrainTakeover.c'
drain = body(takeover, 'protected void ERR_DrainTerrainMode(')
create = body(takeover, 'protected void ERR_CreateTerrainMode(')
assert drain.index('ERR_SetTerrainModeEvents(m_ERRTerrainOriginal, false)') < drain.index('DeleteEntityAndChildren')
assert create.index('ERR_SetTerrainModeEvents(mode, true)') < create.index('ERR_StartTerrainTakeover') < create.index('mode.OnPlayerAuditSuccess')
print('PASS: six editor listeners transferred idempotently, unrelated handlers retained, authority guard and lifecycle ordering')