Files
EscapistsReintroduced/docs/evidence/garage-dlc-yards-2026-11-06/native-fixture.c
T
2026-11-06 11:32:33 +01:00

103 lines
4.3 KiB
C

#ifdef WORKBENCH
modded class ERR_GameMode
{
protected ref ERR_GarageDLCProbe m_ERRGarageProbe;
protected override void StartScenario() {}
protected override void EOnInit(IEntity owner)
{
super.EOnInit(owner);
if (SCR_Global.IsEditMode() || !Replication.IsServer()) return;
GetGame().GetCallqueue().CallLater(ERR_BeginGarageProbe, 2000, false);
}
protected void ERR_BeginGarageProbe()
{
m_ERRGarageProbe = new ERR_GarageDLCProbe(this); m_ERRGarageProbe.Begin();
}
}
class ERR_GarageDLCProbe : ERR_GarageVehicles
{
protected Vehicle m_Car;
protected IEntity m_Observer;
protected int m_Index, m_Phase, m_Passed, m_Rally, m_Street;
protected float m_Deadline;
void ERR_GarageDLCProbe(ERR_GameMode mode) { m_Mode = mode; }
protected override bool Running() { return true; }
void Begin()
{
m_Cars.Find();
foreach (ResourceName name : m_Cars.Prefabs)
{
PrintFormat("ERR GARAGE CATALOG: %1", name);
if (ERR_ParkedCarCatalog.Candidate(name, true)) m_Rally++;
else m_Street++;
}
if (m_Rally != 24 || m_Street != 28) { Fail("catalog expected 24 Rally variants and 28 street cars"); return; }
PrintFormat("ERR SMOKE PASS: garage catalog street=%1 rally=%2",m_Street,m_Rally);
GetGame().GetCallqueue().CallLater(CheckCar, 2000, true);
}
void Fail(string reason)
{
Print("ERR SMOKE FAIL: garage-dlc " + reason, LogLevel.ERROR);
GetGame().GetCallqueue().Remove(CheckCar); Stop();
}
void CheckCar()
{
if (m_Car)
{
vector low, high; m_Car.GetBounds(low, high);
array<BaseCompartmentSlot> seats = {}; bool driver, armed;
ERR_ConvoyRules.CollectSeats(m_Car,seats);
foreach (BaseCompartmentSlot seat : seats)
{
if (seat.GetType() == ECompartmentType.PILOT && seat.IsCompartmentAccessible()) driver = true;
if (seat.GetType() == ECompartmentType.TURRET) armed = true;
}
VehicleWheeledSimulation simulation = VehicleWheeledSimulation.Cast(m_Car.FindComponent(VehicleWheeledSimulation));
int wheelCount=-1; if (simulation) wheelCount=simulation.WheelCount();
PrintFormat("ERR GARAGE FIT: prefab=%1 low=%2 high=%3 driver=%4 armed=%5 wheels=%6",m_Car.GetPrefabData().GetPrefabName(),low,high,driver,armed,wheelCount);
if (!driver || armed || !ERR_GarageVehicleRules.Envelope(low, high) || !simulation || simulation.WheelCount()!=4)
{ Fail("native car fit/seat/wheel validation"); return; }
m_Passed++; ERR_Actors.DeleteSpawned(m_Car); m_Car=null;
}
if (m_Index < m_Cars.Prefabs.Count())
{
m_Car=Vehicle.Cast(ERR_Actors.Spawn(m_Cars.Prefabs[m_Index++],ERR_Actors.Ground("4788 0 11528")+"0 0.15 0"));
if (!m_Car) Fail("native car spawn");
return;
}
PrintFormat("ERR SMOKE PASS: all %1 cars have fitting bounds, unarmed accessible driver seats and four wheels",m_Passed);
GetGame().GetCallqueue().Remove(CheckCar);
m_Observer=ERR_Actors.Spawn(ERR_CivilianTraffic.DriverPrefab(),ERR_Actors.Ground("9730 0 1560"));
if (!m_Observer) { Fail("observer spawn"); return; }
m_Requested=2; m_GarageChance=100; m_SpawnRadius=1000; m_CleanupRadius=1400; m_SpawnInterval=1000;
m_Deadline=Now()+180000;
GetGame().GetCallqueue().CallLater(Step,250,true);
}
protected override bool Observers(array<vector> positions,array<IEntity> actors)
{
positions.Clear();actors.Clear();
if (!m_Observer) return false;
positions.Insert(m_Observer.GetOrigin());actors.Insert(m_Observer);return true;
}
protected override bool Remember(IEntity entity)
{
if (!entity.GetPrefabData() || !ERR_GarageVehicleRules.Yard(entity.GetPrefabData().GetPrefabName())) return true;
return super.Remember(entity);
}
protected override void Step()
{
super.Step();
if (Now()>m_Deadline) { Fail("yard placement deadline"); return; }
if (m_Parked.Count()!=2) return;
foreach (ERR_ParkedVehicle parked:m_Parked)
{
vector matrix[4]; parked.Entity.GetWorldTransform(matrix);
if (!parked.Site.Yard || !YardGround(parked.Origin,matrix) || !Clear(parked.Origin,matrix,parked.Entity)) {Fail("yard ground/clearance");return;}
PrintFormat("ERR GARAGE YARD: prefab=%1 position=%2 anchor=%3",parked.Entity.GetPrefabData().GetPrefabName(),parked.Origin,parked.Site.Garage.GetPrefabData().GetPrefabName());
}
Print("ERR SMOKE PASS: two native residential yard spawns retain road/ground/visibility/collision vetoes");
Print("ERR SMOKE COMPLETE: garage-dlc catalog and native yard placement");Stop();
}
}
#endif