135 lines
8.9 KiB
C
135 lines
8.9 KiB
C
#ifdef WORKBENCH
|
|
modded class SCR_CharacterControllerComponent
|
|
{
|
|
int ProbePrepare, ProbeApply, ProbeInjected;
|
|
override void OnPrepareControls(IEntity owner, ActionManager am, float dt, bool player)
|
|
{
|
|
ProbePrepare++; super.OnPrepareControls(owner, am, dt, player);
|
|
}
|
|
protected override void OnApplyControls(IEntity owner, float timeSlice)
|
|
{
|
|
ProbeApply++; super.OnApplyControls(owner, timeSlice);
|
|
if (GetInputContext().GetVehicleHandBrake() != EHandBrakeType.HANDBRAKE_RELEASED) ProbeInjected++;
|
|
}
|
|
}
|
|
modded class ERR_GameMode
|
|
{
|
|
protected bool m_BrakeTesting;
|
|
protected int m_BrakeStage;
|
|
override bool Active() { return m_BrakeTesting || super.Active(); }
|
|
protected Vehicle m_BrakeCar;
|
|
protected IEntity m_BrakeDriver, m_BrakePassenger;
|
|
protected BaseCompartmentSlot m_BrakeFront;
|
|
protected override void StartScenario() {}
|
|
protected override void EOnInit(IEntity owner)
|
|
{
|
|
super.EOnInit(owner);
|
|
if (!SCR_Global.IsEditMode()) GetGame().GetCallqueue().CallLater(BrakeProbe, 8000, false);
|
|
}
|
|
void BrakeProbe()
|
|
{
|
|
m_BrakeCar = Vehicle.Cast(ERR_Actors.Spawn("{259EE7B78C51B624}Prefabs/Vehicles/Wheeled/UAZ469/UAZ469.et", ERR_Actors.Ground("9730 0 1560")));
|
|
if (!m_BrakeCar) { Print("ERR SMOKE FAIL: car missing", LogLevel.ERROR); return; }
|
|
CarControllerComponent car = CarControllerComponent.Cast(m_BrakeCar.FindComponent(CarControllerComponent));
|
|
BaseCompartmentManagerComponent manager = BaseCompartmentManagerComponent.Cast(m_BrakeCar.FindComponent(BaseCompartmentManagerComponent));
|
|
array<BaseCompartmentSlot> slots = {}; manager.GetCompartments(slots);
|
|
int fronts;
|
|
if (!car.GetPilotCompartmentSlot())
|
|
{
|
|
foreach (BaseCompartmentSlot candidate : slots)
|
|
if (candidate.GetType() == ECompartmentType.PILOT) car.SetPilotCompartmentSlot(PilotCompartmentSlot.Cast(candidate));
|
|
}
|
|
PrintFormat("ERR BRAKE PILOT: car=%1 pilot=%2 root=%3", car, car.GetPilotCompartmentSlot(), m_BrakeCar.GetRootParent());
|
|
foreach (BaseCompartmentSlot slot : slots)
|
|
{
|
|
bool front = ERR_PassengerHandbrake.FrontSeat(m_BrakeCar, slot);
|
|
PrintFormat("ERR BRAKE SEAT: name=%1 type=%2 position=%3 front=%4", slot.GetCompartmentName(), slot.GetType(), slot.GetPassengerPointInfo().GetWorldTransformAxis(3), front);
|
|
if (front) { fronts++; m_BrakeFront = slot; }
|
|
}
|
|
if (fronts != 1) { Print("ERR SMOKE FAIL: expected one UAZ front passenger", LogLevel.ERROR); return; }
|
|
m_BrakeDriver = ERR_Actors.Spawn(ERR_CivilianTraffic.DriverPrefab(), m_BrakeCar.GetOrigin() + "4 0 0");
|
|
m_BrakePassenger = ERR_Actors.Spawn(ERR_CivilianTraffic.DriverPrefab(), m_BrakeCar.GetOrigin() + "6 0 0");
|
|
CompartmentAccessComponent.Cast(m_BrakeDriver.FindComponent(CompartmentAccessComponent)).GetInVehicle(m_BrakeCar, car.GetPilotCompartmentSlot(), true, -1, ECloseDoorAfterActions.INVALID, false);
|
|
CompartmentAccessComponent.Cast(m_BrakePassenger.FindComponent(CompartmentAccessComponent)).GetInVehicle(m_BrakeCar, m_BrakeFront, true, -1, ECloseDoorAfterActions.INVALID, false);
|
|
GetGame().GetCallqueue().CallLater(BrakeSeated, 3000, false);
|
|
}
|
|
void BrakeSeated()
|
|
{
|
|
if (ERR_PassengerHandbrake.VehicleFor(m_BrakePassenger) != m_BrakeCar || ERR_PassengerHandbrake.VehicleFor(m_BrakeDriver)) { Print("ERR SMOKE FAIL: seat eligibility", LogLevel.ERROR); return; }
|
|
SCR_CharacterControllerComponent passenger = SCR_CharacterControllerComponent.Cast(m_BrakePassenger.FindComponent(SCR_CharacterControllerComponent));
|
|
CarControllerComponent.Cast(m_BrakeCar.FindComponent(CarControllerComponent)).SetPersistentHandBrake(false);
|
|
passenger.ERR_SetPassengerBrake(true);
|
|
if (!ERR_PassengerHandbrake.Requested(m_BrakeDriver)) { Print("ERR SMOKE FAIL: passenger request invisible to driver", LogLevel.ERROR); return; }
|
|
passenger.ERR_SetPassengerBrake(false);
|
|
if (ERR_PassengerHandbrake.Requested(m_BrakeDriver)) { Print("ERR SMOKE FAIL: release stuck", LogLevel.ERROR); return; }
|
|
Print("ERR SMOKE PASS: native UAZ front seat classified; rear and driver excluded; held passenger state and release resolved");
|
|
m_BrakeTesting = true;
|
|
PlayerController local = GetGame().GetPlayerController();
|
|
if (!local || !local.SetControlledEntity(m_BrakeDriver)) { Print("ERR SMOKE FAIL: local driver control", LogLevel.ERROR); return; }
|
|
CarControllerComponent car = CarControllerComponent.Cast(m_BrakeCar.FindComponent(CarControllerComponent));
|
|
car.SetPersistentHandBrake(false);
|
|
GetGame().GetCallqueue().CallLater(BrakeKeep, 100, true);
|
|
GetGame().GetCallqueue().CallLater(BrakeAssertHeld, 1500, false);
|
|
}
|
|
void BrakeKeep()
|
|
{
|
|
SCR_CharacterControllerComponent passenger = SCR_CharacterControllerComponent.Cast(m_BrakePassenger.FindComponent(SCR_CharacterControllerComponent));
|
|
passenger.ERR_SetPassengerBrake(true);
|
|
}
|
|
void BrakeAssertHeld()
|
|
{
|
|
CarControllerComponent car = CarControllerComponent.Cast(m_BrakeCar.FindComponent(CarControllerComponent));
|
|
SCR_CharacterControllerComponent dc = SCR_CharacterControllerComponent.Cast(m_BrakeDriver.FindComponent(SCR_CharacterControllerComponent));
|
|
SCR_CharacterControllerComponent pc = SCR_CharacterControllerComponent.Cast(m_BrakePassenger.FindComponent(SCR_CharacterControllerComponent));
|
|
PrintFormat("ERR BRAKE DIAG: active=%1 request=%2 held=%3 prepare=%4 apply=%5 injected=%6 local=%7 pilot=%8", Active(), ERR_PassengerHandbrake.Requested(m_BrakeDriver), pc.ERR_PassengerBrakeHeld(), dc.ProbePrepare, dc.ProbeApply, dc.ProbeInjected, GetGame().GetPlayerController().GetControlledEntity() == m_BrakeDriver, car.GetPilotCompartmentSlot().GetOccupant() == m_BrakeDriver);
|
|
PrintFormat("ERR BRAKE HELD: handbrake=%1 persistent=%2 input=%3", car.GetHandBrake(), car.GetPersistentHandBrake(), CharacterControllerComponent.Cast(m_BrakeDriver.FindComponent(CharacterControllerComponent)).GetInputContext().GetVehicleHandBrake());
|
|
if (!car.GetHandBrake()) { Print("ERR SMOKE FAIL: native handbrake not applied", LogLevel.ERROR); return; }
|
|
GetGame().GetCallqueue().Remove(BrakeKeep);
|
|
SCR_CharacterControllerComponent.Cast(m_BrakePassenger.FindComponent(SCR_CharacterControllerComponent)).ERR_SetPassengerBrake(false);
|
|
GetGame().GetCallqueue().CallLater(BrakeAssertReleased, 1500, false);
|
|
}
|
|
void BrakeAssertReleased()
|
|
{
|
|
CarControllerComponent car = CarControllerComponent.Cast(m_BrakeCar.FindComponent(CarControllerComponent));
|
|
PrintFormat("ERR BRAKE RELEASED: handbrake=%1 persistent=%2 input=%3", car.GetHandBrake(), car.GetPersistentHandBrake(), CharacterControllerComponent.Cast(m_BrakeDriver.FindComponent(CharacterControllerComponent)).GetInputContext().GetVehicleHandBrake());
|
|
if (car.GetHandBrake() || car.GetPersistentHandBrake()) { Print("ERR SMOKE FAIL: native handbrake not released", LogLevel.ERROR); return; }
|
|
car.SetPersistentHandBrake(true);
|
|
BrakeKeep();
|
|
GetGame().GetCallqueue().CallLater(BrakeAssertPersistent, 500, false);
|
|
}
|
|
void BrakeAssertPersistent()
|
|
{
|
|
SCR_CharacterControllerComponent.Cast(m_BrakePassenger.FindComponent(SCR_CharacterControllerComponent)).ERR_SetPassengerBrake(false);
|
|
CarControllerComponent car = CarControllerComponent.Cast(m_BrakeCar.FindComponent(CarControllerComponent));
|
|
if (!car.GetPersistentHandBrake()) { Print("ERR SMOKE FAIL: driver parking brake cleared", LogLevel.ERROR); return; }
|
|
Print("ERR SMOKE PASS: native driver input applies and releases passenger brake, preserving persistent driver brake");
|
|
car.SetPersistentHandBrake(false);
|
|
BrakeKeep();
|
|
GetGame().GetCallqueue().CallLater(BrakeAssertTimeout, 1800, false);
|
|
}
|
|
void BrakeAssertTimeout()
|
|
{
|
|
SCR_CharacterControllerComponent passenger = SCR_CharacterControllerComponent.Cast(m_BrakePassenger.FindComponent(SCR_CharacterControllerComponent));
|
|
CarControllerComponent car = CarControllerComponent.Cast(m_BrakeCar.FindComponent(CarControllerComponent));
|
|
if (passenger.ERR_PassengerBrakeHeld() || car.GetHandBrake()) { Print("ERR SMOKE FAIL: disconnected input lease stuck", LogLevel.ERROR); return; }
|
|
Print("ERR SMOKE PASS: missing heartbeats expire and release the native brake");
|
|
Vehicle sarka = Vehicle.Cast(ERR_Actors.Spawn("{AD80FB47D868C775}Prefabs/Vehicles/Wheeled/S105/S105_green.et", ERR_Actors.Ground("9740 0 1560"), "75 0 0"));
|
|
if (!sarka) { Print("ERR SMOKE FAIL: S105 missing", LogLevel.ERROR); return; }
|
|
CarControllerComponent sc = CarControllerComponent.Cast(sarka.FindComponent(CarControllerComponent));
|
|
array<BaseCompartmentSlot> slots = {};
|
|
BaseCompartmentManagerComponent.Cast(sarka.FindComponent(BaseCompartmentManagerComponent)).GetCompartments(slots);
|
|
foreach (BaseCompartmentSlot pilot : slots) if (pilot.GetType() == ECompartmentType.PILOT) sc.SetPilotCompartmentSlot(PilotCompartmentSlot.Cast(pilot));
|
|
int fronts;
|
|
foreach (BaseCompartmentSlot slot : slots)
|
|
{
|
|
bool front = ERR_PassengerHandbrake.FrontSeat(sarka, slot);
|
|
if (front) fronts++;
|
|
PrintFormat("ERR BRAKE S105 SEAT: name=%1 front=%2", slot.GetCompartmentName(), front);
|
|
}
|
|
if (fronts != 1) { Print("ERR SMOKE FAIL: rotated S105 front-seat classification", LogLevel.ERROR); return; }
|
|
Print("ERR SMOKE PASS: rotated S105 permits exactly one front passenger");
|
|
Print("ERR SMOKE COMPLETE: passenger-brake");
|
|
}
|
|
}
|
|
#endif
|