2020-05-31 19:07:22 +02:00
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 ; } }
2019-07-11 22:54:48 +02:00
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 ;
2020-05-31 19:07:22 +02:00
2019-05-25 21:50:07 +02:00
public override void OnSwitchedStateByServer ( byte [ ] data )
2019-05-27 02:36:52 +02:00
{
// we need to wait for end of frame, because vehicle may not be spawned yet (which can happen if client
// just connected to server)
this . StartCoroutine ( this . SwitchStateAtEndOfFrame ( data ) ) ;
}
protected void ReadNetworkData ( byte [ ] data )
2019-05-25 21:50:07 +02:00
{
// extract vehicle and seat from data
2019-07-11 22:54:48 +02:00
2019-05-25 21:50:07 +02:00
var reader = new Mirror . NetworkReader ( data ) ;
2019-07-11 22:54:48 +02:00
int magicNumber = reader . ReadInt32 ( ) ;
m_currentVehicleNetId = reader . ReadUInt32 ( ) ;
this . CurrentVehicleSeatAlignment = ( Vehicle . SeatAlignment ) reader . ReadSByte ( ) ;
// assign current vehicle
GameObject vehicleGo = Net . NetManager . GetNetworkObjectById ( m_currentVehicleNetId ) ;
2019-05-25 21:50:07 +02:00
this . CurrentVehicle = vehicleGo ! = null ? vehicleGo . GetComponent < Vehicle > ( ) : null ;
2019-07-11 22:54:48 +02:00
if ( magicNumber ! = 123456789 )
Debug . LogErrorFormat ( "magicNumber {0}, m_currentVehicleNetId {1}, data size {2} - this should not happen" , magicNumber , m_currentVehicleNetId , data . Length ) ;
2019-05-25 21:50:07 +02:00
}
2019-05-25 23:38:12 +02:00
public override byte [ ] GetAdditionalNetworkData ( )
{
var writer = new Mirror . NetworkWriter ( ) ;
2019-07-11 22:54:48 +02:00
writer . Write ( ( int ) 123456789 ) ;
2019-05-25 23:38:12 +02:00
if ( this . CurrentVehicle ! = null ) {
2019-07-11 22:54:48 +02:00
writer . Write ( ( uint ) this . CurrentVehicle . NetTransform . netId ) ;
2019-05-25 23:38:12 +02:00
writer . Write ( ( sbyte ) this . CurrentVehicleSeatAlignment ) ;
} else {
2019-07-11 22:54:48 +02:00
writer . Write ( ( uint ) 0 ) ;
2019-05-25 23:38:12 +02:00
writer . Write ( ( sbyte ) Vehicle . SeatAlignment . None ) ;
}
return writer . ToArray ( ) ;
}
2019-05-27 02:36:52 +02:00
System . Collections . IEnumerator SwitchStateAtEndOfFrame ( byte [ ] data )
{
var oldState = m_ped . CurrentState ;
yield return new WaitForEndOfFrame ( ) ;
2019-05-27 20:27:47 +02:00
if ( oldState ! = m_ped . CurrentState )
2019-05-27 02:36:52 +02:00
{
2019-05-27 20:27:47 +02:00
// 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 : "");
2019-05-27 02:36:52 +02:00
yield break ;
}
2019-05-27 20:27:47 +02:00
// read current vehicle here - it should've been spawned by now
2019-05-27 02:36:52 +02:00
this . ReadNetworkData ( data ) ;
2019-05-27 20:27:47 +02:00
// Debug.LogFormat("Switching to state {0}, vehicle: {1}, seat: {2}", this.GetType().Name, this.CurrentVehicle, this.CurrentVehicleSeat);
2019-05-27 02:36:52 +02:00
// now we can enter this state
m_ped . SwitchState ( this . GetType ( ) ) ;
}
2019-04-29 01:15:24 +02:00
protected void Cleanup ( )
{
if ( ! m_ped . IsInVehicle )
{
m_ped . characterController . enabled = true ;
m_ped . transform . SetParent ( null , true ) ;
m_model . IsInVehicle = false ;
2019-05-25 00:28:09 +02:00
// enable network transform
2019-05-06 02:00:53 +02:00
if ( m_ped . NetTransform ! = null )
2019-05-25 00:28:09 +02:00
m_ped . NetTransform . enabled = true ;
2019-04-29 01:15:24 +02:00
}
2019-04-29 02:04:45 +02:00
2019-04-29 02:06:44 +02:00
if ( this . CurrentVehicleSeat ! = null & & this . CurrentVehicleSeat . OccupyingPed = = m_ped )
2019-04-29 02:04:45 +02:00
this . CurrentVehicleSeat . OccupyingPed = null ;
this . CurrentVehicle = null ;
2019-07-11 22:54:48 +02:00
this . CurrentVehicleSeatAlignment = Vehicle . SeatAlignment . None ;
2019-04-29 01:15:24 +02:00
}
2020-05-31 19:07:22 +02:00
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 ;
2019-05-27 20:27:47 +02:00
// this should be removed
2020-05-31 19:07:22 +02:00
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 ;
}
}
}