Combine Workshop addon and fix prison startup
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.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
from policy_harness import body,run
|
||||
ROOT=Path(__file__).resolve().parents[1]
|
||||
s=body(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HelicopterAvailability.c','string Check(')
|
||||
s=body(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HelicopterAvailability.c','string Check(')
|
||||
run('#include <string>\n#include <cassert>\nusing std::string;\nstruct Availability {float m_fGroundedSince=-1;\n'+s+'''};
|
||||
int main(){
|
||||
Availability a;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from pathlib import Path
|
||||
import os, re, subprocess, tempfile
|
||||
ROOT=Path(__file__).resolve().parents[1]
|
||||
source=Path(os.environ.get('ERR_NETWORK_SOURCE', ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQNetwork.c')).read_text()
|
||||
source=Path(os.environ.get('ERR_NETWORK_SOURCE', ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQNetwork.c')).read_text()
|
||||
def extract(signature):
|
||||
a=source.index(signature);b=source.index('{',a);end=b+1;depth=1
|
||||
while depth:depth+=(source[end]=='{')-(source[end]=='}');end+=1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
from policy_harness import body,run
|
||||
ROOT=Path(__file__).resolve().parents[1]
|
||||
s=body(ROOT/'addons/ai/Scripts/Game/ERR/ERR_MortarSalvo.c','static vector Offset(').replace('Math.','Math::')
|
||||
s=body(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_MortarSalvo.c','static vector Offset(').replace('Math.','Math::')
|
||||
run('''#include <cassert>
|
||||
#include <cmath>
|
||||
struct vector { float x,y,z;};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Execute actual action availability methods; native UI rendering is separate."""
|
||||
from policy_harness import ROOT, body, run
|
||||
source=(ROOT/'addons/core/Scripts/Game/ERR/ERR_Actions.c').read_text()
|
||||
source=(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Actions.c').read_text()
|
||||
class Source:
|
||||
def __init__(self,name): self.text=source.split('class '+name+' :',1)[1].split('\nclass ',1)[0]
|
||||
def read_text(self): return self.text
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Exercise actual actor-group lookup with distinct inherited vehicle and controlled character agents."""
|
||||
from policy_harness import ROOT, body, run
|
||||
source=body(ROOT/'addons/core/Scripts/Game/ERR/ERR_Actors.c','static SCR_AIGroup Group(')
|
||||
source=body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Actors.c','static SCR_AIGroup Group(')
|
||||
source=source.replace('static SCR_AIGroup Group(IEntity actor)', 'static SCR_AIGroup* Group(IEntity* actor)')
|
||||
source=source.replace('AIControlComponent control', 'AIControlComponent* control')
|
||||
source=source.replace('AIControlComponent.Cast(', 'AIControlComponent::Cast(').replace('SCR_AIGroup.Cast(', 'SCR_AIGroup::Cast(')
|
||||
|
||||
@@ -6,10 +6,10 @@ import re,os
|
||||
from pathlib import Path
|
||||
BASE=Path(os.environ.get("ERR_CONVOY_SETTINGS_ROOT", Path(__file__).resolve().parents[1]))
|
||||
from policy_harness import ROOT, body, run
|
||||
source = ROOT / 'addons/core/Scripts/Game/ERR/ERR_AdminMenu.c'
|
||||
source = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c'
|
||||
layout = ROOT / 'addons/core/UI/layouts/ERR/AdminMenu.layout'
|
||||
keys = re.findall(r'"([A-Za-z]+)"', body(source, 'static array<string> Keys('))
|
||||
settings = re.findall(r'"([A-Za-z]+)"', body(BASE / 'addons/core/Scripts/Game/ERR/ERR_Settings.c', 'static array<string> Keys('))
|
||||
settings = re.findall(r'"([A-Za-z]+)"', body(BASE / 'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c', 'static array<string> Keys('))
|
||||
assert len(keys) == 10 and set(settings) - set(keys) == {"stingerChanceOneIn", "automaticConvoyEnabled"}
|
||||
assert set(keys) <= set(settings) # New text-command setting does not alter the fixed native menu.
|
||||
# Native layouts place child widget declarations inside an anonymous Children
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Exercise actual admin utility command/state methods through native API adapters."""
|
||||
from policy_harness import ROOT, body, run
|
||||
source=ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminPlayerTools.c'
|
||||
source=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminPlayerTools.c'
|
||||
def adapt(s):
|
||||
s=s.replace('protected ', '').replace('null', 'nullptr')
|
||||
s=s.replace('array<string> replies','Array<String>& replies')
|
||||
@@ -100,8 +100,8 @@ assert 'protected override void OnFailed() { Finish(false); }' in s
|
||||
assert 'protected void Finish(bool success) { if (!Finished)' in s
|
||||
print('PASS: actual admin body authorization, god restoration, vanilla item deposit, callback completion/failure, timeout quarantine and stop/revocation paths')
|
||||
|
||||
bridge=(ROOT/'addons/core/Scripts/Game/ERR/ERR_PlayerAdminCommands.c').read_text()
|
||||
session=(ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminSession.c').read_text()
|
||||
bridge=(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_PlayerAdminCommands.c').read_text()
|
||||
session=(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminSession.c').read_text()
|
||||
assert 'protected ref ERR_AdminGrantState m_ERRAdminGrants = new ERR_AdminGrantState();' in bridge
|
||||
assert 'new ERR_AdminSession(mode, this, token, m_ERRAdminGrants)' in bridge
|
||||
assert session.count('new ERR_AdminPlayerTools(m_Grants)')==2
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
Native script compilation and authenticated RPC tests remain separate checks.
|
||||
"""
|
||||
from policy_harness import ROOT, body, run
|
||||
core = ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminService.c'
|
||||
hq = ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQAdminProvider.c'
|
||||
intel = ROOT/'addons/intel/Scripts/Game/ERR/ERR_IntelAdminProvider.c'
|
||||
core = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c'
|
||||
hq = ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAdminProvider.c'
|
||||
intel = ROOT/'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelAdminProvider.c'
|
||||
source=core.read_text()
|
||||
assert 'ERR_HQ' not in source and 'ERR_IntelService' not in source
|
||||
assert 'modded class' not in (ROOT/'addons/chat/Scripts/Game/ERR/ERR_AdminCommands.c').read_text()
|
||||
assert 'Admin().Register(new ERR_HQAdminProvider(hq))' in (ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c').read_text()
|
||||
assert 'Admin().Register(new ERR_IntelAdminProvider())' in (ROOT/'addons/intel/Scripts/Game/ERR/ERR_IntelService.c').read_text()
|
||||
assert 'modded class' not in (ROOT/'addons/core/Scripts/Game/ERR/40_Chat/ERR_AdminCommands.c').read_text()
|
||||
assert 'Admin().Register(new ERR_HQAdminProvider(hq))' in (ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c').read_text()
|
||||
assert 'Admin().Register(new ERR_IntelAdminProvider())' in (ROOT/'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelService.c').read_text()
|
||||
execute=body(core,'void Execute(')
|
||||
assert execute.index('if (!Replication.IsServer()') < execute.index('if (!authorized)') < execute.index('Extension(mode, arguments, replies)')
|
||||
assert 'arguments = "mission " + arguments' in execute
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""Actual session authority, transport scope and throttle policies; RPC delivery is native."""
|
||||
from policy_harness import ROOT, body, run
|
||||
session=ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminSession.c'
|
||||
bridge=ROOT/'addons/core/Scripts/Game/ERR/ERR_PlayerAdminCommands.c'
|
||||
client=ROOT/'addons/core/Scripts/Game/ERR/ERR_ChatClient.c'
|
||||
session=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminSession.c'
|
||||
bridge=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_PlayerAdminCommands.c'
|
||||
client=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_ChatClient.c'
|
||||
valid=body(session,'bool Valid(')
|
||||
server=body(bridge,'protected ERR_AdminSession ERR_ServerSession(')
|
||||
# Execute the exact admission/token guard prefix, before session allocation.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
Native dispatch/storage and remote ownership remain separate tests.
|
||||
"""
|
||||
from policy_harness import ROOT,body,run
|
||||
admin=ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminService.c'
|
||||
settings=ROOT/'addons/core/Scripts/Game/ERR/ERR_Settings.c'
|
||||
admin=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c'
|
||||
settings=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c'
|
||||
rules='\n'.join(body(path,sig) for path,sig in ((admin,'static string CoreSetting('),(admin,'static bool Integer('),(settings,'static bool Valid(')))
|
||||
rules=(rules.replace('string ', 'std::string ').replace('out int ', 'int& ')
|
||||
.replace('text.Length()', 'int(text.size())').replace('.IsEmpty()', '.empty()')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""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/ERR_AdminSession.c'
|
||||
admin=ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminService.c'
|
||||
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):
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
from pathlib import Path
|
||||
import os
|
||||
from policy_harness import ROOT,body,run
|
||||
P=Path(os.environ.get('ERR_HQ_ADMIN_SOURCE',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQAdminProvider.c')))
|
||||
S=ROOT/'addons/core/Scripts/Game/ERR/ERR_Settings.c'
|
||||
P=Path(os.environ.get('ERR_HQ_ADMIN_SOURCE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAdminProvider.c')))
|
||||
S=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c'
|
||||
valid=body(S,'static bool Valid(').replace('string key','std::string key')
|
||||
integer=body(ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminService.c','static bool Integer(')
|
||||
integer=body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c','static bool Integer(')
|
||||
integer=(integer.replace('string text','std::string text').replace('out int value','int& value').replace('text.IsEmpty()','text.empty()').replace('text.Length()','int(text.size())').replace('text.Substring(','text.substr(').replace('"0123456789".IndexOf(', 'std::string("0123456789").find(').replace('< 0) return false;','== std::string::npos) return false;').replace('text.ToInt()','std::stoi(text)'))
|
||||
method=body(P,'protected void StingerSetting(')
|
||||
method=(method.replace('protected ','').replace('ERR_GameMode mode','ERR_GameMode* mode').replace('array<string>','Array<string>&').replace('mode.Settings().','mode->Settings()->').replace('ERR_CommandArguments.Integer','Integer').replace('mode->Settings()->Get(key).ToString()','std::to_string(mode->Settings()->Get(key))').replace('value.ToString()','std::to_string(value)').replace('int value;','int value=0;'))
|
||||
@@ -50,7 +50,7 @@ int main(){
|
||||
execute=body(P,'override bool Execute(')
|
||||
assert execute.index('arguments.IndexOf("hq stinger ") == 0')<execute.index('if (arguments != "status"')
|
||||
assert 'StingerSetting(mode, parts, replies); return true;' in execute
|
||||
admin=body(ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminService.c','void Execute(')
|
||||
admin=body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c','void Execute(')
|
||||
assert admin.index('if (!authorized)')<admin.index('Extension(mode, arguments, replies)')
|
||||
for forbidden in ('Check(', 'RandomInt(', 'Spawn', 'ConvoyAllowance', 'SetAISkill', 'entry.'):
|
||||
assert forbidden not in body(P,'protected void StingerSetting(')
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
|
||||
FLIGHT=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFlight.c'
|
||||
BRIDGE=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftControlBridge.c'
|
||||
PROBES=[ROOT/'addons/ai/Scripts/Game/ERR'/name for name in ('ERR_NativeAircraftControlProbe.c','ERR_NativeAircraftRouteProbe.c')]
|
||||
FLIGHT=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFlight.c'
|
||||
BRIDGE=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftControlBridge.c'
|
||||
PROBES=[ROOT/'addons/core/Scripts/Game/ERR/10_AI'/name for name in ('ERR_NativeAircraftControlProbe.c','ERR_NativeAircraftRouteProbe.c')]
|
||||
|
||||
def cpp(text):
|
||||
text=text.replace('protected ','').replace('ERR_AircraftFlight flight','ERR_AircraftFlight* flight')
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""Execute bounded whole-field survey with fake native terrain/traces, never fly."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
P=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFieldEnvelope.c'
|
||||
RULES=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFieldRules.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFieldEnvelope.c'
|
||||
RULES=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFieldRules.c'
|
||||
def cpp(s):
|
||||
for name in ('Math','vector','ERR_AircraftFieldRules','SCR_TerrainHelper','TraceFlags'):
|
||||
s=s.replace(name+'.',name+'::')
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"""Execute prototype flight methods with real rules; native boundaries are fakes."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
P=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFieldFlight.c'
|
||||
B=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFlight.c'
|
||||
R=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFieldRules.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFieldFlight.c'
|
||||
B=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFlight.c'
|
||||
R=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFieldRules.c'
|
||||
source=P.read_text()
|
||||
def cpp(s):
|
||||
s=s.replace('protected ','').replace('override ','').replace('ref ','').replace('super.','Base::')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Actual field evidence/observation bodies; physical engine boundaries remain untested."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
P=ROOT/'addons/ai/Scripts/Game/ERR/ERR_NativeAircraftFieldProbe.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_NativeAircraftFieldProbe.c'
|
||||
s=P.read_text()
|
||||
def cpp(x):
|
||||
x=x.replace('ERR_AircraftFlightState.','State::').replace('ERR_NativeAircraftFieldRules.','Rules::').replace('ERR_AircraftFieldRules.','FieldRules::').replace('vector.','vector::').replace('ERR_AircraftFieldFlight flight','Flight* flight').replace('flight.','flight->')
|
||||
@@ -99,7 +99,7 @@ stop=body(P,'void Stop(')
|
||||
assert stop.index('s_Current = null')<stop.index('m_Service.Stop()')<stop.index('ERR_Actors.DeleteSpawned(')<stop.index('m_Service.Tick()')<stop.index('m_Flight = null')
|
||||
assert 'CanDispose(' in stop
|
||||
# Execute root-owned Chat dispatch branch: failure cannot become completion/reset.
|
||||
chat=ROOT/'addons/chat/Scripts/Game/ERR/ERR_NativeSmoke.c';cs=chat.read_text()
|
||||
chat=ROOT/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c';cs=chat.read_text()
|
||||
a=cs.index('if (m_ERRSmokeStep == 240)');opening=cs.index('{',a);i=opening+1;depth=1
|
||||
while depth:depth+=(cs[i]=='{')-(cs[i]=='}');i+=1
|
||||
branch=cs[opening+1:i-1].replace('m_ERRAircraftField.Tick','m_ERRAircraftField.Tick').replace('ERR_Phase.DEFEAT','2')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Execute the actual field policy equations; no claim about native stopping/flight."""
|
||||
from policy_harness import ROOT, run
|
||||
import re
|
||||
source = (ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFieldRules.c').read_text()
|
||||
source = (ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFieldRules.c').read_text()
|
||||
cpp = source.replace('class ERR_AircraftFieldRules', 'struct Rules').replace('out vector nextIntegral', 'vector& nextIntegral')
|
||||
cpp = cpp.replace('Math.', 'Math::').replace('vector.', 'vector::').replace('"0 0 0"', 'vector{}')
|
||||
cpp = re.sub(r'(?<![\w.])(\d+\.\d+)(?![\w.])', r'\1f', cpp)
|
||||
|
||||
@@ -40,7 +40,7 @@ class FieldRunnerTests(unittest.TestCase):
|
||||
normal=self.command('aircraft-field');cancelled=self.command('aircraft-field',True)
|
||||
self.assertEqual(cancelled,normal+['-errSmokeFieldServiceCancel','1'])
|
||||
self.assertEqual(normal[normal.index('-errSmokeOutcome')+1],'aircraft-field')
|
||||
self.assertEqual(normal[normal.index('-gproj')+1],'Z:/private/source/addons/chat/addon.gproj')
|
||||
self.assertEqual(normal[normal.index('-gproj')+1],'Z:/private/source/addons/core/addon.gproj')
|
||||
self.assertEqual(normal[normal.index('--backend')+1],'headless')
|
||||
self.assertIn('-disableCrashReporter',normal)
|
||||
self.assertNotIn('-errSmokeFieldServiceCancel',self.command('aircraft-route'))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Actual qualification claim/footprint bounds and release bodies; native traces remain untested."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
BASE=ROOT/'addons/ai/Scripts/Game/ERR'
|
||||
BASE=ROOT/'addons/core/Scripts/Game/ERR/10_AI'
|
||||
SOURCE=BASE/'ERR_AircraftFlightEnvelope.c'
|
||||
claim=body(SOURCE,'bool Claim(').replace('ERR_GameMode mode','ERR_GameMode* mode').replace('Vehicle aircraft','Vehicle* aircraft').replace('IEntity pilot','IEntity* pilot')
|
||||
claim=claim.replace('Replication.','Replication::').replace('ERR_GameMode.Get()', 'ERR_GameMode::Get()').replace('vector.','vector::').replace('mode.Active()', 'mode->Active()').replace('aircraft.GetOrigin()', 'aircraft->GetOrigin()').replace('GetGame().GetWorld().GetWorldTime()', 'GetGame()->GetWorld()->GetWorldTime()').replace('GetGame().GetWorld()', 'GetGame()->GetWorld()')
|
||||
|
||||
@@ -4,7 +4,7 @@ No native flight, callback ordering, collision or multiplayer claim.
|
||||
"""
|
||||
import re
|
||||
from policy_harness import ROOT, body, run
|
||||
SOURCE=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFlight.c'
|
||||
SOURCE=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFlight.c'
|
||||
def cpp(s):
|
||||
return s.replace('protected ','').replace('ERR_AircraftFlightState.','State::').replace('ERR_AircraftFlightRules.','Rules::').replace('Math.','Math::').replace('CollectiveMode.','CollectiveMode::').replace('vector.','vector::').replace('SignalsManagerComponent signals','SignalsManagerComponent* signals').replace('signals.FindSignal','signals->FindSignal').replace('signals.GetSignalValue','signals->GetSignalValue')
|
||||
rules='\n'.join(cpp(body(SOURCE,s)) for s in ['static bool Terminal(', 'static bool Deadline(', 'static bool Envelope(', 'static bool Hover(', 'static bool Landed(', 'static float Vertical(', 'static int CancelAction('])
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"""Execute actual route demand and control callback; native boundaries are fakes."""
|
||||
from policy_harness import ROOT, body, run
|
||||
|
||||
BASE = ROOT / 'addons/ai/Scripts/Game/ERR/ERR_AircraftFlight.c'
|
||||
ROUTE = ROOT / 'addons/ai/Scripts/Game/ERR/ERR_AircraftRouteFlight.c'
|
||||
RULES = ROOT / 'addons/ai/Scripts/Game/ERR/ERR_AircraftRouteEnvelope.c'
|
||||
PROBE = ROOT / 'addons/ai/Scripts/Game/ERR/ERR_NativeAircraftRouteProbe.c'
|
||||
BASE = ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFlight.c'
|
||||
ROUTE = ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftRouteFlight.c'
|
||||
RULES = ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftRouteEnvelope.c'
|
||||
PROBE = ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_NativeAircraftRouteProbe.c'
|
||||
|
||||
|
||||
def cpp(text):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Actual immutable corridor geometry and native-survey orchestration with fake traces."""
|
||||
from policy_harness import ROOT, body, run
|
||||
P=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftRouteEnvelope.c'
|
||||
BASE=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFlight.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftRouteEnvelope.c'
|
||||
BASE=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFlight.c'
|
||||
def cpp(s):
|
||||
for name in ('Math','vector','ERR_AircraftRouteRules','ERR_AircraftFlightRules','SCR_TerrainHelper','TraceFlags'):
|
||||
s=s.replace(name+'.',name+'::')
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""Actual route entry/stage/cancellation bodies with physical/native boundaries stubbed."""
|
||||
from policy_harness import ROOT, body, run
|
||||
P=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftRouteFlight.c'
|
||||
BASE=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFlight.c'
|
||||
ENV=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftRouteEnvelope.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftRouteFlight.c'
|
||||
BASE=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFlight.c'
|
||||
ENV=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftRouteEnvelope.c'
|
||||
def cpp(s):
|
||||
s=s.replace('protected ','').replace('override ','').replace('super.', 'Base::')
|
||||
for a,b in [('ERR_AircraftFlightState.','State::'),('ERR_AircraftFlightRules.','FlightRules::'),('ERR_AircraftRouteRules.','RouteRules::'),('Math.','Math::'),('vector.','vector::')]:s=s.replace(a,b)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Execute route result policy and audit opt-in finite/native fixture boundaries."""
|
||||
from policy_harness import ROOT, body, run
|
||||
P=ROOT/'addons/ai/Scripts/Game/ERR/ERR_NativeAircraftRouteProbe.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_NativeAircraftRouteProbe.c'
|
||||
source=P.read_text()
|
||||
rules='\n'.join(body(P,k) for k in ('static bool Terminal(', 'static bool TranslateProof(', 'static bool PhysicalFinish(', 'static bool CanDispose(')).replace('ERR_AircraftFlightState.','State::')
|
||||
run('''#include <cassert>
|
||||
@@ -61,7 +61,7 @@ for project,rounds,timeout,extra,message in cases:
|
||||
assert message in result.stderr, (project,rounds,timeout,extra,result.stderr)
|
||||
assert list(temporary.iterdir())==[], 'Refused route invocation must not create profiles or prefix locks'
|
||||
|
||||
chat=ROOT/'addons/chat/Scripts/Game/ERR/ERR_NativeSmoke.c'
|
||||
chat=ROOT/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c'
|
||||
text=chat.read_text()
|
||||
assert 'm_ERRTestAircraftRoute = outcome == "aircraft-route";' in text
|
||||
assert 'if (m_ERRTestAircraftControl || m_ERRTestAircraftRoute || m_ERRTestAircraftField) m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 330000;' in text
|
||||
@@ -167,7 +167,7 @@ for sig in ('void PrepareActions(', 'void PrepareHelicopter('):
|
||||
print('PASS: actual retained-service fixture entry, immutable controller/token/deadline/count bindings, observer getter and cleanup ownership ordering; native route validation pending')
|
||||
|
||||
# Cancellation is a separate explicit variant; no arrival credit or second stop.
|
||||
flight=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFlight.c'
|
||||
flight=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFlight.c'
|
||||
cancel_rules='\n'.join(body(P,k) for k in ('static bool CanStop(', 'static bool CancelProof(')).replace('ERR_AircraftFlightState.','State::').replace('ERR_AircraftFlightRules.Hover','Hover')
|
||||
run('''#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Actual finite service lifecycle methods; controller/physical APIs are fakes."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
P=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftService.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftService.c'
|
||||
|
||||
def cpp(s):
|
||||
s=s.replace('protected ','').replace('return null;', 'return nullptr;')
|
||||
@@ -135,7 +135,7 @@ print('PASS: actual finite registration, unique claims/tokens, retention/cancel/
|
||||
|
||||
# The existing route probe sees only its exact subtype; a field controller can
|
||||
# never be relabeled as route evidence through the shared retained base pointer.
|
||||
route_probe=ROOT/'addons/ai/Scripts/Game/ERR/ERR_NativeAircraftRouteProbe.c'
|
||||
route_probe=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_NativeAircraftRouteProbe.c'
|
||||
getter=body(route_probe,'ERR_AircraftRouteFlight ERR_NativeOriginalFlight(')
|
||||
getter=getter.replace('ERR_AircraftRouteFlight.Cast(entry.Flight)','dynamic_cast<Route*>(entry->Flight)').replace('ERR_AircraftRouteFlight ','Route* ').replace('ERR_AircraftServiceEntry entry','Entry* entry').replace('Vehicle aircraft','int aircraft').replace('null','nullptr')
|
||||
run(r'''#include <cassert>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Actual bounded target/start/stage policy, with native boundaries substituted."""
|
||||
from policy_harness import ROOT, body, run
|
||||
SOURCE=ROOT/'addons/ai/Scripts/Game/ERR/ERR_AircraftFlight.c'
|
||||
SOURCE=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AircraftFlight.c'
|
||||
def cpp(s):
|
||||
return s.replace('protected ','').replace('ERR_AircraftFlightState.','State::').replace('ERR_AircraftFlightRules.','FlightRules::').replace('ERR_AircraftTranslationRules.','Rules::').replace('Math.','Math::').replace('vector.','vector::').replace('SignalsManagerComponent signals','SignalsManagerComponent* signals').replace('signals.FindSignal','signals->FindSignal')
|
||||
rules='\n'.join(cpp(body(SOURCE,key)) for key in ('static bool Target(', 'static bool Reachable(', 'static vector Demand(', 'static bool Held('))
|
||||
|
||||
@@ -13,7 +13,7 @@ from test_vanilla_game_control import BASE
|
||||
|
||||
ORDINARY='''00 SCRIPT : Module: Game; defines: "PLATFORM_WINDOWS"
|
||||
00 SCRIPT : ERR ORDINARY: header verified project=core systems=MissionSystems
|
||||
00 SCRIPT : Rereintroduced [mission]: phase 0 -> 1
|
||||
00 SCRIPT : Reintroduced [mission]: phase 0 -> 1
|
||||
00 SCRIPT : ERR ORDINARY: local participant verified project=core phase=prison
|
||||
'''
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ class PackedChatArchiveTests(unittest.TestCase):
|
||||
for i,project in enumerate(archiver.ADDON_ORDER):
|
||||
name,guid,deps=runner.PACKED_PROJECTS[project]
|
||||
lines.extend([f"00 ENGINE : FileSystem: Adding package '{folder/project}/' (pak count: 1) to filesystem under name {name}", f"00 RESOURCES : ResourceDB: loading cache (id={i} name={name} path={folder/project}/resourceDatabase.rdb)"])
|
||||
lines.extend(['00 SCRIPT : Module: GameLib; defines: "PLATFORM_WINDOWS"','00 SCRIPT : Module: Game; defines: "PLATFORM_WINDOWS"','00 SCRIPT : ERR ORDINARY: header verified project=chat systems=MissionSystems','00 SCRIPT : ERR ORDINARY: local participant verified project=chat phase=prison','00 SCRIPT : Rereintroduced [mission]: phase 0 -> 1'])
|
||||
lines.extend(['00 SCRIPT : Module: GameLib; defines: "PLATFORM_WINDOWS"','00 SCRIPT : Module: Game; defines: "PLATFORM_WINDOWS"','00 SCRIPT : ERR ORDINARY: header verified project=chat systems=MissionSystems','00 SCRIPT : ERR ORDINARY: local participant verified project=chat phase=prison','00 SCRIPT : Reintroduced [mission]: phase 0 -> 1'])
|
||||
return '\n'.join(lines)+'\n'
|
||||
def test_chat_preserves_all_fifteen_artifacts_and_schema(self):
|
||||
destination,status=archiver.archive(self.session,'packed-chat',self.root);self.assertEqual(status,0)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""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/ERR_CasualtyLoadingService.c'
|
||||
action = ROOT/'addons/core/Scripts/Game/ERR/ERR_LoadCasualtyAction.c'
|
||||
feedback = ROOT/'addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingFeedback.c'
|
||||
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']:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
source = body(ROOT/'addons/core/Scripts/Game/ERR/ERR_CasualtyGroundSupport.c', 'static bool SupportHit(')
|
||||
source = body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_CasualtyGroundSupport.c', 'static bool SupportHit(')
|
||||
source = re.sub(r'(?<![\w.])(\d+\.\d+)(?![\w.])', r'\1f', source)
|
||||
run('#include <cassert>\n' + source + '''
|
||||
int main() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Run the actual fixture method against a narrow native-damage API fake."""
|
||||
from policy_harness import ROOT, body, run
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/ERR_NativeCasualtyLoadProbe.c'
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_NativeCasualtyLoadProbe.c'
|
||||
method=body(p,'protected bool IncapacitateGroundCasualty(')
|
||||
method=method.replace('protected bool','bool').replace('m_Damage.','m_Damage->').replace('resilience.','resilience->').replace('ERR_Actors.','ERR_Actors::').replace('null','nullptr')
|
||||
run('''
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
path = ROOT/'addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingService.c'
|
||||
path = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_CasualtyLoadingService.c'
|
||||
source = '\n'.join(body(path, signature) for signature in [
|
||||
'static int RoundAction(', 'static bool ObserveTicket(', 'static bool Within(', 'static bool SettledFor(', 'static bool Ranges(', 'static bool AircraftMotion('])
|
||||
# Enforce float literals are single precision; C++ otherwise promotes these to doubles.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Fixture boundaries and actual safe-exit policy; not an engine substitute."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
source = ROOT/'addons/core/Scripts/Game/ERR/ERR_NativeCasualtyRemoveProbe.c'
|
||||
source = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_NativeCasualtyRemoveProbe.c'
|
||||
method = body(source,'static bool SafeExit(')
|
||||
method = re.sub(r'(?<![\w.])(\d+\.\d+)(?![\w.])',r'\1f',method)
|
||||
run('#include <cassert>\n'+method+'''
|
||||
@@ -29,11 +29,11 @@ assert 'if (m_RemoveStopped) return -1;' in body(source,'override int Tick(')
|
||||
for forbidden in ('GetOutVehicle(', 'GetOutVehicle_NoDoor(', 'KickFromVehicle(', 'SetUnconscious(', 'm_Casualty.Set', 'm_Casualty).Teleport', 'SetActive('):
|
||||
assert forbidden not in text,forbidden
|
||||
# Existing arbitrary-ground mechanism remains exactly its original contract.
|
||||
base=ROOT/'addons/core/Scripts/Game/ERR/ERR_NativeCasualtyLoadProbe.c'
|
||||
base=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_NativeCasualtyLoadProbe.c'
|
||||
assert 'GetOutVehicle_NoDoor(exitTransform, true, false)' in body(base,'protected bool BeginExit(')
|
||||
assert 'exitTransform[3] = m_GroundPosition;' in body(base,'protected bool BeginExit(')
|
||||
assert body(base,'protected bool ExitSettled(').strip().endswith('return ERR_Actors.Alive(m_Casualty) && vector.Distance(m_Casualty.GetOrigin(), m_GroundPosition) < 4 && m_Seat.IsCompartmentAccessible();\n }')
|
||||
base_text=(ROOT/'addons/core/Scripts/Game/ERR/ERR_NativeBaseSmoke.c').read_text()
|
||||
base_text=(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_NativeBaseSmoke.c').read_text()
|
||||
assert base_text.count('m_ERRExtractionCase == "casualty-remove"') == 3
|
||||
assert 'm_ERRCasualtyLoadProbe = new ERR_NativeCasualtyRemoveProbe(this);' in base_text
|
||||
assert 'm_ERRBaseStep = 802; Transition(ERR_Phase.DEFEAT);' in base_text
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
No synthetic fixture is claimed as network/owner-RPC proof.
|
||||
"""
|
||||
from policy_harness import ROOT, body, run
|
||||
path = ROOT/'addons/core/Scripts/Game/ERR/ERR_CasualtyLoadingService.c'
|
||||
path = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_CasualtyLoadingService.c'
|
||||
physical = body(path, 'protected bool PhysicalTicket(')
|
||||
physical = (physical.replace('protected ', '').replace('ERR_CasualtyLoadTicket ticket', 'Ticket* ticket')
|
||||
.replace('ticket.', 'ticket->').replace('m_Mode.', 'm_Mode->')
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
Checks scheduling/authority boundaries, not native aircraft, network or timing.
|
||||
"""
|
||||
from policy_harness import ROOT,body,run
|
||||
MODE=ROOT/'addons/core/Scripts/Game/ERR/ERR_GameMode.c'
|
||||
ACTORS=ROOT/'addons/core/Scripts/Game/ERR/ERR_Actors.c'
|
||||
MODE=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c'
|
||||
ACTORS=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Actors.c'
|
||||
|
||||
def cpp(s):
|
||||
s=s.replace('protected ','').replace('Replication.IsServer()','server').replace('Replication.BumpMe()','Bump()')
|
||||
s=s.replace('ERR_Phase.DEFEAT','5').replace('ERR_Phase.PRISON','1').replace('ERR_MissionRules.Terminal(m_Phase)','(m_Phase>=5)')
|
||||
s=s.replace('ERR_Phase.DEFEAT','5').replace('ERR_Phase.PRISON','1').replace('ERR_Phase.RADIO_SEARCH','2').replace('ERR_MissionRules.Terminal(m_Phase)','(m_Phase>=5)')
|
||||
s=s.replace('array<int> connected = {};','std::vector<int> connected;').replace('foreach (int id : connected)','for (int id : connected)')
|
||||
s=s.replace('SCR_PlayerController controller = SCR_PlayerController.Cast(', 'Controller* controller = Controller::Cast(')
|
||||
s=s.replace('foreach (IEntity entity : m_OwnedEntities)','for (Entity* entity : m_OwnedEntities)')
|
||||
@@ -52,7 +52,7 @@ struct ForceBoundary {int clears=0;void Clear(){clears++;}};
|
||||
struct Mode {
|
||||
ForceBoundary m_Forces,m_ForceAgents;
|
||||
int forceTicks=0;void TickForces(float){forceTicks++;}
|
||||
bool m_Stopped=false,m_NativeEndHandled=false,m_StartedPlayers=false;int m_Phase=1;
|
||||
bool m_Stopped=false,m_NativeEndHandled=false,m_StartedPlayers=false;int m_Phase=2;
|
||||
float m_NoSurvivorsSince=-1;std::string m_EndReason;
|
||||
Work extraction{0,"extraction",{}},radio{0,"radio",{}},recovery{0,"recovery",{}};
|
||||
Work* m_Extraction=&extraction;Work* m_RadioDefence=&radio;Work* m_Recovery=&recovery;
|
||||
@@ -77,6 +77,12 @@ int main(){
|
||||
assert((events==std::vector<std::string>{"extraction","radio","recovery","maintain","observer","tactics","event"}));}
|
||||
// No command service is valid both with and without connected players.
|
||||
{reset();Mode m;m.ServerTick();players.count=1;m.ServerTick();assert(m.m_OnTick.calls==1);}
|
||||
// During prison, maintenance/observers still work, but enemies receive no
|
||||
// tactical updates or virtual route movement before the lockpick.
|
||||
{reset();players.count=1;Mode m;m.m_Phase=1;Retained c;m.m_Command=&c;
|
||||
m.ServerTick();assert(c.maintenance==1&&c.tactics==0&&m.forceTicks==0);
|
||||
assert(players.controller.updates==1&&m.m_OnTick.calls==1);
|
||||
m.m_Phase=2;m.ServerTick();assert(c.tactics==1&&m.forceTicks==1);}
|
||||
// Authority, preparation, terminal phase, native end and stopped service all
|
||||
// refuse maintenance as well as tactics. No stale clock/actor admission exists.
|
||||
for(int fault=0;fault<5;fault++){reset();Mode m;Retained c;m.m_Command=&c;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,body,run
|
||||
path=Path(os.environ.get('ERR_CONVOY_SERVICE',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_ConvoyService.c')))
|
||||
path=Path(os.environ.get('ERR_CONVOY_SERVICE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyService.c')))
|
||||
s=body(path,'protected bool Admit(').replace('protected ','')
|
||||
s=s.replace('SCR_AIVehicleUsageComponent.Cast(unit.Entity.FindComponent(SCR_AIVehicleUsageComponent))','&unit->Entity->usage').replace('ERR_HQ.Cast(m_Mode.Command())','m_Mode->Command()')
|
||||
s=s.replace('array<AIAgent>','Array<AIAgent*>')
|
||||
|
||||
@@ -3,7 +3,7 @@ import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,body,run
|
||||
BASE=Path(os.environ.get('ERR_CONVOY_SETTINGS_ROOT',ROOT))
|
||||
P=BASE/'addons/core/Scripts/Game/ERR/ERR_Settings.c'
|
||||
P=BASE/'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c'
|
||||
keys=body(P,'static array<string> Keys(').replace('array<string>','std::vector<string>')
|
||||
valid=body(P,'static bool Valid(')
|
||||
default=body(P,'static int AddedDefault(')
|
||||
@@ -44,14 +44,14 @@ int main(){
|
||||
}
|
||||
''')
|
||||
assert 'm_Values.Set("automaticConvoyEnabled", AddedDefault("automaticConvoyEnabled"));' in P.read_text()
|
||||
admin=body(BASE/'addons/core/Scripts/Game/ERR/ERR_AdminService.c','void Execute(')
|
||||
admin=body(BASE/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c','void Execute(')
|
||||
assert 'if (key == "automaticConvoyEnabled") line += " (saved for next round; current startup unchanged)";' in admin
|
||||
provider=BASE/'addons/ai/Scripts/Game/ERR/ERR_HQAdminProvider.c'
|
||||
provider=BASE/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAdminProvider.c'
|
||||
helper=body(provider,'protected void ConvoyAutoSetting(')
|
||||
for forbidden in ('StartConvoy','StartScenarioConvoy','Spawn','m_HQ.'):
|
||||
assert forbidden not in helper
|
||||
# Do not advertise this command-only setting as an editable field absent from the actual fixed menu.
|
||||
menu=body(ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminMenu.c','static array<string> Keys(')
|
||||
menu=body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenu.c','static array<string> Keys(')
|
||||
assert 'automaticConvoyEnabled' not in menu
|
||||
assert body(provider,'override bool Help(').count('replies.Insert(')<=4
|
||||
print('PASS: actual read migrates old valid settings, preserves explicit disabled state, rejects invalid data; next-round feedback and fixed menu remain honest')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,run
|
||||
p=Path(os.environ.get('ERR_CONVOY_BUDGET',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_ConvoyBudget.c')))
|
||||
p=Path(os.environ.get('ERR_CONVOY_BUDGET',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyBudget.c')))
|
||||
s=p.read_text();s=re.sub(r'//[^\n]*','',s).replace('protected ','').replace('ref ','').replace('class ','struct ')
|
||||
s=s.replace('array<int>','Array<int>').replace('array<ERR_ConvoyReceipt>','Array<ERR_ConvoyReceipt*>')
|
||||
for typ in ['ERR_GameMode','ERR_ForceLedger','ERR_ForceRecord','ERR_ConvoyReceipt']:
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,body,run
|
||||
rules=Path(os.environ.get('ERR_CONVOY_COMBAT',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_ConvoyCombat.c')))
|
||||
service=Path(os.environ.get('ERR_CONVOY_SERVICE',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_ConvoyService.c')))
|
||||
rules=Path(os.environ.get('ERR_CONVOY_COMBAT',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyCombat.c')))
|
||||
service=Path(os.environ.get('ERR_CONVOY_SERVICE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyService.c')))
|
||||
accept=body(rules,'static bool Accept(')
|
||||
for cls in ['ERR_ConvoyCombatState','ERR_ConvoyCombatOrder']:accept=accept.replace(cls+' ',cls+'* ')
|
||||
accept=accept.replace('state.','state->').replace('order.','order->').replace('ERR_ForceRules.','ERR_ForceRules::')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,body,run
|
||||
path=Path(os.environ.get('ERR_CONVOY_SERVICE',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_ConvoyService.c')))
|
||||
path=Path(os.environ.get('ERR_CONVOY_SERVICE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyService.c')))
|
||||
source=path.read_text()
|
||||
# Dispatch's native calls are doubled; budget behavior is executed separately.
|
||||
code=body(path,'ERR_ConvoyTask Dispatch(')
|
||||
@@ -107,7 +107,7 @@ print('PASS: actual convoy dispatch validates before receipt consumption, consum
|
||||
|
||||
# The resource must suppress authored allocation before native EOnInit, not try
|
||||
# to purge a queued default squad after custom seat occupants have been added.
|
||||
prefab=ROOT/'addons/ai/Prefabs/ERR/ConvoyCrew.et'
|
||||
prefab=ROOT/'addons/core/Prefabs/ERR/ConvoyCrew.et'
|
||||
text=prefab.read_text()
|
||||
assert '"{000CD338713F2B5A}Prefabs/AI/Groups/Group_Base.et"' in text
|
||||
assert 'm_bSpawnImmediately 0' in text and 'm_faction "USSR"' in text
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,run
|
||||
path=Path(os.environ.get('ERR_CONVOY_SERVICE',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_ConvoyService.c')))
|
||||
path=Path(os.environ.get('ERR_CONVOY_SERVICE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyService.c')))
|
||||
source=path.read_text();code=source[source.index('class ERR_ConvoyVehicle'):source.index('class ERR_ConvoyCargoCallback')]
|
||||
code=re.sub(r'//[^\n]*','',code).replace('class ERR_ConvoyVehicle','struct ERR_ConvoyVehicle').replace('ref ','')
|
||||
code=code.replace('array<IEntity>','Array<IEntity*>').replace('array<BaseCompartmentSlot>','Array<BaseCompartmentSlot*>').replace('array<AIAgent>','Array<AIAgent*>')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Execute actual footprint sampling and native query callback policy with API doubles."""
|
||||
import re
|
||||
from policy_harness import ROOT,body,run
|
||||
p=ROOT/'addons/ai/Scripts/Game/ERR/ERR_ConvoyPlacement.c'
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyPlacement.c'
|
||||
code='\n'.join(body(p,s) for s in ('protected bool Occupancy(', 'static bool Terrain(', 'bool Clear('))
|
||||
code=code.replace('null','nullptr').replace('protected ','').replace('IEntity entity','IEntity* entity').replace('entity.GetVObject()', 'entity->GetVObject()')
|
||||
code=code.replace('TraceBox volume', 'TraceBox* volume').replace('volume.', 'volume->').replace('\"0 0.01 0\"', 'Vector(0,.01,0)')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from policy_harness import ROOT, body, run
|
||||
from pathlib import Path
|
||||
p=Path(os.environ.get('ERR_CONVOY_ROAD_PLAN',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_ConvoyRoadPlan.c')))
|
||||
p=Path(os.environ.get('ERR_CONVOY_ROAD_PLAN',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyRoadPlan.c')))
|
||||
code='\n'.join(body(p,s) for s in ('static bool Sample(', 'static bool CandidateStart(', 'static bool FromPolyline(', 'static bool Prefer('))
|
||||
code=re.sub(r'//[^\n]*','',code)
|
||||
code=code.replace('out array<vector>','Array<vector>&').replace('array<vector>','Array<vector>')
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
"""Execute one-shot startup timing and actual HQ dispatch boundary; no native claim."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
p=ROOT/'addons/ai/Scripts/Game/ERR/ERR_ConvoyStartup.c'
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_ConvoyStartup.c'
|
||||
s=p.read_text().replace('protected ','').replace('ERR_ForceRules.','ERR_ForceRules::')
|
||||
s=s[s.index('class ERR_ConvoyStartup'):].replace('void ERR_ConvoyStartup(bool enabled)','void Initialize(bool enabled)')
|
||||
s=s.replace('bool m_Enabled;', 'bool m_Enabled=false;').replace('bool m_Finished;', 'bool m_Finished=false;').replace('float m_Next;', 'float m_Next=0;')
|
||||
s=s.replace('class ERR_ConvoyStartup', 'struct ERR_ConvoyStartup').rstrip()+';'
|
||||
h=body(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c','protected void AutomaticConvoy(')
|
||||
h=body(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c','protected void AutomaticConvoy(')
|
||||
h=h.replace('protected ','').replace('null','nullptr').replace('Replication.','Replication::').replace('ERR_GameMode.','ERR_GameMode::')
|
||||
for name in ('m_Mode','m_ConvoyStartup'):h=h.replace(name+'.',name+'->')
|
||||
run(r'''
|
||||
|
||||
@@ -48,15 +48,15 @@ class DedicatedNativeTests(unittest.TestCase):
|
||||
self.assertEqual(runner.engine_args('header'), runner.engine_args('header', 'core'))
|
||||
expected = {
|
||||
'core': ('2528466DE220D91C', '{AD62322D5213C440}Missions/ERR_Everon_Base.conf'),
|
||||
'chat': ('FA804F411BDDF2C6', '{C1E20667DCE324ED}Missions/ERR_Everon.conf'),
|
||||
'chat': ('2528466DE220D91C', '{C1E20667DCE324ED}Missions/ERR_Everon.conf'),
|
||||
}
|
||||
root = Path(__file__).parents[1]
|
||||
for project, (guid, header) in expected.items():
|
||||
# Keep the CLI identities tied to the actual authored resources.
|
||||
gproj = (root/'addons'/project/'addon.gproj').read_text()
|
||||
gproj = (root/'addons/core'/'addon.gproj').read_text()
|
||||
self.assertIn('GUID "'+guid+'"', gproj)
|
||||
resource = header.split('}', 1)[1]
|
||||
self.assertIn('Name "'+header+'"', (root/'addons'/project/(resource+'.meta')).read_text())
|
||||
self.assertIn('Name "'+header+'"', (root/'addons/core'/(resource+'.meta')).read_text())
|
||||
for route in ('header', 'diag-world'):
|
||||
args = runner.engine_args(route, project)
|
||||
self.assertEqual(args[args.index('-addonsDir')+1], '/tmp/source/addons')
|
||||
@@ -74,14 +74,9 @@ class DedicatedNativeTests(unittest.TestCase):
|
||||
self.assertEqual(args[0], '/tmp/runtime/ArmaReforgerServerDiag')
|
||||
self.assertEqual(args[args.index('-server')+1], '{B6C516F86302C679}Worlds/ERR_Everon.ent')
|
||||
self.assertEqual(args[args.index('-worldSystemsConfig')+1], '{C50579A2EC48E8EF}Configs/Systems/MissionSystems.conf')
|
||||
# Selecting Chat activates the existing declared closure, not invented
|
||||
# runtime addons or an explicit list that could omit dependencies.
|
||||
chat = (root/'addons/chat/addon.gproj').read_text().split('Dependencies', 1)[1]
|
||||
dependencies = set(re.findall(r'"([A-F0-9]{16})"', chat))
|
||||
expected_dependencies = {'58D0FB3206B6F859'}
|
||||
for project in ('core', 'ai', 'intel', 'map'):
|
||||
expected_dependencies.add(re.search(r'GUID "([A-F0-9]{16})"', (root/'addons'/project/'addon.gproj').read_text())[1])
|
||||
self.assertEqual(dependencies, expected_dependencies)
|
||||
definition = (root/'addons/core/addon.gproj').read_text()
|
||||
dependencies = set(re.findall(r'"([A-F0-9]{16})"', re.search(r'Dependencies\s*\{([^}]+)', definition)[1]))
|
||||
self.assertEqual(dependencies, {'58D0FB3206B6F859', '595F2BF2F44836FB', '629B2BA37EFFD577', '5E524E4FEECCA92B'})
|
||||
|
||||
def test_invalid_project_route_combinations_fail_before_files_or_processes(self):
|
||||
for route, project in [('vanilla-everon', 'chat'), ('unknown', 'core'), ('header', 'unknown')]:
|
||||
@@ -101,7 +96,7 @@ class DedicatedNativeTests(unittest.TestCase):
|
||||
launch.assert_not_called()
|
||||
self.assertIn('vanilla-everon cannot be combined with --project chat', stderr.getvalue())
|
||||
|
||||
def addon_input(self, root, names=('core', 'ai', 'intel', 'map', 'chat')):
|
||||
def addon_input(self, root, names=('core',)):
|
||||
repository = Path(__file__).parents[1]
|
||||
for addon in names:
|
||||
folder = root/'addons'/addon
|
||||
@@ -124,16 +119,15 @@ class DedicatedNativeTests(unittest.TestCase):
|
||||
source = Path(directory)
|
||||
self.addon_input(source, ('core',))
|
||||
runner.preflight_addons(source, 'header')
|
||||
with self.assertRaisesRegex(ValueError, 'ai'):
|
||||
runner.preflight_addons(source, 'header', 'chat')
|
||||
runner.preflight_addons(source, 'header', 'chat')
|
||||
runner.preflight_addons(Path('/not-a-real-addon-input'), 'vanilla-everon')
|
||||
|
||||
def test_missing_core_dependency_and_empty_database_refuse_before_archive_or_process(self):
|
||||
for project, relative, empty in [
|
||||
('core', 'core/resourceDatabase.rdb', False),
|
||||
('chat', 'core/addon.gproj', False),
|
||||
('chat', 'ai/resourceDatabase.rdb', False),
|
||||
('chat', 'map/resourceDatabase.rdb', True),
|
||||
('chat', 'core/resourceDatabase.rdb', False),
|
||||
('chat', 'core/resourceDatabase.rdb', True),
|
||||
]:
|
||||
with self.subTest(project=project, relative=relative, empty=empty), tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory); source=root/'source'; archive=root/'archive'
|
||||
@@ -163,7 +157,7 @@ class DedicatedNativeTests(unittest.TestCase):
|
||||
runner.preflight_addons(source, 'header')
|
||||
database.rmdir(); database.write_bytes(b'presence-only')
|
||||
project = source/'addons/core/addon.gproj'
|
||||
project.write_text(project.read_text().replace('2528466DE220D91C', 'FA804F411BDDF2C6'))
|
||||
project.write_text(project.read_text().replace('2528466DE220D91C', '1111111111111111'))
|
||||
with self.assertRaisesRegex(ValueError, 'identity mismatch'):
|
||||
runner.preflight_addons(source, 'header')
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
|
||||
@@ -17,9 +17,9 @@ class DedicatedPreflightTests(unittest.TestCase):
|
||||
self.source, self.runtime = root/'source', root/'runtime'
|
||||
self.runtime.mkdir()
|
||||
for project, header in tool.HEADERS.items():
|
||||
addon = self.source/'addons'/project
|
||||
addon = self.source/'addons/core'
|
||||
path = addon/header
|
||||
path.parent.mkdir(parents=True)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
(addon/'addon.gproj').write_text('GameProject { GUID "2528466DE220D91C" }')
|
||||
path.write_text('SCR_MissionHeader { World "'+tool.WORLD+'" SystemsConfig "'+tool.SYSTEMS+'" }')
|
||||
path.with_suffix('.conf.meta').write_text('MetaFileClass { Name "{AD62322D5213C440}'+header+'" }')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Execute the actual opt-in Load body; no native engine or GUI is launched."""
|
||||
from policy_harness import ROOT, body, run
|
||||
source=ROOT/'addons/core/Scripts/GameLib/ERR/ERR_DiagnosticNoSplash.c'
|
||||
source=ROOT/'addons/core/Scripts/GameLib/ERR/00_Core/ERR_DiagnosticNoSplash.c'
|
||||
load=body(source,'override void Load()').replace('override void','void').replace('System.','System::').replace('super.Load()', 'Base::Load()')
|
||||
run('''#include <cassert>
|
||||
#include <string>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Execute the production coordinate policy; native probe checks marker storage."""
|
||||
from policy_harness import ROOT, body, run
|
||||
source=ROOT/'addons/core/Scripts/Game/ERR/ERR_DiscoveryMap.c'
|
||||
source=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_DiscoveryMap.c'
|
||||
policy=body(source,'static int Coordinate(').replace('Math.Round','std::round').replace('Math.Floor','std::floor')
|
||||
run('''#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,run
|
||||
source=Path(os.environ.get('ERR_EQUIPMENT_SOURCE',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_EnemyEquipment.c'))).read_text()
|
||||
source=Path(os.environ.get('ERR_EQUIPMENT_SOURCE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyEquipment.c'))).read_text()
|
||||
code=source[:source.index('class ERR_EnemyEquipmentGroup')]
|
||||
code=re.sub(r'//[^\n]*','',code)
|
||||
code=code.replace('modded class SCR_AICombatComponent','struct SCR_AICombatComponent : NativeCombat')
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,run
|
||||
helper=Path(os.environ.get('ERR_GUNNER_SOURCE', str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_EnemyGunnerSkill.c'))).read_text()
|
||||
equipment=Path(os.environ.get('ERR_EQUIPMENT_SOURCE', str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_EnemyEquipment.c'))).read_text()
|
||||
helper=Path(os.environ.get('ERR_GUNNER_SOURCE', str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyGunnerSkill.c'))).read_text()
|
||||
equipment=Path(os.environ.get('ERR_EQUIPMENT_SOURCE', str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyEquipment.c'))).read_text()
|
||||
def convert(s):
|
||||
s=re.sub(r'//[^\n]*','',s).replace('protected ','').replace('override ','')
|
||||
s=s.replace('ERR_HQ.Cast(mode.Command())','mode->Command()').replace('TurretCompartmentSlot.Cast(slot)','dynamic_cast<TurretCompartmentSlot*>(slot)')
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
from policy_harness import ROOT,run
|
||||
P=Path(os.environ.get('ERR_OPTICS_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_EnemyOptics.c'))
|
||||
P=Path(os.environ.get('ERR_OPTICS_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyOptics.c'))
|
||||
s=P.read_text()
|
||||
assert 'GetGame(' not in s and 'CallLater' not in s and 'DeleteEntity' not in s
|
||||
callback=(ROOT/'addons/ai/Scripts/Game/ERR/ERR_EnemyEquipment.c').read_text().split('class ERR_EnemyEquipmentCallback',1)[1].split('class ERR_EnemyEquipmentEntry',1)[0]
|
||||
callback=(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyEquipment.c').read_text().split('class ERR_EnemyEquipmentCallback',1)[1].split('class ERR_EnemyEquipmentEntry',1)[0]
|
||||
code='class ERR_EnemyEquipmentCallback'+callback+s
|
||||
code=re.sub(r'//[^\n]*','',code).replace('protected ','').replace('override ','').replace('class ','struct ')
|
||||
for src,dst in {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
from policy_harness import ROOT,run
|
||||
P=Path(os.environ.get('ERR_RADIO_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_EnemyRadio.c'))
|
||||
P=Path(os.environ.get('ERR_RADIO_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyRadio.c'))
|
||||
s=P.read_text()
|
||||
assert 'GetOrigin' not in s and 'CallLater' not in s and 'Math.Random' not in s
|
||||
callback=(ROOT/'addons/ai/Scripts/Game/ERR/ERR_EnemyEquipment.c').read_text().split('class ERR_EnemyEquipmentCallback',1)[1].split('class ERR_EnemyEquipmentEntry',1)[0]
|
||||
callback=(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyEquipment.c').read_text().split('class ERR_EnemyEquipmentCallback',1)[1].split('class ERR_EnemyEquipmentEntry',1)[0]
|
||||
code='class ERR_EnemyEquipmentCallback'+callback+s
|
||||
code=re.sub(r'//[^\n]*','',code).replace('protected ','').replace('override ','').replace('class ','struct ')
|
||||
code=code.replace('InventoryStorageManagerComponent.Cast(actor.FindComponent(InventoryStorageManagerComponent))','actor->inventory')
|
||||
@@ -20,7 +20,7 @@ for name in ('actor','inventory','item','radio','agent','m_Group','m_Operation',
|
||||
code=re.sub(r'\b'+name+r'\.',name+'->',code)
|
||||
code=re.sub(r'\b(bool|int|IEntity|SCR_AIGroup|ERR_EnemyEquipmentCallback\*) (\w+);',r'\1 \2{};',code)
|
||||
code=code.replace('\n}\n','\n};\n')
|
||||
equipment=Path(os.environ.get('ERR_EQUIPMENT_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_EnemyEquipment.c')).read_text()
|
||||
equipment=Path(os.environ.get('ERR_EQUIPMENT_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_EnemyEquipment.c')).read_text()
|
||||
coordinator=equipment[equipment.index('class ERR_EnemyEquipmentGroup'):]
|
||||
coordinator=re.sub(r'//[^\n]*','',coordinator).replace('protected ','').replace('ref ','').replace('class ','struct ')
|
||||
coordinator=coordinator.replace('array<ERR_EnemyEquipmentGroup>','Array<ERR_EnemyEquipmentGroup*>').replace('array<ERR_EnemyEquipmentEntry>','Array<ERR_EnemyEquipmentEntry*>').replace('array<AIAgent>','Array<AIAgent>')
|
||||
|
||||
@@ -4,9 +4,9 @@ Calendar validity expectations come from Python's independent datetime calendar.
|
||||
from datetime import date
|
||||
import re
|
||||
from policy_harness import ROOT, body, run
|
||||
settings = ROOT/'addons/core/Scripts/Game/ERR/ERR_Settings.c'
|
||||
service = ROOT/'addons/core/Scripts/Game/ERR/ERR_EnvironmentService.c'
|
||||
admin = ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminService.c'
|
||||
settings = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c'
|
||||
service = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_EnvironmentService.c'
|
||||
admin = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c'
|
||||
|
||||
def translate(source):
|
||||
source = (source.replace('string ', 'std::string ').replace('out int ', 'int& ')
|
||||
|
||||
@@ -4,7 +4,7 @@ No native replication, end-screen rendering or multiplayer claim.
|
||||
import re
|
||||
from policy_harness import ROOT, body, run
|
||||
|
||||
SOURCE=ROOT/'addons/core/Scripts/Game/ERR/ERR_EscapeGameOverScreenInfo.c'
|
||||
SOURCE=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_EscapeGameOverScreenInfo.c'
|
||||
methods='\n'.join(body(SOURCE, signature) for signature in (
|
||||
'protected ERR_PersonalEscapeResult PersonalResult(',
|
||||
'override string GetTitle(',
|
||||
|
||||
@@ -32,7 +32,7 @@ class ExternalAddonsTests(unittest.TestCase):
|
||||
self.assertTrue(ext.resource_allowed(self.value,{item['addon']},item['guid'],path))
|
||||
self.assertFalse(ext.resource_allowed(self.value,{'core'},item['guid'],path))
|
||||
self.assertFalse(ext.resource_allowed(self.value,{item['addon']},'0000000000000000',path))
|
||||
self.assertEqual(ext.direct_for('core'),set());self.assertEqual(ext.direct_for('chat'),set())
|
||||
self.assertEqual(ext.direct_for('core'),set(ext.DIRECT));self.assertEqual(ext.direct_for('chat'),set())
|
||||
def test_policy_rejects_original_transitive_dependency(self):
|
||||
root=self.home/'root';(root/'docs').mkdir(parents=True)
|
||||
value=copy.deepcopy(self.value);value['addons'][ext.DIRECT[0]]['dependencies'].append('5F16D7E4A1CBE075')
|
||||
|
||||
@@ -40,7 +40,7 @@ class ReviewTests(existing.ExternalAddonsTests):
|
||||
from unittest.mock import patch
|
||||
self.home.joinpath('docs').mkdir();import json
|
||||
policy=self.home/'docs/external-addons.json';policy.write_text(json.dumps(self.value))
|
||||
context=n.external_request('ai',self.source,self.home);session=self.home/'session';session.mkdir()
|
||||
context=n.external_request('core',self.source,self.home);session=self.home/'session';session.mkdir()
|
||||
with patch.object(n,'external_installed',ext.installed):
|
||||
n.capture_external(context,session)
|
||||
folder=self.source/ext.DIRECT[0]/'Scripts';folder.mkdir()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Execute production time policies; do not claim native simulation coverage."""
|
||||
from policy_harness import ROOT, body, run
|
||||
source = ROOT/'addons/core/Scripts/Game/ERR/ERR_ExtractionPlacement.c'
|
||||
source = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_ExtractionPlacement.c'
|
||||
methods = '\n'.join(body(source, signature) for signature in (
|
||||
'static bool CanWake(', 'static bool Fresh(', 'static bool QualificationAllowed(', 'static bool Stable('))
|
||||
run('#include <cassert>\n' + methods + '''
|
||||
@@ -40,12 +40,12 @@ assert poll.index('m_WakeCount = 1;') < poll.index('physics.SetActive(')
|
||||
assert 'fuel.HasFuel() && ERR_CasualtyLoadingRules.AircraftReady(m_Aircraft)' in poll
|
||||
for forbidden in ('SetVelocity(', 'SetAngularVelocity(', 'SetTransform(', 'SetWorldTransform(', 'Teleport(', 'ApplyImpulse', 'EnableDamageHandling('):
|
||||
assert forbidden not in text, forbidden
|
||||
site = (ROOT/'addons/core/Scripts/Game/ERR/ERR_SiteService.c').read_text()
|
||||
site = (ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c').read_text()
|
||||
assert 'if (m_ExtractionPlacement) m_ExtractionPlacement.Stop();' in site
|
||||
assert 'Fail(m_ExtractionPlacement.FailureReason())' in site
|
||||
assert 'pendingGuards > 0 || aircraftPlacement == ERR_PrepareResult.PENDING' in site
|
||||
assert 'SetSpawnImmediately(false)' in site and 'PurgeSpawnRequestsForGroup' in site
|
||||
probe = (ROOT/'addons/core/Scripts/Game/ERR/ERR_NativeCasualtyGroundProbe.c').read_text()
|
||||
probe = (ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_NativeCasualtyGroundProbe.c').read_text()
|
||||
assert 'placement.Ready() && placement.WakeCount() == 1' in probe
|
||||
assert 'SetActive(' not in probe
|
||||
print('PASS: actual one-shot deadline/stability policies and preparation ownership, fuel, cleanup integration contracts')
|
||||
|
||||
@@ -4,8 +4,8 @@ from pathlib import Path
|
||||
REPO=Path(os.environ.get('ERR_REPO','/home/jakub/devel/escapistsrereintroduced'))
|
||||
sys.path.insert(0,str(REPO/'tests'))
|
||||
from policy_harness import body,run
|
||||
SOURCE=Path(os.environ.get('ERR_RESULT_SOURCE',REPO/'addons/core/Scripts/Game/ERR/ERR_EscapeGameOverScreenInfo.c'))
|
||||
MODE=Path(os.environ.get('ERR_MODE_SOURCE',REPO/'addons/core/Scripts/Game/ERR/ERR_GameMode.c'))
|
||||
SOURCE=Path(os.environ.get('ERR_RESULT_SOURCE',REPO/'addons/core/Scripts/Game/ERR/00_Core/ERR_EscapeGameOverScreenInfo.c'))
|
||||
MODE=Path(os.environ.get('ERR_MODE_SOURCE',REPO/'addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c'))
|
||||
def adapt(s):
|
||||
s=s.replace('protected ','').replace('override ','').replace('null','nullptr')
|
||||
s=s.replace('ERR_GameMode.Get()','Mode::Get()').replace('ERR_GameMode mode','Mode* mode')
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""Execute actual bounded force ledger and dormant route bodies without engine claims."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
L=ROOT/'addons/core/Scripts/Game/ERR/ERR_ForceLedger.c'
|
||||
S=ROOT/'addons/core/Scripts/Game/ERR/ERR_ForceSimulation.c'
|
||||
L=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_ForceLedger.c'
|
||||
S=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_ForceSimulation.c'
|
||||
def cpp(s):
|
||||
for old,new in [('protected ',''),('static ', 'static '),('Math.','Math::'),('vector.','vector::'),
|
||||
('ERR_ForceRules.','ERR_ForceRules::'),('ERR_ForceKind.','ERR_ForceKind::'),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Run actual ownership cancellation/Stop bodies with shared-array fixtures."""
|
||||
from policy_harness import ROOT, body, run
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/ERR_SiteService.c'
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c'
|
||||
s='\n'.join(body(p, sig) for sig in ('void CancelInitialGuardRequests(', 'void Stop('))
|
||||
for old,new in [
|
||||
('GetGame().','GetGame()->'),
|
||||
|
||||
@@ -187,7 +187,7 @@ class GameRunnerTests(unittest.TestCase):
|
||||
runner.validate_paths(base/'source', base/'steam', compat, profile)
|
||||
|
||||
def test_command_is_ordinary_game_with_explicit_successor_identity(self):
|
||||
for project, guid in [('core', '2528466DE220D91C'), ('chat', 'FA804F411BDDF2C6')]:
|
||||
for project, guid in [('core', '2528466DE220D91C'), ('chat', '2528466DE220D91C')]:
|
||||
command = runner.command_for(runner.ROOT, Path('/Steam'), Path('/compat'), Path('/profile'), project)
|
||||
self.assertEqual(command[command.index('--')+3], '/Steam/steamapps/common/Arma Reforger/ArmaReforgerSteam.exe')
|
||||
self.assertFalse(any('ArmaReforger_BE.exe' in arg or 'ArmaReforgerSteamDiag.exe' in arg for arg in command))
|
||||
@@ -213,17 +213,17 @@ class GameRunnerTests(unittest.TestCase):
|
||||
|
||||
def test_ready_requires_game_module_without_workbench_and_normal_phase(self):
|
||||
module = 'SCRIPT : Module: Game; loaded 12x files; defines: "PLATFORM_WINDOWS,ENABLE_DIAG"; CRC32: a\n'
|
||||
phase = 'SCRIPT : Rereintroduced [mission]: phase 0 -> 1\nSCRIPT : ERR ORDINARY: header verified project=core systems=MissionSystems\nSCRIPT : ERR ORDINARY: local participant verified project=core phase=prison\n'
|
||||
phase = 'SCRIPT : Reintroduced [mission]: phase 0 -> 1\nSCRIPT : ERR ORDINARY: header verified project=core systems=MissionSystems\nSCRIPT : ERR ORDINARY: local participant verified project=core phase=prison\n'
|
||||
self.assertTrue(runner.game_evidence(module+phase)['ready'])
|
||||
self.assertFalse(runner.game_evidence(phase)['ready'])
|
||||
self.assertFalse(runner.game_evidence(module)['ready'])
|
||||
self.assertFalse(runner.game_evidence(module.replace('ENABLE_DIAG', 'WORKBENCH')+phase)['ready'])
|
||||
for error in ['SCRIPT (E): failure', 'RESOURCES (E): missing', 'ERR SMOKE PASS: fixture leaked', 'Rereintroduced: scenario preparation failed']:
|
||||
for error in ['SCRIPT (E): failure', 'RESOURCES (E): missing', 'ERR SMOKE PASS: fixture leaked', 'Reintroduced: scenario preparation failed']:
|
||||
self.assertTrue(runner.game_evidence(module+phase+error)['failed'])
|
||||
|
||||
def test_startup_requires_selected_header_and_actual_systems_marker(self):
|
||||
module = 'SCRIPT : Module: Game; defines: "PLATFORM_WINDOWS"; CRC32: a\n'
|
||||
phase = 'SCRIPT : Rereintroduced [mission]: phase 0 -> 1\n'
|
||||
phase = 'SCRIPT : Reintroduced [mission]: phase 0 -> 1\n'
|
||||
core = 'SCRIPT : ERR ORDINARY: header verified project=core systems=MissionSystems\nSCRIPT : ERR ORDINARY: local participant verified project=core phase=prison\n'
|
||||
chat = 'SCRIPT : ERR ORDINARY: header verified project=chat systems=MissionSystems\nSCRIPT : ERR ORDINARY: local participant verified project=chat phase=prison\n'
|
||||
self.assertFalse(runner.game_evidence(module+phase, 'core')['ready'])
|
||||
@@ -238,7 +238,7 @@ class GameRunnerTests(unittest.TestCase):
|
||||
|
||||
def test_world_without_normal_local_admission_is_not_ready(self):
|
||||
world = ('SCRIPT : Module: Game; defines: "PLATFORM_WINDOWS"; CRC32: a\n'
|
||||
'SCRIPT : Rereintroduced [mission]: phase 0 -> 1\n'
|
||||
'SCRIPT : Reintroduced [mission]: phase 0 -> 1\n'
|
||||
'SCRIPT : ERR ORDINARY: header verified project=core systems=MissionSystems\n')
|
||||
result = runner.game_evidence(world, 'core')
|
||||
self.assertTrue(result['scenario_header_verified'])
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
from policy_harness import ROOT, body, run
|
||||
from pathlib import Path
|
||||
import os
|
||||
GUIDE=Path(os.environ.get('ERR_GUIDE_SOURCE', ROOT/'addons/core/Scripts/Game/ERR/ERR_PlayerGuide.c'))
|
||||
OBSERVER=ROOT/'addons/core/Scripts/Game/ERR/ERR_Observer.c'
|
||||
GUIDE=Path(os.environ.get('ERR_GUIDE_SOURCE', ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_PlayerGuide.c'))
|
||||
OBSERVER=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Observer.c'
|
||||
def cpp(text):
|
||||
text=text.replace('protected ', '').replace('override ', '').replace('super.OnControlledEntityChanged(from, to);', 'nativeChanges++;')
|
||||
for name in ('ERR_GameMode','ERR_Phase','ERR_ObserverReason','ERR_Actors','ERR_ObjectiveText','SCR_HintManagerComponent','ERR_ObserverGuidance','Resource','ETransformMode','SCR_ManualCamera','SCR_RespawnSystemComponent','RplId'):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Delivered ammo gates new tasks without becoming active-order cancellation."""
|
||||
from policy_harness import ROOT, body, run
|
||||
H=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'
|
||||
H=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'
|
||||
for method in ('protected void Investigate(', 'protected void Retask(', 'protected void Assign('):
|
||||
s=body(H,method)
|
||||
assert 'if (m_Watch.ArmedSearchBlocked(unit.ForceSourceId, now)) continue;' in s
|
||||
|
||||
@@ -3,9 +3,9 @@ from pathlib import Path
|
||||
import os,re
|
||||
from policy_harness import ROOT,body,run
|
||||
BASE=Path(os.environ.get('ERR_AMMO_REPORTING_ROOT',ROOT))
|
||||
P=BASE/'addons/ai/Scripts/Game/ERR/ERR_HQAmmoReporting.c'
|
||||
H=BASE/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'
|
||||
A=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQAmmoSampler.c'
|
||||
P=BASE/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAmmoReporting.c'
|
||||
H=BASE/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'
|
||||
A=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAmmoSampler.c'
|
||||
|
||||
def cpp(s):
|
||||
s=s.replace('protected ','').replace('ERR_HQPursuitRules.', 'ERR_HQPursuitRules::').replace('string.Format','Format')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
from policy_harness import ROOT,run
|
||||
P=Path(os.environ.get('ERR_AMMO_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQAmmoSampler.c'))
|
||||
P=Path(os.environ.get('ERR_AMMO_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAmmoSampler.c'))
|
||||
s=P.read_text()
|
||||
for forbidden in ('Spawn','SetAmmoCount','GetOrigin','GetWorld','GetAgents','TryMove','DeleteEntity'):
|
||||
assert forbidden not in s,forbidden
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Execute actual HQ assignment ownership and failed-radio backoff bodies."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
p=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'
|
||||
unit='\n'.join(body(p,s) for s in ('void CancelPending(', 'ERR_HQTask PlannedTask(', 'void ReleaseAssignment(', 'void Release()'))
|
||||
lost='\n'.join(body(p,s) for s in ('protected void FinishWatch(', 'protected void LostOrder(')).replace('protected ', '')
|
||||
def adapt(code):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from policy_harness import ROOT, run
|
||||
from pathlib import Path
|
||||
import re, os
|
||||
path=Path(os.environ.get('ERR_BODY_SOURCE', str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQBodyObserver.c')))
|
||||
path=Path(os.environ.get('ERR_BODY_SOURCE', str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQBodyObserver.c')))
|
||||
s=path.read_text()
|
||||
assert 'GroupLookup' not in s and 'Spawn(' not in s and 'Accept(' not in s and 'm_Contacts' not in s
|
||||
assert 'GetPlayerManager' not in s and 'DeleteEntity' not in s and 'GetTargets' not in s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Execute production HQ convoy planning/delivery with detached reports and radio-boundary doubles."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
H = ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'
|
||||
H = ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'
|
||||
|
||||
def cpp(s):
|
||||
s=s.replace('protected ', '').replace('null','nullptr').replace('foreach (','for (')
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
from policy_harness import ROOT,body,run
|
||||
import re,os
|
||||
from pathlib import Path
|
||||
H=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'))
|
||||
P=Path(os.environ.get('ERR_HQ_ADMIN_SOURCE',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQAdminProvider.c')))
|
||||
H=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'))
|
||||
P=Path(os.environ.get('ERR_HQ_ADMIN_SOURCE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAdminProvider.c')))
|
||||
BASE=Path(os.environ.get('ERR_CONVOY_SETTINGS_ROOT', ROOT))
|
||||
A=BASE/'addons/core/Scripts/Game/ERR/ERR_AdminService.c'
|
||||
A=BASE/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c'
|
||||
def cpp(s):
|
||||
for old,new in [('protected ',''),('override ',''),('null','nullptr'),('Replication.','Replication::'),
|
||||
('ERR_GameMode.','ERR_GameMode::'),('ERR_ConvoyRoadPlan.','ERR_ConvoyRoadPlan::'),
|
||||
@@ -30,7 +30,7 @@ hq='\n'.join(cpp(body(H,s)) for s in ('static bool MissionActive(', 'bool Prepar
|
||||
'bool StartScenarioConvoy(', 'string ConvoyStatus('))
|
||||
provider=cpp(body(P,'protected void ConvoyAutoSetting('))+cpp(body(P,'protected void StingerSetting('))+cpp(body(P,'override bool Execute('))
|
||||
integer=cpp(body(A,'static bool Integer('))
|
||||
validator=cpp(body(BASE/'addons/core/Scripts/Game/ERR/ERR_Settings.c','static bool Valid('))
|
||||
validator=cpp(body(BASE/'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c','static bool Valid('))
|
||||
extension=cpp(body(A,'protected bool Extension('))
|
||||
# Execute the exact complete auth/normalization/extension-dispatch region.
|
||||
# Unrelated settings/help parsers after this boundary are covered by their own suites.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Actual bounded negative-search coverage rules; physical radio delivery is HQ's boundary."""
|
||||
from policy_harness import ROOT, body, run
|
||||
P=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQCoverage.c'
|
||||
PURSUIT=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQPursuit.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQCoverage.c'
|
||||
PURSUIT=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQPursuit.c'
|
||||
|
||||
def cpp(s):
|
||||
return (s.replace('protected ', '').replace('Math.', 'Math::').replace('vector.', 'vector::')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from pathlib import Path
|
||||
import re
|
||||
from policy_harness import ROOT, run
|
||||
s=(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQDeliveredCasualties.c').read_text()
|
||||
s=(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQDeliveredCasualties.c').read_text()
|
||||
assert all(token not in s for token in ('IEntity','GetOrigin','GetWorld','GetPlayer','IsDestroyed','GetLifeState'))
|
||||
code=s.replace('class ','struct ').replace('protected ','').replace('ref ','').replace('Math.','Math::')
|
||||
code=code.replace('array<int> slots','Array<int>* slots').replace('slots.', 'slots->')
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
from policy_harness import ROOT,body,run
|
||||
P=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'))
|
||||
ROAD=Path(os.environ.get('ERR_HQ_ROAD_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQRoadIntercept.c'))
|
||||
P=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'))
|
||||
ROAD=Path(os.environ.get('ERR_HQ_ROAD_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQRoadIntercept.c'))
|
||||
def cpp(s):
|
||||
s=s.replace('protected ','').replace('null','nullptr').replace('string.Format','Format')
|
||||
for name in ('Math','ERR_GameMode','SCR_EntityHelper','ERR_HQPursuitRules','AIWaypoint','ERR_Actors','ERR_Resources','ERR_ForceDuty','ERR_HQRoadIntercept','ERR_ForceRules','ERR_HQPursuitRole','ERR_HQMemoryKind'):
|
||||
@@ -20,7 +20,7 @@ def cpp(s):
|
||||
units='\n'.join(cpp(body(P,x)) for x in ('void CancelPending(', 'ERR_HQTask PlannedTask(', 'void ReleaseAssignment(', 'void Release()'))
|
||||
methods='\n'.join(cpp(body(P,x)) for x in ('protected void FinishWatch(', 'protected void ReleaseUnit(', 'protected void LostOrder(', 'protected void DeliverOrder('))
|
||||
cleanup=cpp(body(P,' foreach (ERR_HQUnit unit : m_Units)\n {\n if (!unit.Assignment && !unit.PendingOrder) continue;\n if (!unit.PlanEligible || assigned > globalLimit)'))
|
||||
R=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQPursuit.c'
|
||||
R=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQPursuit.c'
|
||||
rules='\n'.join(cpp(body(R,x)) for x in ('static bool Finite(', 'static bool PositionValid(', 'static bool Actionable(', 'static bool Heading(', 'static ERR_HQPursuitRole Role('))
|
||||
eligible=cpp(body(ROAD,'static bool Eligible('))
|
||||
run(r'''
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Execute the actual objective-inference rules; audit the HQ ingestion boundaries."""
|
||||
from policy_harness import ROOT, body, run
|
||||
P=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQDoctrine.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQDoctrine.c'
|
||||
methods='\n'.join(body(P,x) for x in ('static float Threat(', 'static bool Forward(', 'static vector Approach('))
|
||||
methods=methods.replace('Math.','Math::').replace('vector.','vector::').replace('ERR_HQPursuitRules.','ERR_HQPursuitRules::').replace('float alignment;', 'float alignment=0;')
|
||||
run(r'''
|
||||
@@ -37,7 +37,7 @@ int main(){
|
||||
auto same=Doctrine::Approach(origin,origin);assert(same.x==origin.x&&same.z==origin.z);
|
||||
}
|
||||
''')
|
||||
hq=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'
|
||||
hq=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'
|
||||
a=body(hq,'protected void Accept(')
|
||||
assert 'm_Memory.Ingest(report, now)' in a and 'm_Coverage.Forget(report.Position)' in a
|
||||
sweep=body(hq,'protected void AcceptSweep(')
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
from policy_harness import ROOT,body,run
|
||||
network=Path(os.environ.get('ERR_NETWORK_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQNetwork.c'))
|
||||
helper=Path(os.environ.get('ERR_HANDOFF_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQLocalHandoff.c'))
|
||||
network=Path(os.environ.get('ERR_NETWORK_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQNetwork.c'))
|
||||
helper=Path(os.environ.get('ERR_HANDOFF_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQLocalHandoff.c'))
|
||||
# Reuse the existing native graph syntax translation, not its policy doubles.
|
||||
base=Path(os.environ.get('ERR_NETWORK_HARNESS',ROOT/'tests/hq_network_regression.py')).read_text()
|
||||
ns={'__file__':str(ROOT/'tests/hq_network_regression.py')}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,body,run
|
||||
p=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'))
|
||||
p=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'))
|
||||
s='\n'.join(body(p,x) for x in ('protected bool OriginOccupied(', 'protected ERR_HQRoute ObservationRoute(', 'protected void Observe(', 'protected void QueueReports('))
|
||||
s=s.replace('protected ','').replace('array<IEntity>','Arr<IEntity>').replace('array<ref ERR_HQVisualContact>','Arr<ERR_HQVisualContact*>').replace('foreach (','for (')
|
||||
for name in ('ERR_HQUnit','ERR_HQRoute','ERR_HQReport','ERR_HQVisualContact'):
|
||||
|
||||
@@ -4,7 +4,7 @@ No fake world polling: identity stubs deliberately have no position/health API.
|
||||
"""
|
||||
import re
|
||||
from policy_harness import ROOT, run
|
||||
path = ROOT / 'addons/ai/Scripts/Game/ERR/ERR_HQMemory.c'
|
||||
path = ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_HQMemory.c'
|
||||
source = path.read_text()
|
||||
for forbidden in ('GetOrigin(', 'GetControlledEntity(', 'GetPlayerManager(', 'GetDamageManager(', 'GetWorld('):
|
||||
assert forbidden not in source
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Execute actual delivered-belief pursuit rules as C++; no engine/AI behavior claim."""
|
||||
import re
|
||||
from policy_harness import ROOT, body, run
|
||||
P = ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQPursuit.c'
|
||||
P = ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQPursuit.c'
|
||||
source = P.read_text()
|
||||
methods = '\n'.join(body(P, signature) for signature in (
|
||||
'static bool Finite(', 'static bool PositionValid(', 'static int Limit(', 'static bool Actionable(',
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,run
|
||||
p=Path(os.environ.get('ERR_NETWORK_SOURCE', ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQNetwork.c'))
|
||||
p=Path(os.environ.get('ERR_NETWORK_SOURCE', ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQNetwork.c'))
|
||||
s=p.read_text();a=s.index('bool Valid(');b=s.index('{',a);end=b+1;depth=1
|
||||
while depth:depth+=(s[end]=='{')-(s[end]=='}');end+=1
|
||||
code=s[a:end].replace('ERR_GameMode factions = ERR_GameMode.Get()', 'ERR_GameMode* factions = ERR_GameMode::Get()')
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
from policy_harness import ROOT, body, run
|
||||
from pathlib import Path
|
||||
import os
|
||||
source = ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQObservation.c'
|
||||
hq = Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'))
|
||||
source = ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQObservation.c'
|
||||
hq = Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'))
|
||||
select = body(source, 'ERR_HQVisualContact Select(')
|
||||
select = select.replace('array<ref ERR_HQVisualContact> samples', 'Array<ERR_HQVisualContact> samples')
|
||||
select = select.replace('ERR_HQVisualContact selected;', 'ERR_HQVisualContact selected = nullptr;')
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
from policy_harness import ROOT,body,run
|
||||
p=Path(os.environ.get('ERR_ROAD_INTERCEPT_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQRoadIntercept.c'))
|
||||
p=Path(os.environ.get('ERR_ROAD_INTERCEPT_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQRoadIntercept.c'))
|
||||
source=p.read_text()
|
||||
for forbidden in ('GetPlayer','GetControlledEntity','GetOrigin','Spawn(', 'AddWaypoint','SetOrigin','CallLater'):
|
||||
assert forbidden not in source,forbidden
|
||||
rules='\n'.join(body(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQPursuit.c', x) for x in ('static bool Finite(', 'static bool PositionValid(', 'static bool Actionable(', 'static bool Heading(', 'static ERR_HQPursuitRole Role(', 'static vector Direction(', 'static vector Objective('))
|
||||
rules='\n'.join(body(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQPursuit.c', x) for x in ('static bool Finite(', 'static bool PositionValid(', 'static bool Actionable(', 'static bool Heading(', 'static ERR_HQPursuitRole Role(', 'static vector Direction(', 'static vector Objective('))
|
||||
rules=rules.replace('Math.','Math::').replace('vector.','vector::').replace('ERR_HQPursuitRole.','ERR_HQPursuitRole::').replace('vector offset;','vector offset{};')
|
||||
s=re.sub(r'//[^\n]*','',source).replace('class ERR_HQRoadIntercept','struct ERR_HQRoadIntercept')
|
||||
s=s.replace('out vector','vector&').replace('out float','float&').replace('array<vector>','Array<vector>').replace('array<BaseRoad>','Array<BaseRoad*>').replace('foreach (','for (')
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
from policy_harness import ROOT,body,run
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
P=Path(os.environ.get('ERR_SAMPLER_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQStatusSampler.c'))
|
||||
U=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQPursuit.c'
|
||||
P=Path(os.environ.get('ERR_SAMPLER_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQStatusSampler.c'))
|
||||
U=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQPursuit.c'
|
||||
def cpp(s):
|
||||
s=s.replace('DamageManagerComponent.Cast(actor.FindComponent(DamageManagerComponent))',
|
||||
'(actor.hasDamage ? &actor.damage : null)')
|
||||
|
||||
@@ -4,8 +4,8 @@ Native radio and perception remain explicit boundary doubles.
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
from policy_harness import ROOT,body,run
|
||||
P=Path(os.environ.get('ERR_HQ_SOURCE',str(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c')))
|
||||
original=(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c').read_text()
|
||||
P=Path(os.environ.get('ERR_HQ_SOURCE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c')))
|
||||
original=(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c').read_text()
|
||||
legacy='Observe(unit, now);\n ObserveBody(unit, now);\n StatusReport(unit, now);\n Sweep(unit, now);'
|
||||
assert legacy in original or 'QueueReports(unit, now);' in original
|
||||
|
||||
@@ -23,7 +23,7 @@ def cpp(s):
|
||||
s=s.replace('ERR_HQPursuitRules.', 'ERR_HQPursuitRules::')
|
||||
s=s.replace('ERR_HQObservation.','ERR_HQObservation::').replace('vector.DistanceXZ','vector::DistanceXZ').replace('string.Format','Format')
|
||||
return s.replace('AmmoState.', 'AmmoState->')
|
||||
policy_path=Path(os.environ.get('ERR_AMMO_REPORTING_ROOT', ROOT))/'addons/ai/Scripts/Game/ERR/ERR_HQAmmoReporting.c'
|
||||
policy_path=Path(os.environ.get('ERR_AMMO_REPORTING_ROOT', ROOT))/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAmmoReporting.c'
|
||||
policy=cpp(policy_path.read_text()).replace('class ERR_HQAmmoReporting','struct ERR_HQAmmoReporting').rstrip()+';'
|
||||
methods='\n'.join(cpp(body(P,s)) for s in ('protected void Observe(', 'protected void ObserveBody(', 'protected void StatusReport(', 'protected void Sweep(', 'protected void QueueReports('))
|
||||
run(r'''
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
from policy_harness import ROOT, body, run
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
P=Path(os.environ.get('ERR_WATCH_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQWatch.c'))
|
||||
U=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQPursuit.c'
|
||||
P=Path(os.environ.get('ERR_WATCH_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQWatch.c'))
|
||||
U=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQPursuit.c'
|
||||
def cpp(s):
|
||||
for old,new in [('protected ',''),('Math.','Math::'),('ERR_HQPursuitRules.','ERR_HQPursuitRules::'),
|
||||
('ERR_HQWatchRules.','ERR_HQWatchRules::'),('null','nullptr'),
|
||||
@@ -18,13 +18,13 @@ def cpp(s):
|
||||
s=s.replace('report->DeathSlots,', '&report->DeathSlots,')
|
||||
s=s.replace('entry->AmmoState.', 'entry->AmmoState->').replace('report->AmmoState.', 'report->AmmoState->')
|
||||
return s
|
||||
helper=(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQDeliveredCasualties.c').read_text()
|
||||
helper=(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQDeliveredCasualties.c').read_text()
|
||||
helper=helper.replace('class ','struct ').replace('protected ','').replace('ref ','').replace('Math.','Math::')
|
||||
helper=helper.replace('array<int> slots','Array<int>* slots').replace('slots.', 'slots->')
|
||||
helper=helper.replace('array<int>','Array<int>').replace('foreach (','for (')
|
||||
helper=helper.replace(' : slots)', ' : *slots)').replace('int m_Strength;', 'int m_Strength=0;')
|
||||
helper=helper.replace('\n}\n','\n};\n')
|
||||
ammo_source=Path(os.environ.get('ERR_AMMO_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQAmmoSampler.c')).read_text()
|
||||
ammo_source=Path(os.environ.get('ERR_AMMO_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAmmoSampler.c')).read_text()
|
||||
ammo=ammo_source[:ammo_source.index('class ERR_HQAmmoSampler')]
|
||||
ammo=ammo.replace('class ','struct ').replace('ERR_HQAmmoSnapshot Snapshot(', 'ERR_HQAmmoSnapshot* Snapshot(')
|
||||
ammo=ammo.replace('ERR_HQAmmoSnapshot copy', 'ERR_HQAmmoSnapshot* copy').replace('copy.', 'copy->')
|
||||
@@ -36,8 +36,8 @@ methods='\n'.join(cpp(body(P,s)) for s in ('int Count()', 'ERR_HQWatchEntry Find
|
||||
'protected void ApplyLosses(', 'bool Ingest(', 'bool IngestBody(', 'bool RequestDue(string',
|
||||
'bool MarkRequested(', 'bool InvestigationDue(string', 'bool MarkInvestigating(', 'bool FinishInvestigation(', 'void Clear('))
|
||||
common='\n'.join(cpp(body(U,s)) for s in ('static bool Finite(', 'static bool PositionValid('))
|
||||
snapshot=cpp(body(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQReport.c','ERR_HQReport Snapshot(')).replace('copy.', 'copy->')
|
||||
accept=cpp(body(ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c','protected void Accept('))
|
||||
snapshot=cpp(body(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQReport.c','ERR_HQReport Snapshot(')).replace('copy.', 'copy->')
|
||||
accept=cpp(body(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c','protected void Accept('))
|
||||
accept=accept.replace('ERR_MissionRules.', 'ERR_MissionRules::').replace('ERR_HQMemoryRules.', 'ERR_HQMemoryRules::')
|
||||
accept=accept.replace('ERR_HQMemoryKind.', 'ERR_HQMemoryKind::').replace('vector.DistanceXZ(', 'vector::DistanceXZ(')
|
||||
accept=accept.replace('previous.', 'previous->')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,run
|
||||
s=Path(os.environ.get('ERR_INFANTRY_ACCESS_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_InfantryAmmoAccess.c')).read_text()
|
||||
s=Path(os.environ.get('ERR_INFANTRY_ACCESS_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryAmmoAccess.c')).read_text()
|
||||
s=re.sub(r'//[^\n]*','',s).replace('class ERR_InfantryAmmoAccess','struct ERR_InfantryAmmoAccess').replace('protected ','').replace('notnull ','')
|
||||
s=s.replace('ActionsManagerComponent.Cast(donor.FindComponent(ActionsManagerComponent))','donor->manager').replace('SCR_OpenVehicleStorageAction.Cast(action)','dynamic_cast<SCR_OpenVehicleStorageAction*>(action)').replace('ChimeraCharacter.Cast(recipient)','dynamic_cast<Character*>(recipient)')
|
||||
s=s.replace('array<UserActionContext>', 'array<UserActionContext*>').replace('array<BaseUserAction>', 'array<BaseUserAction*>')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from pathlib import Path
|
||||
import os,re
|
||||
from policy_harness import ROOT,run,body
|
||||
p=Path(os.environ.get('ERR_INFANTRY_TRANSFER_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_InfantryAmmoTransfer.c'))
|
||||
p=Path(os.environ.get('ERR_INFANTRY_TRANSFER_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryAmmoTransfer.c'))
|
||||
s=p.read_text()
|
||||
for forbidden in ('TrySpawn','DeleteEntity','SetOrigin','SetTransform','TryInsert','TryRemove','SetAmmoCount'):
|
||||
assert forbidden not in s,forbidden
|
||||
@@ -35,7 +35,7 @@ for name in ('OnComplete','OnFailed','OnAllComplete','OnAllFailed'):
|
||||
m=re.search(r'protected override void '+name+r'\(\) (\{[^\n]+\})',callback)
|
||||
callbacks.append('void ERR_InfantryAmmoCallback::'+name+'() '+m[1].replace('Transfer.','Transfer->'))
|
||||
# Integrate the actual coordinator transfer selector with this actual leaf.
|
||||
coordinator_path=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_InfantryResupply.c'))
|
||||
coordinator_path=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c'))
|
||||
transfer=body(coordinator_path,'protected void Transfer(float now)').replace('protected ','').replace('null','nullptr').replace('foreach (','for (')
|
||||
transfer=transfer.replace('ERR_HQAmmoSnapshot local','ERR_HQAmmoSnapshot* local')
|
||||
for name in ('ERR_Actors','ERR_HQAmmoSampler','ERR_InfantryAmmoTransfer','vector'):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,body,run
|
||||
p=Path(os.environ.get('ERR_INFANTRY_PROBE_SOURCE',ROOT/'addons/chat/Scripts/Game/ERR/ERR_NativeInfantryTransferProbe.c'))
|
||||
p=Path(os.environ.get('ERR_INFANTRY_PROBE_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeInfantryTransferProbe.c'))
|
||||
s=body(p,'protected int Place(float now)')+'\n'+body(p,' void Stop()')
|
||||
s=re.sub(r'//[^\n]*','',s).replace('protected ','')
|
||||
s=s.replace('ChimeraCharacter.Cast(m_Actor)','m_Actor')
|
||||
|
||||
@@ -4,7 +4,7 @@ from pathlib import Path
|
||||
REPO=Path(os.environ.get('ERR_REPO','/home/jakub/devel/escapistsrereintroduced'))
|
||||
sys.path.insert(0,str(REPO/'tests'))
|
||||
from policy_harness import body,run
|
||||
SOURCE=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',REPO/'addons/ai/Scripts/Game/ERR/ERR_InfantryResupply.c'))
|
||||
SOURCE=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',REPO/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c'))
|
||||
def method(signature):
|
||||
s=body(SOURCE,signature).replace('protected ','').replace('null','nullptr')
|
||||
s=s.replace('vector.DistanceXZ','Vec::DistanceXZ').replace('ERR_ForceRules.','ERR_ForceRules::').replace('ERR_InfantryResupplyRules.','ERR_InfantryResupplyRules::').replace('ERR_Actors.','ERR_Actors::')
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
import os,re
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT,body,run
|
||||
P=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_InfantryResupply.c'))
|
||||
I=ROOT/'addons/core/Scripts/Game/ERR/ERR_Inventory.c'
|
||||
H=ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'
|
||||
P=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c'))
|
||||
I=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Inventory.c'
|
||||
H=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'
|
||||
def cpp(s):
|
||||
s=s.replace('protected ','').replace('notnull ','').replace('null','nullptr')
|
||||
s=s.replace('array<IEntity> items = {};','Array<IEntity> items;').replace('array<IEntity> raw = {};','Array<IEntity> raw;').replace('array<AIAgent> agents = {};','Array<AIAgent> agents;')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from pathlib import Path
|
||||
import os
|
||||
from policy_harness import ROOT,body,run
|
||||
P=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_InfantryResupply.c'))
|
||||
P=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c'))
|
||||
s=body(P,'protected bool Waypoints()').replace('protected ','')
|
||||
for name in ('AIWaypoint','ERR_Actors','ERR_Resources'):s=s.replace(name+'.',name+'::')
|
||||
for name in ('m_MoveWaypoint','m_HoldWaypoint','m_Recipient'):s=s.replace(name+'.',name+'->')
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
"""Actual admission-exhaustion/tick rules; engine population and services substituted."""
|
||||
import re
|
||||
from policy_harness import ROOT, body, run
|
||||
MODE = ROOT/'addons/core/Scripts/Game/ERR/ERR_GameMode.c'
|
||||
SPAWN = ROOT/'addons/core/Scripts/Game/ERR/ERR_SpawnLogic.c'
|
||||
MODE = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_GameMode.c'
|
||||
SPAWN = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnLogic.c'
|
||||
def cpp(s):
|
||||
s=s.replace('protected ', '').replace('Replication.IsServer()', 'server').replace('Replication.BumpMe()', '(void)0')
|
||||
s=s.replace('array<int> connected = {};','std::vector<int> connected;').replace('connected.IsEmpty()', 'connected.empty()')
|
||||
s=s.replace('foreach (int id : connected)', 'for (int id : connected)')
|
||||
s=s.replace('ERR_PlayerLife life', 'Life* life').replace('SCR_PlayerController controller', 'Controller* controller').replace('PlayerController controller', 'Controller* controller')
|
||||
s=s.replace('SCR_PlayerController.Cast(', 'Controller::Cast(').replace('ERR_Phase.DEFEAT','5')
|
||||
s=s.replace('SCR_PlayerController.Cast(', 'Controller::Cast(').replace('ERR_Phase.DEFEAT','5').replace('ERR_Phase.RADIO_SEARCH','2')
|
||||
for v in ('m_Roster','controller','life','m_Command','m_Extraction','m_RadioDefence','m_Recovery','GetGame()','GetWorld()','GetPlayerManager()'):
|
||||
s=s.replace(v+'.', v+'->')
|
||||
return s
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Execute initial readiness policy; native population timing needs engine tests."""
|
||||
from policy_harness import ROOT, body, run
|
||||
p = ROOT/'addons/core/Scripts/Game/ERR/ERR_InitialGuardRules.c'
|
||||
p = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_InitialGuardRules.c'
|
||||
s = '\n'.join(body(p, signature) for signature in ('static float TimeoutMilliseconds(', 'static ERR_PrepareResult State(')).replace('ERR_PrepareResult.', 'ERR_PrepareResult::')
|
||||
run('''#include <cassert>
|
||||
#include <initializer_list>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""Run actual companion dispatch and discovery ledger bodies; native RPC is separate."""
|
||||
from policy_harness import ROOT, body, run
|
||||
admin = ROOT / 'addons/core/Scripts/Game/ERR/ERR_AdminService.c'
|
||||
provider = ROOT / 'addons/intel/Scripts/Game/ERR/ERR_IntelAdminProvider.c'
|
||||
discovery = ROOT / 'addons/core/Scripts/Game/ERR/ERR_DiscoveryService.c'
|
||||
admin = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c'
|
||||
provider = ROOT / 'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelAdminProvider.c'
|
||||
discovery = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_DiscoveryService.c'
|
||||
execute = body(admin, 'void Execute(')
|
||||
assert execute.index('if (!Replication.IsServer()') < execute.index('if (!authorized)') < execute.index('if (Extension(mode, arguments, replies))')
|
||||
extension = body(provider, 'override bool Execute(')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Execute production feedback queue/delivery bodies with fake engine boundaries."""
|
||||
from policy_harness import ROOT, body, run
|
||||
P=ROOT/'addons/intel/Scripts/Game/ERR/ERR_IntelDiscoveryFeedback.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelDiscoveryFeedback.c'
|
||||
source=P.read_text()
|
||||
def cpp(s):
|
||||
s=s.replace('protected ', '').replace('static ', '')
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import re,os
|
||||
from pathlib import Path
|
||||
from policy_harness import ROOT, body, run
|
||||
intel=ROOT/'addons/intel/Scripts/Game/ERR/ERR_IntelService.c'
|
||||
hq=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQ.c'))
|
||||
ready=ROOT/'addons/ai/Scripts/Game/ERR/ERR_MortarReadiness.c'
|
||||
system=ROOT/'addons/ai/Scripts/Game/ERR/ERR_MortarSystem.c'
|
||||
intel=ROOT/'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelService.c'
|
||||
hq=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'))
|
||||
ready=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_MortarReadiness.c'
|
||||
system=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_MortarSystem.c'
|
||||
def adapt(s):
|
||||
s=s.replace('override ', '').replace('protected ', '').replace('null','nullptr')
|
||||
s=re.sub(r'array<([^>]+)> (\w+) = \{\};',r'Array<\1> \2;',s)
|
||||
@@ -40,7 +40,7 @@ assert poll.count('mode.RegisterGroup(group)')==1
|
||||
prepare=body(system,'bool Prepare(')
|
||||
assert 'mode.RegisterGroup(group)' not in prepare
|
||||
assert prepare.index('mode.Own(group)')<prepare.index('m_HQ.RegisterGroup(group)')<prepare.index('m_HQ.ReserveGroup(group)')
|
||||
site=body(ROOT/'addons/core/Scripts/Game/ERR/ERR_SiteService.c','void Activate(')
|
||||
site=body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c','void Activate(')
|
||||
assert site.index('m_State != ERR_PrepareResult.READY')<site.index('m_Mode.RegisterGroup(site.Group)')
|
||||
run(r'''
|
||||
#include <cassert>
|
||||
@@ -143,7 +143,7 @@ observer_region=intel_source.split('#ifdef WORKBENCH',1)[1].split('#endif',1)[0]
|
||||
assert 'bool ERR_ProbeWasRolled(IEntity actor)' in observer_region
|
||||
assert 'ERR_Mortar' not in intel_source and 'ERR_HQ' not in intel_source
|
||||
assert 'Insert(' not in observation and 'RandomInt' not in observation and 'TrySpawn' not in observation
|
||||
smoke=(ROOT/'addons/chat/Scripts/Game/ERR/ERR_NativeSmoke.c').read_text()
|
||||
smoke=(ROOT/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c').read_text()
|
||||
step=smoke.split('else if (m_ERRSmokeStep == 120)',1)[1].split('else if (m_ERRSmokeStep == 121)',1)[0]
|
||||
assert step.index('!battery.StartupActivated') < step.index('ERR_ProbeWasRolled(intelActor)') < step.index('DeleteEntityAndChildren(item)')
|
||||
assert '!intelCrew.Contains(intelActor)' in step and 'intelCrew.Count() == 4' in step
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""Execute actual Intel reroll methods against adversarial async inventory adapters."""
|
||||
import re
|
||||
from policy_harness import ROOT, body, run
|
||||
service=ROOT/'addons/intel/Scripts/Game/ERR/ERR_IntelService.c'
|
||||
batch=ROOT/'addons/intel/Scripts/Game/ERR/ERR_IntelReroll.c'
|
||||
service=ROOT/'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelService.c'
|
||||
batch=ROOT/'addons/core/Scripts/Game/ERR/20_Intel/ERR_IntelReroll.c'
|
||||
def adapt(text,cls):
|
||||
text=text.replace('protected ', '').replace('null','nullptr')
|
||||
text=re.sub(r'array<([^>]+)> (\w+) = \{\};',r'Array<\1> \2;',text)
|
||||
|
||||
@@ -26,8 +26,8 @@ def translated(source):
|
||||
|
||||
class InventoryEnumerationPolicy(unittest.TestCase):
|
||||
def test_duplicate_references_distinct_rounds_and_cross_inventory_union(self):
|
||||
helper = ROOT / 'addons/core/Scripts/Game/ERR/ERR_Inventory.c'
|
||||
mortar = ROOT / 'addons/ai/Scripts/Game/ERR/ERR_MortarBattery.c'
|
||||
helper = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_Inventory.c'
|
||||
mortar = ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_MortarBattery.c'
|
||||
methods = '\n'.join(translated(body(helper, signature)) for signature in (
|
||||
'static int AppendUnique(', 'static int Items('))
|
||||
count = translated(body(mortar, 'int InventoryShells('))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Execute candidate hierarchy adapter; native slot regeneration/rendering unqualified."""
|
||||
from policy_harness import ROOT, body, run
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/ERR_InventoryLayout.c'
|
||||
P=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_InventoryLayout.c'
|
||||
def cpp(s):
|
||||
s=s.replace('protected ', '').replace('override ', '').replace('ref ', '')
|
||||
for t in ('Widget','ERR_GameMode','GridLayoutWidget','ERR_InventoryGridPlacement'):
|
||||
|
||||
@@ -7,8 +7,8 @@ import unittest
|
||||
from policy_harness import body, run
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SOURCE = ROOT / 'addons/core/Scripts/Game/ERR/ERR_ItemStationTeardown.c'
|
||||
PROBE = ROOT / 'addons/core/Scripts/Game/ERR/ERR_NativeItemStationTeardownProbe.c'
|
||||
SOURCE = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_ItemStationTeardown.c'
|
||||
PROBE = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_NativeItemStationTeardownProbe.c'
|
||||
|
||||
class ItemStationTeardown(unittest.TestCase):
|
||||
def test_actual_recovery_gate_all_inputs(self):
|
||||
@@ -68,7 +68,7 @@ int main() {
|
||||
self.assertIn('if (m_Kit) delete m_Kit;', source)
|
||||
|
||||
def test_integrated_smoke_steps_finish_only_after_probe_success(self):
|
||||
source = (ROOT / 'addons/core/Scripts/Game/ERR/ERR_NativeBaseSmoke.c').read_text()
|
||||
source = (ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_NativeBaseSmoke.c').read_text()
|
||||
self.assertIn('protected ref ERR_NativeItemStationTeardownProbe m_ERRItemStationTeardownProbe;', source)
|
||||
self.assertIn('if (m_ERRItemStationTeardownProbe) m_ERRItemStationTeardownProbe.Stop();', source)
|
||||
self.assertIn('if (m_ERRBaseStep == 2000)', source)
|
||||
|
||||
@@ -4,7 +4,7 @@ this is not authentication, native GenV4 or multiplayer evidence.
|
||||
"""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
source=ROOT/'addons/core/Scripts/Game/ERR/ERR_LocalAdmission.c'
|
||||
source=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_LocalAdmission.c'
|
||||
s=source.read_text().split('\nmodded class ERR_GameMode')[0]
|
||||
s=s[s.index('class ERR_LocalAdmissionRules'):]
|
||||
s=s.replace('class ERR_LocalAdmissionRules','struct ERR_LocalAdmissionRules').replace('class ERR_LocalAdmission\n','struct ERR_LocalAdmission\n')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from policy_harness import ROOT,body,run
|
||||
source=ROOT/'addons/core/Scripts/Game/ERR/ERR_MissionRules.c'
|
||||
source=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_MissionRules.c'
|
||||
rules='\n'.join(body(source,x) for x in ['static bool Terminal(', 'static bool CanTransition(', 'static bool DefenceComplete(', 'static bool ContactFresh(', 'static int Discovery(']).replace('ERR_Phase.', 'ERR_Phase::')
|
||||
rules += '\n' + body(ROOT/'addons/core/Scripts/Game/ERR/ERR_PlayerRoster.c', 'static bool CanEnter(').replace('ERR_Phase.', 'ERR_Phase::')
|
||||
rules += '\n' + body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_PlayerRoster.c', 'static bool CanEnter(').replace('ERR_Phase.', 'ERR_Phase::')
|
||||
run('''#include <cassert>
|
||||
namespace ERR_Phase {enum {PREPARING,PRISON,RADIO_SEARCH,RADIO_DEFENCE,EXTRACTION,VICTORY,DEFEAT};}
|
||||
'''+rules+'''
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user