Files
EscapistsReintroduced/tests/test_ground_depot_lifecycle.py
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

41 lines
3.9 KiB
Python

"""Execute actual modded HQ owner gates, priority order, Stop and terminal polling."""
import os,re
from pathlib import Path
from policy_harness import ROOT,body,run
base=Path(os.environ.get('ERR_DEPOT_ROOT',ROOT))
p=base/'addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c'
def cpp(s):
s=s.replace('protected ','').replace('override ','').replace('super.','Base::').replace('this)', 'this)')
for n in ('m_Mode','m_GroundDepot'):s=s.replace(n+'.',n+'->')
s=s.replace('Replication.IsServer()', 'server').replace('ERR_GameMode.Get()', 'current')
s=s.replace('ERR_Phase.RADIO_SEARCH','2').replace('GetGame().','GetGame()->').replace('GetCallqueue().','GetCallqueue()->').replace('GetWorld().','GetWorld()->')
s=s.replace('Remove(PollGroundDepot)', 'Remove(0)').replace('CallLater(PollGroundDepot, 1000, false)', 'CallLater(0, 1000, false)')
return s
methods='\n'.join(cpp(body(p,t)) for t in ('override void Tick(', 'override void Stop(', 'protected void CancelGroundDepotPoll(', 'protected void PollGroundDepot('))
run(r'''
#include <cassert>
#include <vector>
std::vector<int> events;bool server=true;struct HQ;
struct Mode{HQ*owner=nullptr;bool active=true;int phase=2;bool Active(){return active;}int Phase(){return phase;}HQ*Command(){return owner;}};Mode*current=nullptr;
struct Queue{int pending=0,calls=0;void Remove(int){pending=0;}void CallLater(int,int ms,bool repeat){assert(ms==1000&&!repeat);pending=1;calls++;}};
struct World{float GetWorldTime(){return 500;}};struct Game{Queue queue;World world;Queue*GetCallqueue(){return &queue;}World*GetWorld(){return &world;}};Game game;Game*GetGame(){return &game;}
struct ERR_GroundDepotLoading{static inline int created=0;bool stopped=false,unknown=false;int plans=0,ticks=0;ERR_GroundDepotLoading(HQ*,Mode*){created++;}void Tick(float){ticks++;events.push_back(3);}void Plan(float){assert(!stopped);plans++;events.push_back(4);}void Stop(){stopped=true;events.push_back(1);}bool Unresolved(){return unknown;}};
struct Base{bool m_Stopping=false;void Tick(float){events.push_back(2);}void Stop(){events.push_back(2);m_Stopping=true;}};
struct HQ:Base{Mode*m_Mode=nullptr;ERR_GroundDepotLoading*m_GroundDepot=nullptr;METHODS};
struct F{HQ h;Mode mode;F(){server=true;game.queue={};current=&mode;mode.owner=&h;h.m_Mode=&mode;events.clear();}};
int main(){
{F f;server=false;f.h.Tick(0);assert(!f.h.m_GroundDepot&&events==std::vector<int>{2});}
{F f;current=nullptr;f.h.Tick(0);assert(!f.h.m_GroundDepot);}
{F f;f.mode.owner=nullptr;f.h.Tick(0);assert(!f.h.m_GroundDepot);}
{F f;f.mode.active=false;f.h.Tick(0);assert(!f.h.m_GroundDepot);}
{F f;f.mode.phase=1;f.h.Tick(0);assert(!f.h.m_GroundDepot);}
{F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;assert(d&&d->plans==1&&events==std::vector<int>({2,4}));events.clear();f.h.Tick(1);assert(f.h.m_GroundDepot==d&&events==std::vector<int>({2,3,4}));}
{F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;d->unknown=true;events.clear();f.h.Stop();assert(d->stopped&&events==std::vector<int>({1,2,3})&&game.queue.pending==1);int plans=d->plans;f.h.Stop();assert(game.queue.pending==1&&d->plans==plans);d->unknown=false;f.h.PollGroundDepot();assert(game.queue.pending==0&&d->plans==plans);}
{F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;d->unknown=true;f.h.Stop();int ticks=d->ticks;f.mode.owner=nullptr;f.h.PollGroundDepot();assert(game.queue.pending==0&&d->ticks==ticks);}
{F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;d->unknown=true;f.h.Stop();int ticks=d->ticks;server=false;f.h.PollGroundDepot();assert(game.queue.pending==0&&d->ticks==ticks);}
{F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;d->unknown=true;f.h.Stop();int ticks=d->ticks;current=nullptr;f.h.PollGroundDepot();assert(game.queue.pending==0&&d->ticks==ticks);}
}
'''.replace('METHODS',methods))
assert 'void ~ERR_HQ() { CancelGroundDepotPoll(); }' in p.read_text()
print('PASS: actual depot HQ lifecycle, existing planner priority, server/mode/owner gates, idempotent polling and owner replacement')