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.
51 lines
2.7 KiB
Python
51 lines
2.7 KiB
Python
"""Run actual fixture placement geometry; protect native clearance/stock boundary."""
|
|
import re
|
|
from policy_harness import ROOT, body, run
|
|
p = ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_NativeMortarCourierProbe.c'
|
|
text = p.read_text()
|
|
geometry = body(p, 'static vector StorageOffset(')
|
|
count = int(re.search(r'STORAGE_CANDIDATES = (\d+)', text).group(1))
|
|
required = int(re.search(r'STORAGE_COUNT = (\d+)', text).group(1))
|
|
assert count == 64 and required == 5
|
|
assert '%' not in geometry, 'Use native Math.Mod; C++ remainder hides Enforce errors'
|
|
run('''#include <cassert>
|
|
#include <cmath>
|
|
#include <vector>
|
|
struct vector {float x,y,z;static const vector Zero;};const vector vector::Zero{0,0,0};
|
|
vector Vector(float x,float y,float z){return {x,y,z};}
|
|
namespace Math {int Mod(int a,int b){return a%b;}}
|
|
constexpr int STORAGE_CANDIDATES=64;
|
|
''' + geometry.replace('Math.', 'Math::').replace('vector.Zero', 'vector::Zero') + '''
|
|
int main(){
|
|
std::vector<vector> seen;
|
|
for(int i=0;i<STORAGE_CANDIDATES;i++){
|
|
auto p=StorageOffset(i);
|
|
assert(p.y==0&&p.x>=20&&p.x<=41&&p.z>=15&&p.z<=36);
|
|
assert(std::hypot(p.x,p.z)<55);
|
|
for(auto old:seen)assert(std::hypot(p.x-old.x,p.z-old.z)>=3);
|
|
seen.push_back(p);
|
|
}
|
|
for(int x=20;x<=41;x+=3)for(int z=15;z<=36;z+=3){
|
|
int matches=0;for(auto p:seen)if(p.x==x&&p.z==z)matches++;assert(matches==1);
|
|
}
|
|
for(int invalid:{-1,64,999}){auto p=StorageOffset(invalid);assert(p.x==0&&p.y==0&&p.z==0);}
|
|
}
|
|
''')
|
|
tick = body(p, 'int Tick(')
|
|
start = tick.index('int tested, lowGround, obstructed;')
|
|
end = tick.index('m_Stage = 1;', start)
|
|
placement = tick[start:end]
|
|
assert 'i < STORAGE_CANDIDATES && m_Stores.Count() < STORAGE_COUNT' in placement
|
|
assert 'if (position[1] <= 1) { lowGround++; continue; }' in placement
|
|
assert 'if (!SCR_WorldTools.TraceCilinderUtil(position + "0 1 0", 1.3, 2, TraceFlags.ENTS | TraceFlags.WORLD)) { obstructed++; continue; }' in placement
|
|
assert placement.index('TraceCilinderUtil') < placement.index('ERR_Actors.Spawn(BOX, position)')
|
|
assert placement.index('m_Mode.Own(box)') < placement.index('box.FindComponent(')
|
|
assert placement.count('ERR_Actors.Spawn(') == 1
|
|
assert 'm_Boxes.Count() == STORAGE_COUNT && m_Stores.Count() == STORAGE_COUNT' in placement
|
|
assert ') return -1;' in placement[placement.index('m_Boxes.Count() == STORAGE_COUNT'):]
|
|
for forbidden in ('TryMoveItem', 'TrySpawn', 'Delete', 'SetOrigin', 'Teleport', 'HandleDamage', 'SHELL'):
|
|
assert forbidden not in placement, forbidden
|
|
assert tick.index('m_Stage = 1;', start) < tick.index('source.TryMoveItemToStorage(')
|
|
assert 'Boxes with borrowed originals remain owned by normal mission cleanup.' in text
|
|
print('PASS: 64 bounded distinct storage candidates; native gates, five-store barrier and finite-stock ownership retained; native placement pending')
|