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.
146 lines
12 KiB
Python
146 lines
12 KiB
Python
"""Execute production feedback control flow; no native UI or network claim."""
|
|
from policy_harness import ROOT, body, run
|
|
service = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_CasualtyLoadingService.c'
|
|
action = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_LoadCasualtyAction.c'
|
|
feedback = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_CasualtyLoadingFeedback.c'
|
|
def convert(s):
|
|
s=s.replace('protected ', '').replace('override ', '').replace('string.Empty','string{}').replace('.IsEmpty()', '.empty()')
|
|
for ns in ['Replication','System','ERR_CasualtyFeedback','ERR_Phase','ERR_CasualtyLoadingRules']:
|
|
s=s.replace(ns+'.',ns+'::')
|
|
s=s.replace('ERR_GameMode.Get()', 'Mode::Get()').replace('ERR_GameMode mode', 'Mode* mode').replace('ERR_GameMode.Cast','Mode::Cast')
|
|
s=s.replace('ERR_PlayerLife life','Life* life').replace('SCR_PlayerController controller = SCR_PlayerController.Cast(GetGame().GetPlayerManager().GetPlayerController(life.ConnectionId));','Controller* controller = GetGame()->GetPlayerManager()->GetPlayerController(life->ConnectionId);')
|
|
s=s.replace('ERR_CasualtyLoadTicket ticket','Ticket* ticket')
|
|
for v in ['mode','m_Mode','ticket','life','controller']:
|
|
s=s.replace(v+'.',v+'->')
|
|
s=s.replace('mode->CasualtyLoading().','mode->CasualtyLoading()->').replace('null','nullptr')
|
|
return s
|
|
methods='\n'.join(convert(body(service, sig)) for sig in ['string RejectionReason(', 'protected void NotifyCaller(', 'void Request(', 'protected void NotifyResolution('])
|
|
permission=convert(body(action,'override bool CanBePerformedScript('))
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
#include <vector>
|
|
using string=std::string;
|
|
struct Actor{int identity=1;};using IEntity=Actor*;
|
|
namespace Replication{bool server=true;bool IsServer(){return server;}}
|
|
namespace System{int GetTickCount(){return 10000;}}
|
|
namespace ERR_Phase{enum{EXTRACTION=4};}
|
|
struct Mode;struct Service;
|
|
struct Life{int ConnectionId=1;};
|
|
struct Controller{IEntity actor=nullptr;int messages=0;string last;IEntity GetControlledEntity(){return actor;}void ERR_CasualtyFeedback(Mode*,IEntity a,string s){assert(a==actor);messages++;last=s;}};
|
|
struct Manager{Controller* current=nullptr;Controller* GetPlayerController(int){return current;}};
|
|
struct Game{Manager manager;Manager* GetPlayerManager(){return &manager;}} game;Game* GetGame(){return &game;}
|
|
struct Mode{bool active=true;int phase=4;Service* service=nullptr;static Mode* current;static Mode* Get(){return current;}bool Active(){return active;}int Phase(){return phase;}Service* CasualtyLoading(){return service;}int ExtractionVehicle(){return 1;}};Mode* Mode::current=nullptr;
|
|
namespace ERR_CasualtyFeedback{string physical;string PhysicalReason(Mode*,IEntity,IEntity){return physical;}}
|
|
struct Ticket{bool FeedbackSubmitted=false;IEntity Caller=nullptr;int CallerAccount=1,CallerConnection=1;};
|
|
struct Service{
|
|
Mode* m_Mode;bool m_Stopped=false,settled=true,pending=false,seat=true,beginOK=true,same=true;int begins=0;Life life;IEntity admittedCaller=nullptr,admittedCasualty=nullptr;
|
|
Life* CurrentLife(IEntity a){return a&&(a==admittedCaller||a==admittedCasualty)?&life:nullptr;}
|
|
bool Settled(IEntity,int){return settled;}bool PendingActor(IEntity,IEntity){return pending;}bool AvailableSeat(IEntity,int){return seat;}
|
|
bool Begin(IEntity,IEntity){begins++;return beginOK;}bool SameLife(IEntity a,int account,int connection){return same&&CurrentLife(a)&&account==1&&connection==1;}
|
|
''' + methods + r'''
|
|
};
|
|
struct Action{string reason="old";IEntity target=nullptr;IEntity GetOwner(){return target;}void SetCannotPerformReason(string s){reason=s;}
|
|
''' + permission + r'''
|
|
};
|
|
int main(){
|
|
Mode mode;Service svc{&mode};mode.service=&svc;Mode::current=&mode;Actor caller,patient,stranger;svc.admittedCaller=&caller;svc.admittedCasualty=&patient;Controller controller;controller.actor=&caller;game.manager.current=&controller;Action action;action.target=&patient;
|
|
assert(action.CanBePerformedScript(&caller)&&action.reason.empty());
|
|
ERR_CasualtyFeedback::physical="No accessible transport seat is available";
|
|
assert(!action.CanBePerformedScript(&caller)&&action.reason==ERR_CasualtyFeedback::physical);
|
|
svc.Request(&caller,&patient);assert(svc.begins==0&&controller.messages==1);
|
|
ERR_CasualtyFeedback::physical.clear();assert(action.CanBePerformedScript(&caller)&&action.reason.empty());
|
|
svc.settled=false;assert(!action.CanBePerformedScript(&caller)&&action.reason.find("five seconds")!=string::npos);svc.settled=true;
|
|
svc.pending=true;assert(svc.RejectionReason(&caller,&patient).find("already")!=string::npos);svc.pending=false;
|
|
svc.seat=false;assert(svc.RejectionReason(&caller,&patient).find("seat")!=string::npos);svc.seat=true;
|
|
assert(svc.RejectionReason(&stranger,&patient).find("connected")!=string::npos);
|
|
int before=controller.messages;svc.Request(&stranger,&patient);assert(controller.messages==before&&svc.begins==0);
|
|
svc.beginOK=false;svc.Request(&caller,&patient);assert(svc.begins==1&&controller.messages==before+1&&controller.last.find("could not start")!=string::npos);
|
|
svc.beginOK=true;before=controller.messages;svc.Request(&caller,&patient);assert(svc.begins==2&&controller.messages==before);
|
|
Ticket ticket;ticket.Caller=&caller;
|
|
svc.NotifyResolution(&ticket,false);assert(controller.messages==before); // failed reservation before submission: Request gives exactly one failure
|
|
ticket.FeedbackSubmitted=true;svc.NotifyResolution(&ticket,true);assert(controller.messages==before);
|
|
svc.NotifyResolution(&ticket,false);assert(controller.messages==before+1&&controller.last.find("could not be confirmed")!=string::npos);
|
|
before=controller.messages;
|
|
svc.same=false;svc.NotifyResolution(&ticket,false);assert(controller.messages==before);svc.same=true;
|
|
ticket.CallerAccount=2;svc.NotifyResolution(&ticket,false);assert(controller.messages==before);ticket.CallerAccount=1;
|
|
ticket.CallerConnection=2;svc.NotifyResolution(&ticket,false);assert(controller.messages==before);ticket.CallerConnection=1;
|
|
controller.actor=&stranger;svc.NotifyResolution(&ticket,false);assert(controller.messages==before);controller.actor=&caller;
|
|
svc.m_Stopped=true;svc.NotifyResolution(&ticket,false);assert(controller.messages==before);svc.m_Stopped=false;
|
|
mode.active=false;svc.NotifyResolution(&ticket,false);assert(controller.messages==before);mode.active=true;
|
|
mode.phase=5;svc.NotifyResolution(&ticket,false);assert(controller.messages==before);mode.phase=4;
|
|
Replication::server=false;svc.Request(&caller,&patient);assert(svc.begins==2&&controller.messages==before);
|
|
// Client presentation never evaluates authoritative roster/settling: physical facts only.
|
|
svc.settled=false;assert(action.CanBePerformedScript(&caller)&&action.reason.empty());
|
|
ERR_CasualtyFeedback::physical="The helicopter must be upright, grounded and stationary";assert(!action.CanBePerformedScript(&caller));
|
|
}
|
|
''')
|
|
# Guard the unchanged transfer path and exact recipient channel around the tested logic.
|
|
owner=feedback.read_text()
|
|
assert '[RplRpc(RplChannel.Reliable, RplRcver.Owner)]' in owner
|
|
assert 'RplRcver.Broadcast' not in owner and 'RplRcver.Server' not in owner
|
|
send=body(feedback,'void ERR_CasualtyFeedback(')
|
|
for guard in ['!Replication.IsServer()', 'mode != ERR_GameMode.Get()', '!mode.Players().CurrentActor(actor)', 'GetPlayerController(GetPlayerId()) != this']:
|
|
assert guard in send
|
|
receive=body(feedback,'protected void ERR_CasualtyFeedbackOwner(')
|
|
for guard in ['this != GetGame().GetPlayerController()', 'EntityId(mode) != modeId', 'EntityId(GetControlledEntity()) != actorId', 'mode.Phase() != ERR_Phase.EXTRACTION']:
|
|
assert guard in receive
|
|
assert receive.index('EntityId(GetControlledEntity()) != actorId') < receive.index('ShowCustom(')
|
|
resolve=body(service,'protected void Resolve(')
|
|
assert resolve.index('m_Pending.Remove(index)') < resolve.index('NotifyResolution(ticket, success)') < resolve.index('m_OnResolved.Invoke')
|
|
begin=body(service,'bool Begin(')
|
|
assert begin.index('IsReservedBy(casualty)') < begin.index('ticket.FeedbackSubmitted = true') < begin.index('ERR_PrepareCasualtyLoad(')
|
|
print('PASS: actual action denial/clearing, server request failure, single submitted-result feedback, current rescuer identity and terminal/stop suppression; native UI/RPC pending')
|
|
physical=convert(body(feedback,'static string PhysicalReason(')).replace('static ','')
|
|
physical=physical.replace('Vehicle aircraft','Actor* aircraft').replace('aircraft.FindComponent(BaseCompartmentManagerComponent)','0')
|
|
physical=physical.replace('BaseCompartmentManagerComponent manager = BaseCompartmentManagerComponent.Cast(0);','Manager* manager = aircraft->manager;')
|
|
physical=physical.replace('array<BaseCompartmentSlot> seats = {}','std::vector<Seat*> seats').replace('foreach (BaseCompartmentSlot seat : seats)','for (Seat* seat : seats)')
|
|
for var in ['caller','casualty','aircraft','manager','seat']:
|
|
physical=physical.replace(var+'.',var+'->')
|
|
physical=physical.replace('vector.Distance','Distance').replace('ERR_Actors.','ERR_Actors::').replace('CompartmentAccessComponent.','CompartmentAccessComponent::')
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
#include <vector>
|
|
using string=std::string;
|
|
struct Actor;using IEntity=Actor*;
|
|
struct Seat{bool transport=true,occupied=false,reserved=false,accessible=true,locked=false;bool GetOccupant(){return occupied;}bool IsReserved(){return reserved;}bool IsCompartmentAccessible(){return accessible;}bool IsGetInLockedFor(IEntity){return locked;}};
|
|
struct Manager{std::vector<Seat*> seats;void GetCompartments(std::vector<Seat*>& out){out=seats;}};
|
|
struct Actor{bool conscious=true,aboard=false,settled=true,ready=true;Manager* manager=nullptr;int GetOrigin(){return 0;}};
|
|
struct Mode{bool active=true;int phase=4;Actor* aircraft=nullptr;bool Active(){return active;}int Phase(){return phase;}Actor* CasualtyLoadingAircraft(){return aircraft;}};
|
|
namespace ERR_Phase{enum{EXTRACTION=4};}
|
|
namespace ERR_Actors{bool CanFight(IEntity a){return a&&a->conscious;}}
|
|
namespace CompartmentAccessComponent{bool GetVehicleIn(IEntity a){return a->aboard;}}
|
|
float Distance(int,int){return 0;}
|
|
namespace ERR_CasualtyLoadingRules{
|
|
bool ranges=true,nearby=true;
|
|
bool GroundSettled(IEntity a){return a&&a->settled;}
|
|
bool Ranges(float,float,float){return ranges;}
|
|
bool AircraftReady(IEntity a){return a&&a->ready;}
|
|
bool Nearby(Mode*,IEntity,IEntity){return nearby;}
|
|
bool TransportBench(Seat* s,IEntity){return s&&s->transport;}
|
|
}
|
|
''' + physical + r'''
|
|
int main(){
|
|
Actor caller,patient,aircraft;Mode mode;mode.aircraft=&aircraft;Manager manager;aircraft.manager=&manager;Seat seat;manager.seats={nullptr,&seat};
|
|
assert(PhysicalReason(&mode,&caller,&patient).empty());
|
|
for(int mask=1;mask<16;mask++){
|
|
seat.occupied=mask&1;seat.reserved=mask&2;seat.accessible=!(mask&4);seat.locked=mask&8;
|
|
assert(PhysicalReason(&mode,&caller,&patient).find("seat")!=string::npos);
|
|
}
|
|
seat=Seat{};seat.transport=false;assert(PhysicalReason(&mode,&caller,&patient).find("seat")!=string::npos);seat.transport=true;
|
|
aircraft.manager=nullptr;assert(PhysicalReason(&mode,&caller,&patient).find("seat")!=string::npos);aircraft.manager=&manager;
|
|
mode.active=false;assert(PhysicalReason(&mode,&caller,&patient).find("Wait")!=string::npos);mode.active=true;
|
|
mode.phase=3;assert(!PhysicalReason(&mode,&caller,&patient).empty());mode.phase=4;
|
|
assert(!PhysicalReason(nullptr,&caller,&patient).empty());assert(!PhysicalReason(&mode,nullptr,&patient).empty());assert(!PhysicalReason(&mode,&patient,&patient).empty());
|
|
caller.conscious=false;assert(PhysicalReason(&mode,&caller,&patient).find("conscious rescuer")!=string::npos);caller.conscious=true;
|
|
caller.aboard=true;assert(PhysicalReason(&mode,&caller,&patient).find("Leave")!=string::npos);caller.aboard=false;
|
|
patient.settled=false;assert(PhysicalReason(&mode,&caller,&patient).find("stable ground")!=string::npos);patient.settled=true;
|
|
ERR_CasualtyLoadingRules::ranges=false;assert(PhysicalReason(&mode,&caller,&patient).find("twelve metres")!=string::npos);ERR_CasualtyLoadingRules::ranges=true;
|
|
aircraft.ready=false;assert(PhysicalReason(&mode,&caller,&patient).find("stationary")!=string::npos);aircraft.ready=true;
|
|
ERR_CasualtyLoadingRules::nearby=false;assert(PhysicalReason(&mode,&caller,&patient).find("clear access")!=string::npos);ERR_CasualtyLoadingRules::nearby=true;
|
|
assert(PhysicalReason(&mode,&caller,&patient).empty());
|
|
}
|
|
''')
|
|
print('PASS: actual physical denial precedence and transport-seat occupancy/reservation/access/lock checks')
|