#ifdef WORKBENCH modded class ERR_RescueFlightComponent { bool ProbePassenger(IEntity passenger) { array seats = {}; CargoSeats(GetOwner(), seats); if (seats.IsEmpty()) return false; CompartmentAccessComponent access = CompartmentAccessComponent.Cast(passenger.FindComponent(CompartmentAccessComponent)); return access && access.GetInVehicle(seats[0].GetOwner(), seats[0], true, -1, ECloseDoorAfterActions.INVALID, false); } void ProbeDeparture() { m_Aircraft = Vehicle.Cast(GetOwner()); m_Departing = true; } } modded class ERR_ExtractionService { void ProbeVictory(ERR_RescueFlightComponent flight) { m_Transports.Insert(flight); m_State = ERR_ExtractionState.ESCAPED; } } modded class ERR_GameMode { protected IEntity m_ProbeAircraft, m_ProbePassenger; protected vector m_ProbePosition; protected ref ERR_ExtractionService m_ProbeExtraction; protected override void StartScenario() {} protected override void EOnInit(IEntity owner) { super.EOnInit(owner); if (!SCR_Global.IsEditMode()) GetGame().GetCallqueue().CallLater(ExtractionProbe, 8000, false); } void ExtractionProbe() { vector position = ERR_Actors.Ground("9730 0 1560") + "0 120 0"; m_ProbeAircraft = ERR_Actors.Spawn("{90B3A9E658D47B20}Prefabs/ERR/RescueHelicopterWest.et", position); if (!m_ProbeAircraft) { Print("ERR SMOKE FAIL: rescue allocation", LogLevel.ERROR); return; } GetGame().GetCallqueue().CallLater(HoldProbe, 500, false); } void HoldProbe() { ERR_RescueFlightComponent flight = ERR_RescueFlightComponent.Cast(m_ProbeAircraft.FindComponent(ERR_RescueFlightComponent)); flight.ProbeDeparture(); if (!flight.AirborneAfterPickup()) { Print("ERR SMOKE FAIL: native airborne classifier", LogLevel.ERROR); return; } m_ProbeAircraft.GetPhysics().SetVelocity("15 -20 3"); m_ProbeExtraction = new ERR_ExtractionService(null); m_ProbeExtraction.ProbeVictory(flight); m_ProbePassenger = ERR_Actors.Spawn(ERR_RescueAssets.Pilot("US"), ERR_Actors.Ground("9730 0 1560")); if (!m_ProbePassenger || !flight.ProbePassenger(m_ProbePassenger)) { Print("ERR SMOKE FAIL: native cargo passenger", LogLevel.ERROR); return; } OnStop().Insert(m_ProbeExtraction.Stop); // Seed the already-resolved phase, then exercise real native end and service cleanup. m_Phase = ERR_Phase.VICTORY; EndGameMode(SCR_GameModeEndData.CreateSimple(EGameOverTypes.VICTORY)); if (GetState() != SCR_EGameModeState.POSTGAME || !m_Stopped) { Print("ERR SMOKE FAIL: native postgame", LogLevel.ERROR); return; } m_ProbePosition = m_ProbeAircraft.GetOrigin(); if (ERR_RescueRules.FlightComplete(0,29999) || !ERR_RescueRules.FlightComplete(0,30000) || ERR_RescueRules.AirborneSince(false,0,30000) != -1) { Print("ERR SMOKE FAIL: native timer", LogLevel.ERROR); return; } Print("ERR SMOKE PASS: native airborne classifier and thirty-second timer"); GetGame().GetCallqueue().CallLater(CheckHold, 12000, false); } void CheckHold() { if (!ERR_Actors.Alive(m_ProbePassenger) || CompartmentAccessComponent.GetVehicleIn(m_ProbePassenger) != m_ProbeAircraft) { Print("ERR SMOKE FAIL: retained passenger", LogLevel.ERROR); return; } float moved = vector.Distance(m_ProbePosition, m_ProbeAircraft.GetOrigin()); float speed = m_ProbeAircraft.GetPhysics().GetVelocity().Length(); PrintFormat("ERR EXTRACTION HOLD: displacement=%1 speed=%2 alive=%3", moved, speed, ERR_Actors.Alive(m_ProbeAircraft)); if (moved > 0.1 || speed > 0.1 || !ERR_Actors.Alive(m_ProbeAircraft)) { Print("ERR SMOKE FAIL: terminal rescue stability", LogLevel.ERROR); return; } Print("ERR SMOKE PASS: native postgame holds occupied helicopter for twelve seconds with living passenger retained"); Print("ERR SMOKE COMPLETE: extraction-end"); } } #endif