Merge owned systems into one addon while preserving resource identities. Gate player admission on the replicated prison scene, restore the original framed door, and hold enemy AI until escape. Correct scenario branding and author metadata, include publishing assets, and retain regression and native verification evidence.
52 lines
3.9 KiB
Python
52 lines
3.9 KiB
Python
"""Actual session Tick and journal router keep tool completions/feed deliveries separate."""
|
|
from policy_harness import ROOT, body, run
|
|
session=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminSession.c'
|
|
admin=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c'
|
|
tick=body(session,'bool Tick(')
|
|
reader=body(admin,'bool ReadJournal(')
|
|
def adapt(s):
|
|
s=s.replace('array<string> replies = {};','Array<string> replies;')
|
|
s=s.replace('array<string> lines','Array<string>& lines').replace('out int cursor','int& cursor')
|
|
s=s.replace('foreach (string reply : replies)', 'for (string reply : replies)').replace('foreach (string line : replies)', 'for (string line : replies)')
|
|
s=s.replace('foreach (ERR_AdminProvider provider : m_Providers)', 'for (Provider* provider : m_Providers)')
|
|
for name in ['m_Tools','m_Controller','m_Mode','provider']:
|
|
s=s.replace(name+'.',name+'->')
|
|
s=s.replace('GetGame().','GetGame()->').replace('GetWorld().','GetWorld()->').replace('Admin().','Admin()->')
|
|
return s
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
#include <vector>
|
|
using string=std::string;
|
|
template<class T>struct Array:std::vector<T>{void Clear(){this->clear();}void Insert(T value){this->push_back(value);}};
|
|
struct Provider{Array<string> journal;int calls=0;bool ReadJournal(int after,Array<string>& lines,int& cursor,int limit){calls++;cursor=after;for(int i=after;i<int(journal.size())&&limit>0;i++,limit--){lines.Insert(journal[i]);cursor=i+1;}return true;}};
|
|
struct Admin{Array<Provider*> m_Providers;
|
|
'''+adapt(reader)+r'''
|
|
};
|
|
struct Mode{struct Admin admin;struct Admin* Admin(){return &admin;}};
|
|
struct Tools{Array<string> pending;int ticks=0;void Tick(Array<string>& replies){ticks++;for(auto line:pending)replies.Insert(line);pending.clear();}};
|
|
struct Controller{Array<string> received;void ERR_AdminDeliverReply(int token,string reply,bool menu){assert(token==7&&!menu);received.Insert(reply);}};
|
|
struct Game{float now=0;Game* GetWorld(){return this;}float GetWorldTime(){return now;}}game;Game* GetGame(){return &game;}
|
|
struct Session{
|
|
bool allowed=true,m_Live=true;int m_Token=7,m_Cursor=0,bodyChecks=0;float m_NextFeed=0;Mode* m_Mode;Tools* m_Tools;Controller* m_Controller;
|
|
bool Authorize(){return allowed;}void CheckBody(){bodyChecks++;}
|
|
'''+adapt(tick)+r'''
|
|
};
|
|
int main(){
|
|
Mode mode;Tools tools;Controller controller;Provider provider;mode.admin.m_Providers.Insert(&provider);
|
|
provider.journal.Insert("hq1");provider.journal.Insert("hq2");tools.pending.Insert("grant complete");
|
|
Session session{true,true,7,0,0,0,&mode,&tools,&controller};
|
|
assert(session.Tick());assert(controller.received.size()==3);
|
|
assert(controller.received[0]=="grant complete"&&controller.received[1]=="hq1"&&controller.received[2]=="hq2");
|
|
assert(session.m_Cursor==2&&session.m_NextFeed==2000);
|
|
game.now=1000;assert(session.Tick());assert(controller.received.size()==3&&provider.calls==1);
|
|
game.now=2000;tools.pending.Insert("grant failed");assert(session.Tick());assert(controller.received.size()==4&&controller.received[3]=="grant failed");
|
|
game.now=4000;provider.journal.Insert("hq3");assert(session.Tick());assert(controller.received.size()==5&&controller.received[4]=="hq3");
|
|
session.m_Live=false;game.now=6000;tools.pending.Insert("grant timeout");assert(session.Tick());assert(controller.received.size()==6&&provider.calls==3);
|
|
session.m_Live=true;session.allowed=false;game.now=8000;tools.pending.Insert("must not deliver");assert(!session.Tick());assert(controller.received.size()==6&&provider.calls==3&&tools.pending.size()==1);
|
|
// No provider still clears tool replies before the live-feed loop.
|
|
session.allowed=true;mode.admin.m_Providers.clear();assert(session.Tick());assert(controller.received.size()==7&&controller.received.back()=="must not deliver");
|
|
}
|
|
''')
|
|
print('PASS: actual session Tick + journal router delivers each grant completion and new HQ line once, without repeats on empty/unavailable feeds or unauthorized ticks')
|