Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Tow Tuner v0.2.4
BepInEx/plugins/Robin-TowTuner/RepoTowTuner.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RepoTowTuner")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.4.0")] [assembly: AssemblyInformationalVersion("0.2.4")] [assembly: AssemblyProduct("RepoTowTuner")] [assembly: AssemblyTitle("RepoTowTuner")] [assembly: AssemblyVersion("0.2.4.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RepoTowTuner { internal static class TowCartGrip { private sealed class Pending { internal PhysGrabObject Item; internal TowGripWindow Window; internal Vector3 LocalPoint; } internal sealed class Pulse { internal PhysGrabber Grabber; internal float Previous; internal bool CheckArea; } private static readonly FieldRef<PhysGrabber, PhysGrabObject> GrabbedItem = AccessTools.FieldRefAccess<PhysGrabber, PhysGrabObject>("grabbedPhysGrabObject"); private static readonly Dictionary<PhysGrabber, Pending> pending = new Dictionary<PhysGrabber, Pending>(); private static bool Enabled { get { if (TowRuntime.Host && TowRuntime.Ready) { return TowRuntime.Compatible; } return false; } } internal static bool Holds(PhysGrabber? grabber, PhysGrabObject item) { if (Object.op_Implicit((Object)(object)grabber) && grabber.grabbed) { return (Object)(object)GrabbedItem.Invoke(grabber) == (Object)(object)item; } return false; } internal static bool HasPlayer(PhysGrabObject item) { if (Object.op_Implicit((Object)(object)item)) { if (!item.playerGrabbing.Any((PhysGrabber p) => Object.op_Implicit((Object)(object)p))) { if (Object.op_Implicit((Object)(object)GameDirector.instance)) { return SemiFunc.PlayerGetList().Any((PlayerAvatar p) => Object.op_Implicit((Object)(object)p) && Holds(p.physGrabber, item)); } return false; } return true; } return false; } internal static void ClearPending() { pending.Clear(); } internal static void Begin(PhysGrabber grabber, PhysGrabObject item) { if (Enabled && !grabber.isLocal) { pending[grabber] = new Pending { Item = item, Window = new TowGripWindow(Time.unscaledTime) }; } } internal static void PointReceived(PhysGrabber grabber, PhysGrabObject item, Vector3 localPoint) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (Enabled && pending.TryGetValue(grabber, out Pending value) && !((Object)(object)value.Item != (Object)(object)item) && Holds(grabber, item) && !float.IsNaN(((Vector3)(ref localPoint)).sqrMagnitude) && !float.IsInfinity(((Vector3)(ref localPoint)).sqrMagnitude) && value.Window.WaitingForPoint(Time.unscaledTime)) { value.LocalPoint = localPoint; value.Window.ConfirmPoint(Time.unscaledTime); } } internal static void Cancel(PhysGrabber? grabber, PhysGrabObject item) { if (Object.op_Implicit((Object)(object)grabber) && pending.TryGetValue(grabber, out Pending value) && (Object)(object)value.Item == (Object)(object)item) { pending.Remove(grabber); } } internal static List<Pulse>? BeforeNative(PhysGrabObjectGrabArea area, bool steering) { //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if (!Enabled) { return null; } PhysGrabObject component = ((Component)area).GetComponent<PhysGrabObject>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)((Component)component).GetComponent<PhysGrabCart>())) { return null; } List<Pulse> list = new List<Pulse>(); KeyValuePair<PhysGrabber, Pending>[] array = pending.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<PhysGrabber, Pending> keyValuePair = array[i]; PhysGrabber key = keyValuePair.Key; Pending value = keyValuePair.Value; if (!Object.op_Implicit((Object)(object)key) || !Object.op_Implicit((Object)(object)value.Item) || !value.Window.Alive(Time.unscaledTime) || !Holds(key, value.Item)) { pending.Remove(key); } else { if ((Object)(object)value.Item != (Object)(object)component || !component.playerGrabbing.Contains(key)) { continue; } bool flag = (steering ? value.Window.ForSteering(Time.unscaledTime) : value.Window.ForArea(Time.unscaledTime)); if (!flag && (steering || !value.Window.WaitingForPoint(Time.unscaledTime))) { continue; } if (steering && !area.listOfAllGrabbers.Contains(key)) { pending.Remove(key); continue; } list.Add(new Pulse { Grabber = key, Previous = key.initialPressTimer, CheckArea = flag }); if (!steering && flag) { key.physGrabPoint.position = ((Component)component).transform.TransformPoint(value.LocalPoint); } key.initialPressTimer = (flag ? Mathf.Max(0.1f, key.initialPressTimer) : 0f); } } return list; } internal static void AfterArea(PhysGrabObjectGrabArea area, List<Pulse>? pulses) { if (pulses == null) { return; } foreach (Pulse pulse in pulses) { if (pulse.CheckArea && pending.TryGetValue(pulse.Grabber, out Pending value)) { value.Window.CheckedArea(area.listOfAllGrabbers.Contains(pulse.Grabber)); } } } internal static void Restore(List<Pulse>? pulses, bool complete) { if (pulses == null) { return; } foreach (Pulse pulse in pulses) { if (Object.op_Implicit((Object)(object)pulse.Grabber)) { pulse.Grabber.initialPressTimer = pulse.Previous; } if (complete && pending.TryGetValue(pulse.Grabber, out Pending value)) { value.Window.Complete(); } } } internal static void ReleaseTow(PhysGrabObject item) { if (!TowRuntime.Host || !Object.op_Implicit((Object)(object)item)) { return; } PhysGrabCart component = ((Component)item).GetComponent<PhysGrabCart>(); if (!Object.op_Implicit((Object)(object)component)) { return; } foreach (TowVehicle vehicle in TowRuntime.Vehicles) { if (Object.op_Implicit((Object)(object)vehicle) && (Object)(object)vehicle.AttachedCart == (Object)(object)component) { vehicle.Detach(); } } } internal static bool HandleAimed(PlayerAvatar player, PhysGrabCart? cart) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)cart) || !Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)player.localCamera) || cart.grabMesh == null) { return false; } Transform overrideTransform = player.localCamera.GetOverrideTransform(); MeshRenderer val = cart.grabMesh.Where((MeshRenderer r) => Object.op_Implicit((Object)(object)r)).OrderBy(delegate(MeshRenderer r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Bounds bounds2 = ((Renderer)r).bounds; return Mathf.Abs(Vector3.Dot(((Bounds)(ref bounds2)).center - ((Component)cart).transform.position, ((Component)cart).transform.right)); }).FirstOrDefault(); if (Object.op_Implicit((Object)(object)val) && ((Renderer)val).enabled && ((Component)val).gameObject.activeInHierarchy) { MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.sharedMesh)) { return false; } Ray val2 = default(Ray); ((Ray)(ref val2))..ctor(((Component)val).transform.InverseTransformPoint(overrideTransform.position), ((Component)val).transform.InverseTransformVector(overrideTransform.forward)); Bounds bounds = component.sharedMesh.bounds; float num = default(float); if (!((Bounds)(ref bounds)).IntersectRay(val2, ref num)) { return false; } Vector3 val3 = ((Component)val).transform.TransformPoint(((Ray)(ref val2)).GetPoint(num)); if (Vector3.Distance(overrideTransform.position, val3) <= 3f) { return true; } } return false; } } [HarmonyPatch(typeof(PhysGrabObject), "GrabLinkRPC")] internal static class CartGrabLinkHandoff { private static void Prefix(PhysGrabObject __instance, int playerPhotonID, out bool __state) { __state = false; if (TowRuntime.Host && TowRuntime.Ready && TowRuntime.Compatible && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<PhysGrabCart>())) { PhotonView val = PhotonView.Find(playerPhotonID); PhysGrabber val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<PhysGrabber>() : null); __state = Object.op_Implicit((Object)(object)val2) && !val2.isLocal && !TowCartGrip.Holds(val2, __instance); } } private static void Postfix(PhysGrabObject __instance, int playerPhotonID, PhotonMessageInfo _info, bool __state) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!TowRuntime.Host || !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<PhysGrabCart>())) { return; } PhotonView val = PhotonView.Find(playerPhotonID); PhysGrabber grabber = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<PhysGrabber>() : null); if (TowCartGrip.Holds(grabber, __instance) && SemiFunc.OwnerOnlyRPC(_info, val)) { TowCartGrip.ReleaseTow(__instance); if (__state) { TowCartGrip.Begin(grabber, __instance); } } } } [HarmonyPatch(typeof(PhysGrabObject), "GrabPlayerAddRPC")] internal static class RemoteCartGrabRegistered { private static void Postfix(PhysGrabObject __instance, int photonViewID, PhotonMessageInfo _info) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (TowRuntime.Host && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<PhysGrabCart>()) && SemiFunc.MasterOnlyRPC(_info)) { PhotonView val = PhotonView.Find(photonViewID); PhysGrabber val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<PhysGrabber>() : null); if (Object.op_Implicit((Object)(object)val2) && __instance.playerGrabbing.Contains(val2)) { TowCartGrip.ReleaseTow(__instance); } } } } [HarmonyPatch(typeof(PhysGrabObject), "GrabPointSyncRPC")] internal static class RemoteCartPointReceived { private static void Postfix(PhysGrabObject __instance, int playerPhotonID, Vector3 localPointInBox, PhotonMessageInfo _info) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (TowRuntime.Host && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<PhysGrabCart>())) { PhotonView val = PhotonView.Find(playerPhotonID); PhysGrabber val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<PhysGrabber>() : null); if (Object.op_Implicit((Object)(object)val2) && SemiFunc.OwnerOnlyRPC(_info, val)) { TowCartGrip.PointReceived(val2, __instance, localPointInBox); } } } } [HarmonyPatch(typeof(PhysGrabObject), "GrabPlayerRemoveRPC")] internal static class RemoteCartGripEnded { private static void Postfix(PhysGrabObject __instance, int photonViewID, PhotonMessageInfo _info) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (TowRuntime.Host && SemiFunc.MasterOnlyRPC(_info)) { PhotonView val = PhotonView.Find(photonViewID); TowCartGrip.Cancel(Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<PhysGrabber>() : null, __instance); } } } [HarmonyPatch(typeof(PhysGrabObjectGrabArea), "Update")] internal static class RemoteCartAreaActivation { private static void Prefix(PhysGrabObjectGrabArea __instance, out List<TowCartGrip.Pulse>? __state) { __state = TowCartGrip.BeforeNative(__instance, steering: false); } private static void Postfix(PhysGrabObjectGrabArea __instance, List<TowCartGrip.Pulse>? __state) { TowCartGrip.AfterArea(__instance, __state); } private static void Finalizer(List<TowCartGrip.Pulse>? __state) { TowCartGrip.Restore(__state, complete: false); } } [HarmonyPatch(typeof(PhysGrabCart), "CartSteer")] internal static class RemoteCartSteerActivation { private static void Prefix(PhysGrabCart __instance, out List<TowCartGrip.Pulse>? __state) { PhysGrabObjectGrabArea component = ((Component)__instance).GetComponent<PhysGrabObjectGrabArea>(); __state = (Object.op_Implicit((Object)(object)component) ? TowCartGrip.BeforeNative(component, steering: true) : null); } private static void Finalizer(List<TowCartGrip.Pulse>? __state) { TowCartGrip.Restore(__state, complete: true); } } [HarmonyPatch(typeof(PhysGrabCart), "FixedUpdate")] internal static class CartPhysicsHandoff { private static void Prefix(PhysGrabCart __instance) { if (TowRuntime.Host) { PhysGrabObject component = ((Component)__instance).GetComponent<PhysGrabObject>(); if (TowCartGrip.HasPlayer(component)) { TowCartGrip.ReleaseTow(component); } } } } public sealed class TowCartHitch : MonoBehaviour { private Transform hardware; private Transform eye; private Material steel; private Material glow; private LineRenderer ring; private PhysGrabCart cart; public Vector3 EyePosition => eye.position; public Transform Hardware => hardware; public bool Highlighted { get; private set; } public static TowCartHitch Ensure(PhysGrabCart cart) { return ((Component)cart).GetComponent<TowCartHitch>() ?? ((Component)cart).gameObject.AddComponent<TowCartHitch>(); } private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) cart = ((Component)this).GetComponent<PhysGrabCart>(); steel = new Material(Shader.Find("Standard")) { color = new Color(0.3f, 0.33f, 0.23f) }; steel.SetFloat("_Glossiness", 0.32f); glow = new Material(steel); glow.EnableKeyword("_EMISSION"); glow.SetColor("_EmissionColor", new Color(0.25f, 1.1f, 0.025f)); Transform val = (Object.op_Implicit((Object)(object)cart.cartGrabPoint) ? cart.cartGrabPoint : cart.handlePoint); MeshRenderer val2 = cart.grabMesh?.Where((MeshRenderer r) => Object.op_Implicit((Object)(object)r)).OrderBy(delegate(MeshRenderer r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) Bounds bounds2 = ((Renderer)r).bounds; return Mathf.Abs(Vector3.Dot(((Bounds)(ref bounds2)).center - ((Component)this).transform.position, ((Component)this).transform.right)); }).FirstOrDefault(); ? val3; if (!Object.op_Implicit((Object)(object)val2)) { val3 = (Object.op_Implicit((Object)(object)val) ? val.position : (((Component)this).transform.position + ((Component)this).transform.up * 0.6f)); } else { Bounds bounds = ((Renderer)val2).bounds; val3 = ((Bounds)(ref bounds)).center; } Vector3 val4 = (Vector3)val3; hardware = new GameObject("Tow cart mounting bracket").transform; hardware.SetParent(((Component)this).transform, false); hardware.position = val4 - ((Component)this).transform.right * 0.3f + ((Component)this).transform.up * 0.12f - ((Component)this).transform.forward * 0.065f; Part("Bolted mounting plate", new Vector3(0f, -0.1f, 0.09f), new Vector3(0.18f, 0.085f, 0.1f)); Part("Eye support", new Vector3(0f, -0.1f, -0.015f), new Vector3(0.045f, 0.055f, 0.14f)); for (int num = -1; num <= 1; num += 2) { ((Component)TowPresentation.Primitive("Hitch bolt", (PrimitiveType)2, hardware, new Vector3((float)num * 0.06f, -0.1f, 0.032f), new Vector3(0.028f, 0.008f, 0.028f), steel)).transform.localRotation = Quaternion.Euler(90f, 0f, 0f); } eye = new GameObject("Tow attachment eye").transform; eye.SetParent(hardware, false); eye.localPosition = new Vector3(0f, -0.1f, -0.085f); Vector3[] array = (Vector3[])(object)new Vector3[13]; for (int num2 = 0; num2 < array.Length; num2++) { float num3 = MathF.PI * 2f * (float)num2 / 12f; array[num2] = new Vector3(Mathf.Sin(num3) * 0.085f, Mathf.Cos(num3) * 0.06f, 0f); } TowPresentation.Stroke("Steel attachment eye", eye, array, 0.024f, steel); ring = ((Component)eye).GetComponentInChildren<LineRenderer>(); } private void Part(string name, Vector3 position, Vector3 size) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) TowPresentation.Primitive(name, (PrimitiveType)3, hardware, position, size, steel); } private void LateUpdate() { bool flag = TowRuntime.Ready && TowRuntime.Compatible; ((Component)hardware).gameObject.SetActive(flag); Highlighted = flag && TowInteractions.Gripping && (Object)(object)TowInteractions.Target == (Object)(object)cart; bool flag2 = TowRuntime.Vehicles.Any((TowVehicle v) => Object.op_Implicit((Object)(object)v) && v.Active && (Object)(object)v.AttachedCart == (Object)(object)cart); ((Renderer)ring).sharedMaterial = ((Highlighted || flag2) ? glow : steel); } private void OnDestroy() { if (Object.op_Implicit((Object)(object)hardware)) { Object.Destroy((Object)(object)((Component)hardware).gameObject); } if (Object.op_Implicit((Object)(object)steel)) { Object.Destroy((Object)(object)steel); } if (Object.op_Implicit((Object)(object)glow)) { Object.Destroy((Object)(object)glow); } } } [HarmonyPatch(typeof(PhysGrabCart), "Start")] internal static class AddCartHitch { private static void Postfix(PhysGrabCart __instance) { TowCartHitch.Ensure(__instance); } } public sealed class TowGripWindow { public const float Timeout = 3f; private readonly float started; private bool point; private bool area; private bool done; public TowGripWindow(float now) { started = now; } public bool Alive(float now) { if (!done && now >= started) { return now - started <= 3f; } return false; } public bool WaitingForPoint(float now) { if (Alive(now)) { return !point; } return false; } public bool ForArea(float now) { if (Alive(now) && point) { return !area; } return false; } public bool ForSteering(float now) { if (Alive(now)) { return area; } return false; } public void ConfirmPoint(float now) { if (Alive(now)) { point = true; } } public void CheckedArea(bool accepted) { if (accepted) { area = true; } else { done = true; } } public void Complete() { done = true; } } public static class TowInteractions { private static TowVehicle? carrying; private static int tickFrame = -1; private static float beganAt; private static float targetAt; private static bool consumeGrabUntilRelease; public static bool ConsumingButtonGrab => consumeGrabUntilRelease; public static bool Gripping => Object.op_Implicit((Object)(object)carrying); public static Vector3 LocalTip { get; private set; } public static PhysGrabCart? Target { get; private set; } internal static bool CursorCaptured() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 return (int)Cursor.lockState == 1; } public static bool Aimed(PlayerAvatar player, Vector3 point, float radius, TowVehicle vehicle, PhysGrabCart? cart = null) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)player.localCamera)) { return false; } Transform overrideTransform = player.localCamera.GetOverrideTransform(); Vector3 val = point - overrideTransform.position; float num = Vector3.Dot(val, overrideTransform.forward); if (!(num < 0f) && !(num > 3f)) { Vector3 val2 = val - overrideTransform.forward * num; if (!(((Vector3)(ref val2)).magnitude > radius)) { return !Physics.RaycastAll(overrideTransform.position, ((Vector3)(ref val)).normalized, Mathf.Max(0f, ((Vector3)(ref val)).magnitude - 0.06f), -1, (QueryTriggerInteraction)1).Any((RaycastHit h) => (Object)(object)((RaycastHit)(ref h)).rigidbody != (Object)(object)vehicle.Vehicle.rb && (!Object.op_Implicit((Object)(object)cart) || (Object)(object)((RaycastHit)(ref h)).rigidbody != (Object)(object)((Component)cart).GetComponent<Rigidbody>()) && !((RaycastHit)(ref h)).transform.IsChildOf(((Component)player).transform) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref h)).collider).GetComponentInParent<PlayerTumble>()) && ((Component)((RaycastHit)(ref h)).collider).gameObject.layer != LayerMask.NameToLayer("Player")); } } return false; } public static void Tick() { //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) if (tickFrame == Time.frameCount) { return; } tickFrame = Time.frameCount; PlayerAvatar p = SemiFunc.PlayerGetLocal(); if (!Object.op_Implicit((Object)(object)p) || !TowRuntime.Ready || !TowRuntime.Compatible || !CursorCaptured() || !SemiFunc.NoTextInputsActive() || Time.timeScale <= 0f) { CancelLocal(); return; } TowRuntime instance = TowRuntime.Instance; if (!Object.op_Implicit((Object)(object)instance)) { return; } if (consumeGrabUntilRelease) { p.physGrabber.OverrideGrabDisable(0.12f); if (!SemiFunc.InputHold((InputKey)10)) { consumeGrabUntilRelease = false; } return; } if (Object.op_Implicit((Object)(object)carrying)) { TowVehicle v = carrying; p.physGrabber.OverrideGrabDisable(0.12f); if (!v.Active || !v.NearRear(p) || Object.op_Implicit((Object)(object)ItemVehicle.GetVehicleForPlayer(p)) || Time.unscaledTime - beganAt > 25f || (Time.unscaledTime - beganAt > 1.5f && !v.IsHeldBy(p))) { CancelLocal(); return; } Transform cam = p.localCamera.GetOverrideTransform(); if (!Object.op_Implicit((Object)(object)Target) || !(Time.unscaledTime - targetAt <= 0.4f) || !v.CanAttach(Target, ((Component)v).transform.TransformPoint(v.RearAnchor)) || !Aimed(p, TowVehicle.Hitch(Target), 0.55f, v, Target)) { Target = (from c in Object.FindObjectsOfType<PhysGrabCart>() where v.CanAttach(c, ((Component)v).transform.TransformPoint(v.RearAnchor)) && Aimed(p, TowVehicle.Hitch(c), 0.36f, v, c) orderby Vector3.Distance(cam.position, TowVehicle.Hitch(c)) select c).FirstOrDefault(); } if (Object.op_Implicit((Object)(object)Target) && Aimed(p, TowVehicle.Hitch(Target), 0.36f, v, Target)) { targetAt = Time.unscaledTime; } LocalTip = (Object.op_Implicit((Object)(object)Target) ? TowVehicle.Hitch(Target) : CarryTip(p, v)); if (!SemiFunc.InputHold((InputKey)10)) { if (Object.op_Implicit((Object)(object)Target)) { instance.Request(v, 4, TowRuntime.Multiplayer ? ((Component)Target).GetComponent<PhotonView>().ViewID : 0, Target); } else { instance.Request(v, 5, 0); } carrying = null; Target = null; } return; } TowVehicle towVehicle = TowRuntime.Vehicles.FirstOrDefault((TowVehicle towVehicle4) => Object.op_Implicit((Object)(object)towVehicle4) && (Object)(object)towVehicle4.Driver == (Object)(object)p); TowVehicle towVehicle2 = TowRuntime.Vehicles.FirstOrDefault((TowVehicle towVehicle4) => Object.op_Implicit((Object)(object)towVehicle4) && towVehicle4.Active && towVehicle4.Presentation.ButtonAimed(p)); bool flag = SemiFunc.InputDown((InputKey)10); if (Object.op_Implicit((Object)(object)towVehicle2) && (flag || SemiFunc.InputDown((InputKey)2))) { if (!Object.op_Implicit((Object)(object)towVehicle) && !p.physGrabber.grabbed && flag) { consumeGrabUntilRelease = true; p.physGrabber.OverrideGrabDisable(0.15f); } if (towVehicle2.CanUseSwitch(p)) { instance.Request(towVehicle2, 1, (!towVehicle2.BoostEnabled) ? 1 : 0); } } else { if (Object.op_Implicit((Object)(object)towVehicle) || p.physGrabber.grabbed || !SemiFunc.InputDown((InputKey)10)) { return; } TowVehicle towVehicle3 = (from towVehicle4 in TowRuntime.Vehicles where Object.op_Implicit((Object)(object)towVehicle4) && towVehicle4.Active && towVehicle4.HookActor == 0 && !TowCartGrip.HandleAimed(p, towVehicle4.AttachedCart) && Aimed(p, towVehicle4.Presentation.HookPosition, 0.14f, towVehicle4, towVehicle4.AttachedCart) orderby Vector3.Distance(towVehicle4.Presentation.HookPosition, ((Component)p).transform.position) select towVehicle4).FirstOrDefault(); if (!Object.op_Implicit((Object)(object)towVehicle3)) { return; } p.physGrabber.OverrideGrabDisable(0.15f); if (towVehicle3.HasCart) { consumeGrabUntilRelease = true; instance.Request(towVehicle3, 0, 0); return; } carrying = towVehicle3; beganAt = Time.unscaledTime; Target = null; targetAt = -100f; LocalTip = towVehicle3.Presentation.HookPosition; instance.Request(towVehicle3, 3, 0); if (TowRuntime.Host && !towVehicle3.IsHeldBy(p)) { carrying = null; } } } public static Vector3 CarryTip(PlayerAvatar player, TowVehicle vehicle) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) Transform overrideTransform = player.localCamera.GetOverrideTransform(); float num = 1.1f; RaycastHit[] array = Physics.RaycastAll(overrideTransform.position, overrideTransform.forward, num, -1, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if ((Object)(object)((RaycastHit)(ref val)).rigidbody != (Object)(object)vehicle.Vehicle.rb && !((RaycastHit)(ref val)).transform.IsChildOf(((Component)player).transform) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PlayerTumble>())) { num = Mathf.Min(num, Mathf.Max(0.25f, ((RaycastHit)(ref val)).distance - 0.08f)); } } return overrideTransform.position + overrideTransform.forward * num - overrideTransform.up * 0.1f; } public static Vector3 TipFor(TowVehicle v, PlayerAvatar holder) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)carrying == (Object)(object)v)) { return CarryTip(holder, v); } return LocalTip; } public static void CancelLocal() { if (Object.op_Implicit((Object)(object)carrying) && Object.op_Implicit((Object)(object)TowRuntime.Instance) && TowRuntime.Ready) { TowRuntime.Instance.Request(carrying, 5, 0); } carrying = null; Target = null; consumeGrabUntilRelease = false; } } [HarmonyPatch(typeof(PhysGrabber), "Update")] internal static class HookGrabInput { private static void Prefix(PhysGrabber __instance) { if ((Object)(object)__instance == (Object)(object)PhysGrabber.instance && TowRuntime.Ready) { TowInteractions.Tick(); } } } [HarmonyPatch(typeof(ItemVehicle), "Update")] internal static class VehicleInputScope { internal static ItemVehicle? Current; private static void Prefix(ItemVehicle __instance, out ItemVehicle? __state) { __state = Current; Current = __instance; } private static void Finalizer(ItemVehicle? __state) { Current = __state; } } [HarmonyPatch(typeof(SemiFunc), "InputDown")] internal static class PowerButtonConsumesHonk { private static void Postfix(InputKey key, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)key == 2 && Object.op_Implicit((Object)(object)VehicleInputScope.Current) && TowRuntime.Ready) { TowVehicle component = ((Component)VehicleInputScope.Current).GetComponent<TowVehicle>(); PlayerAvatar val = SemiFunc.PlayerGetLocal(); if (Object.op_Implicit((Object)(object)component) && component.Active && Object.op_Implicit((Object)(object)val) && !((Object)(object)component.Driver != (Object)(object)val) && component.Presentation.ButtonAimed(val)) { __result = false; } } } } internal static class TowPatches { internal static readonly FieldRef<ItemVehicle, float> Hyper = AccessTools.FieldRefAccess<ItemVehicle, float>("hyperSpeedOverTime"); private static readonly FieldRef<ItemVehicle, float> BoostTimer = AccessTools.FieldRefAccess<ItemVehicle, float>("driftBoostActiveTimer"); private static readonly FieldRef<ItemVehicle, float> BoostForce = AccessTools.FieldRefAccess<ItemVehicle, float>("driftBoostActiveForce"); private static readonly FieldRef<ItemVehicle, float> ExitTimer = AccessTools.FieldRefAccess<ItemVehicle, float>("driftExitDelayTimer"); private static readonly FieldRef<ItemVehicle, int> PendingLevel = AccessTools.FieldRefAccess<ItemVehicle, int>("driftExitPendingBoostLevel"); private static readonly FieldRef<ItemVehicle, bool> PendingRestore = AccessTools.FieldRefAccess<ItemVehicle, bool>("driftExitPendingSpeedRestore"); private static readonly FieldRef<ItemVehicle, int> BoostLevel = AccessTools.FieldRefAccess<ItemVehicle, int>("driftBoostLevel"); private static readonly FieldRef<ItemVehicle, float> BoostProgress = AccessTools.FieldRefAccess<ItemVehicle, float>("driftBoostProgress"); internal static TowVehicle? Control(ItemVehicle vehicle) { return ((Component)vehicle).GetComponent<TowVehicle>(); } internal static bool BoostOff(ItemVehicle vehicle) { TowVehicle towVehicle = Control(vehicle); if (Object.op_Implicit((Object)(object)towVehicle) && towVehicle.Active) { return !towVehicle.BoostEnabled; } return false; } internal static void ClearBoost(ItemVehicle vehicle) { Hyper.Invoke(vehicle) = 0f; BoostTimer.Invoke(vehicle) = 0f; BoostForce.Invoke(vehicle) = 0f; ExitTimer.Invoke(vehicle) = 0f; PendingLevel.Invoke(vehicle) = 0; PendingRestore.Invoke(vehicle) = false; BoostLevel.Invoke(vehicle) = 0; BoostProgress.Invoke(vehicle) = 0f; } } [HarmonyPatch(typeof(ItemVehicle), "Start")] internal static class AddTowControls { private static void Postfix(ItemVehicle __instance) { if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<TowVehicle>())) { ((Component)__instance).gameObject.AddComponent<TowVehicle>(); } } } [HarmonyPatch(typeof(PhysGrabCart), "AutoTurnOff")] internal static class TowedCartHandling { private static readonly FieldRef<PhysGrabCart, bool> CartActive = AccessTools.FieldRefAccess<PhysGrabCart, bool>("cartActive"); internal static void Release(PhysGrabCart cart) { PhysGrabObjectGrabArea component = ((Component)cart).GetComponent<PhysGrabObjectGrabArea>(); PhysGrabObject item = ((Component)cart).GetComponent<PhysGrabObject>(); if (!Object.op_Implicit((Object)(object)component) || !component.listOfAllGrabbers.Any((PhysGrabber p) => TowCartGrip.Holds(p, item))) { CartActive.Invoke(cart) = false; } } private static void Postfix(PhysGrabCart __instance) { if (TowRuntime.Host) { PhysGrabObject component = ((Component)__instance).GetComponent<PhysGrabObject>(); if (TowCartGrip.HasPlayer(component)) { TowCartGrip.ReleaseTow(component); } else if (TowRuntime.Vehicles.Any((TowVehicle v) => Object.op_Implicit((Object)(object)v) && v.Active && (Object)(object)v.AttachedCart == (Object)(object)__instance && v.HasJoint)) { CartActive.Invoke(__instance) = true; } } } } [HarmonyPatch(typeof(ItemVehicle), "ApplyVehicleMovement")] internal static class HyperControl { private static void Prefix(ItemVehicle __instance, out float? __state) { __state = null; if (TowPatches.BoostOff(__instance)) { TowPatches.ClearBoost(__instance); __state = __instance.hyperAcceleration; __instance.hyperAcceleration = 0f; } } private static void Finalizer(ItemVehicle __instance, float? __state) { if (__state.HasValue) { __instance.hyperAcceleration = __state.Value; TowPatches.Hyper.Invoke(__instance) = 0f; } } } [HarmonyPatch] internal static class ExtraBoostControl { private static IEnumerable<MethodBase> TargetMethods() { string[] array = new string[6] { "ApplyRampBoost", "ApplyDriftBoost", "UpdateDriftBoostActive", "UpdateDriftExitDelay", "UpdateDriftBoostProgress", "DriftBoostEffects" }; foreach (string text in array) { yield return AccessTools.Method(typeof(ItemVehicle), text, (Type[])null, (Type[])null); } } private static bool Prefix(ItemVehicle __instance) { if (!TowPatches.BoostOff(__instance)) { return true; } TowPatches.ClearBoost(__instance); return false; } } [HarmonyPatch(typeof(ItemVehicle), "ApplyVelocityLimits")] internal static class GovernorBrake { private static void Postfix(ItemVehicle __instance) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) TowVehicle towVehicle = TowPatches.Control(__instance); if (Object.op_Implicit((Object)(object)towVehicle) && towVehicle.Active && TowRuntime.Host && Object.op_Implicit((Object)(object)towVehicle.Driver) && !__instance.rb.isKinematic) { Rigidbody rb = __instance.rb; Vector3 velocity = rb.velocity; Vector3 val = rb.GetAccumulatedForce(Time.fixedDeltaTime) * (Time.fixedDeltaTime / rb.mass); (float, float) tuple = TowRules.GovernorCorrection(velocity.x, velocity.z, val.x, val.z, towVehicle.SpeedLimit, Time.fixedDeltaTime); rb.AddForce(new Vector3(tuple.Item1, 0f, tuple.Item2), (ForceMode)2); } } } [BepInPlugin("robin.repotowtuner", "Tow Tuner", "0.2.4")] public sealed class TowPlugin : BaseUnityPlugin { public const string Id = "robin.repotowtuner"; public const string Name = "Tow Tuner"; public const string Version = "0.2.4"; internal static ManualLogSource Log; internal static ConfigEntry<int> DefaultSpeed; internal static ConfigEntry<bool> DefaultBoost; internal static ConfigEntry<bool> WheelEnabled; private void Awake() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; WheelEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "ScrollSpeed", true, "Driver only: scroll up/down to change the speed limit by 5 displayed km/h."); DefaultSpeed = ((BaseUnityPlugin)this).Config.Bind<int>("Vehicle", "DefaultSpeedLimit", 45, new ConfigDescription("Displayed km/h. New scooters start full. The dashboard segments show the limit, the small marker shows current speed.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 45), Array.Empty<object>())); DefaultBoost = ((BaseUnityPlugin)this).Config.Bind<bool>("Vehicle", "DefaultBoostEnabled", true, "New scooters start with boost ON. Driver uses the physical power button, not a keyboard shortcut."); ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("Migration", "DashboardDefaults", 0, "Internal one-time migration from the prototype defaults."); if (val.Value < 2) { DefaultSpeed.Value = 45; DefaultBoost.Value = true; val.Value = 2; } new Harmony("robin.repotowtuner").PatchAll(typeof(TowPlugin).Assembly); GameObject val2 = new GameObject("Tow Tuner Session") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val2); val2.AddComponent<TowRuntime>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Tow Tuner 0.2.4: dashboard speed gauge, physical power button and drag-to-connect hook. No screen overlay or H/B shortcuts."); } } public sealed class TowPresentation : MonoBehaviour { private TowVehicle owner; private Transform panel; private Transform button; private Transform marker; private Transform hook; private Transform dock; private readonly List<Material> materials = new List<Material>(); private readonly List<Renderer> bars = new List<Renderer>(); private Material green; private Material darkGreen; private Material amber; private Material metal; private Material casing; private Material white; private Renderer lamp; private float halfHeight; private float pressAt = -100f; private Vector3 buttonHome; private bool lastBoost; private bool lastAttached; private int lastHolder; private bool initialized; public Vector3 ButtonPosition { get { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)button)) { return ((Component)this).transform.position; } return button.position; } } public Transform Panel => panel; public Vector3 SocketPosition { get { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)dock)) { return ((Component)this).transform.TransformPoint(owner.RearAnchor); } return dock.position; } } public int DisplayedSegments { get; private set; } public bool Highlighted { get; private set; } public Vector3 HookPosition { get { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)owner.AttachedCart)) { return ((Component)owner.AttachedCart).transform.TransformPoint(owner.CartAnchor); } PlayerAvatar hookHolder = owner.HookHolder; if (Object.op_Implicit((Object)(object)hookHolder)) { return TowInteractions.TipFor(owner, hookHolder); } return SocketPosition - (Object.op_Implicit((Object)(object)dock) ? dock.forward : ((Component)this).transform.forward) * 0.11f; } } public bool ButtonAimed(PlayerAvatar player) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)player.localCamera) || !Object.op_Implicit((Object)(object)button)) { return false; } Transform overrideTransform = player.localCamera.GetOverrideTransform(); Ray val = default(Ray); ((Ray)(ref val))..ctor(button.InverseTransformPoint(overrideTransform.position), button.InverseTransformDirection(overrideTransform.forward)); Bounds val2 = new Bounds(Vector3.zero, new Vector3(0.12f, 0.13f, 0.08f)); float num = default(float); if (((Bounds)(ref val2)).IntersectRay(val, ref num) && num <= 3f) { return TowInteractions.Aimed(player, ButtonPosition, 0.12f, owner); } return false; } public void Initialize(TowVehicle vehicle) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_050a: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0567: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Unknown result type (might be due to invalid IL or missing references) //IL_05f8: Unknown result type (might be due to invalid IL or missing references) //IL_0602: Unknown result type (might be due to invalid IL or missing references) //IL_0607: Unknown result type (might be due to invalid IL or missing references) //IL_0651: Unknown result type (might be due to invalid IL or missing references) //IL_0656: Unknown result type (might be due to invalid IL or missing references) //IL_066c: Unknown result type (might be due to invalid IL or missing references) //IL_0671: Unknown result type (might be due to invalid IL or missing references) //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_06de: Unknown result type (might be due to invalid IL or missing references) //IL_06e3: Unknown result type (might be due to invalid IL or missing references) //IL_06f9: Unknown result type (might be due to invalid IL or missing references) //IL_071d: Unknown result type (might be due to invalid IL or missing references) //IL_0731: Unknown result type (might be due to invalid IL or missing references) //IL_075c: Unknown result type (might be due to invalid IL or missing references) //IL_0770: Unknown result type (might be due to invalid IL or missing references) //IL_079b: Unknown result type (might be due to invalid IL or missing references) //IL_07af: Unknown result type (might be due to invalid IL or missing references) //IL_07c6: Unknown result type (might be due to invalid IL or missing references) //IL_0802: Unknown result type (might be due to invalid IL or missing references) //IL_0816: Unknown result type (might be due to invalid IL or missing references) //IL_082b: Unknown result type (might be due to invalid IL or missing references) //IL_084a: Unknown result type (might be due to invalid IL or missing references) //IL_0864: Unknown result type (might be due to invalid IL or missing references) //IL_08b9: Unknown result type (might be due to invalid IL or missing references) //IL_08df: Unknown result type (might be due to invalid IL or missing references) //IL_08fb: Unknown result type (might be due to invalid IL or missing references) //IL_0904: Unknown result type (might be due to invalid IL or missing references) //IL_093e: Unknown result type (might be due to invalid IL or missing references) //IL_0952: Unknown result type (might be due to invalid IL or missing references) owner = vehicle; casing = Make(new Color(0.045f, 0.055f, 0.039f), Color.black, 0.05f); metal = Make(new Color(0.23f, 0.25f, 0.21f), Color.black, 0.35f); darkGreen = Make(new Color(0.025f, 0.07f, 0.015f), new Color(0.008f, 0.025f, 0.004f)); green = Make(new Color(0.12f, 0.48f, 0.02f), new Color(0.35f, 1.1f, 0.035f)); amber = Make(new Color(0.28f, 0.12f, 0.02f), new Color(0.6f, 0.12f, 0.015f)); white = Make(new Color(0.7f, 0.8f, 0.45f), new Color(0.9f, 1f, 0.45f)); MeshRenderer grabMesh = vehicle.Vehicle.grabMesh; Transform val = (Object.op_Implicit((Object)(object)grabMesh) ? ((Component)grabMesh).transform : ((Component)this).transform); MeshFilter val2 = (Object.op_Implicit((Object)(object)grabMesh) ? ((Component)grabMesh).GetComponent<MeshFilter>() : null); Bounds val3 = (Bounds)((Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.sharedMesh)) ? val2.sharedMesh.bounds : new Bounds(Vector3.zero, new Vector3(0.5f, 0.25f, 0.01f))); panel = new GameObject("Tow dashboard").transform; panel.SetParent(val, false); panel.localPosition = new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).center.y, ((Bounds)(ref val3)).min.z - 0.008f); Vector3 lossyScale = val.lossyScale; panel.localScale = new Vector3(1f / Mathf.Max(0.01f, Mathf.Abs(lossyScale.x)), 1f / Mathf.Max(0.01f, Mathf.Abs(lossyScale.y)), 1f / Mathf.Max(0.01f, Mathf.Abs(lossyScale.z))); float num = Mathf.Clamp(((Bounds)(ref val3)).extents.x * Mathf.Abs(lossyScale.x), 0.15f, 0.5f); halfHeight = Mathf.Clamp(((Bounds)(ref val3)).extents.y * Mathf.Abs(lossyScale.y) * 0.82f, 0.075f, 0.13f); float num2 = num * 0.7f; Cube("Speed gauge bezel", panel, new Vector3(num2, 0f, 0f), new Vector3(0.052f, halfHeight * 2f + 0.024f, 0.014f), casing); Cube("Gauge glass", panel, new Vector3(num2, 0f, -0.008f), new Vector3(0.038f, halfHeight * 2f, 0.006f), darkGreen); float num3 = halfHeight * 2f / 9f; for (int i = 0; i < 9; i++) { bars.Add(Cube("Speed segment " + (i + 1), panel, new Vector3(num2, 0f - halfHeight + num3 * ((float)i + 0.5f), -0.013f), new Vector3(0.03f, num3 * 0.63f, 0.005f), green)); } marker = ((Component)Cube("Actual speed marker", panel, new Vector3(num2 + 0.032f, 0f - halfHeight, -0.014f), new Vector3(0.01f, 0.009f, 0.007f), white)).transform; Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(0f - num - 0.075f, 0f, -0.028f); Cube("Power button bezel", panel, val4 + new Vector3(0f, 0f, 0.005f), new Vector3(0.095f, 0.1f, 0.025f), casing); button = new GameObject("Boost power switch").transform; button.SetParent(panel, false); button.localPosition = val4; buttonHome = val4; ((Component)Primitive("Power button", (PrimitiveType)2, button, Vector3.zero, new Vector3(0.074f, 0.01f, 0.074f), metal)).transform.localRotation = Quaternion.Euler(90f, 0f, 0f); lamp = Cube("Boost indicator", button, new Vector3(0f, -0.036f, -0.014f), new Vector3(0.04f, 0.008f, 0.004f), green); Transform transform = new GameObject("Power symbol").transform; transform.SetParent(button, false); transform.localPosition = new Vector3(0f, 0.003f, -0.013f); Vector3[] array = (Vector3[])(object)new Vector3[13]; for (int j = 0; j < array.Length; j++) { float num4 = (40f + 280f * (float)j / 12f) * (MathF.PI / 180f); array[j] = new Vector3(Mathf.Sin(num4), Mathf.Cos(num4), 0f) * 0.023f; } Stroke("Power ring", transform, array, 0.004f, white); Stroke("Power stem", transform, (Vector3[])(object)new Vector3[2] { new Vector3(0f, 0.008f, 0f), new Vector3(0f, 0.03f, 0f) }, 0.004f, white); dock = new GameObject("Tow cable socket").transform; dock.SetParent(Object.op_Implicit((Object)(object)vehicle.Vehicle.meshTransform) ? vehicle.Vehicle.meshTransform : ((Component)this).transform, false); dock.position = ((Component)this).transform.TransformPoint(owner.RearAnchor); dock.rotation = ((Component)this).transform.rotation; Cube("Hitch socket", dock, new Vector3(0f, 0f, 0.022f), new Vector3(0.18f, 0.12f, 0.075f), casing); Cube("Hitch stripe", dock, new Vector3(0f, 0.037f, -0.005f), new Vector3(0.13f, 0.008f, 0.005f), green); Cube("Hook retaining clip", dock, new Vector3(0f, 0.065f, -0.055f), new Vector3(0.085f, 0.026f, 0.13f), casing); hook = new GameObject("Tow hook").transform; hook.SetParent(((Component)this).transform, false); ((Component)Primitive("Hook grip", (PrimitiveType)2, hook, new Vector3(0f, 0.035f, 0f), new Vector3(0.044f, 0.065f, 0.044f), casing)).transform.localRotation = Quaternion.identity; List<Vector3> list = new List<Vector3> { new Vector3(0f, 0.02f, 0f), new Vector3(0f, -0.055f, 0f) }; for (int k = 0; k <= 7; k++) { float num5 = MathF.PI - (float)k / 7f * MathF.PI; list.Add(new Vector3(0.035f + Mathf.Cos(num5) * 0.035f, -0.055f - Mathf.Sin(num5) * 0.035f, 0f)); } list.Add(new Vector3(0.07f, -0.025f, 0f)); for (int l = 1; l < list.Count; l++) { Rod(hook, list[l - 1], list[l], 0.025f); } Cube("Hook grip stripe", hook, new Vector3(0f, 0.042f, -0.024f), new Vector3(0.028f, 0.016f, 0.005f), green); lastBoost = owner.BoostEnabled; lastAttached = owner.HasCart; lastHolder = owner.HookActor; initialized = true; Present(); } private Material Make(Color color, Color emission, float gloss = 0f) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(Shader.Find("Standard")); val.color = color; val.SetFloat("_Glossiness", gloss); val.EnableKeyword("_EMISSION"); val.SetColor("_EmissionColor", emission); materials.Add(val); return val; } internal static Renderer Primitive(string name, PrimitiveType type, Transform parent, Vector3 position, Vector3 size, Material material) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive(type); ((Object)obj).name = name; obj.layer = LayerMask.NameToLayer("Ignore Raycast"); Collider component = obj.GetComponent<Collider>(); component.enabled = false; Object.Destroy((Object)(object)component); obj.transform.SetParent(parent, false); obj.transform.localPosition = position; obj.transform.localScale = size; Renderer component2 = obj.GetComponent<Renderer>(); component2.sharedMaterial = material; component2.shadowCastingMode = (ShadowCastingMode)0; return component2; } private static Renderer Cube(string name, Transform parent, Vector3 position, Vector3 size, Material material) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) return Primitive(name, (PrimitiveType)3, parent, position, size, material); } private void Rod(Transform parent, Vector3 a, Vector3 b, float width) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) ((Component)Primitive("Steel hook", (PrimitiveType)2, parent, (a + b) * 0.5f, new Vector3(width, Vector3.Distance(a, b) * 0.5f, width), metal)).transform.localRotation = Quaternion.FromToRotation(Vector3.up, b - a); } internal static void Stroke(string name, Transform parent, Vector3[] points, float width, Material material) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); LineRenderer obj = val.AddComponent<LineRenderer>(); ((Renderer)obj).sharedMaterial = material; obj.useWorldSpace = false; obj.positionCount = points.Length; obj.SetPositions(points); float startWidth = (obj.endWidth = width); obj.startWidth = startWidth; obj.numCornerVertices = 0; obj.numCapVertices = 0; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; } private void LateUpdate() { if (initialized) { Present(); } } public void Present() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) if (!initialized) { return; } bool active = owner.Active; ((Component)panel).gameObject.SetActive(active); ((Component)hook).gameObject.SetActive(active); ((Component)dock).gameObject.SetActive(active); DisplayedSegments = TowRules.LitSegments(owner.SpeedLimit); for (int i = 0; i < bars.Count; i++) { bars[i].sharedMaterial = ((i < DisplayedSegments) ? green : darkGreen); } Vector3 localPosition = marker.localPosition; float num = Mathf.Lerp(0f - halfHeight, halfHeight, Mathf.Clamp01(owner.ActualSpeedKmh / 45f)); localPosition.y = Mathf.Lerp(localPosition.y, num, 1f - Mathf.Exp((0f - Time.unscaledDeltaTime) * 15f)); marker.localPosition = localPosition; lamp.sharedMaterial = (owner.BoostEnabled ? green : amber); if (lastBoost != owner.BoostEnabled || lastAttached != owner.HasCart || lastHolder != owner.HookActor) { if (Object.op_Implicit((Object)(object)AssetManager.instance)) { ((owner.BoostEnabled == lastBoost) ? ((owner.HasCart || owner.HookActor != 0) ? AssetManager.instance.soundDeviceTurnOn : AssetManager.instance.soundDeviceTurnOff) : (owner.BoostEnabled ? AssetManager.instance.soundDeviceTurnOn : AssetManager.instance.soundDeviceTurnOff)).Play((owner.BoostEnabled != lastBoost) ? ButtonPosition : HookPosition, 1f, 1f, 1f, 1f); } if (lastBoost != owner.BoostEnabled) { pressAt = Time.time; } lastBoost = owner.BoostEnabled; lastAttached = owner.HasCart; lastHolder = owner.HookActor; } float num2 = Mathf.Sin(Mathf.Clamp01((Time.time - pressAt) / 0.25f) * MathF.PI) * 0.012f; button.localPosition = buttonHome + Vector3.forward * num2; hook.position = HookPosition; hook.rotation = (Object.op_Implicit((Object)(object)owner.AttachedCart) ? ((Component)owner.AttachedCart).transform.rotation : (Object.op_Implicit((Object)(object)owner.HookHolder) ? owner.HookHolder.localCamera.GetOverrideTransform().rotation : dock.rotation)); if (Object.op_Implicit((Object)(object)owner.AttachedCart)) { Transform obj = hook; obj.position += hook.rotation * new Vector3(-0.035f, 0.055f, -0.022f); } Highlighted = active && owner.IsHeldBy(SemiFunc.PlayerGetLocal()) && Object.op_Implicit((Object)(object)TowInteractions.Target); } private void OnDestroy() { if (Object.op_Implicit((Object)(object)panel)) { Object.Destroy((Object)(object)((Component)panel).gameObject); } if (Object.op_Implicit((Object)(object)dock)) { Object.Destroy((Object)(object)((Component)dock).gameObject); } foreach (Material material in materials) { if (Object.op_Implicit((Object)(object)material)) { Object.Destroy((Object)(object)material); } } } } public static class TowRules { public const byte NetworkEventCode = 196; public const int MinSpeed = 5; public const int MaxSpeed = 45; public const int Step = 5; public const float HudSpeedFactor = 7.2f; public const float Reach = 3f; public const float CouplingReach = 2.8f; public const float AttachRadius = 0.36f; public const float AttachRetainRadius = 0.55f; public const float AttachHostRadius = 0.65f; public const float TargetGrace = 0.4f; public const float HookRadius = 0.14f; public static int ClampSpeed(int speed) { return Math.Max(5, Math.Min(45, speed)); } public static int Scroll(int speed, float input) { if (!float.IsNaN(input) && !float.IsInfinity(input) && input != 0f) { return ClampSpeed(speed + ((input > 0f) ? 5 : (-5))); } return ClampSpeed(speed); } public static bool ValidLimit(int speed) { if (speed >= 5) { return speed <= 45; } return false; } public static bool ValidOperation(int operation) { if (operation >= 0) { return operation <= 6; } return false; } public static bool ValidScrollStep(int step) { if (step != -1) { return step == 1; } return true; } public static bool ValidActualSpeed(float speed) { return ValidDistance(speed, 1000f); } public static int LitSegments(int speed) { return (ClampSpeed(speed) + 5 - 1) / 5; } public static bool ValidDistance(float distance, float maximum) { if (!float.IsNaN(distance) && distance >= 0f) { return distance <= maximum; } return false; } public static float BrakeSpeed(float speed, int limit, float dt) { return Math.Max((float)ClampSpeed(limit) / 7.2f, speed - 6f * Math.Max(0f, dt)); } public static (float x, float z) GovernorCorrection(float vx, float vz, float pendingX, float pendingZ, int limit, float dt) { float num = BrakeSpeed((float)Math.Sqrt(vx * vx + vz * vz), limit, dt); float num2 = vx + pendingX; float num3 = vz + pendingZ; float num4 = (float)Math.Sqrt(num2 * num2 + num3 * num3); if (float.IsNaN(num4) || float.IsInfinity(num4) || num4 <= num) { return (x: 0f, z: 0f); } float num5 = num / num4 - 1f; return (x: num2 * num5, z: num3 * num5); } public static bool MayUseParkedSwitch(bool occupied, bool seatedElsewhere, float speed, float distance) { if (!occupied && !seatedElsewhere && ValidDistance(speed, 1.5f)) { return ValidDistance(distance, 3f); } return false; } public static bool MayChange(bool driver, bool nearby, int operation, bool parkedSwitch = false) { if (operation != 0 && operation != 3 && operation != 4 && operation != 5) { if (operation != 1) { return (operation == 2 || operation == 6) && driver; } return driver || parkedSwitch; } return nearby; } } public sealed class TowRuntime : MonoBehaviour, IOnEventCallback { private const byte EventCode = 196; private const string Protocol = "robin.towtuner/3"; private const string VersionKey = "TowTuner.Version"; internal static readonly List<TowVehicle> Vehicles = new List<TowVehicle>(); private bool registered; private float nextSync; private float nextScroll; private static float nextSendWarning; private readonly Dictionary<int, float> requests = new Dictionary<int, float>(); private LevelGenerator? generation; public static TowRuntime? Instance { get; private set; } public static bool Ready { get { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)GameManager.instance) && Object.op_Implicit((Object)(object)RunManager.instance) && Object.op_Implicit((Object)(object)GameDirector.instance) && (int)GameDirector.instance.currentState == 2 && Object.op_Implicit((Object)(object)LevelGenerator.Instance) && LevelGenerator.Instance.Generated) { return !SemiFunc.RunIsArena(); } return false; } } internal static bool Multiplayer { get { if (Object.op_Implicit((Object)(object)GameManager.instance)) { return GameManager.Multiplayer(); } return false; } } internal static bool Host { get { if (Multiplayer) { if (PhotonNetwork.InRoom) { return PhotonNetwork.IsMasterClient; } return false; } return true; } } internal static bool Compatible { get; private set; } private void Awake() { Instance = this; } private void OnDestroy() { if (registered) { PhotonNetwork.RemoveCallbackTarget((object)this); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } Compatible = false; TowCartGrip.ClearPending(); } private void Update() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Invalid comparison between Unknown and I4 if (!Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)RunManager.instance) || !Object.op_Implicit((Object)(object)LevelGenerator.Instance)) { Compatible = false; return; } if (!registered) { PhotonNetwork.AddCallbackTarget((object)this); registered = true; } if ((Object)(object)generation != (Object)(object)LevelGenerator.Instance) { generation = LevelGenerator.Instance; requests.Clear(); TowCartGrip.ClearPending(); nextSync = 0f; } if (Multiplayer && PhotonNetwork.InRoom && (!(PhotonNetwork.LocalPlayer.CustomProperties[(object)"TowTuner.Version"] is string text) || !(text == "0.2.4"))) { PhotonNetwork.LocalPlayer.SetCustomProperties(new Hashtable { [(object)"TowTuner.Version"] = "0.2.4" }, (Hashtable)null, (WebFlags)null); } Compatible = !Multiplayer || (PhotonNetwork.InRoom && PhotonNetwork.PlayerList.All((Player p) => p.CustomProperties[(object)"TowTuner.Version"] is string text2 && text2 == "0.2.4")); if (!Ready) { TowInteractions.CancelLocal(); return; } if (Host && Time.unscaledTime >= nextSync) { nextSync = Time.unscaledTime + 0.2f; TowVehicle[] array = Vehicles.ToArray(); foreach (TowVehicle towVehicle in array) { if (Object.op_Implicit((Object)(object)towVehicle)) { Broadcast(towVehicle); } } } PlayerAvatar local = SemiFunc.PlayerGetLocal(); if (!Object.op_Implicit((Object)(object)local)) { return; } TowInteractions.Tick(); TowVehicle towVehicle2 = Vehicles.FirstOrDefault((TowVehicle v) => Object.op_Implicit((Object)(object)v) && (Object)(object)v.Driver == (Object)(object)local); if (Object.op_Implicit((Object)(object)towVehicle2) && (int)Cursor.lockState == 1 && SemiFunc.NoTextInputsActive() && !(Time.timeScale <= 0f) && !((Object)(object)towVehicle2.Driver != (Object)(object)local) && TowPlugin.WheelEnabled.Value && Time.unscaledTime >= nextScroll) { float num2 = SemiFunc.InputScrollY(); if (Mathf.Abs(num2) > 0.01f) { nextScroll = Time.unscaledTime + 0.12f; Request(towVehicle2, 6, (num2 > 0f) ? 1 : (-1)); } } } public void Request(TowVehicle vehicle, int operation, int value, PhysGrabCart? cart = null) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown if (!Ready || !Compatible) { Show("Iedereen in de lobby heeft Tow Tuner 0.2.4 nodig."); return; } PlayerAvatar val = SemiFunc.PlayerGetLocal(); if (Object.op_Implicit((Object)(object)val)) { if (Host) { Apply(vehicle, val, operation, value, cart); return; } SendEvent(new object[5] { "robin.towtuner/3", 0, vehicle.View.ViewID, operation, value }, new RaiseEventOptions { Receivers = (ReceiverGroup)2 }); } } private void Apply(TowVehicle vehicle, PlayerAvatar player, int operation, int value, PhysGrabCart? cart = null) { string text = vehicle.HandleRequest(player, operation, value, cart); if ((Object)(object)player == (Object)(object)SemiFunc.PlayerGetLocal()) { Show(text); } else if (Multiplayer && Object.op_Implicit((Object)(object)player.photonView) && player.photonView.Owner != null) { Send(new object[3] { "robin.towtuner/3", 2, text }, new int[1] { player.photonView.OwnerActorNr }); } Broadcast(vehicle); } internal static void Broadcast(TowVehicle vehicle) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (Multiplayer && PhotonNetwork.InRoom && Host && Object.op_Implicit((Object)(object)vehicle.View) && vehicle.View.ViewID > 0) { Send(new object[11] { "robin.towtuner/3", 1, vehicle.View.ViewID, vehicle.SpeedLimit, vehicle.BoostEnabled, vehicle.CartViewId, vehicle.CartAnchor, vehicle.RearAnchor, vehicle.RopeLength, vehicle.HookActor, vehicle.ActualSpeedKmh }, PeerActors()); } } private static int[] PeerActors() { return (from p in PhotonNetwork.PlayerListOthers where p.CustomProperties[(object)"TowTuner.Version"] is string text && text == "0.2.4" select p.ActorNumber).ToArray(); } private static void Send(object[] data, int[] actors) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (actors.Length != 0) { SendEvent(data, new RaiseEventOptions { TargetActors = actors }); } } private static void SendEvent(object[] data, RaiseEventOptions options) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.RaiseEvent((byte)196, (object)data, options, SendOptions.SendReliable) && !(Time.unscaledTime < nextSendWarning)) { nextSendWarning = Time.unscaledTime + 5f; TowPlugin.Log.LogWarning((object)"Tow Tuner could not send its multiplayer update. Check the room connection and that everyone has version 0.2.4."); } } public void OnEvent(EventData ev) { //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) if (ev.Code != 196 || !Ready || !(ev.CustomData is object[] array) || array.Length < 3 || !(array[0] is string text) || text != "robin.towtuner/3" || !(array[1] is int num)) { return; } object obj; if (num == 0 && Host && Compatible && array.Length == 5) { obj = array[2]; if (obj is int) { int viewId = (int)obj; if (array[3] is int num2 && array[4] is int num3) { if (!TowRules.ValidOperation(num2)) { return; } int key = ev.Sender * 8 + num2; if (!requests.TryGetValue(key, out var value) || !(Time.unscaledTime - value < 0.08f)) { requests[key] = Time.unscaledTime; PlayerAvatar val = ((IEnumerable<PlayerAvatar>)SemiFunc.PlayerGetList()).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => Object.op_Implicit((Object)(object)p) && Object.op_Implicit((Object)(object)p.photonView) && p.photonView.OwnerActorNr == ev.Sender)); TowVehicle towVehicle = Vehicles.FirstOrDefault((TowVehicle v) => Object.op_Implicit((Object)(object)v) && Object.op_Implicit((Object)(object)v.View) && v.View.ViewID == viewId); object obj2; if (num2 != 4 || num3 <= 0) { obj2 = null; } else { PhotonView obj3 = PhotonView.Find(num3); obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<PhysGrabCart>() : null); } PhysGrabCart cart = (PhysGrabCart)obj2; if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)towVehicle)) { Apply(towVehicle, val, num2, num3, cart); } } return; } } } if (!PhotonNetwork.InRoom || ev.Sender != PhotonNetwork.MasterClient.ActorNumber) { return; } if (num == 2 && array.Length == 3 && array[2] is string text2) { Show(text2); } if (num != 1 || array.Length != 11) { return; } obj = array[2]; if (!(obj is int)) { return; } int id = (int)obj; if (array[3] is int speed && array[4] is bool boost && array[5] is int num4 && array[6] is Vector3 val2 && array[7] is Vector3 val3 && array[8] is float num5 && array[9] is int num6 && num6 >= 0 && TowRules.ValidLimit(speed) && num4 >= 0 && Finite(val2) && Finite(val3) && TowRules.ValidDistance(num5, 2.8f) && array[10] is float num7 && TowRules.ValidActualSpeed(num7)) { TowVehicle towVehicle2 = Vehicles.FirstOrDefault((TowVehicle v) => Object.op_Implicit((Object)(object)v) && Object.op_Implicit((Object)(object)v.View) && v.View.ViewID == id); if (Object.op_Implicit((Object)(object)towVehicle2)) { towVehicle2.ReceiveState(speed, boost, num4, val2, val3, num5, num6, num7); } } } private static bool Finite(Vector3 value) { if (!float.IsNaN(((Vector3)(ref value)).sqrMagnitude) && !float.IsInfinity(((Vector3)(ref value)).sqrMagnitude)) { return ((Vector3)(ref value)).sqrMagnitude < 10000f; } return false; } internal void Show(string text) { TowPlugin.Log.LogDebug((object)text); } } public sealed class TowVehicle : MonoBehaviour { private float hookDeadline; private PhysGrabCart? cart; private Rigidbody? cartBody; private PhysGrabObject? cartItem; private SpringJoint? joint; private LineRenderer? line; private Material? lineMaterial; private bool hadJoint; private float lastSwitchAt = -100f; private float cartContactUntil = -1f; private float receivedSpeed; public ItemVehicle Vehicle { get; private set; } public PhotonView View { get; private set; } public int SpeedLimit { get; private set; } public bool BoostEnabled { get; private set; } public float ActualSpeedKmh { get { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!TowRuntime.Host) { return receivedSpeed; } Vector3 velocity = Vehicle.rb.velocity; Vector2 val = new Vector2(velocity.x, velocity.z); float num = ((Vector2)(ref val)).magnitude * 7.2f; if (!float.IsNaN(num) && !float.IsInfinity(num)) { return Mathf.Clamp(num, 0f, 1000f); } return 0f; } } public int CartViewId { get; private set; } public Vector3 CartAnchor { get; private set; } public Vector3 RearAnchor { get; private set; } public float RopeLength { get; private set; } public bool HasCart { get { if (!Object.op_Implicit((Object)(object)cart)) { return CartViewId > 0; } return true; } } public PlayerAvatar? Driver { get { if (!Object.op_Implicit((Object)(object)Vehicle) || Vehicle.seats == null || Vehicle.seats.Length == 0) { return null; } return Vehicle.seats[0].seatedPlayer; } } public bool Active { get { if (((Behaviour)this).enabled && ((Component)this).gameObject.activeInHierarchy && TowRuntime.Ready) { return TowRuntime.Compatible; } return false; } } public PhysGrabCart? AttachedCart => cart; public bool HasJoint => Object.op_Implicit((Object)(object)joint); public TowPresentation Presentation { get; private set; } public int HookActor { get; private set; } public PlayerAvatar? HookHolder { get { if (HookActor != 0) { if (HookActor != -1) { return ((IEnumerable<PlayerAvatar>)SemiFunc.PlayerGetList()).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => Object.op_Implicit((Object)(object)p) && Object.op_Implicit((Object)(object)p.photonView) && p.photonView.OwnerActorNr == HookActor)); } return SemiFunc.PlayerGetLocal(); } return null; } } public bool IsSeatedDriver(PlayerAvatar player) { if (Object.op_Implicit((Object)(object)player) && (Object)(object)Driver == (Object)(object)player) { if (!Vehicle.seats[0].reachedFirstMount) { return !Object.op_Implicit((Object)(object)Vehicle.seats[0].firstMountTransform); } return true; } return false; } private void Awake() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) Vehicle = ((Component)this).GetComponent<ItemVehicle>(); View = ((Component)this).GetComponent<PhotonView>(); SpeedLimit = TowRules.ClampSpeed(TowPlugin.DefaultSpeed.Value); BoostEnabled = TowPlugin.DefaultBoost.Value; RearAnchor = FindRearAnchor(Vehicle); TowRuntime.Vehicles.Add(this); Presentation = ((Component)this).gameObject.AddComponent<TowPresentation>(); Presentation.Initialize(this); } public static Vector3 FindRearAnchor(ItemVehicle vehicle) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) MeshFilter val = ((IEnumerable<MeshFilter>)((Component)(Object.op_Implicit((Object)(object)vehicle.meshTransform) ? vehicle.meshTransform : ((Component)vehicle).transform)).GetComponentsInChildren<MeshFilter>(true)).FirstOrDefault((Func<MeshFilter, bool>)((MeshFilter m) => ((Object)m).name == "item vehicle bike back lights holder MAIN" && Object.op_Implicit((Object)(object)m.sharedMesh))); if (Object.op_Implicit((Object)(object)val)) { Bounds bounds = val.sharedMesh.bounds; Vector3 val2 = ((Component)val).transform.TransformPoint(new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).center.y, ((Bounds)(ref bounds)).max.z)); return ((Component)vehicle).transform.InverseTransformPoint(val2 - ((Component)vehicle).transform.forward * 0.025f); } TowPlugin.Log.LogWarning((object)"Unknown vehicle body: using compact fallback hitch mount."); return new Vector3(0f, 0.46f, -0.5f); } public bool CanUseSwitch(PlayerAvatar player) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)player)) { if (!((Object)(object)Driver == (Object)(object)player)) { bool occupied = Vehicle.seats.Any((VehicleSeat s) => Object.op_Implicit((Object)(object)s.seatedPlayer)); bool seatedElsewhere = Object.op_Implicit((Object)(object)ItemVehicle.GetVehicleForPlayer(player)); Vector3 velocity = Vehicle.rb.velocity; return TowRules.MayUseParkedSwitch(occupied, seatedElsewhere, ((Vector3)(ref velocity)).magnitude, Vector3.Distance(((Component)player).transform.position, Presentation.ButtonPosition)); } return true; } return false; } public bool NearRear(PlayerAvatar player) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)player)) { return Vector3.Distance(((Component)player).transform.position, ((Component)this).transform.TransformPoint(RearAnchor)) <= 3f; } return false; } public string HandleRequest(PlayerAvatar player, int operation, int value, PhysGrabCart? requestedCart = null) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) bool nearby = Object.op_Implicit((Object)(object)player) && (NearRear(player) || (HasCart && Object.op_Implicit((Object)(object)cart) && Vector3.Distance(((Component)player).transform.position, Hitch(cart)) <= 3f)); if (!Active || !TowRuntime.Host || !Object.op_Implicit((Object)(object)player) || !TowRules.MayChange(IsSeatedDriver(player), nearby, operation, operation == 1 && CanUseSwitch(player))) { return "Niet bereikbaar of niet de bestuurder."; } Vector3 velocity; switch (operation) { case 3: if (!HasCart && HookActor == 0) { velocity = Vehicle.rb.velocity; if (!(((Vector3)(ref velocity)).magnitude > 1.5f) && NearRear(player) && !player.physGrabber.grabbed && !Object.op_Implicit((Object)(object)ItemVehicle.GetVehicleForPlayer(player)) && TowInteractions.Aimed(player, Presentation.HookPosition, 0.14f, this)) { HookActor = Actor(player); hookDeadline = Time.unscaledTime + 25f; return "Haak opgepakt."; } } return "Haak niet beschikbaar."; case 5: if (IsHeldBy(player)) { CancelHook(); } return "Haak teruggezet."; case 1: if ((value != 0 && value != 1) || !CanUseSwitch(player) || !Presentation.ButtonAimed(player) || Time.unscaledTime - lastSwitchAt < 0.25f) { return "Richt op de boostknop."; } lastSwitchAt = Time.unscaledTime; BoostEnabled = value == 1; if (!BoostEnabled) { TowPatches.ClearBoost(Vehicle); } return "Boost " + (BoostEnabled ? "aan." : "uit."); case 2: if (!TowRules.ValidLimit(value)) { return "Ongeldige snelheid."; } SpeedLimit = value; return $"Maximumsnelheid: {SpeedLimit} km/h."; case 6: if (!TowRules.ValidScrollStep(value)) { return "Ongeldige snelheidsstap."; } SpeedLimit = TowRules.Scroll(SpeedLimit, value); return $"Maximumsnelheid: {SpeedLimit} km/h."; case 0: if (HasCart && !TowCartGrip.HandleAimed(player, cart) && TowInteractions.Aimed(player, Presentation.HookPosition, 0.14f, this, cart)) { Detach(); return "Kar losgemaakt."; } return "Richt op de aangesloten haak."; case 4: if (IsHeldBy(player)) { CancelHook(); velocity = Vehicle.rb.velocity; if (((Vector3)(ref velocity)).magnitude > 1.5f) { return "Stop even om de kar aan te koppelen."; } Vector3 val = ((Component)this).transform.TransformPoint(RearAnchor); if (!Object.op_Implicit((Object)(object)requestedCart) || !CanAttach(requestedCart, val) || !TowInteractions.Aimed(player, Hitch(requestedCart), 0.65f, this, requestedCart)) { return "Breng de haak naar het bevestigingsoog op de kar."; } cart = requestedCart; cartBody = ((Component)cart).GetComponent<Rigidbody>(); cartItem = ((Component)cart).GetComponent<PhysGrabObject>(); CartAnchor = ((Component)cart).transform.InverseTransformPoint(Hitch(cart)); RopeLength = Mathf.Clamp(Vector3.Distance(val, Hitch(cart)), 0.45f, 2.8f); CartViewId = (TowRuntime.Multiplayer ? ((Component)cart).GetComponent<PhotonView>().ViewID : 0); EnsureJoint(); return "Kar aangekoppeld. Rij rustig; de kar kan nog steeds tegen dingen botsen."; } goto default; default: return "Pak eerst de haak."; } } public bool IsHeldBy(PlayerAvatar player) { if (HookActor != 0 && Object.op_Implicit((Object)(object)player)) { return HookActor == Actor(player); } return false; } private static int Actor(PlayerAvatar p) { if (!TowRuntime.Multiplayer) { return -1; } return p.photonView.OwnerActorNr; } public void CancelHook() { HookActor = 0; hookDeadline = 0f; } public bool CanAttach(PhysGrabCart candidate, Vector3 rear) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)candidate) || !((Component)candidate).gameObject.activeInHierarchy) { return false; } Rigidbody body = ((Component)candidate).GetComponent<Rigidbody>(); PhysGrabObject component = ((Component)candidate).GetComponent<PhysGrabObject>(); if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)component) || (TowRuntime.Host && body.isKinematic) || TowCartGrip.HasPlayer(component)) { return false; } if (TowRuntime.Multiplayer && (!Object.op_Implicit((Object)(object)((Component)candidate).GetComponent<PhotonView>()) || ((Component)candidate).GetComponent<PhotonView>().ViewID <= 0)) { return false; } int candidateId = (TowRuntime.Multiplayer ? ((Component)candidate).GetComponent<PhotonView>().ViewID : 0); if (TowRuntime.Vehicles.Any((TowVehicle v) => Object.op_Implicit((Object)(object)v) && (Object)(object)v != (Object)(object)this && ((Object)(object)v.cart == (Object)(object)candidate || (candidateId > 0 && v.CartViewId == candidateId)))) { return false; } Vector3 val = Hitch(candidate); if (!TowRules.ValidDistance(Vector3.Distance(rear, val), 2.8f) || Vector3.Dot(val - ((Component)this).transform.position, ((Component)this).transform.forward) > -0.2f) {