mirror of
https://github.com/GTA-ASM/SanAndreasUnity
synced 2024-11-27 14:30:17 +00:00
244 lines
6.3 KiB
C#
244 lines
6.3 KiB
C#
using UnityEngine;
|
|
using SanAndreasUnity.Utilities;
|
|
using SanAndreasUnity.Behaviours.Vehicles;
|
|
|
|
namespace SanAndreasUnity.Behaviours.Peds.States
|
|
{
|
|
|
|
public class BaseVehicleState : BaseScriptState, IVehicleState
|
|
{
|
|
private Vehicle m_currentVehicle;
|
|
public Vehicle CurrentVehicle { get { return m_currentVehicle; } protected set { m_currentVehicle = value; } }
|
|
|
|
public Vehicle.Seat CurrentVehicleSeat { get => this.CurrentVehicle != null ? this.CurrentVehicle.GetSeat(this.CurrentVehicleSeatAlignment) : null; }
|
|
public Vehicle.SeatAlignment CurrentVehicleSeatAlignment { get; protected set; }
|
|
|
|
protected uint m_currentVehicleNetId = 0;
|
|
|
|
|
|
|
|
public override void OnSwitchedStateByServer(byte[] data)
|
|
{
|
|
// we need to wait for end of frame, because vehicle may not be spawned yet
|
|
//this.StartCoroutine(this.SwitchStateAtEndOfFrame(data));
|
|
|
|
|
|
// check if this state was already activated
|
|
// it can happen when, among other things, syncvar hooks get invoked twice when creating the ped
|
|
if (this.IsActiveState)
|
|
return;
|
|
|
|
this.ReadNetworkData(data);
|
|
|
|
m_ped.SwitchState(this.GetType());
|
|
|
|
if (this.CurrentVehicle != null)
|
|
this.OnVehicleAssigned();
|
|
|
|
}
|
|
|
|
protected void ReadNetworkData(byte[] data)
|
|
{
|
|
var reader = new Mirror.NetworkReader(data);
|
|
this.ReadNetworkData(reader);
|
|
}
|
|
|
|
protected virtual void ReadNetworkData(Mirror.NetworkReader reader)
|
|
{
|
|
// first reset params
|
|
this.CurrentVehicle = null;
|
|
this.CurrentVehicleSeatAlignment = Vehicle.SeatAlignment.None;
|
|
m_currentVehicleNetId = 0;
|
|
|
|
// extract vehicle and seat from data
|
|
|
|
int magicNumber = reader.ReadInt32();
|
|
m_currentVehicleNetId = reader.ReadUInt32();
|
|
this.CurrentVehicleSeatAlignment = (Vehicle.SeatAlignment) reader.ReadSByte();
|
|
|
|
// assign current vehicle
|
|
GameObject vehicleGo = Net.NetManager.GetNetworkObjectById(m_currentVehicleNetId);
|
|
this.CurrentVehicle = vehicleGo != null ? vehicleGo.GetComponent<Vehicle>() : null;
|
|
|
|
if (magicNumber != 123456789)
|
|
Debug.LogErrorFormat("magicNumber {0}, m_currentVehicleNetId {1}, data size {2} - this should not happen", magicNumber, m_currentVehicleNetId, reader.Length);
|
|
|
|
}
|
|
|
|
public override byte[] GetAdditionalNetworkData()
|
|
{
|
|
var writer = new Mirror.NetworkWriter();
|
|
this.GetAdditionalNetworkData(writer);
|
|
return writer.ToArray();
|
|
}
|
|
|
|
protected virtual void GetAdditionalNetworkData(Mirror.NetworkWriter writer)
|
|
{
|
|
writer.Write((int)123456789);
|
|
if (this.CurrentVehicle != null) {
|
|
writer.Write((uint)this.CurrentVehicle.NetTransform.netId);
|
|
writer.Write((sbyte)this.CurrentVehicleSeatAlignment);
|
|
} else {
|
|
writer.Write((uint)0);
|
|
writer.Write((sbyte)Vehicle.SeatAlignment.None);
|
|
}
|
|
}
|
|
|
|
System.Collections.IEnumerator SwitchStateAtEndOfFrame(byte[] data)
|
|
{
|
|
var oldState = m_ped.CurrentState;
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
if (oldState != m_ped.CurrentState)
|
|
{
|
|
// state changed in the meantime
|
|
// did server change it ? or syncvar hooks invoked twice ? either way, we should stop here
|
|
|
|
// Debug.LogFormat("state changed in the meantime, old: {0}, new: {1}", oldState != null ? oldState.GetType().Name : "",
|
|
// m_ped.CurrentState != null ? m_ped.CurrentState.GetType().Name : "");
|
|
yield break;
|
|
}
|
|
|
|
// read current vehicle here - it should've been spawned by now
|
|
this.ReadNetworkData(data);
|
|
|
|
// Debug.LogFormat("Switching to state {0}, vehicle: {1}, seat: {2}", this.GetType().Name, this.CurrentVehicle, this.CurrentVehicleSeat);
|
|
|
|
// now we can enter this state
|
|
m_ped.SwitchState(this.GetType());
|
|
}
|
|
|
|
protected virtual void OnVehicleAssigned()
|
|
{
|
|
|
|
}
|
|
|
|
public static void PreparePedForVehicle(Ped ped, Vehicle vehicle, Vehicle.Seat seat)
|
|
{
|
|
|
|
seat.OccupyingPed = ped;
|
|
|
|
ped.characterController.enabled = false;
|
|
|
|
|
|
ped.transform.SetParent(seat.Parent);
|
|
ped.transform.localPosition = Vector3.zero;
|
|
ped.transform.localRotation = Quaternion.identity;
|
|
|
|
ped.PlayerModel.IsInVehicle = true;
|
|
|
|
if (!VehicleManager.Instance.syncPedTransformWhileInVehicle) {
|
|
if (ped.NetTransform != null)
|
|
ped.NetTransform.enabled = false;
|
|
}
|
|
|
|
F.RunExceptionSafe( () => vehicle.OnPedPreparedForVehicle(ped, seat) );
|
|
|
|
}
|
|
|
|
protected void Cleanup()
|
|
{
|
|
if (!m_ped.IsInVehicle)
|
|
{
|
|
m_ped.characterController.enabled = true;
|
|
m_ped.transform.SetParent(null, true);
|
|
m_model.IsInVehicle = false;
|
|
// enable network transform
|
|
if (m_ped.NetTransform != null)
|
|
m_ped.NetTransform.enabled = true;
|
|
if (this.CurrentVehicle != null)
|
|
F.RunExceptionSafe( () => this.CurrentVehicle.OnPedRemovedFromVehicle(m_ped, this.CurrentVehicleSeat) );
|
|
}
|
|
|
|
if (this.CurrentVehicleSeat != null && this.CurrentVehicleSeat.OccupyingPed == m_ped)
|
|
this.CurrentVehicleSeat.OccupyingPed = null;
|
|
|
|
this.CurrentVehicle = null;
|
|
this.CurrentVehicleSeatAlignment = Vehicle.SeatAlignment.None;
|
|
m_currentVehicleNetId = 0;
|
|
|
|
}
|
|
|
|
|
|
public override void UpdateState()
|
|
{
|
|
base.UpdateState();
|
|
|
|
if (!this.IsActiveState)
|
|
return;
|
|
|
|
if (Net.NetStatus.IsClientOnly)
|
|
{
|
|
if (null == this.CurrentVehicle)
|
|
{
|
|
// check if vehicle was spawned in the meantime
|
|
GameObject vehicleGo = Net.NetManager.GetNetworkObjectById(m_currentVehicleNetId);
|
|
if (vehicleGo != null)
|
|
{
|
|
// vehicle is spawned
|
|
this.CurrentVehicle = vehicleGo.GetComponent<Vehicle>();
|
|
this.OnVehicleAssigned();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
protected override void UpdateHeading()
|
|
{
|
|
|
|
}
|
|
|
|
protected override void UpdateRotation()
|
|
{
|
|
|
|
}
|
|
|
|
protected override void UpdateMovement()
|
|
{
|
|
|
|
}
|
|
|
|
protected override void ConstrainRotation ()
|
|
{
|
|
|
|
}
|
|
|
|
public bool CanEnterVehicle (Vehicle vehicle, Vehicle.SeatAlignment seatAlignment)
|
|
{
|
|
if (m_ped.IsInVehicle)
|
|
return false;
|
|
|
|
// this should be removed
|
|
if (m_ped.IsAiming || m_ped.WeaponHolder.IsFiring)
|
|
return false;
|
|
|
|
var seat = vehicle.GetSeat (seatAlignment);
|
|
if (null == seat)
|
|
return false;
|
|
|
|
// check if specified seat is taken
|
|
if (seat.IsTaken)
|
|
return false;
|
|
|
|
// everything is ok, we can enter vehicle
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void KillPed()
|
|
{
|
|
if (m_ped.CurrentVehicle != null && m_ped.CurrentVehicle.ExplodedThisFrame)
|
|
{
|
|
base.KillPed();
|
|
return;
|
|
}
|
|
|
|
// don't detach ragdoll, because it will collide with vehicle and vehicle will fly away
|
|
Object.Destroy(m_ped.gameObject);
|
|
}
|
|
|
|
}
|
|
|
|
}
|