Decompiled source of Beacon v1.0.0

BepInEx/plugins/Beacon.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Fusion;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using Steamworks;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Beacon")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Beacon")]
[assembly: AssemblyTitle("Beacon")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 ShiftAtMidnightBeacon
{
	[BepInPlugin("clementinise.shiftatmidnight.beacon", "Beacon", "1.0.0")]
	public class BeaconPlugin : BasePlugin
	{
		public const string Guid = "clementinise.shiftatmidnight.beacon";

		internal static ConfigEntry<KeyCode> PingKey;

		public const float Lifetime = 6f;

		public const float Size = 0.8f;

		public const float Reach = 100f;

		public const float Volume = 1f;

		public override void Load()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			ModLog.Source = ((BasePlugin)this).Log;
			PingKey = ((BasePlugin)this).Config.Bind<KeyCode>("Ping", "PingKey", (KeyCode)325, "What drops a marker. Mouse2 is the middle mouse button.");
			ClassInjector.RegisterTypeInIl2Cpp<BeaconBehaviour>();
			((BasePlugin)this).AddComponent<BeaconBehaviour>();
			ModLog.Msg($"Beacon ready. {PingKey.Value} drops a marker.");
		}
	}
	public class BeaconBehaviour : MonoBehaviour
	{
		private PingField _field;

		private PingSync _sync;

		private PingInput _input;

		private int _lastSceneHandle;

		public BeaconBehaviour(IntPtr handle)
			: base(handle)
		{
		}

		private void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			_field = new PingField();
			_sync = new PingSync(_field);
			_input = new PingInput(_field, _sync);
			Scene activeScene = SceneManager.GetActiveScene();
			_lastSceneHandle = ((Scene)(ref activeScene)).handle;
		}

		private void Update()
		{
			try
			{
				DetectSceneChange();
				_input.Tick();
				_sync.Tick();
			}
			catch (Exception value)
			{
				ModLog.Error($"Update: {value}");
			}
		}

		private void LateUpdate()
		{
			try
			{
				_field.LateTick();
			}
			catch (Exception value)
			{
				ModLog.Error($"LateUpdate: {value}");
			}
		}

		private void DetectSceneChange()
		{
			//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)
			Scene activeScene = SceneManager.GetActiveScene();
			int handle = ((Scene)(ref activeScene)).handle;
			if (handle != _lastSceneHandle)
			{
				_lastSceneHandle = handle;
				_field.Clear();
				_sync.Clear();
				MarkerMesh.Rescan();
				MarkerMesh.Ensure();
			}
		}

		private void OnDestroy()
		{
			try
			{
				_field.Clear();
			}
			catch
			{
			}
		}
	}
	internal static class Interop
	{
		public static IEnumerable<T> Safe<T>(Il2CppArrayBase<T> array) where T : Il2CppObjectBase
		{
			if (array == null)
			{
				yield break;
			}
			for (int i = 0; i < array.Length; i++)
			{
				T v = array[i];
				if (v != null)
				{
					yield return v;
				}
			}
		}
	}
	internal static class MarkerMesh
	{
		private const string GameMeshName = "SM_Icon_Arrow_Long_02";

		private const string TipChildName = "Arrow Tip";

		private const string PreferredShader = "Hidden/Internal-Colored";

		private const string FallbackShader = "Universal Render Pipeline/Unlit";

		private const int ZTestLessEqual = 4;

		private const int ZTestGreater = 5;

		private const int CullOff = 0;

		private const int BlendSrcAlpha = 5;

		private const int BlendOneMinusSrcAlpha = 10;

		private const int ZWriteOff = 0;

		private const int VisibleQueue = 3000;

		private const int OccludedQueue = 3100;

		private static Mesh _mesh;

		private static Material _material;

		private static Material _occluded;

		private static bool _tried;

		private static bool _improvised;

		public static Quaternion Correction { get; private set; }

		public static Vector3 Tip { get; private set; }

		public static float UnitScale { get; private set; }

		public static Mesh Ring { get; private set; }

		public static Mesh Mesh => _mesh;

		public static Material Material => _material;

		public static Material Occluded => _occluded;

		public static bool Ready => (Object)(object)_mesh != (Object)null && (Object)(object)_material != (Object)null;

		public static void Ensure()
		{
			try
			{
				BuildMaterial();
				BuildMesh();
				BuildRing();
			}
			catch (Exception value)
			{
				ModLog.Error($"Building the marker failed: {value}");
			}
		}

		public static void Rescan()
		{
			if (_improvised)
			{
				_tried = false;
			}
		}

		private static void BuildMaterial()
		{
			if ((Object)(object)_material != (Object)null)
			{
				return;
			}
			Shader val = Shader.Find("Hidden/Internal-Colored");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Universal Render Pipeline/Unlit");
				ModLog.Warning(((Object)(object)val == (Object)null) ? "Neither 'Hidden/Internal-Colored' nor 'Universal Render Pipeline/Unlit' is in this build. Pings will not draw." : "'Hidden/Internal-Colored' is not in this build, falling back to 'Universal Render Pipeline/Unlit'. Pings will be hidden by walls.");
			}
			if (!((Object)(object)val == (Object)null))
			{
				_material = Translucent(val, 4, 3000);
				if (!_material.HasProperty("_ZTest"))
				{
					ModLog.Warning("'" + ((Object)val).name + "' has no _ZTest property, so pings will be hidden by walls with nothing shown through them.");
				}
				else
				{
					_occluded = Translucent(val, 5, 3100);
				}
			}
		}

		private static Material Translucent(Shader shader, int zTest, int queue)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Material val = new Material(shader)
			{
				hideFlags = (HideFlags)61
			};
			SetIfPresent(val, "_SrcBlend", 5);
			SetIfPresent(val, "_DstBlend", 10);
			SetIfPresent(val, "_Cull", 0);
			SetIfPresent(val, "_ZWrite", 0);
			SetIfPresent(val, "_ZTest", zTest);
			val.renderQueue = queue;
			return val;
		}

		private static bool SetIfPresent(Material material, string property, int value)
		{
			if (!material.HasProperty(property))
			{
				return false;
			}
			material.SetInt(property, value);
			return true;
		}

		private static void BuildMesh()
		{
			//IL_003c: 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)
			//IL_0046: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (_tried)
			{
				return;
			}
			_tried = true;
			Mesh val = FindGameMesh();
			if ((Object)(object)val == (Object)null)
			{
				Improvise("'SM_Icon_Arrow_Long_02' is not loaded, using a built-in arrow instead.");
				return;
			}
			Vector3 val2 = ThinnestAxis(val.bounds);
			Bounds bounds;
			Vector3 val4;
			if (TipOf(val, out var tip))
			{
				Vector3 val3 = tip;
				bounds = val.bounds;
				val4 = Vector3.ProjectOnPlane(val3 - ((Bounds)(ref bounds)).center, val2);
			}
			else
			{
				val4 = LongestAxis(val.bounds);
				bounds = val.bounds;
				tip = ((Bounds)(ref bounds)).center + val4 * Extent(val.bounds, val4);
				ModLog.Warning("'SM_Icon_Arrow_Long_02' has no 'Arrow Tip' child, so which end is the point had to be guessed. The arrow may be back to front.");
			}
			if (((Vector3)(ref val4)).sqrMagnitude < Mathf.Epsilon)
			{
				Improvise("'SM_Icon_Arrow_Long_02' has no usable length, using a built-in arrow instead.");
				return;
			}
			_improvised = false;
			Adopt(val, ((Vector3)(ref val4)).normalized, val2, tip);
		}

		private static void Improvise(string why)
		{
			//IL_000e: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = ProceduralArrow.Build();
			_improvised = true;
			Adopt(val, Vector3.forward, Vector3.up, Vector3.zero);
			Object.Destroy((Object)(object)val);
			ModLog.Msg(why);
		}

		private static void Adopt(Mesh source, Vector3 pointAxis, Vector3 faceAxis, Vector3 tipLocal)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_007f: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00b3: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)source == (Object)null)
			{
				return;
			}
			Mesh val = ((Il2CppObjectBase)Object.Instantiate<Mesh>(source)).TryCast<Mesh>();
			if ((Object)(object)val == (Object)null)
			{
				ModLog.Error("Could not copy the marker mesh.");
				return;
			}
			if ((Object)(object)_mesh != (Object)null)
			{
				Object.Destroy((Object)(object)_mesh);
			}
			_mesh = val;
			((Object)_mesh).hideFlags = (HideFlags)61;
			((Object)_mesh).name = "BeaconArrow";
			Correction = Quaternion.Inverse(Quaternion.LookRotation(pointAxis, faceAxis));
			Tip = tipLocal;
			Bounds bounds = _mesh.bounds;
			float x = ((Bounds)(ref bounds)).size.x;
			bounds = _mesh.bounds;
			float y = ((Bounds)(ref bounds)).size.y;
			bounds = _mesh.bounds;
			float num = Mathf.Max(x, Mathf.Max(y, ((Bounds)(ref bounds)).size.z));
			UnitScale = ((num > Mathf.Epsilon) ? (1f / num) : 1f);
		}

		private static Mesh FindGameMesh()
		{
			foreach (Mesh item in Interop.Safe<Mesh>(Resources.FindObjectsOfTypeAll<Mesh>()))
			{
				if (((Object)item).name == "SM_Icon_Arrow_Long_02")
				{
					return item;
				}
			}
			return null;
		}

		private static void BuildRing()
		{
			if (!((Object)(object)Ring != (Object)null))
			{
				Ring = ProceduralRing.Build();
				((Object)Ring).hideFlags = (HideFlags)61;
				((Object)Ring).name = "BeaconRing";
			}
		}

		private static bool TipOf(Mesh mesh, out Vector3 tip)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			tip = Vector3.zero;
			foreach (MeshFilter item in Interop.Safe<MeshFilter>(Resources.FindObjectsOfTypeAll<MeshFilter>()))
			{
				if (!((Object)(object)item.sharedMesh == (Object)null) && !(((Il2CppObjectBase)item.sharedMesh).Pointer != ((Il2CppObjectBase)mesh).Pointer))
				{
					Transform val = ((Component)item).transform.Find("Arrow Tip");
					if (!((Object)(object)val == (Object)null))
					{
						tip = val.localPosition;
						return true;
					}
				}
			}
			return false;
		}

		private static Vector3 ThinnestAxis(Bounds bounds)
		{
			//IL_0003: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			//IL_004c: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Vector3 size = ((Bounds)(ref bounds)).size;
			if (size.x <= size.y && size.x <= size.z)
			{
				return Vector3.right;
			}
			return (size.y <= size.z) ? Vector3.up : Vector3.forward;
		}

		private static Vector3 LongestAxis(Bounds bounds)
		{
			//IL_0003: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			//IL_004c: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Vector3 size = ((Bounds)(ref bounds)).size;
			if (size.x >= size.y && size.x >= size.z)
			{
				return Vector3.right;
			}
			return (size.y >= size.z) ? Vector3.up : Vector3.forward;
		}

		private static float Extent(Bounds bounds, Vector3 axis)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Abs(Vector3.Dot(((Bounds)(ref bounds)).extents, axis));
		}
	}
	internal static class ProceduralArrow
	{
		private const float Length = 1f;

		private const float HeadLength = 0.45f;

		private const float HeadHalfWidth = 0.3f;

		private const float ShaftHalfWidth = 0.11f;

		public static Mesh Build()
		{
			//IL_0042: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_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_0136: Expected O, but got Unknown
			Vector3[] array = Face();
			Vector3[] array2 = Face();
			Il2CppStructArray<Vector3> val = new Il2CppStructArray<Vector3>((long)(array.Length + array2.Length));
			Il2CppStructArray<Vector3> val2 = new Il2CppStructArray<Vector3>((long)((Il2CppArrayBase<Vector3>)(object)val).Length);
			Il2CppStructArray<Color> val3 = new Il2CppStructArray<Color>((long)((Il2CppArrayBase<Vector3>)(object)val).Length);
			for (int i = 0; i < array.Length; i++)
			{
				((Il2CppArrayBase<Vector3>)(object)val)[i] = array[i];
				((Il2CppArrayBase<Vector3>)(object)val2)[i] = Vector3.up;
				((Il2CppArrayBase<Color>)(object)val3)[i] = Color.white;
				((Il2CppArrayBase<Vector3>)(object)val)[array.Length + i] = array2[i];
				((Il2CppArrayBase<Vector3>)(object)val2)[array.Length + i] = Vector3.down;
				((Il2CppArrayBase<Color>)(object)val3)[array.Length + i] = Color.white;
			}
			int[] array3 = new int[9] { 0, 1, 2, 3, 5, 4, 4, 5, 6 };
			Il2CppStructArray<int> val4 = new Il2CppStructArray<int>((long)(array3.Length * 2));
			for (int j = 0; j < array3.Length; j++)
			{
				((Il2CppArrayBase<int>)(object)val4)[j] = array3[j];
				((Il2CppArrayBase<int>)(object)val4)[array3.Length + j] = array.Length + array3[array3.Length - 1 - j];
			}
			Mesh val5 = new Mesh
			{
				name = "BeaconArrowSource"
			};
			val5.vertices = val;
			val5.normals = val2;
			val5.colors = val3;
			val5.triangles = val4;
			val5.RecalculateBounds();
			return val5;
		}

		private static Vector3[] Face()
		{
			//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_0032: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00b9: 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)
			return (Vector3[])(object)new Vector3[7]
			{
				new Vector3(0f, 0f, 0f),
				new Vector3(-0.3f, 0f, -0.45f),
				new Vector3(0.3f, 0f, -0.45f),
				new Vector3(-0.11f, 0f, -0.45f),
				new Vector3(0.11f, 0f, -0.45f),
				new Vector3(-0.11f, 0f, -1f),
				new Vector3(0.11f, 0f, -1f)
			};
		}
	}
	internal static class ProceduralRing
	{
		private const int Segments = 48;

		private const float OuterRadius = 0.5f;

		private const float Thickness = 0.18f;

		private const float EdgeSoftness = 0.85f;

		private const int Rings = 3;

		public static Mesh Build()
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Expected O, but got Unknown
			int num = 144;
			float num2 = 0.41f;
			float num3 = 0.14999998f;
			float[] array = new float[3]
			{
				0.5f,
				(0.5f + num2) * 0.5f,
				num2
			};
			float[] array2 = new float[3] { num3, 1f, num3 };
			Il2CppStructArray<Vector3> val = new Il2CppStructArray<Vector3>((long)(num * 2));
			Il2CppStructArray<Vector3> val2 = new Il2CppStructArray<Vector3>((long)((Il2CppArrayBase<Vector3>)(object)val).Length);
			Il2CppStructArray<Color> val3 = new Il2CppStructArray<Color>((long)((Il2CppArrayBase<Vector3>)(object)val).Length);
			Vector3 val4 = default(Vector3);
			Color val5 = default(Color);
			for (int i = 0; i < 48; i++)
			{
				float num4 = (float)i / 48f * (float)Math.PI * 2f;
				((Vector3)(ref val4))..ctor(Mathf.Cos(num4), 0f, Mathf.Sin(num4));
				for (int j = 0; j < 3; j++)
				{
					int num5 = i * 3 + j;
					((Color)(ref val5))..ctor(1f, 1f, 1f, array2[j]);
					((Il2CppArrayBase<Vector3>)(object)val)[num5] = val4 * array[j];
					((Il2CppArrayBase<Vector3>)(object)val2)[num5] = Vector3.up;
					((Il2CppArrayBase<Color>)(object)val3)[num5] = val5;
					((Il2CppArrayBase<Vector3>)(object)val)[num + num5] = ((Il2CppArrayBase<Vector3>)(object)val)[num5];
					((Il2CppArrayBase<Vector3>)(object)val2)[num + num5] = Vector3.down;
					((Il2CppArrayBase<Color>)(object)val3)[num + num5] = val5;
				}
			}
			Il2CppStructArray<int> val6 = new Il2CppStructArray<int>(1152L);
			int num6 = 0;
			for (int k = 0; k < 48; k++)
			{
				int num7 = (k + 1) % 48;
				for (int l = 0; l < 2; l++)
				{
					int num8 = k * 3 + l;
					int num9 = num8 + 1;
					int num10 = num7 * 3 + l;
					int num11 = num10 + 1;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num8;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num9;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num10;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num10;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num9;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num11;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num + num8;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num + num10;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num + num9;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num + num10;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num + num11;
					((Il2CppArrayBase<int>)(object)val6)[num6++] = num + num9;
				}
			}
			Mesh val7 = new Mesh
			{
				name = "BeaconRingSource"
			};
			val7.vertices = val;
			val7.normals = val2;
			val7.colors = val3;
			val7.triangles = val6;
			val7.RecalculateBounds();
			return val7;
		}
	}
	internal static class ModLog
	{
		public static ManualLogSource Source;

		[Conditional("DEVTOOLS")]
		public static void Debug(string message)
		{
			ManualLogSource source = Source;
			if (source != null)
			{
				source.LogInfo((object)message);
			}
		}

		public static void Msg(string message)
		{
			ManualLogSource source = Source;
			if (source != null)
			{
				source.LogInfo((object)message);
			}
		}

		public static void Warning(string message)
		{
			ManualLogSource source = Source;
			if (source != null)
			{
				source.LogWarning((object)message);
			}
		}

		public static void Error(string message)
		{
			ManualLogSource source = Source;
			if (source != null)
			{
				source.LogError((object)message);
			}
		}
	}
	internal static class NetworkContext
	{
		public static NetworkRunner Runner
		{
			get
			{
				FusionNetworkManager instance = FusionNetworkManager.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return null;
				}
				NetworkRunner runner = instance._runner;
				if ((Object)(object)runner == (Object)null || !runner.IsRunning)
				{
					return null;
				}
				return runner;
			}
		}

		public static PlayerManager LocalPlayerManager
		{
			get
			{
				ClientPlayer instance = ClientPlayer.Instance;
				return ((Object)(object)instance == (Object)null) ? null : instance.playerMan;
			}
		}

		public static ThirdPersonManager LocalBody
		{
			get
			{
				PlayerManager localPlayerManager = LocalPlayerManager;
				return ((Object)(object)localPlayerManager == (Object)null) ? null : localPlayerManager.thirdPersonMan;
			}
		}

		public static Camera LocalCamera
		{
			get
			{
				PlayerManager localPlayerManager = LocalPlayerManager;
				if ((Object)(object)localPlayerManager != (Object)null)
				{
					FPSController fpsScript = localPlayerManager.fpsScript;
					if ((Object)(object)fpsScript != (Object)null && (Object)(object)fpsScript.playerCamera != (Object)null)
					{
						return fpsScript.playerCamera;
					}
					InteractManager interactMan = localPlayerManager.interactMan;
					if ((Object)(object)interactMan != (Object)null && (Object)(object)interactMan.mainCamera != (Object)null)
					{
						return interactMan.mainCamera;
					}
				}
				return Camera.main;
			}
		}

		public static ulong LocalSteamId
		{
			get
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					return SteamUser.GetSteamID().m_SteamID;
				}
				catch
				{
					return 0uL;
				}
			}
		}

		public static CSteamID Lobby
		{
			get
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: 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)
				//IL_0014: 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_0037: Unknown result type (might be due to invalid IL or missing references)
				PlatformManager instance = PlatformManager.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return default(CSteamID);
				}
				return new CSteamID
				{
					m_SteamID = instance._lobbyID
				};
			}
		}
	}
	internal sealed class PingField
	{
		public const int MostPerPlayer = 5;

		private readonly List<PingMarker> _markers = new List<PingMarker>();

		public void Place(ulong owner, Vector3 point, Vector3 normal, Transform follow, Color colour, float lifetime)
		{
			//IL_002d: 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)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			MarkerMesh.Ensure();
			if (MarkerMesh.Ready)
			{
				EvictSame(follow);
				EvictOldest(owner);
				_markers.Add(new PingMarker(owner, point, normal, follow, colour, lifetime, NetworkContext.LocalCamera));
			}
		}

		public void LateTick()
		{
			if (_markers.Count == 0)
			{
				return;
			}
			Camera localCamera = NetworkContext.LocalCamera;
			for (int num = _markers.Count - 1; num >= 0; num--)
			{
				if (_markers[num].Expired)
				{
					_markers[num].Destroy();
					_markers.RemoveAt(num);
				}
				else
				{
					_markers[num].Aim(localCamera);
				}
			}
		}

		public void Clear()
		{
			foreach (PingMarker marker in _markers)
			{
				marker.Destroy();
			}
			_markers.Clear();
		}

		private void EvictSame(Transform follow)
		{
			if ((Object)(object)follow == (Object)null)
			{
				return;
			}
			for (int num = _markers.Count - 1; num >= 0; num--)
			{
				Transform following = _markers[num].Following;
				if (!((Object)(object)following == (Object)null) && !(((Il2CppObjectBase)following).Pointer != ((Il2CppObjectBase)follow).Pointer))
				{
					_markers[num].Destroy();
					_markers.RemoveAt(num);
				}
			}
		}

		private void EvictOldest(ulong owner)
		{
			int num = 0;
			foreach (PingMarker marker in _markers)
			{
				if (marker.Owner == owner)
				{
					num++;
				}
			}
			if (num < 5)
			{
				return;
			}
			for (int i = 0; i < _markers.Count; i++)
			{
				if (_markers[i].Owner == owner)
				{
					_markers[i].Destroy();
					_markers.RemoveAt(i);
					break;
				}
			}
		}
	}
	internal sealed class PingInput
	{
		private const float Cooldown = 0.1f;

		private readonly PingField _field;

		private readonly PingSync _sync;

		private float _nextAllowed;

		public PingInput(PingField field, PingSync sync)
		{
			_field = field;
			_sync = sync;
		}

		public void Tick()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(BeaconPlugin.PingKey.Value) && !(Time.unscaledTime < _nextAllowed) && Allowed())
			{
				Camera localCamera = NetworkContext.LocalCamera;
				if (!((Object)(object)localCamera == (Object)null) && PingReach.Find(((Component)localCamera).transform.position, ((Component)localCamera).transform.forward, 100f, out var hit))
				{
					_nextAllowed = Time.unscaledTime + 0.1f;
					int num = ShirtColour.LocalIndex();
					float lifetime = 6f;
					NetworkObject val = PingTarget.Creature(((RaycastHit)(ref hit)).collider);
					Transform follow = (((Object)(object)val == (Object)null) ? null : ((Component)val).transform);
					uint target = ((!((Object)(object)val == (Object)null)) ? val.Id.Raw : 0u);
					_field.Place(NetworkContext.LocalSteamId, ((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, follow, ShirtColour.Of(num), lifetime);
					_sync.Add(((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, target, num, lifetime);
				}
			}
		}

		private static bool Allowed()
		{
			PlayerManager localPlayerManager = NetworkContext.LocalPlayerManager;
			if ((Object)(object)localPlayerManager == (Object)null)
			{
				return false;
			}
			return !localPlayerManager.paused && !localPlayerManager.dead && !localPlayerManager.customizablesMenuOpen && !localPlayerManager.dontAllowLockCursor;
		}
	}
	internal sealed class PingMarker
	{
		private sealed class Piece
		{
			public readonly Transform Transform;

			private readonly Material _visible;

			private readonly Material _hidden;

			private readonly Color _colour;

			public Piece(string name, Transform parent, Mesh mesh, Color colour)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Expected O, but got Unknown
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				_colour = colour;
				GameObject val = new GameObject(name);
				val.transform.SetParent(parent, false);
				Transform = val.transform;
				_visible = Draw(val, mesh, MarkerMesh.Material);
				if (!((Object)(object)MarkerMesh.Occluded == (Object)null))
				{
					GameObject val2 = new GameObject("Behind");
					val2.transform.SetParent(Transform, false);
					_hidden = Draw(val2, mesh, MarkerMesh.Occluded);
				}
			}

			public void Fade(float alpha)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				Set(_visible, new Color(_colour.r, _colour.g, _colour.b, alpha));
				Set(_hidden, new Color(_colour.r * 0.45f, _colour.g * 0.45f, _colour.b * 0.45f, alpha * 0.5f));
			}

			private static Material Draw(GameObject on, Mesh mesh, Material material)
			{
				on.AddComponent<MeshFilter>().sharedMesh = mesh;
				MeshRenderer val = on.AddComponent<MeshRenderer>();
				((Renderer)val).material = material;
				((Renderer)val).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val).receiveShadows = false;
				return ((Renderer)val).material;
			}

			private static void Set(Material material, Color colour)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)material == (Object)null))
				{
					if (material.HasProperty("_Color"))
					{
						material.SetColor("_Color", colour);
					}
					if (material.HasProperty("_BaseColor"))
					{
						material.SetColor("_BaseColor", colour);
					}
				}
			}
		}

		private const float RingLift = 0.05f;

		private const float RingWidth = 0.68f;

		private const float MinimumRollAngle = 4f;

		private const float HoverLow = 0.135f;

		private const float HoverSwing = 0.11f;

		private const float BobSpeed = 3.2f;

		private const float ArrivalDuration = 0.3f;

		private const float ShrinkDuration = 0.5f;

		private const float ArrowArrivalScale = 2.6f;

		private const float RingArrivalScale = 0f;

		private const float RingPulse = 0.09f;

		private const float SolidDistance = 8f;

		private const float FaintDistance = 40f;

		private const float FaintestAlpha = 0.3f;

		private const float OccludedDim = 0.45f;

		private const float OccludedAlpha = 0.5f;

		private readonly GameObject _object;

		private readonly Piece _arrow;

		private readonly Piece _ring;

		private readonly Vector3 _normal;

		private readonly float _placedAt;

		private readonly Transform _follow;

		private readonly float _followHeight;

		private readonly bool _follows;

		private readonly Hittable _hittable;

		private readonly PlayerManager _person;

		private float _expiresAt;

		private Vector3 _point;

		private Quaternion _rotation;

		public readonly ulong Owner;

		public Transform Following => _follow;

		public bool Expired => Time.unscaledTime >= _expiresAt;

		public PingMarker(ulong owner, Vector3 point, Vector3 normal, Transform follow, Color colour, float lifetime, Camera camera)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0075: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_00fb: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			Owner = owner;
			_follow = follow;
			_placedAt = Time.unscaledTime;
			_expiresAt = _placedAt + lifetime;
			if ((Object)(object)follow != (Object)null)
			{
				_normal = Vector3.up;
				_follows = true;
				_followHeight = PingTarget.HoverHeight(follow);
				_point = follow.position + Vector3.up * _followHeight;
				_hittable = ((Component)follow).GetComponentInChildren<Hittable>(true);
				ThirdPersonManager componentInChildren = ((Component)follow).GetComponentInChildren<ThirdPersonManager>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					_person = componentInChildren.playerMan;
				}
			}
			else
			{
				_point = point;
				_normal = normal;
			}
			_rotation = Quaternion.LookRotation(-_normal, Sideways(_normal)) * MarkerMesh.Correction;
			_object = new GameObject("BeaconPing");
			_object.transform.position = _point;
			Object.DontDestroyOnLoad((Object)(object)_object);
			_arrow = new Piece("Arrow", _object.transform, MarkerMesh.Mesh, colour);
			if ((Object)(object)_follow == (Object)null)
			{
				_ring = new Piece("Ring", _object.transform, MarkerMesh.Ring, colour);
			}
			PingSound.PlayOn(_object, 1f);
			Aim(camera);
		}

		public void Aim(Camera camera)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_009a: 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_00b4: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: 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_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: 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_0053: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_object == (Object)null || (Object)(object)camera == (Object)null)
			{
				return;
			}
			if (_follows)
			{
				if (Gone())
				{
					Cut();
				}
				else
				{
					_point = _follow.position + Vector3.up * _followHeight;
					_object.transform.position = _point;
				}
			}
			Vector3 position = ((Component)camera).transform.position;
			Roll(position - _point);
			float num = 0.8f;
			float num2 = Leaving();
			float alpha = Alpha(Vector3.Distance(position, _point));
			float num3 = Mathf.Sin((Time.unscaledTime - _placedAt) * 3.2f) * 0.5f + 0.5f;
			float num4 = num * MarkerMesh.UnitScale * Arriving(2.6f) * num2;
			_arrow.Transform.localRotation = _rotation;
			_arrow.Transform.localScale = Vector3.one * num4;
			_arrow.Transform.localPosition = _normal * ((0.135f + num3 * 0.11f) * num) - _rotation * (MarkerMesh.Tip * num4);
			_arrow.Fade(alpha);
			if (_ring != null)
			{
				float num5 = num * 0.68f * Mathf.Lerp(1.09f, 0.90999997f, num3) * Arriving(0f) * num2;
				_ring.Transform.localRotation = Quaternion.FromToRotation(Vector3.up, _normal);
				_ring.Transform.localScale = Vector3.one * num5;
				_ring.Transform.localPosition = _normal * (0.05f * num);
				_ring.Fade(alpha);
			}
		}

		public void Destroy()
		{
			if ((Object)(object)_object != (Object)null)
			{
				Object.Destroy((Object)(object)_object);
			}
		}

		private bool Gone()
		{
			if ((Object)(object)_follow == (Object)null)
			{
				return true;
			}
			if ((Object)(object)_person != (Object)null && _person.dead)
			{
				return true;
			}
			return (Object)(object)_hittable != (Object)null && _hittable.maxHealth > 0f && _hittable.health <= 0f;
		}

		private void Cut()
		{
			float num = Time.unscaledTime + 0.5f;
			if (num < _expiresAt)
			{
				_expiresAt = num;
			}
		}

		private static float Alpha(float distance)
		{
			return Mathf.Lerp(1f, 0.3f, Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(8f, 40f, distance)));
		}

		private float Arriving(float from)
		{
			float num = (Time.unscaledTime - _placedAt) / 0.3f;
			if (num >= 1f)
			{
				return 1f;
			}
			float num2 = 1f - num;
			return Mathf.Lerp(from, 1f, 1f - num2 * num2 * num2);
		}

		private float Leaving()
		{
			return Mathf.SmoothStep(0f, 1f, (_expiresAt - Time.unscaledTime) / 0.5f);
		}

		private void Roll(Vector3 toCamera)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane(toCamera, _normal);
			if (!(((Vector3)(ref val)).magnitude < ((Vector3)(ref toCamera)).magnitude * Mathf.Sin((float)Math.PI / 45f)))
			{
				_rotation = Quaternion.LookRotation(-_normal, val) * MarkerMesh.Correction;
			}
		}

		private static Vector3 Sideways(Vector3 normal)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.Cross(normal, Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude < Mathf.Epsilon)
			{
				val = Vector3.Cross(normal, Vector3.forward);
			}
			return ((Vector3)(ref val)).normalized;
		}
	}
	internal static class PingReach
	{
		private const string SeeThroughLayer = "Curb";

		private static readonly string[] LookPast = new string[2] { "AboveCollider", "ForestRoof" };

		private static int _mask;

		private static bool _built;

		public static int Mask
		{
			get
			{
				if (_built)
				{
					return _mask;
				}
				_built = true;
				_mask = -5;
				int num = LayerMask.NameToLayer("Curb");
				if (num >= 0)
				{
					_mask &= ~(1 << num);
				}
				else
				{
					ModLog.Warning("No layer called 'Curb', so pings will stop on fences.");
				}
				return _mask;
			}
		}

		public static bool Find(Vector3 origin, Vector3 direction, float reach, out RaycastHit hit)
		{
			//IL_0002: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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)
			hit = default(RaycastHit);
			Il2CppStructArray<RaycastHit> val = Physics.RaycastAll(origin, direction, reach, Mask, (QueryTriggerInteraction)1);
			if (val == null)
			{
				return false;
			}
			bool flag = false;
			for (int i = 0; i < ((Il2CppArrayBase<RaycastHit>)(object)val).Length; i++)
			{
				RaycastHit val2 = ((Il2CppArrayBase<RaycastHit>)(object)val)[i];
				if (!Ignored(((RaycastHit)(ref val2)).collider) && (!flag || !(((RaycastHit)(ref val2)).distance >= ((RaycastHit)(ref hit)).distance)))
				{
					hit = val2;
					flag = true;
				}
			}
			return flag;
		}

		private static bool Ignored(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return true;
			}
			string[] lookPast = LookPast;
			foreach (string value in lookPast)
			{
				if (((Object)collider).name.StartsWith(value, StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		public static string Describe(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return "nothing";
			}
			int layer = ((Component)collider).gameObject.layer;
			return $"'{((Object)collider).name}' on layer {layer} ({LayerMask.LayerToName(layer)})";
		}

		public static string Identify(Collider collider)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)collider == (Object)null)
			{
				return "nothing";
			}
			NetworkObject componentInParent = ((Component)collider).GetComponentInParent<NetworkObject>(true);
			if ((Object)(object)componentInParent == (Object)null)
			{
				return "static, under " + Path(((Component)collider).transform);
			}
			return $"NetworkObject {componentInParent.Id} on '{((Object)componentInParent).name}', under {Path(((Component)collider).transform)}";
		}

		private static string Path(Transform t)
		{
			List<string> list = new List<string>();
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				list.Insert(0, ((Object)val).name);
				val = val.parent;
			}
			return string.Join("/", list);
		}
	}
	internal static class PingSound
	{
		private const float SpatialBlend = 0.75f;

		private static bool _warned;

		public static void PlayOn(GameObject marker, float volume)
		{
			AudioSource val = Alert();
			if ((Object)(object)val == (Object)null || (Object)(object)val.clip == (Object)null)
			{
				WarnOnce();
				return;
			}
			AudioSource val2 = marker.AddComponent<AudioSource>();
			val2.clip = val.clip;
			val2.outputAudioMixerGroup = val.outputAudioMixerGroup;
			val2.spatialBlend = 0.75f;
			val2.volume = volume;
			val2.Play();
		}

		private static AudioSource Alert()
		{
			StoreManager instance = StoreManager.Instance;
			return ((Object)(object)instance == (Object)null) ? null : instance.alertSuccessAudio;
		}

		private static void WarnOnce()
		{
			if (!_warned)
			{
				_warned = true;
				ModLog.Warning("The store's alert sound is not available, so pings will be silent.");
			}
		}
	}
	internal sealed class PingSync
	{
		private struct Outgoing
		{
			public int Id;

			public uint Target;

			public Vector3 Point;

			public Vector3 Normal;

			public float ExpiresAt;
		}

		private const string Key = "beacon";

		private const string Version = "3";

		private const char FieldSeparator = '|';

		private const char PartSeparator = ':';

		private const float PollInterval = 0.2f;

		private const float PublishInterval = 0.25f;

		private const string PositionFormat = "0.##";

		private const string NormalFormat = "0.###";

		private const int PartsPerPing = 8;

		private readonly PingField _field;

		private readonly List<Outgoing> _mine = new List<Outgoing>();

		private readonly Dictionary<ulong, int> _highest = new Dictionary<ulong, int>();

		private readonly StringBuilder _payload = new StringBuilder();

		private float _nextPoll;

		private float _nextPublish;

		private string _published;

		private int _lastId;

		private int _colourIndex = -1;

		private bool _changed;

		public PingSync(PingField field)
		{
			_field = field;
		}

		public void Tick()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				CSteamID lobby = NetworkContext.Lobby;
				if (lobby.m_SteamID != 0)
				{
					Expire();
					Publish(lobby);
					if (!(Time.unscaledTime < _nextPoll))
					{
						_nextPoll = Time.unscaledTime + 0.2f;
						Poll(lobby);
					}
				}
			}
			catch (Exception value)
			{
				ModLog.Error($"Sync: {value}");
			}
		}

		public void Add(Vector3 point, Vector3 normal, uint target, int colourIndex, float lifetime)
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			if (target != 0)
			{
				for (int num = _mine.Count - 1; num >= 0; num--)
				{
					if (_mine[num].Target == target)
					{
						_mine.RemoveAt(num);
					}
				}
			}
			if (_mine.Count >= 5)
			{
				_mine.RemoveAt(0);
			}
			_mine.Add(new Outgoing
			{
				Id = ++_lastId,
				Target = target,
				Point = point,
				Normal = normal,
				ExpiresAt = Time.unscaledTime + lifetime
			});
			_colourIndex = colourIndex;
			_changed = true;
		}

		public void Clear()
		{
			_mine.Clear();
			_highest.Clear();
			_published = null;
			_changed = false;
		}

		private void Expire()
		{
			for (int num = _mine.Count - 1; num >= 0; num--)
			{
				if (!(Time.unscaledTime < _mine[num].ExpiresAt))
				{
					_mine.RemoveAt(num);
					_changed = true;
				}
			}
		}

		private void Publish(CSteamID lobby)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (_changed && !(Time.unscaledTime < _nextPublish))
			{
				string text = Serialise();
				_changed = false;
				if (!(text == _published))
				{
					SteamMatchmaking.SetLobbyMemberData(lobby, "beacon", text);
					_published = text;
					_nextPublish = Time.unscaledTime + 0.25f;
				}
			}
		}

		private string Serialise()
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			if (_mine.Count == 0)
			{
				return string.Empty;
			}
			_payload.Clear();
			_payload.Append("3").Append('|').Append(Text(_colourIndex));
			foreach (Outgoing item in _mine)
			{
				_payload.Append('|').Append(Text(item.Id)).Append(':')
					.Append(item.Target.ToString(CultureInfo.InvariantCulture))
					.Append(':')
					.Append(Number(item.Point.x, "0.##"))
					.Append(':')
					.Append(Number(item.Point.y, "0.##"))
					.Append(':')
					.Append(Number(item.Point.z, "0.##"))
					.Append(':')
					.Append(Number(item.Normal.x, "0.###"))
					.Append(':')
					.Append(Number(item.Normal.y, "0.###"))
					.Append(':')
					.Append(Number(item.Normal.z, "0.###"));
			}
			return _payload.ToString();
		}

		private void Poll(CSteamID lobby)
		{
			//IL_0007: 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_0015: 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_002c: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			ulong localSteamId = NetworkContext.LocalSteamId;
			int numLobbyMembers = SteamMatchmaking.GetNumLobbyMembers(lobby);
			for (int i = 0; i < numLobbyMembers; i++)
			{
				CSteamID lobbyMemberByIndex = SteamMatchmaking.GetLobbyMemberByIndex(lobby, i);
				if (lobbyMemberByIndex.m_SteamID != localSteamId)
				{
					string lobbyMemberData = SteamMatchmaking.GetLobbyMemberData(lobby, lobbyMemberByIndex, "beacon");
					if (!string.IsNullOrEmpty(lobbyMemberData))
					{
						Read(lobbyMemberByIndex.m_SteamID, lobbyMemberData);
					}
				}
			}
		}

		private void Read(ulong owner, string raw)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_00a7: 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)
			string[] array = raw.Split('|');
			if (array.Length < 3 || array[0] != "3" || !int.TryParse(array[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
			{
				return;
			}
			_highest.TryGetValue(owner, out var value);
			int num = value;
			Color colour = ShirtColour.Of(result);
			for (int i = 2; i < array.Length; i++)
			{
				if (ParsePing(array[i], out var id, out var target, out var point, out var normal) && id > value)
				{
					Transform follow = PingTarget.Resolve(target);
					_field.Place(owner, point, normal, follow, colour, 6f);
					if (id > num)
					{
						num = id;
					}
				}
			}
			_highest[owner] = num;
		}

		private static bool ParsePing(string text, out int id, out uint target, out Vector3 point, out Vector3 normal)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_00e9: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			id = 0;
			target = 0u;
			point = Vector3.zero;
			normal = Vector3.up;
			string[] array = text.Split(':');
			if (array.Length != 8)
			{
				return false;
			}
			if (!int.TryParse(array[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out id))
			{
				return false;
			}
			if (!uint.TryParse(array[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out target))
			{
				return false;
			}
			if (!Coordinate(array[2], out var value) || !Coordinate(array[3], out var value2) || !Coordinate(array[4], out var value3))
			{
				return false;
			}
			if (!Coordinate(array[5], out var value4) || !Coordinate(array[6], out var value5) || !Coordinate(array[7], out var value6))
			{
				return false;
			}
			point = new Vector3(value, value2, value3);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(value4, value5, value6);
			if (((Vector3)(ref val)).sqrMagnitude < Mathf.Epsilon)
			{
				return false;
			}
			normal = ((Vector3)(ref val)).normalized;
			return true;
		}

		private static string Number(float value, string format)
		{
			return value.ToString(format, CultureInfo.InvariantCulture);
		}

		private static string Text(int value)
		{
			return value.ToString(CultureInfo.InvariantCulture);
		}

		private static bool Coordinate(string text, out float value)
		{
			return float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out value);
		}
	}
	internal static class PingTarget
	{
		private const string BodyHolder = "GFXHolder";

		private const string CrownBone = "mixamorig:HeadTop_End";

		private const float Gap = 0.2f;

		private const float ShortestCreature = 0.4f;

		private const float TallestCreature = 4f;

		public static NetworkObject Creature(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return null;
			}
			NetworkObject componentInParent = ((Component)collider).GetComponentInParent<NetworkObject>(true);
			if ((Object)(object)componentInParent == (Object)null)
			{
				return null;
			}
			if ((Object)(object)((Component)componentInParent).GetComponentInChildren<ThirdPersonManager>(true) != (Object)null)
			{
				return componentInParent;
			}
			if ((Object)(object)((Component)componentInParent).GetComponentInChildren<Pet>(true) != (Object)null)
			{
				return componentInParent;
			}
			if ((Object)(object)((Component)componentInParent).GetComponentInChildren<Enemy>(true) != (Object)null)
			{
				return componentInParent;
			}
			if ((Object)(object)Holder(((Component)componentInParent).transform) != (Object)null)
			{
				return componentInParent;
			}
			return null;
		}

		private static Transform Holder(Transform root)
		{
			foreach (Transform item in Interop.Safe<Transform>(((Component)root).GetComponentsInChildren<Transform>(true)))
			{
				if (((Object)item).name == "GFXHolder")
				{
					return item;
				}
			}
			return null;
		}

		public static Transform Resolve(uint raw)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (raw == 0)
			{
				return null;
			}
			NetworkRunner runner = NetworkContext.Runner;
			if ((Object)(object)runner == (Object)null)
			{
				return null;
			}
			NetworkObject val = default(NetworkObject);
			if (!runner.TryFindObject(new NetworkId(raw), ref val) || (Object)(object)val == (Object)null)
			{
				return null;
			}
			return ((Component)val).transform;
		}

		public static float HoverHeight(Transform root)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Transform val = Crown(root);
			float top;
			if ((Object)(object)val != (Object)null)
			{
				top = val.position.y - root.position.y;
				string text = "mixamorig:HeadTop_End";
			}
			else if (!Tallest(root, out top))
			{
				top = 0.4f;
				string text = "nothing to measure";
			}
			else
			{
				string text = "renderer bounds";
			}
			return Mathf.Clamp(top, 0.4f, 4f) + 0.2f;
		}

		private static Transform Crown(Transform root)
		{
			foreach (Transform item in Interop.Safe<Transform>(((Component)root).GetComponentsInChildren<Transform>(true)))
			{
				if (((Object)item).name == "mixamorig:HeadTop_End")
				{
					return item;
				}
			}
			return null;
		}

		private static bool Tallest(Transform root, out float top)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			top = 0f;
			bool flag = false;
			foreach (Renderer item in Interop.Safe<Renderer>(((Component)root).GetComponentsInChildren<Renderer>(true)))
			{
				if (!((Object)(object)((Il2CppObjectBase)item).TryCast<MeshRenderer>() == (Object)null) || !((Object)(object)((Il2CppObjectBase)item).TryCast<SkinnedMeshRenderer>() == (Object)null))
				{
					Bounds bounds = item.bounds;
					float num = ((Bounds)(ref bounds)).max.y - root.position.y;
					if (!flag || num > top)
					{
						top = num;
					}
					flag = true;
				}
			}
			return flag;
		}
	}
	internal static class ShirtColour
	{
		private static readonly string[] ColourProperties = new string[3] { "_BaseColor", "_Color", "_TintColor" };

		private const string InstanceSuffix = " (Instance)";

		public const int Unknown = -1;

		private static readonly Color Fallback = Color.white;

		private static bool _warned;

		public static int LocalIndex()
		{
			ThirdPersonManager localBody = NetworkContext.LocalBody;
			if ((Object)(object)localBody == (Object)null || (Object)(object)localBody.shirt == (Object)null || localBody.shirtColors == null)
			{
				return -1;
			}
			Material sharedMaterial = ((Renderer)localBody.shirt).sharedMaterial;
			if ((Object)(object)sharedMaterial == (Object)null)
			{
				return -1;
			}
			string text = Strip(((Object)sharedMaterial).name);
			for (int i = 0; i < ((Il2CppArrayBase<Material>)(object)localBody.shirtColors).Length; i++)
			{
				Material val = ((Il2CppArrayBase<Material>)(object)localBody.shirtColors)[i];
				if ((Object)(object)val != (Object)null && Strip(((Object)val).name) == text)
				{
					return i;
				}
			}
			return -1;
		}

		public static Color Of(int index)
		{
			//IL_0020: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//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_00a1: 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_00a8: 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)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			ThirdPersonManager localBody = NetworkContext.LocalBody;
			if ((Object)(object)localBody == (Object)null || localBody.shirtColors == null)
			{
				return Fallback;
			}
			if (index < 0 || index >= ((Il2CppArrayBase<Material>)(object)localBody.shirtColors).Length)
			{
				return Fallback;
			}
			Material val = ((Il2CppArrayBase<Material>)(object)localBody.shirtColors)[index];
			if ((Object)(object)val == (Object)null)
			{
				return Fallback;
			}
			string[] colourProperties = ColourProperties;
			foreach (string text in colourProperties)
			{
				if (val.HasProperty(text))
				{
					Color color = val.GetColor(text);
					if (!IsWhite(color))
					{
						color.a = 1f;
						return color;
					}
				}
			}
			WarnOnce(val);
			return Fallback;
		}

		private static bool IsWhite(Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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)
			return Mathf.Approximately(c.r, 1f) && Mathf.Approximately(c.g, 1f) && Mathf.Approximately(c.b, 1f);
		}

		private static void WarnOnce(Material material)
		{
			if (!_warned)
			{
				_warned = true;
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(41, 2);
				defaultInterpolatedStringHandler.AppendLiteral("Shirt material '");
				defaultInterpolatedStringHandler.AppendFormatted(((Object)material).name);
				defaultInterpolatedStringHandler.AppendLiteral("' (shader '");
				Shader shader = material.shader;
				defaultInterpolatedStringHandler.AppendFormatted((shader != null) ? ((Object)shader).name : null);
				defaultInterpolatedStringHandler.AppendLiteral("') carries no ");
				ModLog.Warning(defaultInterpolatedStringHandler.ToStringAndClear() + "colour this can read, so pings will all be white.");
			}
		}

		private static string Strip(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return name;
			}
			return name.EndsWith(" (Instance)") ? name.Substring(0, name.Length - " (Instance)".Length) : name;
		}
	}
}