2020-05-31 17:07:22 +00:00
|
|
|
using UnityEngine;
|
|
|
|
using SanAndreasUnity.Utilities;
|
|
|
|
using SanAndreasUnity.Behaviours.Vehicles;
|
|
|
|
using SanAndreasUnity.Behaviours.World;
|
|
|
|
using SanAndreasUnity.Importing.Animation;
|
2019-04-28 22:02:46 +00:00
|
|
|
using System.Linq;
|
2020-05-31 17:07:22 +00:00
|
|
|
|
|
|
|
namespace SanAndreasUnity.Behaviours.Peds.States
|
|
|
|
{
|
|
|
|
|
|
|
|
public class VehicleEnteringState : BaseVehicleState
|
|
|
|
{
|
2019-04-28 21:33:47 +00:00
|
|
|
Coroutine m_coroutine;
|
|
|
|
|
2020-05-31 17:07:22 +00:00
|
|
|
|
2019-04-28 20:57:04 +00:00
|
|
|
public override void OnBecameInactive()
|
|
|
|
{
|
|
|
|
// restore everything
|
|
|
|
|
2019-04-28 23:15:24 +00:00
|
|
|
this.Cleanup();
|
2019-04-28 20:57:04 +00:00
|
|
|
|
2019-04-28 21:33:47 +00:00
|
|
|
if (m_coroutine != null)
|
|
|
|
StopCoroutine(m_coroutine);
|
|
|
|
m_coroutine = null;
|
|
|
|
|
|
|
|
base.OnBecameInactive();
|
2020-05-31 17:07:22 +00:00
|
|
|
}
|
|
|
|
|
2019-04-29 00:26:44 +00:00
|
|
|
public static void PreparePedForVehicle(Ped ped, Vehicle vehicle, Vehicle.Seat seat)
|
2019-04-28 23:46:13 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2019-05-06 00:00:53 +00:00
|
|
|
if (!VehicleManager.Instance.syncPedTransformWhileInVehicle) {
|
|
|
|
if (ped.NetTransform != null)
|
|
|
|
ped.NetTransform.syncInterval = 0;
|
|
|
|
}
|
|
|
|
|
2019-04-28 23:46:13 +00:00
|
|
|
}
|
|
|
|
|
2020-05-31 17:07:22 +00:00
|
|
|
public bool TryEnterVehicle(Vehicle vehicle, Vehicle.SeatAlignment seatAlignment, bool immediate = false)
|
|
|
|
{
|
2019-04-28 20:17:37 +00:00
|
|
|
Net.NetStatus.ThrowIfNotOnServer();
|
|
|
|
|
2020-05-31 17:07:22 +00:00
|
|
|
if (!this.CanEnterVehicle (vehicle, seatAlignment))
|
|
|
|
return false;
|
2019-04-28 21:36:40 +00:00
|
|
|
|
|
|
|
this.EnterVehicle(vehicle, seatAlignment, immediate);
|
2020-05-31 17:07:22 +00:00
|
|
|
|
2019-04-28 21:36:40 +00:00
|
|
|
return true;
|
|
|
|
}
|
2020-05-31 17:07:22 +00:00
|
|
|
|
2019-04-28 22:22:41 +00:00
|
|
|
internal void EnterVehicle(Vehicle vehicle, Vehicle.SeatAlignment seatAlignment, bool immediate)
|
2019-04-28 21:36:40 +00:00
|
|
|
{
|
|
|
|
|
2020-05-31 17:07:22 +00:00
|
|
|
Vehicle.Seat seat = vehicle.GetSeat (seatAlignment);
|
|
|
|
|
|
|
|
// switch state here
|
|
|
|
m_ped.SwitchState<VehicleEnteringState>();
|
|
|
|
|
|
|
|
this.CurrentVehicle = vehicle;
|
|
|
|
this.CurrentVehicleSeat = seat;
|
2019-04-28 23:46:13 +00:00
|
|
|
|
2019-04-29 00:26:44 +00:00
|
|
|
PreparePedForVehicle(m_ped, vehicle, seat);
|
2020-05-31 17:07:22 +00:00
|
|
|
|
2019-04-28 20:57:04 +00:00
|
|
|
if (seat.IsDriver)
|
2020-05-31 17:07:22 +00:00
|
|
|
{
|
2019-04-29 15:24:08 +00:00
|
|
|
// TODO: this should be done when ped enters the car - or, it should be removed, because
|
|
|
|
// vehicle should know if it has a driver
|
2020-05-31 17:07:22 +00:00
|
|
|
vehicle.StartControlling();
|
2019-05-05 21:12:42 +00:00
|
|
|
|
|
|
|
if (m_isServer) {
|
|
|
|
var p = Net.Player.GetOwningPlayer(m_ped);
|
|
|
|
if (p != null)
|
|
|
|
Net.NetManager.AssignAuthority(vehicle.gameObject, p);
|
|
|
|
}
|
2020-05-31 17:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!vehicle.IsNightToggled && WorldController.IsNight)
|
|
|
|
vehicle.IsNightToggled = true;
|
|
|
|
else if (vehicle.IsNightToggled && !WorldController.IsNight)
|
|
|
|
vehicle.IsNightToggled = false;
|
|
|
|
|
|
|
|
|
2019-04-28 21:17:50 +00:00
|
|
|
// send message to clients
|
2019-04-28 22:02:46 +00:00
|
|
|
if (m_isServer)
|
|
|
|
{
|
|
|
|
if (!immediate)
|
|
|
|
{
|
|
|
|
foreach(var pedSync in Net.Player.AllPlayers.Select(p => p.GetComponent<Net.PedSync>()))
|
|
|
|
pedSync.PedStartedEnteringVehicle(m_ped);
|
|
|
|
}
|
|
|
|
}
|
2019-04-28 21:17:50 +00:00
|
|
|
|
|
|
|
|
2019-04-28 21:33:47 +00:00
|
|
|
m_coroutine = StartCoroutine (EnterVehicleAnimation (seat, immediate));
|
2020-05-31 17:07:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private System.Collections.IEnumerator EnterVehicleAnimation(Vehicle.Seat seat, bool immediate)
|
|
|
|
{
|
|
|
|
var animIndex = seat.IsLeftHand ? AnimIndex.GetInLeft : AnimIndex.GetInRight;
|
|
|
|
|
2019-04-28 20:26:12 +00:00
|
|
|
m_model.VehicleParentOffset = Vector3.Scale(m_model.GetAnim(AnimGroup.Car, animIndex).RootEnd, new Vector3(-1, -1, -1));
|
2020-05-31 17:07:22 +00:00
|
|
|
|
|
|
|
if (!immediate)
|
|
|
|
{
|
2019-04-28 20:26:12 +00:00
|
|
|
var animState = m_model.PlayAnim(AnimGroup.Car, animIndex, PlayMode.StopAll);
|
2020-05-31 17:07:22 +00:00
|
|
|
animState.wrapMode = WrapMode.Once;
|
|
|
|
|
2019-04-29 15:52:03 +00:00
|
|
|
// wait until anim is finished or vehicle is destroyed
|
|
|
|
while (animState.enabled && this.CurrentVehicle != null)
|
2020-05-31 17:07:22 +00:00
|
|
|
{
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-29 15:52:03 +00:00
|
|
|
// check if vehicle is alive
|
|
|
|
if (null == this.CurrentVehicle)
|
|
|
|
{
|
|
|
|
// vehicle destroyed in the meantime ? hmm... ped is a child of vehicle, so it should be
|
|
|
|
// destroyed as well ?
|
|
|
|
// anyway, switch to stand state
|
|
|
|
if (m_isServer)
|
|
|
|
m_ped.SwitchState<StandState>();
|
|
|
|
yield break;
|
|
|
|
}
|
2020-05-31 17:07:22 +00:00
|
|
|
|
|
|
|
|
2019-04-28 20:26:12 +00:00
|
|
|
// ped now completely entered the vehicle
|
2020-05-31 17:07:22 +00:00
|
|
|
|
2019-04-28 20:26:12 +00:00
|
|
|
// call method from VehicleSittingState - he will switch state
|
2019-04-28 22:02:46 +00:00
|
|
|
if (m_isServer)
|
|
|
|
m_ped.GetStateOrLogError<VehicleSittingState> ().EnterVehicle(this.CurrentVehicle, seat);
|
2020-05-31 17:07:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|