Prepare independent successor playtest with spawn recovery and casualty feedback
This commit is contained in:
@@ -22,12 +22,50 @@ class ERR_AircraftFieldEnvelope : ERR_AircraftFlightEnvelope
|
||||
if (columns < 1 || rows < 1 || columns >= MAX_TERRAIN_NODES || rows >= MAX_TERRAIN_NODES) return false;
|
||||
return (columns + 1) * (rows + 1) <= MAX_TERRAIN_NODES;
|
||||
}
|
||||
#ifdef WORKBENCH
|
||||
// At most the first refusal of each exact survey call is logged. No query,
|
||||
// predicate, retry or resource allocation is added to the qualification.
|
||||
protected static bool SurveyDiagnostics()
|
||||
{
|
||||
string enabled, outcome;
|
||||
return System.GetCLIParam("errSmoke", enabled) && enabled == "1" && System.GetCLIParam("errSmokeOutcome", outcome) && outcome == "aircraft-field";
|
||||
}
|
||||
protected static void SurveyTraceFailure(string stage, float fraction, TraceBox trace)
|
||||
{
|
||||
if (!SurveyDiagnostics()) return;
|
||||
IEntity hit = trace.TraceEnt;
|
||||
string kind = "none", resource = "";
|
||||
if (hit)
|
||||
{
|
||||
kind = hit.Type().ToString();
|
||||
if (hit.GetPrefabData()) resource = hit.GetPrefabData().GetPrefabName();
|
||||
}
|
||||
if (hit)
|
||||
{
|
||||
vector lower, upper; hit.GetWorldBounds(lower, upper);
|
||||
PrintFormat("ERR AIRCRAFT FIELD SURVEY HIT BOUNDS: lower=%1 upper=%2", lower, upper);
|
||||
}
|
||||
PrintFormat("ERR AIRCRAFT FIELD SURVEY REFUSED: stage=%1 fraction=%2 entity=%3 class=%4 prefab=%5 start=%6 end=%7", stage, fraction, hit, kind, resource, trace.Start, trace.End);
|
||||
}
|
||||
#endif
|
||||
static bool Survey(vector start, vector end, array<IEntity> excluded = null)
|
||||
{
|
||||
if (!GetGame() || !GetGame().GetWorld() || !FinitePoint(start) || !FinitePoint(end)) return false;
|
||||
if (!GetGame() || !GetGame().GetWorld() || !FinitePoint(start) || !FinitePoint(end))
|
||||
{
|
||||
#ifdef WORKBENCH
|
||||
if (SurveyDiagnostics()) PrintFormat("ERR AIRCRAFT FIELD SURVEY REFUSED: stage=context-or-finite-points start=%1 end=%2", start, end);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
float distance = vector.DistanceXZ(start, end);
|
||||
int columns = TerrainColumns(distance), rows = 40;
|
||||
if (!TerrainBudget(columns, rows) || !(start[1] >= 2) || !(Math.AbsFloat(end[1] - start[1]) <= 0.3)) return false;
|
||||
if (!TerrainBudget(columns, rows) || !(start[1] >= 2) || !(Math.AbsFloat(end[1] - start[1]) <= 0.3))
|
||||
{
|
||||
#ifdef WORKBENCH
|
||||
if (SurveyDiagnostics()) PrintFormat("ERR AIRCRAFT FIELD SURVEY REFUSED: stage=budget-or-endpoints start=%1 end=%2 distance=%3 columns=%4 rows=%5 startHeight=%6 endHeight=%7 delta=%8", start, end, distance, columns, rows, start[1], end[1], Math.AbsFloat(end[1] - start[1]));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
vector along = end - start; along[1] = 0; along = along * (1 / distance);
|
||||
vector across = Vector(-along[2], 0, along[0]);
|
||||
float span = distance + 80;
|
||||
@@ -38,7 +76,14 @@ class ERR_AircraftFieldEnvelope : ERR_AircraftFlightEnvelope
|
||||
for (int z = 0; z <= rows; z++)
|
||||
{
|
||||
vector sample = start + along * (-40 + span * x / columns) + across * (-40 + 80 * z / rows);
|
||||
if (!(Math.AbsFloat(SCR_TerrainHelper.GetTerrainY(sample) - start[1]) <= 0.3)) return false;
|
||||
float terrain = SCR_TerrainHelper.GetTerrainY(sample);
|
||||
if (!(Math.AbsFloat(terrain - start[1]) <= 0.3))
|
||||
{
|
||||
#ifdef WORKBENCH
|
||||
if (SurveyDiagnostics()) PrintFormat("ERR AIRCRAFT FIELD SURVEY REFUSED: stage=terrain x=%1 z=%2 columns=%3 rows=%4 sample=%5 terrainHeight=%6 startHeight=%7 delta=%8", x, z, columns, rows, sample, terrain, start[1], Math.AbsFloat(terrain - start[1]));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
vector lower, upper;
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
@@ -55,11 +100,22 @@ class ERR_AircraftFieldEnvelope : ERR_AircraftFlightEnvelope
|
||||
corridor.Start = centre + "0 3 0"; corridor.End = centre + "0 60 0";
|
||||
corridor.Mins = Vector(-half[0], -1, -half[2]); corridor.Maxs = Vector(half[0], 1, half[2]);
|
||||
corridor.Flags = TraceFlags.ENTS | TraceFlags.WORLD; corridor.ExcludeArray = excluded;
|
||||
if (!(GetGame().GetWorld().TraceMove(corridor, null) >= 1)) return false;
|
||||
float corridorFraction = GetGame().GetWorld().TraceMove(corridor, null);
|
||||
if (!(corridorFraction >= 1))
|
||||
{
|
||||
#ifdef WORKBENCH
|
||||
SurveyTraceFailure("corridor", corridorFraction, corridor);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
TraceBox low = new TraceBox(); low.Start = centre + "0 0.5 0"; low.End = centre + "0 3 0";
|
||||
low.Mins = Vector(-half[0], -0.2, -half[2]); low.Maxs = Vector(half[0], 0.2, half[2]);
|
||||
low.Flags = TraceFlags.ENTS; low.ExcludeArray = excluded;
|
||||
return GetGame().GetWorld().TraceMove(low, null) >= 1;
|
||||
float lowFraction = GetGame().GetWorld().TraceMove(low, null);
|
||||
#ifdef WORKBENCH
|
||||
if (!(lowFraction >= 1)) SurveyTraceFailure("low-objects", lowFraction, low);
|
||||
#endif
|
||||
return lowFraction >= 1;
|
||||
}
|
||||
static ERR_AircraftFieldEnvelope QualifyField(ERR_GameMode mode, Vehicle aircraft, IEntity pilot, vector destination)
|
||||
{
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// Unqualified 100m field-route prototype. No allocation, HQ dispatch or service
|
||||
// integration. The shared base registry/bridge remains the sole input owner.
|
||||
// Unqualified 100m field-route prototype, admitted by the typed service only.
|
||||
// No allocation or HQ dispatch; the shared registry/bridge owns native inputs.
|
||||
class ERR_AircraftFieldFlight : ERR_AircraftFlight
|
||||
{
|
||||
protected ref ERR_AircraftFieldEnvelope m_Field;
|
||||
protected int m_FieldPhase; // 0 startup, 1 cruise, 2 braking, 3 slow settling
|
||||
protected vector m_FieldReference;
|
||||
protected vector m_FieldIntegral;
|
||||
protected float m_FieldBrakeSpeed;
|
||||
protected vector m_FieldLandingPoint;
|
||||
protected bool m_FieldStopFrozen;
|
||||
protected bool m_FieldArrived;
|
||||
@@ -55,6 +54,7 @@ class ERR_AircraftFieldFlight : ERR_AircraftFlight
|
||||
{
|
||||
if (m_FieldStopFrozen) return true;
|
||||
if (!Owns() || !m_Field || !Healthy()) { Fail("field braking ownership or capability unavailable"); return false; }
|
||||
if (m_Simulation.HasAnyGroundContact()) { Fail("field airborne braking refused ground contact"); return false; }
|
||||
vector point = m_Field.Destination();
|
||||
if (m_Cancelled)
|
||||
{
|
||||
@@ -70,9 +70,9 @@ class ERR_AircraftFieldFlight : ERR_AircraftFlight
|
||||
m_Controller.SetAutohoverEnabled(true);
|
||||
if (!m_Controller.GetAutohoverEnabled()) { Fail("native field braking autohover enable refused"); return false; }
|
||||
m_FieldLandingPoint = point; m_FieldStopFrozen = true;
|
||||
// Begin reducing the reference at entry, before the modeled reserve boundary.
|
||||
// This one frozen ceiling cannot increase on another cancellation or tick.
|
||||
m_FieldBrakeSpeed = m_FieldReference.Length() * 0.9;
|
||||
// Remove cruise integral once; retain the bounded vector slew toward rest.
|
||||
// Repeated cancellation must not reset this state or the frozen deadline.
|
||||
m_FieldIntegral = "0 0 0";
|
||||
m_FieldPhase = 2; m_State = ERR_AircraftFlightState.TRANSLATING;
|
||||
m_FieldLowSince = -1; m_Stable = -1;
|
||||
// Includes braking, two low-speed seconds and five seconds of final hold.
|
||||
@@ -112,6 +112,7 @@ class ERR_AircraftFieldFlight : ERR_AircraftFlight
|
||||
float now = Now();
|
||||
if (now < 0 || now >= m_Deadline || now >= m_StageDeadline) { Fail("bounded field stage expired"); return false; }
|
||||
if (!Healthy() || !m_Readback) { Fail("field capability or native input readback lost"); return false; }
|
||||
if (m_FieldPhase == 2 && m_Simulation.HasAnyGroundContact()) { Fail("field ground contact during airborne braking"); return false; }
|
||||
vector transform[4]; m_Aircraft.GetWorldTransform(transform);
|
||||
if (!FieldContains(transform[3], transform[1][1]) || !ERR_AircraftFieldRules.SpeedAllowed(m_Simulation.GetVelocity())) { Fail("qualified field position, attitude or speed exceeded"); return false; }
|
||||
return true;
|
||||
@@ -121,10 +122,12 @@ class ERR_AircraftFieldFlight : ERR_AircraftFlight
|
||||
vector target = m_Field.Destination(); if (m_FieldStopFrozen) target = m_FieldLandingPoint;
|
||||
if (m_FieldPhase == 3 || m_State == ERR_AircraftFlightState.LANDING) return ERR_AircraftTranslationRules.Demand(target, position, velocity);
|
||||
vector direction = target - position; direction[1] = 0;
|
||||
float remaining = direction.Length(); float targetSpeed = 2;
|
||||
if (m_FieldPhase == 2) targetSpeed = ERR_AircraftFieldRules.ApproachSpeed(remaining, Math.Min(m_FieldReference.Length(), m_FieldBrakeSpeed));
|
||||
vector desired;
|
||||
if (remaining > 0.001) desired = direction * (targetSpeed / remaining);
|
||||
float remaining = direction.Length();
|
||||
vector desired = "0 0 0";
|
||||
// Braking targets rest immediately, independently of distance or bearing.
|
||||
// A lagging native airframe can still accelerate while the reference slews;
|
||||
// only native measurements can qualify the declared actual-speed reserve.
|
||||
if (m_FieldPhase != 2 && remaining > 0.001) desired = direction * (2 / remaining);
|
||||
m_FieldReference = ERR_AircraftFieldRules.RampReference(m_FieldReference, desired, dt);
|
||||
vector nextIntegral;
|
||||
vector demand = ERR_AircraftFieldRules.VelocityDemand(m_FieldReference, velocity, m_FieldIntegral, dt, nextIntegral);
|
||||
@@ -173,9 +176,10 @@ class ERR_AircraftFieldFlight : ERR_AircraftFlight
|
||||
}
|
||||
if (m_FieldPhase == 2)
|
||||
{
|
||||
if (m_Simulation.HasAnyGroundContact()) { Fail("field ground contact during airborne braking"); return; }
|
||||
if (!(horizontal < 0.25)) m_FieldLowSince = -1;
|
||||
else if (m_FieldLowSince < 0) m_FieldLowSince = now;
|
||||
if (!ERR_AircraftFieldRules.LowSpeedHeld(horizontal, m_FieldLowSince, now)) return;
|
||||
if (!ERR_AircraftFieldRules.LowSpeedHeld(horizontal, m_FieldLowSince, now) || !(m_FieldReference.Length() <= 0.01)) return;
|
||||
m_FieldPhase = 3; m_FieldReference = "0 0 0"; m_FieldIntegral = "0 0 0"; m_Stable = -1;
|
||||
// No new deadline: slow positioning/hold belongs to the same braking budget.
|
||||
}
|
||||
|
||||
@@ -37,18 +37,6 @@ class ERR_AircraftFieldRules
|
||||
desired = CapHorizontal(desired, 2);
|
||||
return CapHorizontal(current + CapHorizontal(desired - current, 0.2 * dt), 2);
|
||||
}
|
||||
// Remaining target distance includes permitted takeoff/corridor drift; its
|
||||
// 120m arithmetic bound grants no authority beyond Contains/Length.
|
||||
// Invert the entire candidate stopping reserve (including1s latency and3m
|
||||
// margin), not just its deceleration term. Caller also freezes a0.9 entry-speed
|
||||
// cap to begin reducing the velocityReference immediately, then slews the vector.
|
||||
// The assumed0.15m/s² physical deceleration still requires native measurement.
|
||||
static float ApproachSpeed(float remaining, float current)
|
||||
{
|
||||
if (!(remaining >= 0 && remaining <= 120) || !(current >= 0 && current <= 2)) return 0;
|
||||
float reservedSpeed = (Math.Sqrt(0.09 + 1.2 * Math.Max(0, remaining - 3)) - 0.3) * 0.5;
|
||||
return Math.Min(current, Math.Max(0, reservedSpeed));
|
||||
}
|
||||
// Integral units are (m/s)*seconds; nextIntegral is caller-owned state.
|
||||
// Horizontal demand is world-space; the exact-owner controller converts it
|
||||
// to the native airframe basis. The caller resets state at phase transitions.
|
||||
@@ -76,7 +64,9 @@ class ERR_AircraftFieldRules
|
||||
static bool ShouldBrake(float remaining, float speed)
|
||||
{
|
||||
if (!(remaining >= 0 && remaining <= 120) || !(speed >= 0 && speed <= 2.5)) return true;
|
||||
return remaining <= Math.Max(25, BrakingReserve(speed));
|
||||
// The candidate reserve uses actual speed; phase2 immediately targets rest.
|
||||
// This predicate does not assert measured native stopping performance.
|
||||
return remaining <= BrakingReserve(speed);
|
||||
}
|
||||
// Admit only the full experimental lease, with <=1s dispatch allowance.
|
||||
// Never recompute a deadline from these checks or renew the original lease.
|
||||
|
||||
@@ -18,7 +18,7 @@ modded class ERR_AircraftFieldFlight
|
||||
bool alreadyFrozen = m_FieldStopFrozen;
|
||||
bool result = super.BeginFieldBrake(now);
|
||||
ERR_NativeAircraftFieldProbe probe = ERR_NativeAircraftFieldProbe.Current();
|
||||
if (result && !alreadyFrozen && probe && m_Aircraft && m_Simulation) probe.BrakeBegan(this, now, m_Aircraft.GetOrigin(), m_Simulation.GetVelocity());
|
||||
if (result && !alreadyFrozen && probe && m_Aircraft && m_Simulation) probe.BrakeBegan(this, now, m_Aircraft.GetOrigin(), m_Simulation.GetVelocity(), m_Simulation.HasAnyGroundContact());
|
||||
return result;
|
||||
}
|
||||
protected override void CheckTranslation(float now, vector position, float height, float speed, float upright)
|
||||
@@ -26,7 +26,7 @@ modded class ERR_AircraftFieldFlight
|
||||
int oldPhase = m_FieldPhase;
|
||||
super.CheckTranslation(now, position, height, speed, upright);
|
||||
ERR_NativeAircraftFieldProbe probe = ERR_NativeAircraftFieldProbe.Current();
|
||||
if (oldPhase == 2 && m_FieldPhase == 3 && probe && m_Aircraft && m_Simulation) probe.BrakeStopped(this, now, m_Aircraft.GetOrigin(), m_Simulation.GetVelocity());
|
||||
if (oldPhase == 2 && m_FieldPhase == 3 && probe && m_Aircraft && m_Simulation) probe.BrakeStopped(this, now, m_Aircraft.GetOrigin(), m_Simulation.GetVelocity(), m_Simulation.HasAnyGroundContact());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -65,9 +65,9 @@ class ERR_NativeAircraftFieldRules
|
||||
{
|
||||
return phase == 1 && !contact && alongSpeed >= 1 && horizontal >= 1 && horizontal <= 2.5;
|
||||
}
|
||||
static bool Braking(float reserve, float sampledTravel, float displacement, float lowSince, float now, float horizontal)
|
||||
static bool Braking(float reserve, float sampledTravel, float displacement, float lowSince, float now, float horizontal, bool contactObserved)
|
||||
{
|
||||
return reserve >= 3 && reserve <= 26.334 && sampledTravel >= 0 && sampledTravel <= reserve && displacement >= 0 && displacement <= reserve && horizontal >= 0 && horizontal < 0.25 && lowSince >= 0 && now - lowSince >= 2000;
|
||||
return !contactObserved && reserve >= 3 && reserve <= 26.334 && sampledTravel >= 0 && sampledTravel <= reserve && displacement >= 0 && displacement <= reserve && horizontal >= 0 && horizontal < 0.25 && lowSince >= 0 && now - lowSince >= 2000;
|
||||
}
|
||||
static bool Terminal(bool cancellation, int state, int stops, bool arrived, bool cruiseHeld, bool endpointHeld, bool braking, float displacement, float targetError)
|
||||
{
|
||||
@@ -123,6 +123,7 @@ class ERR_NativeAircraftFieldProbe
|
||||
protected bool m_BrakeObserved;
|
||||
protected bool m_BrakeStopped;
|
||||
protected bool m_BrakePassed;
|
||||
protected bool m_BrakeContactObserved;
|
||||
protected string m_ObservationFailure;
|
||||
protected vector m_BrakeOrigin;
|
||||
protected vector m_BrakeLandingPoint;
|
||||
@@ -140,6 +141,7 @@ class ERR_NativeAircraftFieldProbe
|
||||
protected int m_HelicopterHooks;
|
||||
protected bool m_LastEngine;
|
||||
protected bool m_AllocationRequested;
|
||||
protected bool m_TerrainAudited;
|
||||
protected bool m_PilotRequested;
|
||||
protected bool m_Stopped;
|
||||
protected bool m_Complete;
|
||||
@@ -196,14 +198,49 @@ class ERR_NativeAircraftFieldProbe
|
||||
if (m_Stopped || !m_Flight || controller != m_Controller) return;
|
||||
// Observation only: super-chain order cannot cause a second control write.
|
||||
m_HelicopterHooks++;
|
||||
ObserveBrakingContact(!m_Simulation || m_Simulation.HasAnyGroundContact());
|
||||
}
|
||||
static bool TerrainAuditEnabled()
|
||||
{
|
||||
string audit, cancellation;
|
||||
return Enabled() && System.GetCLIParam("errSmokeFieldTerrainAudit", audit) && audit == "1" && !(System.GetCLIParam("errSmokeFieldServiceCancel", cancellation) && cancellation == "1");
|
||||
}
|
||||
protected void AuditTerrain()
|
||||
{
|
||||
if (m_TerrainAudited || !TerrainAuditEnabled() || m_Stopped || m_AllocationRequested || m_Aircraft || m_Group || m_Pilot || !GetGame() || !GetGame().GetWorld()) return;
|
||||
m_TerrainAudited = true;
|
||||
// Read-only fixed coarse grid for offline corridor authorship. No selected
|
||||
// candidate, fallback, traces, entity allocation or qualification is produced.
|
||||
Print("ERR AIRCRAFT FIELD TERRAIN AUDIT BEGIN: minX=4750 maxX=5150 minZ=11600 maxZ=12000 spacing=10 columns=41 rows=41 nodes=1681");
|
||||
for (int x = 0; x <= 40; x++)
|
||||
{
|
||||
for (int z = 0; z <= 40; z++)
|
||||
{
|
||||
vector point = "0 0 0";
|
||||
point[0] = 4750 + x * 10; point[2] = 11600 + z * 10;
|
||||
float terrain = SCR_TerrainHelper.GetTerrainY(point);
|
||||
int index = x * 41 + z;
|
||||
if (!(Math.AbsFloat(terrain) <= 1000000))
|
||||
{
|
||||
PrintFormat("ERR AIRCRAFT FIELD TERRAIN AUDIT ABORT: index=%1 x=%2 z=%3 nonfiniteOrInvalidHeight=%4", index, point[0], point[2], terrain);
|
||||
return;
|
||||
}
|
||||
PrintFormat("ERR AIRCRAFT FIELD TERRAIN AUDIT POINT: index=%1 x=%2 z=%3 height=%4", index, point[0], point[2], terrain);
|
||||
}
|
||||
}
|
||||
Print("ERR AIRCRAFT FIELD TERRAIN AUDIT END: nodes=1681; original survey refusal unchanged; no candidate qualified");
|
||||
}
|
||||
protected bool FindPad(out vector result)
|
||||
{
|
||||
// This exact airport start was observed in the twenty-metre fixture. The
|
||||
// longer corridor still requires its own complete survey; there is no search.
|
||||
vector candidate = ERR_Actors.Ground("4850.953 0 11787.412");
|
||||
vector destination = ERR_Actors.Ground(candidate + "100 0 0");
|
||||
if (!ERR_AircraftFieldEnvelope.Survey(candidate, destination)) return false;
|
||||
// Authored from terrain, warehouse and tree evidence: one south-shifted northbound candidate.
|
||||
// Coarse data grants no clearance; the complete survey below is mandatory.
|
||||
vector candidate = ERR_Actors.Ground("4890 0 11730");
|
||||
vector destination = ERR_Actors.Ground(candidate + "0 0 100");
|
||||
if (!ERR_AircraftFieldEnvelope.Survey(candidate, destination))
|
||||
{
|
||||
AuditTerrain();
|
||||
return false;
|
||||
}
|
||||
PrintFormat("ERR AIRCRAFT FIELD FIXTURE CORRIDOR: singleStart=%1 destination=%2; fixed100m complete survey passed", candidate, destination);
|
||||
result = candidate; m_Destination = destination; return true;
|
||||
}
|
||||
@@ -259,27 +296,35 @@ class ERR_NativeAircraftFieldProbe
|
||||
PrintFormat("ERR AIRCRAFT FIELD MOTION: now=%1 state=%2 phase=%3 position=%4 velocity=%5 refVelocity=%6 integral=%7 observedLocalInput=%8 fuel=%9", now, m_Flight.State(), m_Flight.FieldPhase(), position, velocity, m_Flight.ReferenceVelocity(), m_Flight.IntegralDemand(), m_Flight.ERR_NativeFieldInputDemand(), m_Fuel.GetTotalFuel());
|
||||
PrintFormat("ERR AIRCRAFT FIELD LEASE: token=%1 originalDeadline=%2 stageDeadline=%3 actions=%4 helicopter=%5 contact=%6 engine=%7 targetError=%8", m_Flight.OrderToken(), m_ControlDeadline, m_Flight.ERR_NativeFieldStageDeadline(), m_Flight.ERR_NativeFieldActionUpdates(), m_Flight.ERR_NativeFieldHelicopterUpdates(), m_Simulation.HasAnyGroundContact(), m_Controller.IsEngineOn(), vector.DistanceXZ(position, m_Flight.LandingPoint()));
|
||||
}
|
||||
void BrakeBegan(ERR_AircraftFieldFlight flight, float now, vector position, vector velocity)
|
||||
void ObserveBrakingContact(bool contact)
|
||||
{
|
||||
if (m_Stopped || !m_BrakeObserved || m_BrakeStopped || !contact) return;
|
||||
m_BrakeContactObserved = true;
|
||||
m_ObservationFailure = "native ground contact cannot qualify airborne braking";
|
||||
}
|
||||
void BrakeBegan(ERR_AircraftFieldFlight flight, float now, vector position, vector velocity, bool contact)
|
||||
{
|
||||
if (m_Stopped || flight != m_Flight) return;
|
||||
if (m_BrakeObserved) { m_ObservationFailure = "production brake event occurs exactly once"; return; }
|
||||
m_BrakeObserved = true; m_BrakeAt = now;
|
||||
ObserveBrakingContact(contact);
|
||||
m_BrakeOrigin = position; m_BrakePrevious = position;
|
||||
m_BrakeReserve = ERR_AircraftFieldRules.BrakingReserve(ERR_AircraftFieldRules.HorizontalSpeed(velocity));
|
||||
m_BrakeStageDeadline = flight.ERR_NativeFieldStageDeadline(); m_BrakeLandingPoint = flight.LandingPoint();
|
||||
PrintFormat("ERR AIRCRAFT FIELD BRAKE OBSERVED: now=%1 position=%2 velocity=%3 declaredHypothesisReserve=%4 stageDeadline=%5 originalDeadline=%6", now, position, velocity, m_BrakeReserve, m_BrakeStageDeadline, m_ControlDeadline);
|
||||
}
|
||||
void BrakeStopped(ERR_AircraftFieldFlight flight, float now, vector position, vector velocity)
|
||||
void BrakeStopped(ERR_AircraftFieldFlight flight, float now, vector position, vector velocity, bool contact)
|
||||
{
|
||||
if (m_Stopped || flight != m_Flight) return;
|
||||
if (!m_BrakeObserved || m_BrakeStopped) { m_ObservationFailure = "one actual low-speed braking transition after original brake event"; return; }
|
||||
ObserveBrakingContact(contact);
|
||||
m_BrakeStopped = true;
|
||||
m_BrakeSampledTravel += vector.DistanceXZ(position, m_BrakePrevious);
|
||||
m_BrakePrevious = position;
|
||||
float displacement = vector.DistanceXZ(position, m_BrakeOrigin);
|
||||
m_BrakePassed = ERR_NativeAircraftFieldRules.Braking(m_BrakeReserve, m_BrakeSampledTravel, displacement, m_BrakeLowSince, now, ERR_AircraftFieldRules.HorizontalSpeed(velocity));
|
||||
PrintFormat("ERR AIRCRAFT FIELD STOP OBSERVED: now=%1 position=%2 sampledTravel=%3 displacement=%4 declaredReserve=%5 lowSince=%6 passed=%7", now, position, m_BrakeSampledTravel, displacement, m_BrakeReserve, m_BrakeLowSince, m_BrakePassed);
|
||||
if (!m_BrakePassed) m_ObservationFailure = "observed braking exceeded declared reserve or lacked independent two-second low-speed observations";
|
||||
m_BrakePassed = ERR_NativeAircraftFieldRules.Braking(m_BrakeReserve, m_BrakeSampledTravel, displacement, m_BrakeLowSince, now, ERR_AircraftFieldRules.HorizontalSpeed(velocity), m_BrakeContactObserved);
|
||||
PrintFormat("ERR AIRCRAFT FIELD STOP OBSERVED: now=%1 position=%2 sampledTravel=%3 displacement=%4 declaredReserve=%5 lowSince=%6 passed=%7 contactObserved=%8", now, position, m_BrakeSampledTravel, displacement, m_BrakeReserve, m_BrakeLowSince, m_BrakePassed, m_BrakeContactObserved);
|
||||
if (!m_BrakePassed && !m_BrakeContactObserved) m_ObservationFailure = "observed braking exceeded declared reserve or lacked independent two-second low-speed observations";
|
||||
}
|
||||
int Tick(float now)
|
||||
{
|
||||
@@ -356,6 +401,7 @@ class ERR_NativeAircraftFieldProbe
|
||||
if (!StopRetainedField(now)) return -1;
|
||||
if (m_BrakeObserved && !m_BrakeStopped)
|
||||
{
|
||||
ObserveBrakingContact(contact);
|
||||
m_BrakeSampledTravel += vector.DistanceXZ(position, m_BrakePrevious); m_BrakePrevious = position;
|
||||
if (!(horizontal < 0.25)) m_BrakeLowSince = -1;
|
||||
else if (m_BrakeLowSince < 0) m_BrakeLowSince = now;
|
||||
|
||||
Reference in New Issue
Block a user