r2mods/ilspy_dump/ror2_csproj/RoR2/PingerController.cs

333 lines
8.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using RoR2.UI;
using Unity;
using UnityEngine;
using UnityEngine.Networking;
namespace RoR2;
public class PingerController : NetworkBehaviour
{
[Serializable]
public struct PingInfo : IEquatable<PingInfo>
{
public bool active;
public Vector3 origin;
public Vector3 normal;
public NetworkIdentity targetNetworkIdentity;
public GameObject targetGameObject
{
get
{
if (!targetNetworkIdentity)
{
return null;
}
return targetNetworkIdentity.gameObject;
}
}
public bool Equals(PingInfo other)
{
if (active.Equals(other.active) && origin.Equals(other.origin) && normal.Equals(other.normal))
{
return (object)targetNetworkIdentity == other.targetNetworkIdentity;
}
return false;
}
public override bool Equals(object obj)
{
return (obj as PingInfo?)?.Equals(this) ?? false;
}
public override int GetHashCode()
{
return (((-1814869148 * -1521134295 + active.GetHashCode()) * -1521134295 + EqualityComparer<Vector3>.Default.GetHashCode(origin)) * -1521134295 + EqualityComparer<Vector3>.Default.GetHashCode(normal)) * -1521134295 + EqualityComparer<NetworkIdentity>.Default.GetHashCode(targetNetworkIdentity);
}
}
private int pingStock = 3;
private float pingRechargeStopwatch;
private const int maximumPingStock = 3;
private const float pingRechargeInterval = 1.5f;
private static readonly PingInfo emptyPing;
private PingIndicator pingIndicator;
[SyncVar(hook = "OnSyncCurrentPing")]
public PingInfo currentPing;
private static int kCmdCmdPing;
public PingInfo NetworkcurrentPing
{
get
{
return currentPing;
}
[param: In]
set
{
if (NetworkServer.localClientActive && !base.syncVarHookGuard)
{
base.syncVarHookGuard = true;
OnSyncCurrentPing(value);
base.syncVarHookGuard = false;
}
SetSyncVar(value, ref currentPing, 1u);
}
}
private void RebuildPing(PingInfo pingInfo)
{
if (!pingInfo.active && (object)pingIndicator != null)
{
if ((bool)pingIndicator)
{
UnityEngine.Object.Destroy(pingIndicator.gameObject);
}
pingIndicator = null;
return;
}
if (!pingIndicator)
{
GameObject gameObject = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load<GameObject>("Prefabs/PingIndicator"));
pingIndicator = gameObject.GetComponent<PingIndicator>();
pingIndicator.pingOwner = base.gameObject;
}
pingIndicator.pingOrigin = pingInfo.origin;
pingIndicator.pingNormal = pingInfo.normal;
pingIndicator.pingTarget = pingInfo.targetGameObject;
pingIndicator.RebuildPing();
}
private void OnDestroy()
{
if ((bool)pingIndicator)
{
UnityEngine.Object.Destroy(pingIndicator.gameObject);
}
}
private void OnSyncCurrentPing(PingInfo newPingInfo)
{
if (!base.hasAuthority)
{
SetCurrentPing(newPingInfo);
}
}
private void SetCurrentPing(PingInfo newPingInfo)
{
if ((bool)currentPing.targetGameObject)
{
currentPing.targetGameObject.GetComponent<TeleporterInteraction>()?.CancelTeleporterPing(pingIndicator);
}
NetworkcurrentPing = newPingInfo;
RebuildPing(currentPing);
if (base.hasAuthority)
{
CallCmdPing(currentPing);
}
}
[Command]
private void CmdPing(PingInfo incomingPing)
{
NetworkcurrentPing = incomingPing;
}
private void FixedUpdate()
{
if (base.hasAuthority)
{
pingRechargeStopwatch -= Time.fixedDeltaTime;
if (pingRechargeStopwatch <= 0f)
{
pingStock = Mathf.Min(pingStock + 1, 3);
pingRechargeStopwatch = 1.5f;
}
}
}
private static bool GeneratePingInfo(Ray aimRay, GameObject bodyObject, out PingInfo result)
{
result = new PingInfo
{
active = true,
origin = Vector3.zero,
normal = Vector3.zero,
targetNetworkIdentity = null
};
aimRay = CameraRigController.ModifyAimRayIfApplicable(aimRay, bodyObject, out var extraRaycastDistance);
float maxDistance = 1000f + extraRaycastDistance;
if (Util.CharacterRaycast(bodyObject, aimRay, out var hitInfo, maxDistance, (int)LayerIndex.entityPrecise.mask | (int)LayerIndex.world.mask, QueryTriggerInteraction.UseGlobal))
{
HurtBox component = hitInfo.collider.GetComponent<HurtBox>();
if ((bool)component && (bool)component.healthComponent)
{
CharacterBody body = component.healthComponent.body;
result.origin = body.corePosition;
result.normal = Vector3.zero;
result.targetNetworkIdentity = body.networkIdentity;
return true;
}
}
if (Util.CharacterRaycast(bodyObject, aimRay, out hitInfo, maxDistance, (int)LayerIndex.world.mask | (int)LayerIndex.CommonMasks.characterBodiesOrDefault | (int)LayerIndex.pickups.mask, QueryTriggerInteraction.Collide))
{
GameObject gameObject = hitInfo.collider.gameObject;
NetworkIdentity networkIdentity = gameObject.GetComponentInParent<NetworkIdentity>();
ForcePingable component2 = gameObject.GetComponent<ForcePingable>();
if (!networkIdentity && (component2 == null || !component2.bypassEntityLocator))
{
Transform parent = gameObject.transform.parent;
EntityLocator entityLocator = (parent ? parent.GetComponentInChildren<EntityLocator>() : gameObject.GetComponent<EntityLocator>());
if ((bool)entityLocator)
{
gameObject = entityLocator.entity;
networkIdentity = gameObject.GetComponent<NetworkIdentity>();
}
}
result.origin = hitInfo.point;
result.normal = hitInfo.normal;
if ((bool)networkIdentity && networkIdentity.isPingable)
{
result.targetNetworkIdentity = networkIdentity;
}
return true;
}
return false;
}
public void AttemptPing(Ray aimRay, GameObject bodyObject)
{
if (pingStock <= 0)
{
Chat.AddMessage(Language.GetString("PLAYER_PING_COOLDOWN"));
return;
}
if (!RoR2Application.isInSinglePlayer)
{
pingStock--;
}
if (!GeneratePingInfo(aimRay, bodyObject, out var result))
{
return;
}
if ((object)result.targetNetworkIdentity != null && (object)result.targetNetworkIdentity == currentPing.targetNetworkIdentity)
{
if ((bool)currentPing.targetGameObject && (bool)currentPing.targetGameObject.GetComponent<TeleporterInteraction>())
{
if ((bool)pingIndicator)
{
result = emptyPing;
pingStock++;
}
}
else
{
result = emptyPing;
pingStock++;
}
}
SetCurrentPing(result);
}
static PingerController()
{
kCmdCmdPing = 1170265357;
NetworkBehaviour.RegisterCommandDelegate(typeof(PingerController), kCmdCmdPing, InvokeCmdCmdPing);
NetworkCRC.RegisterBehaviour("PingerController", 0);
}
private void UNetVersion()
{
}
protected static void InvokeCmdCmdPing(NetworkBehaviour obj, NetworkReader reader)
{
if (!NetworkServer.active)
{
Debug.LogError("Command CmdPing called on client.");
}
else
{
((PingerController)obj).CmdPing(GeneratedNetworkCode._ReadPingInfo_PingerController(reader));
}
}
public void CallCmdPing(PingInfo incomingPing)
{
if (!NetworkClient.active)
{
Debug.LogError("Command function CmdPing called on server.");
return;
}
if (base.isServer)
{
CmdPing(incomingPing);
return;
}
NetworkWriter networkWriter = new NetworkWriter();
networkWriter.Write((short)0);
networkWriter.Write((short)5);
networkWriter.WritePackedUInt32((uint)kCmdCmdPing);
networkWriter.Write(GetComponent<NetworkIdentity>().netId);
GeneratedNetworkCode._WritePingInfo_PingerController(networkWriter, incomingPing);
SendCommandInternal(networkWriter, 0, "CmdPing");
}
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
if (forceAll)
{
GeneratedNetworkCode._WritePingInfo_PingerController(writer, currentPing);
return true;
}
bool flag = false;
if ((base.syncVarDirtyBits & (true ? 1u : 0u)) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
GeneratedNetworkCode._WritePingInfo_PingerController(writer, currentPing);
}
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
}
return flag;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if (initialState)
{
currentPing = GeneratedNetworkCode._ReadPingInfo_PingerController(reader);
return;
}
int num = (int)reader.ReadPackedUInt32();
if (((uint)num & (true ? 1u : 0u)) != 0)
{
OnSyncCurrentPing(GeneratedNetworkCode._ReadPingInfo_PingerController(reader));
}
}
public override void PreStartClient()
{
}
}