#ifdef WORKBENCH modded class ERR_GameMode { protected override void StartScenario() {} } modded class ERR_GarageVehicles { protected IEntity m_ProbeObserver; protected int m_ProbePhase, m_ProbeTotal, m_ProbeMax, m_ProbeSteps, m_ProbeSpawnMax, m_ProbeLoadMax; protected float m_ProbeClock; protected Vehicle m_ProbeClaimed; protected ref ERR_GarageSite m_ProbeConsumed; override void Start() { if (!m_Mode.Settings().Set("garageVehicleCount", 4) || !m_Mode.Settings().Set("garageChancePercent", 100) || !m_Mode.Settings().Set("garageRadiusMetres", 750) || !m_Mode.Settings().Set("garageSpawnIntervalSeconds", 8)) { Fail("cannot persist fixture settings"); return; } super.Start(); if (m_Requested != 4 || m_GarageChance != 100 || m_SpawnRadius != 750 || m_SpawnInterval != 8000) { Fail("configured settings did not reach runtime"); return; } m_Mode.Settings().Set("garageRadiusMetres", 250); if (m_SpawnRadius != 750) { Fail("next-round setting changed running round"); return; } PrintFormat("ERR GARAGE MENU SETTINGS: count=%1 chance=%2 radius=%3 delayMs=%4 savedRadius=%5", m_Requested, m_GarageChance, m_SpawnRadius, m_SpawnInterval, m_Mode.Settings().Get("garageRadiusMetres")); } protected override bool Running() { return true; } protected override float Now() { return super.Now() + m_ProbeClock; } protected override bool Observers(array positions, array actors) { positions.Clear(); actors.Clear(); if (!m_ProbeObserver) { m_ProbeObserver = ERR_Actors.Spawn(ERR_CivilianTraffic.DriverPrefab(), ERR_Actors.Ground("9730 0 1560")); } if (!m_ProbeObserver) return false; positions.Insert(m_ProbeObserver.GetOrigin()); actors.Insert(m_ProbeObserver); return true; } protected override void Step() { int stage; if (m_Pending) stage = m_Stage; int start = System.GetTickCount(); super.Step(); int elapsed = System.GetTickCount() - start; m_ProbeSteps++; m_ProbeTotal += elapsed; m_ProbeMax = Math.Max(m_ProbeMax, elapsed); if (stage == 1) m_ProbeLoadMax = Math.Max(m_ProbeLoadMax, elapsed); if (stage == 2) { m_ProbeSpawnMax = Math.Max(m_ProbeSpawnMax, elapsed); PrintFormat("ERR GARAGE STREAM SPAWN STEP: elapsedMs=%1 spawned=%2 phase=%3", elapsed, m_Spawned, m_ProbePhase); } if (m_ProbePhase == 0 && m_Parked.Count() == 4) { GetGame().GetCallqueue().CallLater(ProbeFirst, 6000, false); m_ProbePhase = 1; } if (m_ProbePhase == 2 && m_Parked.IsEmpty()) { if (!m_ProbeClaimed || !ERR_Actors.Alive(m_ProbeClaimed) || !m_ProbeConsumed.Consumed) { Fail("claimed car lost"); return; } m_ProbeObserver.SetOrigin(ERR_Actors.Ground("5100 0 4050")); m_ProbePhase = 3; } if (m_ProbePhase == 3 && m_Parked.Count() == 4) { m_ProbePhase = 4; GetGame().GetCallqueue().CallLater(ProbeFinal, 6000, false); } } void Fail(string reason) { Stop(); Print("ERR SMOKE FAIL: garage-streaming " + reason, LogLevel.ERROR); } void ProbeFirst() { if (m_Parked.Count() != 4) { Fail("first population count changed"); return; } int bikes; foreach (ERR_ParkedVehicle parked : m_Parked) { Vehicle car = parked.Entity; if (!car) { Fail("missing parked vehicle"); return; } vector matrix[4]; car.GetWorldTransform(matrix); SCR_FuelManagerComponent fuel = SCR_FuelManagerComponent.Cast(car.FindComponent(SCR_FuelManagerComponent)); if (!fuel || fuel.GetTotalFuel() <= 0 || !Clear(car.GetOrigin(), matrix, car) || vector.Distance(car.GetOrigin(), parked.Origin) > 0.5) { Fail("vehicle fit/fuel/settling"); return; } if (car.GetPrefabData().GetPrefabName().Contains("/RX100/")) bikes++; PrintFormat("ERR GARAGE STREAM VEHICLE: prefab=%1 distance=%2 fuel=%3", car.GetPrefabData().GetPrefabName(), vector.DistanceXZ(car.GetOrigin(), m_ProbeObserver.GetOrigin()), fuel.GetTotalFuel()); } if (bikes != 1) { Fail("expected one optional bike"); return; } m_ProbeClaimed = m_Parked[0].Entity; m_ProbeConsumed = m_Parked[0].Site; Claim(0); m_ProbeObserver.SetOrigin(ERR_Actors.Ground("1000 0 1000")); m_NextSpawn = Now() + 200000; array observers = {m_ProbeObserver.GetOrigin()}; array actors = {m_ProbeObserver}; for (int i = 0; i < 3; i++) Maintain(observers, actors, Now(), true); if (m_Parked.Count() != 3) { Fail("retired without grace"); return; } m_ProbeClock += 61000; m_ProbePhase = 2; GetGame().GetCallqueue().CallLater(ProbeAllow, 4000, false); } void ProbeAllow() { m_NextSpawn = 0; } void ProbeFinal() { if (!m_ProbeClaimed || !ERR_Actors.Alive(m_ProbeClaimed) || !m_ProbeConsumed.Consumed || m_Parked.Count() != 4) { Fail("claimed vehicle/cap after travel"); return; } foreach (ERR_ParkedVehicle parked : m_Parked) if (parked.Site == m_ProbeConsumed || vector.DistanceXZ(parked.Entity.GetOrigin(), m_ProbeObserver.GetOrigin()) > 1000) { Fail("used garage refilled or distant spawn"); return; } int sites = m_Sites.Count(); int before = m_Spawned; Stop(); Step(); if (m_Spawned != before) { Fail("spawn after stop"); return; } PrintFormat("ERR GARAGE STREAM TOTALS: spawned=%1 nearby=%2 claimed=%3 cells=%4 garages=%5 steps=%6 workMs=%7 maxStepMs=%8 loadMaxMs=%9", m_Spawned, m_Parked.Count(), m_Claimed, m_KnownCells.Count(), sites, m_ProbeSteps, m_ProbeTotal, m_ProbeMax, m_ProbeLoadMax); PrintFormat("ERR GARAGE STREAM SPAWN MAX: %1 ms", m_ProbeSpawnMax); Print("ERR SMOKE PASS: garage-streaming near-player creation, hidden native bays, staged work, far grace cleanup, claimed retention and population after travel"); Print("ERR SMOKE COMPLETE: garage-vehicles"); } } #endif