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.
86 lines
6.9 KiB
Python
86 lines
6.9 KiB
Python
"""Execute actual fixture commit/event/closure gates; not native artillery simulation."""
|
|
from policy_harness import ROOT, body, run
|
|
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_NativeMortarFiringProbe.c'
|
|
policies='\n'.join(body(p, sig) for sig in ['static bool AimFresh(', 'static bool CommitFresh(', 'static bool EventBound(', 'static bool ExpiredClosure('])
|
|
policies=policies.replace('ERR_MortarPrediction.', 'ERR_MortarPrediction::').replace('string failure', 'Text failure')
|
|
methods='\n'.join(body(p,sig) for sig in ['void NativeCommit(', 'void NativeClosing(', 'void NativeProjectile('])
|
|
methods=methods.replace('ERR_MortarBattery battery','Battery* battery').replace('IEntity gun, IEntity projectile','Entity* gun, Entity* projectile').replace('string reason, string failure','Text reason, Text failure')
|
|
methods=methods.replace('m_Battery.', 'm_Battery->').replace('battery.', 'battery->').replace('Report.', 'Report->').replace('projectile.GetOrigin()', 'projectile->GetOrigin()')
|
|
methods=methods.replace('GetGame().GetWorld().GetWorldTime()', 'clockNow').replace('ERR_NativeMortarEvidenceRules.', 'ERR_NativeMortarEvidenceRules::').replace('ERR_MortarSalvo.', 'ERR_MortarSalvo::')
|
|
run('''#include <cassert>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <string>
|
|
float clockNow=20000;
|
|
struct Text:std::string {using std::string::string;bool Contains(const char* part){return find(part)!=npos;}};
|
|
struct ERR_MortarPrediction {static constexpr float MAX_REPORT_AGE_MS=60000;};
|
|
struct ERR_MortarSalvo {static constexpr int ROUNDS=8;};
|
|
struct ERR_NativeMortarEvidenceRules {
|
|
'''+policies+'''};
|
|
struct Entity {int GetOrigin(){return 0;}};
|
|
struct Report {int MessageId=7;float ObservedAt=1000;};
|
|
struct Battery {bool CommandOpen=true,Released=true,stopped=false;int SourceId=7,OrderId=1,OrderShots=0;float AimedAt=19000,AimValidatedAt=19000,FlightTime=20;struct Report report;struct Report* Report=&report;bool Stopped(){return stopped;}};
|
|
struct Items {std::vector<Entity*> values;bool Contains(Entity* p){return std::find(values.begin(),values.end(),p)!=values.end();}void Insert(Entity* p){values.push_back(p);}};
|
|
template<class... Args>void PrintFormat(Args...args){}
|
|
struct Probe {
|
|
bool m_Stopped=false,m_BadProjectile=false,m_WaitForExpiry=true,m_CommitPending=false,m_ClosureSeen=false,m_ClosureComplete=false,m_ClosureExpired=false;
|
|
Battery* m_Battery;Entity* m_Gun;Items m_Projectiles;int m_Events=0,m_Step=1,m_Source=7,m_Order=1,m_Commits=0,m_CommitOrder=0,m_CommitShot=0;float m_ObservedAt=1000,m_CommittedAt=0;std::string m_BadReason;
|
|
'''+methods+'''
|
|
};
|
|
int main(){
|
|
using Rules=ERR_NativeMortarEvidenceRules;
|
|
assert(Rules::AimFresh(1000,19000,20000)); // old actual command, genuinely recent equivalent solve
|
|
assert(!Rules::AimFresh(-1,19000,20000));assert(!Rules::AimFresh(21000,21000,20000));
|
|
assert(!Rules::AimFresh(19000,18000,20000));assert(!Rules::AimFresh(1000,20001,20000));
|
|
assert(!Rules::AimFresh(1000,9999,20000));assert(Rules::AimFresh(1000,10000,20000));
|
|
assert(Rules::EventBound(true,1,1,0,0,60999,90000)); // original fresh commit survives delayed native emission
|
|
assert(Rules::CommitFresh(1000,1000,61000));assert(!Rules::CommitFresh(1000,1000,61001));
|
|
assert(!Rules::CommitFresh(1100,1000,20000));assert(!Rules::CommitFresh(1000,1000,999));
|
|
assert(Rules::ExpiredClosure(1000,61001,"aim: delivered target report expired or invalid"));
|
|
assert(!Rules::ExpiredClosure(1000,61000,"aim: delivered target report expired or invalid"));
|
|
assert(!Rules::ExpiredClosure(1000,65000,"native artillery activity FAILED"));
|
|
Entity gun,other,projectile;Battery b;Probe p;p.m_Battery=&b;p.m_Gun=&gun;
|
|
p.NativeProjectile(&other,&projectile);assert(!p.m_BadProjectile&&p.m_Events==0);
|
|
p.NativeCommit(&b,clockNow);assert(p.m_CommitPending&&p.m_Commits==1&&!p.m_BadProjectile);
|
|
p.NativeProjectile(&gun,&projectile);assert(p.m_Events==1&&!p.m_BadProjectile&&!p.m_CommitPending);
|
|
p.NativeProjectile(&gun,&projectile);assert(p.m_BadProjectile&&p.m_Events==1);
|
|
Probe nullEvent;nullEvent.m_Battery=&b;nullEvent.m_Gun=&gun;nullEvent.NativeProjectile(&gun,nullptr);assert(nullEvent.m_BadProjectile&&nullEvent.m_Events==0);
|
|
Probe stoppedObserver;stoppedObserver.m_Battery=&b;stoppedObserver.m_Gun=&gun;stoppedObserver.m_Stopped=true;stoppedObserver.NativeCommit(&b,20000);stoppedObserver.NativeProjectile(&gun,&projectile);assert(stoppedObserver.m_Commits==0&&stoppedObserver.m_Events==0&&!stoppedObserver.m_BadProjectile);
|
|
// Physical launch after report expiry is legitimate if its commit was fresh.
|
|
b=Battery();b.Report=&b.report;b.AimedAt=60500;b.AimValidatedAt=60500;Probe delayed;delayed.m_Battery=&b;delayed.m_Gun=&gun;delayed.m_Step=3;
|
|
delayed.NativeCommit(&b,60999);clockNow=62999;delayed.NativeProjectile(&gun,&projectile);
|
|
assert(delayed.m_Events==1&&!delayed.m_BadProjectile);
|
|
for(int fault=0;fault<10;++fault){
|
|
b=Battery();b.Report=&b.report;clockNow=20000;Probe q;q.m_Battery=&b;q.m_Gun=&gun;
|
|
if(fault==0)b.CommandOpen=false;
|
|
if(fault==1)b.Released=false;
|
|
if(fault==2)b.SourceId=8;
|
|
if(fault==3)b.AimedAt=-1;
|
|
if(fault==4)b.AimValidatedAt=9999;
|
|
if(fault==5)b.FlightTime=0;
|
|
if(fault==6)q.m_Step=2;
|
|
if(fault==7)b.report.ObservedAt=1001;
|
|
if(fault==8)b.OrderId=2;
|
|
if(fault==9){clockNow=61001;b.AimedAt=61000;b.AimValidatedAt=61000;}
|
|
q.NativeCommit(&b,clockNow);assert(q.m_BadProjectile&&!q.m_CommitPending&&q.m_Commits==0);
|
|
}
|
|
b=Battery();b.Report=&b.report;clockNow=20000;Probe missing;missing.m_Battery=&b;missing.m_Gun=&gun;
|
|
missing.NativeProjectile(&gun,&projectile);assert(missing.m_BadProjectile);
|
|
Probe duplicate;duplicate.m_Battery=&b;duplicate.m_Gun=&gun;duplicate.NativeCommit(&b,20000);duplicate.NativeCommit(&b,20000);assert(duplicate.m_BadProjectile&&duplicate.m_Commits==1);
|
|
for(int fault=0;fault<3;++fault){
|
|
b=Battery();b.Report=&b.report;clockNow=20000;Probe changed;changed.m_Battery=&b;changed.m_Gun=&gun;changed.NativeCommit(&b,20000);
|
|
if(fault==0)b.OrderId++;
|
|
if(fault==1)b.OrderShots++;
|
|
if(fault==2)clockNow=19999;
|
|
|
|
changed.NativeProjectile(&gun,&projectile);assert(changed.m_BadProjectile);
|
|
}
|
|
b=Battery();b.Report=&b.report;clockNow=65000;Probe expired;expired.m_Battery=&b;expired.m_Gun=&gun;
|
|
expired.NativeClosing(&b,"native aim or firing authorization rejected","aim: delivered target report expired or invalid");assert(expired.m_ClosureSeen&&expired.m_ClosureExpired&&!expired.m_BadProjectile);
|
|
Probe unrelated;unrelated.m_Battery=&b;unrelated.NativeClosing(&b,"native activity FAILED","");assert(unrelated.m_BadProjectile);
|
|
Probe stopped;stopped.m_Battery=&b;b.stopped=true;stopped.NativeClosing(&b,"HQ stopped","aim: delivered target report expired or invalid");assert(stopped.m_BadProjectile);
|
|
b.stopped=false;b.OrderShots=8;Probe complete;complete.m_Battery=&b;complete.m_Events=8;clockNow=50000;complete.NativeClosing(&b,"native artillery activity COMPLETED","");assert(complete.m_ClosureComplete&&!complete.m_BadProjectile);
|
|
}
|
|
''')
|
|
print('PASS: actual probe binds native events to fresh immutable commits, permits delayed emission, rejects unrelated expiry closure and premature stop')
|