85 lines
3.6 KiB
C#
85 lines
3.6 KiB
C#
using System.Collections;
|
|
using NitroxClient.Communication.Packets.Processors.Abstract;
|
|
using NitroxClient.GameLogic;
|
|
using NitroxClient.MonoBehaviours;
|
|
using NitroxClient.MonoBehaviours.Vehicles;
|
|
using NitroxClient.Unity.Helper;
|
|
using NitroxModel.DataStructures;
|
|
using NitroxModel.Packets;
|
|
using UnityEngine;
|
|
|
|
namespace NitroxClient.Communication.Packets.Processors;
|
|
|
|
public class VehicleDockingProcessor : ClientPacketProcessor<VehicleDocking>
|
|
{
|
|
private readonly Vehicles vehicles;
|
|
|
|
public VehicleDockingProcessor(Vehicles vehicles)
|
|
{
|
|
this.vehicles = vehicles;
|
|
}
|
|
|
|
public override void Process(VehicleDocking packet)
|
|
{
|
|
if (!NitroxEntity.TryGetComponentFrom(packet.VehicleId, out Vehicle vehicle))
|
|
{
|
|
Log.Error($"[{nameof(VehicleDockingProcessor)}] could not find Vehicle component on {packet.VehicleId}");
|
|
return;
|
|
}
|
|
|
|
if (!NitroxEntity.TryGetComponentFrom(packet.DockId, out VehicleDockingBay dockingBay))
|
|
{
|
|
Log.Error($"[{nameof(VehicleDockingProcessor)}] could not find VehicleDockingBay component on {packet.DockId}");
|
|
return;
|
|
}
|
|
|
|
if (vehicle.TryGetComponent(out VehicleMovementReplicator vehicleMovementReplicator))
|
|
{
|
|
vehicleMovementReplicator.enabled = false;
|
|
Log.Debug($"[{nameof(VehicleDockingProcessor)}] Disabled VehicleMovementReplicator on {packet.VehicleId}");
|
|
}
|
|
|
|
vehicle.StartCoroutine(DelayAnimationAndDisablePiloting(vehicle, vehicleMovementReplicator, dockingBay, packet.VehicleId, packet.PlayerId));
|
|
}
|
|
|
|
private IEnumerator DelayAnimationAndDisablePiloting(Vehicle vehicle, VehicleMovementReplicator vehicleMovementReplicator, VehicleDockingBay vehicleDockingBay, NitroxId vehicleId, ushort playerId)
|
|
{
|
|
// Consider the vehicle movement latency (we don't teleport the vehicle to the docking position)
|
|
if (vehicleMovementReplicator)
|
|
{
|
|
// NB: We don't have a lifetime ahead of us
|
|
float waitTime = Mathf.Clamp(vehicleMovementReplicator.maxAllowedLatency, 0f, 2f);
|
|
yield return new WaitForSeconds(waitTime);
|
|
}
|
|
else
|
|
{
|
|
yield return Yielders.WaitFor1Second;
|
|
}
|
|
|
|
// DockVehicle sets the rigid body kinematic of the vehicle to true, we don't want that behaviour
|
|
// Therefore disable kinematic (again) to remove the bouncing behavior
|
|
DockRemoteVehicle(vehicleDockingBay, vehicle);
|
|
vehicle.useRigidbody.isKinematic = false;
|
|
|
|
yield return Yielders.WaitFor2Seconds;
|
|
vehicles.SetOnPilotMode(vehicleId, playerId, false);
|
|
}
|
|
|
|
/// Copy of <see cref="VehicleDockingBay.DockVehicle"/> without the player centric bits
|
|
private void DockRemoteVehicle(VehicleDockingBay bay, Vehicle vehicle)
|
|
{
|
|
bay.dockedVehicle = vehicle;
|
|
LargeWorldStreamer.main.cellManager.UnregisterEntity(bay.dockedVehicle.gameObject);
|
|
bay.dockedVehicle.transform.parent = bay.GetSubRoot().transform;
|
|
vehicle.docked = true;
|
|
bay.vehicle_docked_param = true;
|
|
SkyEnvironmentChanged.Broadcast(vehicle.gameObject, bay.subRoot);
|
|
bay.GetSubRoot().BroadcastMessage("UnlockDoors", SendMessageOptions.DontRequireReceiver);
|
|
|
|
// We are only actually adding the health if we have a lock on the vehicle so we're fine to keep this routine going on.
|
|
// If vehicle ownership changes then it'll still be fine because the verification will still be on the vehicle ownership.
|
|
bay.CancelInvoke(nameof(VehicleDockingBay.RepairVehicle));
|
|
bay.InvokeRepeating(nameof(VehicleDockingBay.RepairVehicle), 0.0f, 5f);
|
|
}
|
|
}
|