Decompiled source of ThrowPreview v0.3.0

plugins/MycopunkThrowPreview/MycopunkThrowPreview.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
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 HarmonyLib;
using Microsoft.CodeAnalysis;
using MycopunkShared;
using Pigeon.Movement;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MycopunkThrowPreview")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: AssemblyInformationalVersion("0.3.0+fe8cef1291afd0a7f7ea8a9ddfd28d3607c4cdd5")]
[assembly: AssemblyProduct("MycopunkThrowPreview")]
[assembly: AssemblyTitle("MycopunkThrowPreview")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.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 MycopunkThrowPreview
{
	internal sealed class ArcDrawer
	{
		private GameObject _root;

		private LineRenderer _line;

		private LineRenderer _markerDot;

		private Material _lineMaterial;

		private Material _markerMaterial;

		private Texture2D _dashTexture;

		private float _dashRatio = -1f;

		private const int TextureWidth = 128;

		public void Draw(List<Vector3> points, bool hasEnd, Color color, float thickness, float dashLength, float gapLength)
		{
			//IL_00e0: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: 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_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: 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_028e: 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_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: 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)
			Camera localCamera = PlayerLook.LocalCamera;
			if ((Object)(object)localCamera == (Object)null || points.Count < 2 || !EnsureRoot(localCamera))
			{
				Hide();
				return;
			}
			float num = Mathf.Max(0.005f, thickness * 0.01f);
			float num2 = Mathf.Max(1f, dashLength);
			float num3 = Mathf.Max(0f, gapLength);
			float num4 = num2 / (num2 + num3);
			if (!Mathf.Approximately(num4, _dashRatio))
			{
				_dashRatio = num4;
				int num5 = Mathf.Clamp(Mathf.RoundToInt(128f * num4), 1, 128);
				for (int i = 0; i < 128; i++)
				{
					_dashTexture.SetPixel(i, 0, (i < num5) ? Color.white : Color.clear);
				}
				_dashTexture.Apply();
			}
			_line.textureScale = new Vector2(20f / (num2 + num3), 1f);
			SetColor(_lineMaterial, color);
			SetColor(_markerMaterial, color);
			LineRenderer line = _line;
			float startWidth = (_line.endWidth = num);
			line.startWidth = startWidth;
			_line.positionCount = points.Count;
			for (int j = 0; j < points.Count; j++)
			{
				_line.SetPosition(j, points[j]);
			}
			((Renderer)_line).enabled = true;
			((Renderer)_markerDot).enabled = hasEnd;
			if (!hasEnd)
			{
				return;
			}
			Vector3 val = points[points.Count - 1];
			float z = localCamera.WorldToViewportPoint(val).z;
			if (z <= 0f)
			{
				((Renderer)_markerDot).enabled = false;
				return;
			}
			Vector3 val2 = ((Component)localCamera).transform.position - val;
			if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
			{
				val += ((Vector3)(ref val2)).normalized * 0.025f;
			}
			float num7 = (localCamera.orthographic ? (localCamera.orthographicSize * 2f) : (2f * z * Mathf.Tan(localCamera.fieldOfView * (MathF.PI / 180f) * 0.5f)));
			float num8 = Mathf.Max(0.08f, num7 * 0.022f);
			float num9 = Mathf.Max(num, num7 * 0.004f);
			Vector3 val3 = ((Component)localCamera).transform.right * num8;
			LineRenderer markerDot = _markerDot;
			startWidth = (_markerDot.endWidth = num9 * 2f);
			markerDot.startWidth = startWidth;
			_markerDot.SetPosition(0, val - val3 * 0.025f);
			_markerDot.SetPosition(1, val + val3 * 0.025f);
		}

		public void Hide()
		{
			if ((Object)(object)_line != (Object)null)
			{
				((Renderer)_line).enabled = false;
			}
			if ((Object)(object)_markerDot != (Object)null)
			{
				((Renderer)_markerDot).enabled = false;
			}
		}

		public void Destroy()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			if ((Object)(object)_lineMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)_lineMaterial);
			}
			if ((Object)(object)_markerMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)_markerMaterial);
			}
			if ((Object)(object)_dashTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_dashTexture);
			}
			_root = null;
			_line = (_markerDot = null);
			_lineMaterial = (_markerMaterial = null);
			_dashTexture = null;
			_dashRatio = -1f;
		}

		private bool EnsureRoot(Camera camera)
		{
			//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)
			//IL_00cb: Expected O, but got Unknown
			//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_007c: 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_0090: Expected O, but got Unknown
			//IL_0126: 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_0133: Expected O, but got Unknown
			if ((Object)(object)_line != (Object)null && (Object)(object)_markerDot != (Object)null)
			{
				return true;
			}
			Shader val = Shader.Find("Universal Render Pipeline/Particles/Unlit") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Universal Render Pipeline/Unlit");
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("No suitable shader for the throw arc.");
			}
			if ((Object)(object)_lineMaterial == (Object)null)
			{
				_dashTexture = new Texture2D(128, 1, (TextureFormat)4, false)
				{
					wrapMode = (TextureWrapMode)0,
					filterMode = (FilterMode)0,
					hideFlags = (HideFlags)61
				};
				_lineMaterial = CreateMaterial(val, (Texture)(object)_dashTexture);
				_markerMaterial = CreateMaterial(val, (Texture)(object)Texture2D.whiteTexture);
			}
			_root = new GameObject("MycoThrowArc")
			{
				hideFlags = (HideFlags)52
			};
			int i;
			for (i = 0; i < 31 && (camera.cullingMask & (1 << i)) == 0; i++)
			{
			}
			_root.layer = i;
			_line = _root.AddComponent<LineRenderer>();
			Configure(_line, _lineMaterial);
			_line.textureMode = (LineTextureMode)1;
			GameObject val2 = new GameObject("Landing marker center")
			{
				layer = i
			};
			val2.transform.SetParent(_root.transform, false);
			_markerDot = val2.AddComponent<LineRenderer>();
			Configure(_markerDot, _markerMaterial);
			_markerDot.positionCount = 2;
			_markerDot.numCapVertices = 4;
			((Renderer)_markerDot).sortingOrder = 1;
			return true;
		}

		private static Material CreateMaterial(Shader shader, Texture texture)
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			Material val = new Material(shader)
			{
				hideFlags = (HideFlags)61,
				renderQueue = 3000
			};
			if (val.HasProperty("_MainTex"))
			{
				val.SetTexture("_MainTex", texture);
			}
			if (val.HasProperty("_BaseMap"))
			{
				val.SetTexture("_BaseMap", texture);
			}
			if (val.HasProperty("_Surface"))
			{
				val.SetFloat("_Surface", 1f);
			}
			if (val.HasProperty("_SrcBlend"))
			{
				val.SetFloat("_SrcBlend", 5f);
			}
			if (val.HasProperty("_DstBlend"))
			{
				val.SetFloat("_DstBlend", 10f);
			}
			if (val.HasProperty("_ZWrite"))
			{
				val.SetFloat("_ZWrite", 0f);
			}
			val.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			return val;
		}

		private static void SetColor(Material material, Color color)
		{
			//IL_0013: 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)
			if (material.HasProperty("_BaseColor"))
			{
				material.SetColor("_BaseColor", color);
			}
			if (material.HasProperty("_Color"))
			{
				material.SetColor("_Color", color);
			}
		}

		private static void Configure(LineRenderer line, Material material)
		{
			//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_002b: 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)
			((Renderer)line).sharedMaterial = material;
			line.useWorldSpace = true;
			line.alignment = (LineAlignment)0;
			((Renderer)line).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)line).receiveShadows = false;
			Color startColor = (line.endColor = Color.white);
			line.startColor = startColor;
			((Renderer)line).enabled = false;
		}
	}
	internal sealed class FireOffsetStore
	{
		public const float Tolerance = 0.01f;

		private const string Header = "# grenade\tright_m\tup_m\tforward_m  (Mycopunk Throw Preview: fire point relative to the camera)";

		private readonly string _path;

		private readonly Dictionary<string, float[]> _offsets = new Dictionary<string, float[]>();

		public int Count => _offsets.Count;

		public FireOffsetStore(string path)
		{
			_path = path;
		}

		public bool TryGet(string name, out float x, out float y, out float z)
		{
			x = (y = (z = 0f));
			if (name == null || !_offsets.TryGetValue(name, out var value))
			{
				return false;
			}
			x = value[0];
			y = value[1];
			z = value[2];
			return true;
		}

		public bool Set(string name, float x, float y, float z)
		{
			if (string.IsNullOrEmpty(name) || name.IndexOf('\t') >= 0 || name.IndexOf('\n') >= 0)
			{
				return false;
			}
			if (_offsets.TryGetValue(name, out var value) && Math.Abs(value[0] - x) <= 0.01f && Math.Abs(value[1] - y) <= 0.01f && Math.Abs(value[2] - z) <= 0.01f)
			{
				return false;
			}
			_offsets[name] = new float[3] { x, y, z };
			return true;
		}

		public void Load()
		{
			_offsets.Clear();
			if (File.Exists(_path))
			{
				string[] array = File.ReadAllLines(_path, Encoding.UTF8);
				for (int i = 0; i < array.Length; i++)
				{
					Parse(array[i], _offsets);
				}
			}
		}

		public void Save()
		{
			string directoryName = Path.GetDirectoryName(_path);
			if (!string.IsNullOrEmpty(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("# grenade\tright_m\tup_m\tforward_m  (Mycopunk Throw Preview: fire point relative to the camera)").Append('\n');
			List<string> list = new List<string>(_offsets.Keys);
			list.Sort(StringComparer.Ordinal);
			foreach (string item in list)
			{
				float[] array = _offsets[item];
				stringBuilder.Append(item).Append('\t').Append(F(array[0]))
					.Append('\t')
					.Append(F(array[1]))
					.Append('\t')
					.Append(F(array[2]))
					.Append('\n');
			}
			string text = _path + ".tmp";
			File.WriteAllText(text, stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
			if (File.Exists(_path))
			{
				File.Replace(text, _path, null);
			}
			else
			{
				File.Move(text, _path);
			}
		}

		internal static void Parse(string line, Dictionary<string, float[]> into)
		{
			if (!string.IsNullOrWhiteSpace(line) && !line.StartsWith("#"))
			{
				string[] array = line.Split('\t');
				if (array.Length >= 4 && array[0].Length != 0 && float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
				{
					into[array[0]] = new float[3] { result, result2, result3 };
				}
			}
		}

		private static string F(float v)
		{
			return v.ToString("0.000", CultureInfo.InvariantCulture);
		}
	}
	internal static class GrenadeAim
	{
		private sealed class Learned
		{
			public BulletData Data;

			public float Lifetime;
		}

		[HarmonyPatch(typeof(Player), "OnThrowPressed")]
		internal static class OnThrowPressedPatch
		{
			[HarmonyPrefix]
			private static void Prefix(CallbackContext context)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				CallbackContext val = context;
				_throwAction = ((CallbackContext)(ref val)).action;
			}
		}

		[HarmonyPatch(typeof(Player), "TryThrow")]
		internal static class TryThrowPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(Player __instance)
			{
				try
				{
					if (!_available || _releasing || !Plugin.GrenadeAim.Value || (Object)(object)__instance != (Object)(object)Player.LocalPlayer)
					{
						return true;
					}
					GrenadeGear val = Grenade(__instance);
					if ((Object)(object)val == (Object)null || ((Throwable)val).Active || ((IActivatedAbility)val).Charge < 1f)
					{
						return true;
					}
					if (_throwAction == null || !_throwAction.IsPressed())
					{
						return true;
					}
					_aiming = __instance;
					return false;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Grenade aiming failed; throwing normally: " + ex));
					_aiming = null;
					return true;
				}
			}
		}

		[HarmonyPatch(typeof(Throwable), "FireBullet")]
		internal static class FireBulletPatch
		{
			[HarmonyPostfix]
			private static void Postfix(Throwable __instance)
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: 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)
				//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_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)
				//IL_004f: 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_0065: 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_0071: Unknown result type (might be due to invalid IL or missing references)
				if (!(__instance is GrenadeGear) || (Object)(object)__instance.Player != (Object)(object)Player.LocalPlayer)
				{
					return;
				}
				FireData fireData = __instance.fireData;
				GearInfo info = ((IUpgradable)__instance).Info;
				if ((Object)(object)info == (Object)null || _offsets == null)
				{
					return;
				}
				Vector3 val = Quaternion.Inverse(PlayerLook.Rotation) * (fireData.firePosition - PlayerLook.Position);
				if (!_offsets.Set(((Object)info).name, val.x, val.y, val.z))
				{
					return;
				}
				try
				{
					_offsets.Save();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Could not save the grenade fire points: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(SimpleProjectileBullet), "Initialize")]
		internal static class BulletInitializePatch
		{
			[HarmonyPostfix]
			private static void Postfix(SimpleProjectileBullet __instance, BulletData data, IDamageSource source, BulletFlags flags)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//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_0003: 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_004e: 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_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)
				BulletData data2 = data;
				try
				{
					if (!(__instance is GrenadeBullet) || !BulletFlagsExtensions.IsOwner(flags))
					{
						return;
					}
					GrenadeGear val = (GrenadeGear)(object)((source is GrenadeGear) ? source : null);
					if (val == null)
					{
						return;
					}
					float num = Lifetime(__instance);
					GearInfo info = ((IUpgradable)val).Info;
					if (!((Object)(object)info == (Object)null))
					{
						LearnedData[info] = new Learned
						{
							Data = data2,
							Lifetime = ((num > 0f) ? num : 10f)
						};
						BulletData? predicted = _predicted;
						if (predicted.HasValue)
						{
							BulletData valueOrDefault = predicted.GetValueOrDefault();
							Plugin.Log.LogInfo((object)("grenade thrown (" + ((object)__instance).GetType().Name + ", lifetime " + num.ToString("F1") + " s, prediction from " + (_predictedLearned ? "its last throw" : "GunData") + "). predicted vs real: pos " + ((Vector3)(ref valueOrDefault.position)).ToString("F2") + " / " + ((Vector3)(ref data2.position)).ToString("F2") + ", dir " + ((Vector3)(ref valueOrDefault.direction)).ToString("F3") + " / " + ((Vector3)(ref data2.direction)).ToString("F3") + ", speed " + valueOrDefault.speed.ToString("F1") + " / " + data2.speed.ToString("F1") + ", gravity " + valueOrDefault.gravity.ToString("F2") + " / " + data2.gravity.ToString("F2") + ", bounces " + valueOrDefault.maxBounces + " / " + data2.maxBounces + ", surface mask " + valueOrDefault.surfaceCollisionMask + " / " + data2.surfaceCollisionMask + ", target mask " + valueOrDefault.targetCollisionMask + " / " + data2.targetCollisionMask + ", range " + valueOrDefault.range.maxDamageRange.ToString("F0") + " / " + data2.range.maxDamageRange.ToString("F0") + " | arc: " + _lastEnd));
							_predicted = null;
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Could not read the thrown grenade: " + ex));
				}
			}
		}

		private const BulletFlags OwnerFlags = (BulletFlags)11;

		private const int MaxSteps = 600;

		private const float DefaultLifetime = 10f;

		private static InputAction _throwAction;

		private static Player _aiming;

		private static bool _releasing;

		private static bool _available;

		private static FireOffsetStore _offsets;

		private static readonly Vector3 DefaultFireOffset = new Vector3(0.05f, -0.25f, 0.03f);

		private static readonly Dictionary<GearInfo, Learned> LearnedData = new Dictionary<GearInfo, Learned>();

		private static BulletData? _predicted;

		private static bool _predictedLearned;

		private static string _lastEnd = "";

		internal static bool Aiming => (Object)(object)_aiming != (Object)null;

		private static float Lifetime(SimpleProjectileBullet bullet)
		{
			return bullet.Lifetime;
		}

		public static void Install(Harmony harmony)
		{
			try
			{
				ModSetup.PatchTogether(harmony, new Type[4]
				{
					typeof(OnThrowPressedPatch),
					typeof(TryThrowPatch),
					typeof(FireBulletPatch),
					typeof(BulletInitializePatch)
				});
				_available = true;
			}
			catch (Exception ex)
			{
				Disable();
				Plugin.Log.LogWarning((object)("Grenade aiming unavailable: " + ex));
			}
		}

		internal static void Disable()
		{
			_available = false;
			_aiming = null;
		}

		public static void LoadOffsets(string path)
		{
			_offsets = new FireOffsetStore(path);
			try
			{
				_offsets.Load();
				Plugin.Log.LogInfo((object)("Grenade fire points: " + _offsets.Count + " known (" + path + ")."));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not read the grenade fire points; starting without them: " + ex.Message));
			}
		}

		private static Vector3 FireOffset(GearInfo info)
		{
			//IL_0028: 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)
			if (!((Object)(object)info != (Object)null) || _offsets == null || !_offsets.TryGet(((Object)info).name, out var x, out var y, out var z))
			{
				return DefaultFireOffset;
			}
			return new Vector3(x, y, z);
		}

		public static void Tick()
		{
			Player aiming = _aiming;
			if ((Object)(object)aiming == (Object)null)
			{
				return;
			}
			if ((Object)(object)AimedGrenade(aiming) == (Object)null)
			{
				_aiming = null;
			}
			else if (_throwAction == null || !_throwAction.IsPressed())
			{
				_aiming = null;
				_releasing = true;
				try
				{
					aiming.TryThrow();
				}
				finally
				{
					_releasing = false;
				}
			}
		}

		public static bool Fill(List<Vector3> points)
		{
			points.Clear();
			GrenadeGear val = (((Object)(object)_aiming != (Object)null) ? AimedGrenade(_aiming) : null);
			if ((Object)(object)val != (Object)null)
			{
				return Predict(val, points);
			}
			return false;
		}

		private static GrenadeGear AimedGrenade(Player player)
		{
			GrenadeGear val = ((player.IsAlive && (Object)(object)player == (Object)(object)Player.LocalPlayer) ? Grenade(player) : null);
			if ((Object)(object)val == (Object)null || ((Throwable)val).Active || ((IActivatedAbility)val).Charge < 1f || !Plugin.GrenadeAim.Value)
			{
				return null;
			}
			return val;
		}

		private static GrenadeGear Grenade(Player player)
		{
			IGear[] gear = player.Gear;
			if (gear == null || gear.Length <= 3)
			{
				return null;
			}
			IGear obj = gear[3];
			return (GrenadeGear)(object)((obj is GrenadeGear) ? obj : null);
		}

		private static bool Predict(GrenadeGear grenade, List<Vector3> points)
		{
			//IL_001f: 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)
			//IL_0027: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0057: 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_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_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00ea: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: 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_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: 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_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: 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_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			points.Clear();
			PlayerLook instance = PlayerLook.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			GearInfo info = ((IUpgradable)grenade).Info;
			GunData gunData = ((Throwable)grenade).gunData;
			FireData val = default(FireData);
			float num = 0f;
			Vector3 val2 = default(Vector3);
			Quaternion val3 = default(Quaternion);
			((Component)instance).transform.GetPositionAndRotation(ref val2, ref val3);
			Vector3 val4 = val2 + val3 * FireOffset(info);
			((GunData)(ref gunData)).PrepareFireData(ref val, val4, instance, ref num);
			BulletData bulletData = ((GunData)(ref gunData)).GetBulletData(ref val.firePosition, ref val.bulletRotation);
			((Throwable)grenade).ModifyBulletData(ref bulletData, (BulletFlags)11);
			float num2 = 10f;
			Learned value = null;
			_predictedLearned = (Object)(object)info != (Object)null && LearnedData.TryGetValue(info, out value);
			if (_predictedLearned)
			{
				BulletData data = value.Data;
				num2 = value.Lifetime;
				bulletData.speed = data.speed;
				bulletData.gravity = data.gravity;
				bulletData.maxBounces = data.maxBounces;
				bulletData.surfaceCollisionMask = data.surfaceCollisionMask;
				bulletData.targetCollisionMask = data.targetCollisionMask;
				bulletData.surfaceMagnetism = data.surfaceMagnetism;
				bulletData.targetMagnetism = data.targetMagnetism;
				bulletData.range = data.range;
				bulletData.impactSize = data.impactSize;
			}
			if (bulletData.surfaceCollisionMask == 0 && (Object)(object)Player.LocalPlayer != (Object)null)
			{
				bulletData.surfaceCollisionMask = ((LayerMask)(ref Player.LocalPlayer.groundLayerMask)).value;
			}
			_predicted = bulletData;
			Vector3 val5 = bulletData.direction * bulletData.speed;
			Vector3 val6 = bulletData.position;
			Vector3 val7 = bulletData.position;
			Quaternion rotation = bulletData.rotation;
			Quaternion rotation2 = bulletData.rotation;
			RaycastHit val8 = default(RaycastHit);
			int num3 = 0;
			points.Add(val7);
			int num4 = Mathf.Min(600, Mathf.CeilToInt(num2 / Time.fixedDeltaTime));
			float maxDamageRange = bulletData.range.maxDamageRange;
			for (int i = 0; i < num4; i++)
			{
				int num5 = IBullet.SimulateProjectile(ref bulletData, ref val5, ref val6, ref val7, ref rotation, ref rotation2, ref val8, (BulletFlags)11);
				Vector3 val9;
				if (num5 == 0)
				{
					points.Add(val7);
					if (maxDamageRange > 0f)
					{
						val9 = val7 - bulletData.position;
						if (((Vector3)(ref val9)).magnitude > maxDamageRange)
						{
							_lastEnd = "out of range after " + i + " steps, " + num3 + " bounces";
							return true;
						}
					}
					continue;
				}
				points.Add(((RaycastHit)(ref val8)).point);
				if (num3 >= bulletData.maxBounces)
				{
					string[] obj = new string[9]
					{
						"hit (",
						num5.ToString(),
						") at ",
						null,
						null,
						null,
						null,
						null,
						null
					};
					val9 = ((RaycastHit)(ref val8)).point;
					obj[3] = ((Vector3)(ref val9)).ToString("F1");
					obj[4] = " after ";
					obj[5] = i.ToString();
					obj[6] = " steps, ";
					obj[7] = num3.ToString();
					obj[8] = " bounces";
					_lastEnd = string.Concat(obj);
					return true;
				}
				num3++;
				val5 = Vector3.Reflect(val5, ((RaycastHit)(ref val8)).normal) * 0.75f;
				bulletData.direction = ((Vector3)(ref val5)).normalized;
				bulletData.position = ((RaycastHit)(ref val8)).point;
				val6 = (val7 = ((RaycastHit)(ref val8)).point);
			}
			_lastEnd = "no hit in " + num4 + " steps, " + num3 + " bounces";
			return true;
		}
	}
	internal static class HoldablePreview
	{
		[HarmonyPatch(typeof(HoldableObject), "StartThrow")]
		internal static class StartThrowPatch
		{
			[HarmonyPostfix]
			private static void Postfix(HoldableObject __instance)
			{
				_charging = __instance;
			}
		}

		private const int MaxSteps = 400;

		private const float Radius = 0.15f;

		private const float ConnectDistance = 2f;

		private static readonly List<Vector3> Targets = new List<Vector3>();

		private static HoldableObject _charging;

		private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[16];

		public static bool Connects { get; private set; }

		public static bool Tick(List<Vector3> points)
		{
			HoldableObject charging = _charging;
			if ((Object)(object)charging == (Object)null)
			{
				return false;
			}
			if (!charging.Active || (Object)(object)charging.player != (Object)(object)Player.LocalPlayer)
			{
				_charging = null;
				return false;
			}
			if (!Plugin.HoldableArc.Value || charging.startThrowTime <= 0f)
			{
				return false;
			}
			Rigidbody rigidbody = charging.rigidbody;
			if ((Object)(object)rigidbody == (Object)null)
			{
				return false;
			}
			Predict(charging, rigidbody, points);
			return true;
		}

		private static void Predict(HoldableObject h, Rigidbody rb, List<Vector3> points)
		{
			//IL_000c: 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_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)
			//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_0034: 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_0053: 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_0058: 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_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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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)
			//IL_0146: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: 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_015a: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			points.Clear();
			Vector3 val = ((Component)rb).transform.position;
			Vector3 val2 = h.CalculateCurrentThrowVelocity();
			PlayerLook instance = PlayerLook.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				val2 = ((Component)instance).transform.forward * Vector3.Dot(val2, PlayerLook.Forward);
			}
			Vector3 val3 = (rb.useGravity ? Physics.gravity : Vector3.zero);
			DeadPlayerPart val4 = (DeadPlayerPart)(object)((h is DeadPlayerPart) ? h : null);
			if (val4 != null)
			{
				val3 += new Vector3(0f, val4.thrownGravity, 0f);
			}
			float fixedDeltaTime = Time.fixedDeltaTime;
			float num = 1f / (1f + fixedDeltaTime * rb.linearDamping);
			Player localPlayer = Player.LocalPlayer;
			int num2 = (((Object)(object)localPlayer != (Object)null) ? ((LayerMask)(ref localPlayer.groundLayerMask)).value : (-5));
			if (num2 == 0)
			{
				num2 = -5;
			}
			Transform me = (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).transform : null);
			Connects = false;
			Vector3 offset = default(Vector3);
			DeadPlayerPart val5 = (DeadPlayerPart)(object)((h is DeadPlayerPart) ? h : null);
			bool flag = val5 != null && JoinTargets(val5, val, out offset);
			points.Add(val);
			if (flag && Joins(val, offset))
			{
				return;
			}
			for (int i = 0; i < 400; i++)
			{
				val2 = (val2 + val3 * fixedDeltaTime) * num;
				Vector3 val6 = val2 * fixedDeltaTime;
				float magnitude = ((Vector3)(ref val6)).magnitude;
				if (magnitude > 1E-05f && Cast(val, val6 / magnitude, magnitude, num2, ((Component)h).transform, me, out var point))
				{
					points.Add(point);
					if (flag)
					{
						Joins(point, offset);
					}
					break;
				}
				val += val6;
				points.Add(val);
				if (flag && Joins(val, offset))
				{
					break;
				}
			}
		}

		private static bool Joins(Vector3 bodyPosition, Vector3 offset)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_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_001d: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = bodyPosition + offset;
			foreach (Vector3 target in Targets)
			{
				Vector3 val2 = val - target;
				if (((Vector3)(ref val2)).sqrMagnitude < 4f)
				{
					return Connects = true;
				}
			}
			return false;
		}

		private static bool JoinTargets(DeadPlayerPart part, Vector3 bodyPosition, out Vector3 offset)
		{
			//IL_0001: 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_0061: 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_0067: 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)
			offset = default(Vector3);
			Targets.Clear();
			if ((Object)(object)part.ParentPlayer == (Object)null || part.repairProgress < 0f)
			{
				return false;
			}
			if (part.AreAllSectionsActive)
			{
				return false;
			}
			Dictionary<Player, List<DeadPlayerPart>> allParts = DeadPlayerPart.allParts;
			if (allParts == null || !allParts.TryGetValue(part.ParentPlayer, out var value))
			{
				return false;
			}
			if (!Centre(part, out var centre))
			{
				return false;
			}
			offset = centre - bodyPosition;
			foreach (DeadPlayerPart item in value)
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item != (Object)(object)part && Centre(item, out var centre2))
				{
					Targets.Add(centre2);
				}
			}
			return Targets.Count > 0;
		}

		private static bool Centre(DeadPlayerPart part, out Vector3 centre)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//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_0060: 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_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)
			centre = default(Vector3);
			PartSectionData[] sections = part.sections;
			if (sections == null)
			{
				return false;
			}
			int initialActiveSection = part.initialActiveSection;
			if (initialActiveSection < 0 || initialActiveSection >= sections.Length)
			{
				return false;
			}
			PartSectionData val = sections[initialActiveSection];
			GameObject parent = val.parent;
			BoxCollider mainCollider = val.mainCollider;
			if ((Object)(object)parent == (Object)null || (Object)(object)mainCollider == (Object)null)
			{
				return false;
			}
			centre = parent.transform.position + parent.transform.rotation * mainCollider.center;
			return true;
		}

		private static bool Cast(Vector3 from, Vector3 dir, float len, int mask, Transform self, Transform me, out Vector3 point)
		{
			//IL_0000: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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)
			int num = Physics.SphereCastNonAlloc(from, 0.15f, dir, Hits, len, mask, (QueryTriggerInteraction)1);
			float num2 = float.MaxValue;
			point = default(Vector3);
			for (int i = 0; i < num; i++)
			{
				Transform val = (((Object)(object)((RaycastHit)(ref Hits[i])).collider != (Object)null) ? ((Component)((RaycastHit)(ref Hits[i])).collider).transform : null);
				if (!((Object)(object)val == (Object)null) && !val.IsChildOf(self) && (!((Object)(object)me != (Object)null) || !val.IsChildOf(me)) && !(((RaycastHit)(ref Hits[i])).distance <= 0f) && ((RaycastHit)(ref Hits[i])).distance < num2)
				{
					num2 = ((RaycastHit)(ref Hits[i])).distance;
					point = ((RaycastHit)(ref Hits[i])).point;
				}
			}
			return num2 < float.MaxValue;
		}
	}
	internal static class MenuText
	{
		private static readonly Dictionary<string, Dictionary<string, string>> Names = new Dictionary<string, Dictionary<string, string>>
		{
			["en"] = new Dictionary<string, string>
			{
				["throw.grenade"] = "Hold to aim grenades, release to throw",
				["throw.arc"] = "Arc for thrown objects",
				["throw.color"] = "Arc color",
				["throw.revive_color"] = "Arc color when it revives"
			},
			["ja"] = new Dictionary<string, string>
			{
				["throw.grenade"] = "グレネードを長押しで狙い、離して投げる",
				["throw.arc"] = "投げる物の軌道を表示",
				["throw.color"] = "軌道の色",
				["throw.revive_color"] = "蘇生できるときの軌道の色"
			}
		};

		private static readonly Dictionary<string, Dictionary<string, string>> Descriptions = new Dictionary<string, Dictionary<string, string>> { ["ja"] = new Dictionary<string, string>
		{
			["throw.grenade"] = "グレネードキーを押している間は投げる場所を表示し、離すと投げます。短く押した場合はすぐに投げます。この変更は即時に反映されます。",
			["throw.arc"] = "持っている物を投げるためにチャージしている間、軌道を表示します。この変更は即時に反映されます。",
			["throw.color"] = "軌道の線の色です。不透明度は設定ファイルの値のままです。",
			["throw.revive_color"] = "味方のパーツを投げて、同じ味方の別のパーツに繋がる(蘇生が進む)ときの軌道の色です。不透明度は設定ファイルの値のままです。"
		} };

		public static object[] Label(string key)
		{
			return ModsMenuTag.Label(key, (IDictionary<string, Dictionary<string, string>>)Names, (IDictionary<string, Dictionary<string, string>>)Descriptions);
		}
	}
	[BepInPlugin("t4t5u0.mycopunk.throwpreview", "Mycopunk Throw Preview", "0.3.0")]
	[BepInDependency("doku_macaron.mycopunk.macaroncore", "1.1.0")]
	[MycoMod(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "t4t5u0.mycopunk.throwpreview";

		public const string Name = "Mycopunk Throw Preview";

		public const string Version = "0.3.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> GrenadeAim;

		internal static ConfigEntry<bool> HoldableArc;

		internal static ConfigEntry<Color> ArcColor;

		internal static ConfigEntry<Color> ReviveColor;

		internal static ConfigEntry<float> Thickness;

		internal static ConfigEntry<float> DashLength;

		internal static ConfigEntry<float> GapLength;

		private readonly ArcDrawer _drawer = new ArcDrawer();

		private readonly List<Vector3> _points = new List<Vector3>();

		private bool _failed;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			GrenadeAim = ((BaseUnityPlugin)this).Config.Bind<bool>("Grenade", "HoldToAim", true, new ConfigDescription("Hold the grenade key to see where it will go, release to throw (the game throws on press). A quick tap still throws at once. Takes effect at once.", (AcceptableValueBase)null, MenuText.Label("throw.grenade")));
			HoldableArc = ((BaseUnityPlugin)this).Config.Bind<bool>("Holdables", "ShowArc", true, new ConfigDescription("Show the arc while charging a throw of a held object (a teammate's part, barrels...). Takes effect at once.", (AcceptableValueBase)null, MenuText.Label("throw.arc")));
			ArcColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Style", "Color", new Color(1f, 1f, 1f, 0.75f), new ConfigDescription("Arc color (RRGGBBAA).", (AcceptableValueBase)null, MenuText.Label("throw.color")));
			ReviveColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Style", "ReviveColor", new Color(0.3f, 1f, 0.4f, 0.9f), new ConfigDescription("Arc color when a thrown teammate's part would join another of their parts (which revives them). RRGGBBAA.", (AcceptableValueBase)null, MenuText.Label("throw.revive_color")));
			Thickness = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "Thickness", 3f, "Arc thickness (1 unit = 0.01 meters).");
			DashLength = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "DashLength", 12f, "Dash length (1 unit = 0.05 meters).");
			GapLength = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "GapLength", 8f, "Gap length (1 unit = 0.05 meters; 0 = solid).");
			_harmony = new Harmony("t4t5u0.mycopunk.throwpreview");
			ModSetup.Try(Log, "grenade fire points", (Action)delegate
			{
				MycopunkThrowPreview.GrenadeAim.LoadOffsets(Path.Combine(Paths.BepInExRootPath, "ThrowPreview", "fire-offsets.tsv"));
			});
			ModSetup.Try(Log, "grenade aiming", (Action)delegate
			{
				MycopunkThrowPreview.GrenadeAim.Install(_harmony);
			});
			ModSetup.Try(Log, "held object arcs", (Action)delegate
			{
				_harmony.CreateClassProcessor(typeof(HoldablePreview.StartThrowPatch)).Patch();
			});
			ModSetup.Try(Log, "MODS tab", (Action)delegate
			{
				ModsMenu.Install(_harmony, (BaseUnityPlugin)(object)this);
			});
			ModSetup.Try(Log, "hotkey report", (Action)delegate
			{
				Hotkeys.ReportConflicts((BaseUnityPlugin)(object)this);
			});
			Log.LogInfo((object)("Mycopunk Throw Preview 0.3.0 loaded (grenade aim=" + GrenadeAim.Value + ", object arcs=" + HoldableArc.Value + ")."));
		}

		private void OnEnable()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(Redraw));
			RenderPipelineManager.beginCameraRendering += RedrawSrp;
		}

		private void OnDisable()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(Redraw));
			RenderPipelineManager.beginCameraRendering -= RedrawSrp;
			_drawer.Hide();
		}

		private void OnDestroy()
		{
			MycopunkThrowPreview.GrenadeAim.Disable();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_drawer.Destroy();
		}

		private void Update()
		{
			if (_failed)
			{
				return;
			}
			try
			{
				MycopunkThrowPreview.GrenadeAim.Tick();
			}
			catch (Exception ex)
			{
				_failed = true;
				MycopunkThrowPreview.GrenadeAim.Disable();
				_drawer.Hide();
				Log.LogError((object)("Throw preview failed and is turned off: " + ex));
			}
		}

		private void RedrawSrp(ScriptableRenderContext context, Camera camera)
		{
			Redraw(camera);
		}

		private void Redraw(Camera camera)
		{
			//IL_006c: 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)
			if (_failed || (Object)(object)camera != (Object)(object)PlayerLook.LocalCamera)
			{
				return;
			}
			try
			{
				bool hasEnd = MycopunkThrowPreview.GrenadeAim.Fill(_points);
				bool flag = MycopunkThrowPreview.GrenadeAim.Aiming;
				bool flag2 = false;
				if (!flag)
				{
					flag = HoldablePreview.Tick(_points);
					hasEnd = flag;
					flag2 = flag && HoldablePreview.Connects;
				}
				if (flag)
				{
					_drawer.Draw(_points, hasEnd, flag2 ? ReviveColor.Value : ArcColor.Value, Thickness.Value, DashLength.Value, GapLength.Value);
				}
				else
				{
					_drawer.Hide();
				}
			}
			catch (Exception ex)
			{
				_failed = true;
				MycopunkThrowPreview.GrenadeAim.Disable();
				_drawer.Hide();
				Log.LogError((object)("Throw preview failed and is turned off: " + ex));
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}