using UnityEngine; using SanAndreasUnity.Utilities; using SanAndreasUnity.Behaviours.Vehicles; using SanAndreasUnity.Behaviours.World; using SanAndreasUnity.Importing.Animation; using System.Linq; namespace SanAndreasUnity.Behaviours.Peds.States { public class VehicleEnteringState : BaseVehicleState { Coroutine m_coroutine; bool m_immediate = false; public override void OnBecameActive() { base.OnBecameActive(); if (m_isServer) // clients will do this when vehicle gets assigned this.EnterVehicleInternal(); } public override void OnBecameInactive() { // restore everything m_immediate = false; this.Cleanup(); if (m_coroutine != null) StopCoroutine(m_coroutine); m_coroutine = null; base.OnBecameInactive(); } protected override void OnVehicleAssigned() { this.EnterVehicleInternal(); } public bool TryEnterVehicle(Vehicle vehicle, Vehicle.SeatAlignment seatAlignment, bool immediate = false) { Net.NetStatus.ThrowIfNotOnServer(); if (!this.CanEnterVehicle (vehicle, seatAlignment)) return false; this.EnterVehicle(vehicle, seatAlignment, immediate); return true; } internal void EnterVehicle(Vehicle vehicle, Vehicle.SeatAlignment seatAlignment, bool immediate) { // first assign params this.CurrentVehicle = vehicle; this.CurrentVehicleSeatAlignment = seatAlignment; m_immediate = immediate; // switch state m_ped.SwitchState(); } void EnterVehicleInternal() { Vehicle vehicle = this.CurrentVehicle; Vehicle.Seat seat = this.CurrentVehicleSeat; bool immediate = m_immediate; BaseVehicleState.PreparePedForVehicle(m_ped, vehicle, seat); if (seat.IsDriver) { // TODO: this should be done when ped enters the car - or, it should be removed, because // vehicle should know if it has a driver vehicle.StartControlling(); // if (m_isServer) { // var p = Net.Player.GetOwningPlayer(m_ped); // if (p != null) // Net.NetManager.AssignAuthority(vehicle.gameObject, p); // } } if (!vehicle.IsNightToggled && WorldController.IsNight) vehicle.IsNightToggled = true; else if (vehicle.IsNightToggled && !WorldController.IsNight) vehicle.IsNightToggled = false; m_coroutine = StartCoroutine (EnterVehicleAnimation (seat, immediate)); } private System.Collections.IEnumerator EnterVehicleAnimation(Vehicle.Seat seat, bool immediate) { var animIndex = seat.IsLeftHand ? AnimIndex.GetInLeft : AnimIndex.GetInRight; m_model.VehicleParentOffset = Vector3.Scale(m_model.GetAnim(AnimGroup.Car, animIndex).RootEnd, new Vector3(-1, -1, -1)); if (!immediate) { var animState = m_model.PlayAnim(AnimGroup.Car, animIndex, PlayMode.StopAll); animState.wrapMode = WrapMode.Once; // wait until anim is finished or vehicle is destroyed while (animState != null && animState.enabled && this.CurrentVehicle != null) { yield return new WaitForEndOfFrame(); } } // 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(); yield break; } // ped now completely entered the vehicle // call method from VehicleSittingState - he will switch state if (m_isServer) m_ped.GetStateOrLogError ().EnterVehicle(this.CurrentVehicle, seat); } } }