72 lines
3.5 KiB
Python
72 lines
3.5 KiB
Python
"""Execute production-of-fixture geometry rules, without native mesh claims."""
|
|
from pathlib import Path
|
|
import unittest
|
|
from policy_harness import body, run
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
HELPER = ROOT/'addons/core/Scripts/Game/ERR/ERR_NativeFlightFootprint.c'
|
|
PROBE = ROOT/'addons/core/Scripts/Game/ERR/ERR_NativePoweredFlightProbe.c'
|
|
|
|
class FlightFootprint(unittest.TestCase):
|
|
def test_actual_complete_envelope_gate(self):
|
|
run('#include <cassert>\n#include <limits>\n'+body(HELPER,'static bool Fits(')+'''
|
|
int main(){
|
|
assert(Fits(28,0,1)); assert(Fits(30,1,1));
|
|
assert(!Fits(30,1.01f,1)); assert(!Fits(32,0,1));
|
|
assert(!Fits(15,24,1)); // smaller craft still cannot escape its clear column
|
|
assert(!Fits(0,0,1)); assert(!Fits(-1,0,1));
|
|
assert(!Fits(20,-1,1)); assert(!Fits(20,0,6)); assert(!Fits(20,0,-4));
|
|
float nan=std::numeric_limits<float>::quiet_NaN();
|
|
float inf=std::numeric_limits<float>::infinity();
|
|
assert(!Fits(nan,0,1)); assert(!Fits(20,nan,1)); assert(!Fits(20,0,nan));
|
|
assert(!Fits(inf,0,1)); assert(!Fits(20,inf,1));
|
|
for(int r=1;r<=40;r++)for(int d=0;d<=40;d++){
|
|
bool expected=r<32&&d<32&&r+d+9<=40;
|
|
assert(Fits(r,d,1)==expected);
|
|
}
|
|
}
|
|
''')
|
|
|
|
def test_actual_rotor_cylinder_sphere_overbounds_every_orientation(self):
|
|
run('#include <cassert>\n#include <cmath>\n#include <initializer_list>\n'+body(HELPER,'static float CylinderSphere(')+'''
|
|
int main(){
|
|
for(float radius:{2.3f,12.f})for(float thickness:{.75f,1.5f}) {
|
|
float pivot=14.5f; float bound=CylinderSphere(pivot,radius,thickness);
|
|
assert(bound>=pivot+std::hypot(radius,thickness));
|
|
for(int angle=0;angle<360;angle++) {
|
|
float a=angle*3.14159265f/180; float x=radius*std::cos(a),z=radius*std::sin(a);
|
|
float distance=std::sqrt(x*x+thickness*thickness+(z+pivot)*(z+pivot));
|
|
assert(distance<=bound+.0001f);
|
|
}
|
|
}
|
|
assert(CylinderSphere(13.6f,2.3f,.75f)>15);
|
|
}
|
|
''')
|
|
|
|
def test_native_measurement_is_bounded_and_requires_both_damage_sweeps(self):
|
|
source=HELPER.read_text()
|
|
for text in ['MAX_ENTITIES = 256','MAX_DEPTH = 16','MAX_HITZONES = 512',
|
|
'entities.Contains(child)', 'CountAllHitZones()', 'GetAllHitZones(zones)',
|
|
'aircraft.GetWorldTransform(worldTransform)', 'origin = worldTransform[3]',
|
|
'entity.GetWorldBounds(mins, maxs)', 'simulation.RotorGetTransform(rotor, localRotor)',
|
|
'simulation.RotorGetRadius(rotor)', 'rotorZone.GetPointInfo()',
|
|
'point.GetWorldTransform(rotorWorld)', 'mainSweeps != 1 || tailSweeps != 1',
|
|
'expectedRadius = 12; thickness = 1.5', 'expectedRadius = 2.3; thickness = 0.75',
|
|
'Math.Sqrt(scaleSquared)', 'radius = Math.Max(modelRadius, Math.Max(damageRadius, simulationRadius))']:
|
|
self.assertIn(text,source)
|
|
self.assertNotIn('simulation.GetWorldTransform(',source)
|
|
for forbidden in ['SetOrigin(', 'SetWorldTransform(', 'SetVelocity(', 'SetHealth(', 'Spawn(', 'ForceStartEngine(']:
|
|
self.assertNotIn(forbidden,source)
|
|
|
|
def test_gate_precedes_single_engine_request_and_tightens_drift(self):
|
|
source=PROBE.read_text()
|
|
self.assertLess(source.index('ERR_NativeFlightFootprint.Measure('),source.index('m_Controller.StartEngine()'))
|
|
self.assertEqual(source.count('m_Controller.StartEngine()'),1)
|
|
self.assertIn('m_Home = measuredOrigin;',source)
|
|
self.assertIn('drift >= 8',source)
|
|
self.assertNotIn('drift > 22',source)
|
|
self.assertIn('clearance.Mins = "-40 -1 -40"; clearance.Maxs = "40 1 40"',source)
|
|
self.assertIn('clearance.End = candidate + "0 60 0"',source)
|
|
self.assertIn('refinementAnchor = bestCandidate',source)
|
|
|
|
if __name__=='__main__': unittest.main()
|