r2mods/ilspy_dump/ror2_csproj/RoR2/VehicleSeat.cs

583 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using EntityStates;
using RoR2.ConVar;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Serialization;
namespace RoR2;
[DisallowMultipleComponent]
public class VehicleSeat : NetworkBehaviour, IInteractable
{
private struct PassengerInfo
{
private static readonly List<EntityStateMachine> sharedBuffer = new List<EntityStateMachine>();
public readonly Transform transform;
public readonly CharacterBody body;
public readonly InputBankTest inputBank;
public readonly InteractionDriver interactionDriver;
public readonly CharacterMotor characterMotor;
public readonly EntityStateMachine bodyStateMachine;
public readonly CharacterModel characterModel;
public readonly NetworkIdentity networkIdentity;
public readonly Collider collider;
public bool hasEffectiveAuthority => Util.HasEffectiveAuthority(networkIdentity);
public PassengerInfo(GameObject passengerBodyObject)
{
transform = passengerBodyObject.transform;
body = passengerBodyObject.GetComponent<CharacterBody>();
inputBank = passengerBodyObject.GetComponent<InputBankTest>();
interactionDriver = passengerBodyObject.GetComponent<InteractionDriver>();
characterMotor = passengerBodyObject.GetComponent<CharacterMotor>();
networkIdentity = passengerBodyObject.GetComponent<NetworkIdentity>();
collider = passengerBodyObject.GetComponent<Collider>();
bodyStateMachine = null;
passengerBodyObject.GetComponents(sharedBuffer);
for (int i = 0; i < sharedBuffer.Count; i++)
{
EntityStateMachine entityStateMachine = sharedBuffer[i];
if (string.CompareOrdinal(entityStateMachine.customName, "Body") == 0)
{
bodyStateMachine = entityStateMachine;
break;
}
}
sharedBuffer.Clear();
characterModel = null;
if ((bool)body.modelLocator && (bool)body.modelLocator.modelTransform)
{
characterModel = body.modelLocator.modelTransform.GetComponent<CharacterModel>();
}
}
public string GetString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("transform=").Append(transform).AppendLine();
stringBuilder.Append("body=").Append(body).AppendLine();
stringBuilder.Append("inputBank=").Append(inputBank).AppendLine();
stringBuilder.Append("interactionDriver=").Append(interactionDriver).AppendLine();
stringBuilder.Append("characterMotor=").Append(characterMotor).AppendLine();
stringBuilder.Append("bodyStateMachine=").Append(bodyStateMachine).AppendLine();
stringBuilder.Append("characterModel=").Append(characterModel).AppendLine();
stringBuilder.Append("networkIdentity=").Append(networkIdentity).AppendLine();
stringBuilder.Append("hasEffectiveAuthority=").Append(hasEffectiveAuthority).AppendLine();
return stringBuilder.ToString();
}
}
public delegate void InteractabilityCheckDelegate(CharacterBody activator, ref Interactability? resultOverride);
public SerializableEntityStateType passengerState;
public Transform seatPosition;
public Transform exitPosition;
public bool ejectOnCollision;
public bool hidePassenger = true;
public float exitVelocityFraction = 1f;
public UnityEvent onPassengerEnterUnityEvent;
[FormerlySerializedAs("OnPassengerExitUnityEvent")]
public UnityEvent onPassengerExitUnityEvent;
public string enterVehicleContextString;
public string exitVehicleContextString;
public bool disablePassengerMotor;
public bool isEquipmentActivationAllowed;
public bool shouldProximityHighlight = true;
[SyncVar(hook = "SetPassenger")]
private GameObject passengerBodyObject;
private PassengerInfo passengerInfo;
private Rigidbody rigidbody;
private Collider collider;
[HideInInspector]
public CameraTargetParams targetParams;
public CallbackCheck<Interactability, CharacterBody> enterVehicleAllowedCheck = new CallbackCheck<Interactability, CharacterBody>();
public CallbackCheck<Interactability, CharacterBody> exitVehicleAllowedCheck = new CallbackCheck<Interactability, CharacterBody>();
public CallbackCheck<bool, GameObject> handleVehicleEnterRequestServer = new CallbackCheck<bool, GameObject>();
public CallbackCheck<bool, GameObject> handleVehicleExitRequestServer = new CallbackCheck<bool, GameObject>();
private static readonly BoolConVar cvVehicleSeatDebug;
private Run.FixedTimeStamp passengerAssignmentTime = Run.FixedTimeStamp.negativeInfinity;
private readonly float passengerAssignmentCooldown = 0.2f;
private NetworkInstanceId ___passengerBodyObjectNetId;
private static int kCmdCmdEjectPassenger;
public CharacterBody currentPassengerBody => passengerInfo.body;
public InputBankTest currentPassengerInputBank => passengerInfo.inputBank;
private static bool shouldLog => cvVehicleSeatDebug.value;
public bool hasPassenger => passengerBodyObject;
public GameObject NetworkpassengerBodyObject
{
get
{
return passengerBodyObject;
}
[param: In]
set
{
if (NetworkServer.localClientActive && !base.syncVarHookGuard)
{
base.syncVarHookGuard = true;
SetPassenger(value);
base.syncVarHookGuard = false;
}
SetSyncVarGameObject(value, ref passengerBodyObject, 1u, ref ___passengerBodyObjectNetId);
}
}
public event Action<GameObject> onPassengerEnter;
public event Action<GameObject> onPassengerExit;
public static event Action<VehicleSeat, GameObject> onPassengerEnterGlobal;
public static event Action<VehicleSeat, GameObject> onPassengerExitGlobal;
public string GetContextString(Interactor activator)
{
if (!passengerBodyObject)
{
return Language.GetString(enterVehicleContextString);
}
if ((object)passengerBodyObject == activator.gameObject)
{
return Language.GetString(exitVehicleContextString);
}
return null;
}
public Interactability GetInteractability(Interactor activator)
{
CharacterBody component = activator.GetComponent<CharacterBody>();
if (!passengerBodyObject)
{
return enterVehicleAllowedCheck.Evaluate(component) ?? Interactability.Available;
}
if ((object)passengerBodyObject == activator.gameObject && passengerAssignmentTime.timeSince >= passengerAssignmentCooldown)
{
return exitVehicleAllowedCheck.Evaluate(component) ?? Interactability.Available;
}
if ((bool)component && (bool)component.currentVehicle && (object)component.currentVehicle != this)
{
return Interactability.ConditionsNotMet;
}
return Interactability.Disabled;
}
public void OnInteractionBegin(Interactor activator)
{
if (!passengerBodyObject)
{
if (!handleVehicleEnterRequestServer.Evaluate(activator.gameObject).HasValue)
{
SetPassenger(activator.gameObject);
}
}
else if ((object)activator.gameObject == passengerBodyObject && !handleVehicleExitRequestServer.Evaluate(activator.gameObject).HasValue)
{
SetPassenger(null);
}
}
public bool ShouldIgnoreSpherecastForInteractibility(Interactor activator)
{
return false;
}
public bool ShouldShowOnScanner()
{
return true;
}
public bool ShouldProximityHighlight()
{
return shouldProximityHighlight;
}
private void Awake()
{
rigidbody = GetComponent<Rigidbody>();
collider = GetComponent<Collider>();
targetParams = GetComponent<CameraTargetParams>();
}
public override void OnStartClient()
{
base.OnStartClient();
if (!NetworkServer.active && (bool)passengerBodyObject)
{
OnPassengerEnter(passengerBodyObject);
}
}
private void SetPassengerInternal(GameObject newPassengerBodyObject)
{
if ((bool)passengerBodyObject)
{
OnPassengerExit(passengerBodyObject);
}
NetworkpassengerBodyObject = newPassengerBodyObject;
passengerInfo = default(PassengerInfo);
passengerAssignmentTime = Run.FixedTimeStamp.now;
if ((bool)passengerBodyObject)
{
OnPassengerEnter(passengerBodyObject);
}
_ = shouldLog;
}
private void SetPassenger(GameObject newPassengerBodyObject)
{
string text = (newPassengerBodyObject ? Util.GetBestBodyName(newPassengerBodyObject) : "null");
if (shouldLog)
{
Debug.LogFormat("SetPassenger passenger={0}", text);
}
if (base.syncVarHookGuard)
{
_ = shouldLog;
NetworkpassengerBodyObject = newPassengerBodyObject;
return;
}
_ = shouldLog;
if ((object)passengerBodyObject == newPassengerBodyObject)
{
_ = shouldLog;
return;
}
_ = shouldLog;
SetPassengerInternal(newPassengerBodyObject);
}
private void OnPassengerMovementHit(ref CharacterMotor.MovementHitInfo movementHitInfo)
{
if (NetworkServer.active && ejectOnCollision && passengerAssignmentTime.timeSince > Time.fixedDeltaTime)
{
SetPassenger(null);
}
}
private void ForcePassengerState()
{
if ((bool)passengerInfo.bodyStateMachine && passengerInfo.hasEffectiveAuthority)
{
Type type = passengerState.GetType();
if (passengerInfo.bodyStateMachine.state.GetType() != type)
{
passengerInfo.bodyStateMachine.SetInterruptState(EntityStateCatalog.InstantiateState(ref passengerState), InterruptPriority.Vehicle);
}
}
}
private void FixedUpdate()
{
ForcePassengerState();
UpdatePassengerPosition();
if ((bool)passengerInfo.characterMotor)
{
passengerInfo.characterMotor.velocity = Vector3.zero;
}
}
private void UpdatePassengerPosition()
{
Vector3 position = seatPosition.position;
if ((bool)passengerInfo.characterMotor)
{
passengerInfo.characterMotor.velocity = Vector3.zero;
passengerInfo.characterMotor.Motor.BaseVelocity = Vector3.zero;
passengerInfo.characterMotor.Motor.SetPosition(position);
if (!disablePassengerMotor && Time.inFixedTimeStep)
{
passengerInfo.characterMotor.rootMotion = position - passengerInfo.transform.position;
}
}
else if ((bool)passengerInfo.transform)
{
passengerInfo.transform.position = position;
}
}
[Server]
public bool AssignPassenger(GameObject bodyObject)
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Boolean RoR2.VehicleSeat::AssignPassenger(UnityEngine.GameObject)' called on client");
return false;
}
if ((bool)passengerBodyObject)
{
return false;
}
if ((bool)bodyObject)
{
CharacterBody component = bodyObject.GetComponent<CharacterBody>();
if ((bool)component && (bool)component.currentVehicle)
{
component.currentVehicle.EjectPassenger(bodyObject);
}
}
SetPassenger(bodyObject);
return true;
}
[Server]
public void EjectPassenger(GameObject bodyObject)
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.VehicleSeat::EjectPassenger(UnityEngine.GameObject)' called on client");
}
else if ((object)bodyObject == passengerBodyObject)
{
SetPassenger(null);
}
}
[Server]
public void EjectPassenger()
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.VehicleSeat::EjectPassenger()' called on client");
}
else
{
SetPassenger(null);
}
}
[Command]
public void CmdEjectPassenger()
{
SetPassenger(null);
}
private void OnDestroy()
{
SetPassenger(null);
}
private void OnPassengerEnter(GameObject passenger)
{
passengerInfo = new PassengerInfo(passengerBodyObject);
if ((bool)passengerInfo.body)
{
passengerInfo.body.currentVehicle = this;
}
if (hidePassenger && (bool)passengerInfo.characterModel)
{
passengerInfo.characterModel.invisibilityCount++;
}
ForcePassengerState();
if ((bool)passengerInfo.characterMotor)
{
if (disablePassengerMotor)
{
passengerInfo.characterMotor.enabled = false;
}
else
{
passengerInfo.characterMotor.onMovementHit += OnPassengerMovementHit;
}
}
if ((bool)passengerInfo.collider && (bool)collider)
{
Physics.IgnoreCollision(collider, passengerInfo.collider, ignore: true);
}
if ((bool)passengerInfo.interactionDriver)
{
passengerInfo.interactionDriver.interactableOverride = base.gameObject;
}
_ = shouldLog;
this.onPassengerEnter?.Invoke(passengerBodyObject);
onPassengerEnterUnityEvent?.Invoke();
VehicleSeat.onPassengerEnterGlobal?.Invoke(this, passengerBodyObject);
}
private void OnPassengerExit(GameObject passenger)
{
_ = shouldLog;
if (hidePassenger && (bool)passengerInfo.characterModel)
{
passengerInfo.characterModel.invisibilityCount--;
}
if ((bool)passengerInfo.body)
{
passengerInfo.body.currentVehicle = null;
}
if ((bool)passengerInfo.characterMotor)
{
if (disablePassengerMotor)
{
passengerInfo.characterMotor.enabled = true;
}
else
{
passengerInfo.characterMotor.onMovementHit -= OnPassengerMovementHit;
}
passengerInfo.characterMotor.velocity = Vector3.zero;
passengerInfo.characterMotor.rootMotion = Vector3.zero;
passengerInfo.characterMotor.Motor.BaseVelocity = Vector3.zero;
}
if ((bool)passengerInfo.collider && (bool)collider)
{
Physics.IgnoreCollision(collider, passengerInfo.collider, ignore: false);
}
if (passengerInfo.hasEffectiveAuthority)
{
if ((bool)passengerInfo.bodyStateMachine && passengerInfo.bodyStateMachine.CanInterruptState(InterruptPriority.Vehicle))
{
passengerInfo.bodyStateMachine.SetNextStateToMain();
}
Vector3 newPosition = (exitPosition ? exitPosition.position : seatPosition.position);
TeleportHelper.TeleportGameObject(passengerInfo.transform.gameObject, newPosition);
}
if ((bool)passengerInfo.interactionDriver && (object)passengerInfo.interactionDriver.interactableOverride == base.gameObject)
{
passengerInfo.interactionDriver.interactableOverride = null;
}
if ((bool)rigidbody && (bool)passengerInfo.characterMotor)
{
passengerInfo.characterMotor.velocity = rigidbody.velocity * exitVelocityFraction;
}
this.onPassengerExit?.Invoke(passengerBodyObject);
onPassengerExitUnityEvent?.Invoke();
VehicleSeat.onPassengerExitGlobal?.Invoke(this, passengerBodyObject);
}
static VehicleSeat()
{
cvVehicleSeatDebug = new BoolConVar("vehicle_seat_debug", ConVarFlags.None, "0", "Enables debug logging for VehicleSeat.");
kCmdCmdEjectPassenger = -1985903462;
NetworkBehaviour.RegisterCommandDelegate(typeof(VehicleSeat), kCmdCmdEjectPassenger, InvokeCmdCmdEjectPassenger);
NetworkCRC.RegisterBehaviour("VehicleSeat", 0);
}
private void UNetVersion()
{
}
protected static void InvokeCmdCmdEjectPassenger(NetworkBehaviour obj, NetworkReader reader)
{
if (!NetworkServer.active)
{
Debug.LogError("Command CmdEjectPassenger called on client.");
}
else
{
((VehicleSeat)obj).CmdEjectPassenger();
}
}
public void CallCmdEjectPassenger()
{
if (!NetworkClient.active)
{
Debug.LogError("Command function CmdEjectPassenger called on server.");
return;
}
if (base.isServer)
{
CmdEjectPassenger();
return;
}
NetworkWriter networkWriter = new NetworkWriter();
networkWriter.Write((short)0);
networkWriter.Write((short)5);
networkWriter.WritePackedUInt32((uint)kCmdCmdEjectPassenger);
networkWriter.Write(GetComponent<NetworkIdentity>().netId);
SendCommandInternal(networkWriter, 0, "CmdEjectPassenger");
}
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
if (forceAll)
{
writer.Write(passengerBodyObject);
return true;
}
bool flag = false;
if ((base.syncVarDirtyBits & (true ? 1u : 0u)) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(passengerBodyObject);
}
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
}
return flag;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if (initialState)
{
___passengerBodyObjectNetId = reader.ReadNetworkId();
return;
}
int num = (int)reader.ReadPackedUInt32();
if (((uint)num & (true ? 1u : 0u)) != 0)
{
SetPassenger(reader.ReadGameObject());
}
}
public override void PreStartClient()
{
if (!___passengerBodyObjectNetId.IsEmpty())
{
NetworkpassengerBodyObject = ClientScene.FindLocalObject(___passengerBodyObjectNetId);
}
}
}