Decompiled source of BowTrajectory v1.1.1

BowTrajectory.dll

Decompiled 2 weeks 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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("BowTrajectory")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: AssemblyProduct("BowTrajectory")]
[assembly: AssemblyTitle("BowTrajectory")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.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 BowTrajectory
{
	internal static class BetterArcheryCompat
	{
		internal const string Guid = "ishid4.mods.betterarchery";

		private static bool _resolved;

		private static bool _present;

		private static ConfigEntry<bool> _improvementsEnabled;

		private static ConfigEntry<float> _arrowVelocity;

		private static ConfigEntry<float> _arrowGravity;

		private static ConfigEntry<Vector3> _arrowAimDir;

		internal static void Initialize()
		{
			Resolve();
		}

		internal static bool AppliesTo(Player player)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			if (!ImprovementsActive() || (Object)(object)player == (Object)null)
			{
				return false;
			}
			ItemData leftItem = ((Humanoid)player).GetLeftItem();
			if (leftItem?.m_shared != null)
			{
				return (int)leftItem.m_shared.m_itemType == 4;
			}
			return false;
		}

		internal static bool TryGetImprovements(out float gravity, out Vector3 aimDir)
		{
			//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_003b: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			gravity = 0f;
			aimDir = Vector3.zero;
			if (!ImprovementsActive())
			{
				return false;
			}
			gravity = _arrowGravity.Value;
			aimDir = ((_arrowAimDir != null) ? _arrowAimDir.Value : Vector3.zero);
			return true;
		}

		internal static bool TryGetBowVelocity(out float velocity)
		{
			velocity = 0f;
			if (!ImprovementsActive() || _arrowVelocity == null)
			{
				return false;
			}
			velocity = _arrowVelocity.Value;
			return true;
		}

		private static bool ImprovementsActive()
		{
			if (BowTrajectoryPlugin.UseBetterArcheryPhysics == null || !BowTrajectoryPlugin.UseBetterArcheryPhysics.Value)
			{
				return false;
			}
			Resolve();
			if (_present && _improvementsEnabled != null && _improvementsEnabled.Value)
			{
				return _arrowGravity != null;
			}
			return false;
		}

		private static void Resolve()
		{
			if (_resolved)
			{
				return;
			}
			_resolved = true;
			if (!Chainloader.PluginInfos.TryGetValue("ishid4.mods.betterarchery", out var value) || (Object)(object)((value != null) ? value.Instance : null) == (Object)null)
			{
				return;
			}
			ConfigFile config = value.Instance.Config;
			if (!config.TryGetEntry<bool>("Arrow Improvements", "Enable Arrow Improvements", ref _improvementsEnabled) || !config.TryGetEntry<float>("Arrow Improvements", "Set Arrow Velocity", ref _arrowVelocity) || !config.TryGetEntry<float>("Arrow Improvements", "Set Arrow Gravity", ref _arrowGravity))
			{
				ManualLogSource log = BowTrajectoryPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"Better Archery is installed but Arrow Improvements config entries were not found. Trajectory will use vanilla ItemData physics.");
				}
				return;
			}
			config.TryGetEntry<Vector3>("Arrow Improvements", "Set Aim Direction", ref _arrowAimDir);
			_present = true;
			ManualLogSource log2 = BowTrajectoryPlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)"Better Archery detected — using its arrow velocity/gravity when Arrow Improvements are enabled.");
			}
		}
	}
	[BepInPlugin("ModdedWolf.BowTrajectory", "Bow Trajectory", "1.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BowTrajectoryPlugin : BaseUnityPlugin
	{
		public const string GUID = "ModdedWolf.BowTrajectory";

		public const string NAME = "Bow Trajectory";

		public const string VERSION = "1.1.1";

		internal static BowTrajectoryPlugin Instance;

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<KeyboardShortcut> ToggleKey;

		internal static ConfigEntry<float> MinDrawPercent;

		internal static ConfigEntry<bool> StopAtCharacters;

		internal static ConfigEntry<bool> ShowForCrossbows;

		internal static ConfigEntry<string> StartColor;

		internal static ConfigEntry<string> StartColorHex;

		internal static ConfigEntry<string> EndColor;

		internal static ConfigEntry<string> EndColorHex;

		internal static ConfigEntry<float> LineWidth;

		internal static ConfigEntry<bool> ShowImpactMarker;

		internal static ConfigEntry<bool> HideVanillaCrosshair;

		internal static ConfigEntry<string> ImpactColor;

		internal static ConfigEntry<string> ImpactColorHex;

		internal static ConfigEntry<float> ImpactMarkerSize;

		internal static ConfigEntry<int> MaxPoints;

		internal static ConfigEntry<bool> UseBetterArcheryPhysics;

		private GameObject _manager;

		private void Awake()
		{
			//IL_00ac: 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_00f8: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Expected O, but got Unknown
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Expected O, but got Unknown
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Expected O, but got Unknown
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Expected O, but got Unknown
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			int num = (int)(0u | (ConfigMigration.ScrubLegacyColorPreset(((BaseUnityPlugin)this).Config, "Appearance", "StartColor", "StartColorHex", ColorConfig.ToDisplayName(ColorPreset.White)) ? 1u : 0u) | (ConfigMigration.ScrubLegacyColorPreset(((BaseUnityPlugin)this).Config, "Appearance", "EndColor", "EndColorHex", ColorConfig.ToDisplayName(ColorPreset.Red)) ? 1u : 0u)) | (ConfigMigration.ScrubLegacyColorPreset(((BaseUnityPlugin)this).Config, "Appearance", "ImpactColor", "ImpactColorHex", ColorConfig.ToDisplayName(ColorPreset.Red)) ? 1 : 0);
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle for the trajectory preview.");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)98, Array.Empty<KeyCode>()), "Hotkey to toggle the trajectory preview on/off while playing.");
			MinDrawPercent = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MinDrawPercent", 0.05f, new ConfigDescription("Only show the bow trajectory once the draw passes this fraction (0-1).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			ShowForCrossbows = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowForCrossbows", true, "Also show the trajectory while aiming a crossbow (crossbows always fire at full power).");
			StopAtCharacters = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "StopAtCharacters", true, "If true, the predicted path and impact marker stop on creatures/animals/players too, not just terrain and structures. Set false to let the line pass through characters and only land on the world.");
			AcceptableValueList<string> val = new AcceptableValueList<string>(ColorConfig.PresetDisplayNames);
			StartColor = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "StartColor", ColorConfig.ToDisplayName(ColorPreset.White), new ConfigDescription("Line color near the bow. Named color, RGB Cycle Slow/Medium/Fast, or Custom + StartColorHex.", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			StartColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "StartColorHex", "#FFFFFFD9", "Used only when StartColor is Custom. Hex as #RRGGBB or #RRGGBBAA.");
			EndColor = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "EndColor", ColorConfig.ToDisplayName(ColorPreset.Red), new ConfigDescription("Line color near the impact point. Named color, RGB Cycle Slow/Medium/Fast, or Custom + EndColorHex.", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			EndColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "EndColorHex", "#FF4033D9", "Used only when EndColor is Custom. Hex as #RRGGBB or #RRGGBBAA.");
			LineWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "LineWidth", 0.06f, new ConfigDescription("Width of the trajectory line in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f), Array.Empty<object>()));
			ShowImpactMarker = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "ShowImpactMarker", true, "Show a ring marker where the arrow is predicted to land.");
			HideVanillaCrosshair = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "HideVanillaCrosshair", true, "Hide the game's default crosshair and bow-draw ring while the trajectory preview is visible.");
			ImpactColor = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "ImpactColor", ColorConfig.ToDisplayName(ColorPreset.Red), new ConfigDescription("Color of the impact marker ring. Named color, RGB Cycle Slow/Medium/Fast, or Custom + ImpactColorHex.", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			ImpactColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "ImpactColorHex", "#FF4033E6", "Used only when ImpactColor is Custom. Hex as #RRGGBB or #RRGGBBAA.");
			ImpactMarkerSize = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "ImpactMarkerSize", 0.5f, new ConfigDescription("Radius of the impact marker ring in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 3f), Array.Empty<object>()));
			MaxPoints = ((BaseUnityPlugin)this).Config.Bind<int>("Advanced", "MaxPoints", 400, new ConfigDescription("Maximum number of simulated points along the path. The simulation always uses the game's live physics timestep so the predicted arc matches the real arrow.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(16, 2048), Array.Empty<object>()));
			UseBetterArcheryPhysics = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "UseBetterArcheryPhysics", true, "When Better Archery is installed and its Arrow Improvements are enabled, use that mod's arrow velocity, gravity, and aim offset for the bow trajectory preview. Set false to always use vanilla ItemData physics.");
			if (num != 0)
			{
				((BaseUnityPlugin)this).Config.Save();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated legacy Appearance color values to presets / Custom + Hex.");
			}
			ConfigMigration.MigrateFromLegacy(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger, Enabled, ToggleKey, MinDrawPercent, ShowForCrossbows, StopAtCharacters, StartColor, StartColorHex, EndColor, EndColorHex, LineWidth, ShowImpactMarker, ImpactColor, ImpactColorHex, ImpactMarkerSize, MaxPoints);
			new Harmony("ModdedWolf.BowTrajectory").PatchAll();
			_manager = new GameObject("BowTrajectory_Manager");
			_manager.AddComponent<TrajectoryRenderer>();
			Object.DontDestroyOnLoad((Object)(object)_manager);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Bow Trajectory v1.1.1 loaded.");
		}

		private void Start()
		{
			BetterArcheryCompat.Initialize();
		}

		internal static Color ResolveStartColor()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			return ColorConfig.Resolve(StartColor.Value, StartColorHex.Value, ColorConfig.DefaultLineAlpha);
		}

		internal static Color ResolveEndColor()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			return ColorConfig.Resolve(EndColor.Value, EndColorHex.Value, ColorConfig.DefaultLineAlpha, 0.15f);
		}

		internal static Color ResolveImpactColor()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			return ColorConfig.Resolve(ImpactColor.Value, ImpactColorHex.Value, ColorConfig.DefaultMarkerAlpha);
		}

		private void OnDestroy()
		{
			if ((Object)(object)_manager != (Object)null)
			{
				Object.Destroy((Object)(object)_manager);
				_manager = null;
			}
		}
	}
	public enum ColorPreset
	{
		White,
		Red,
		Green,
		Blue,
		Yellow,
		Cyan,
		Magenta,
		Orange,
		Purple,
		Black,
		RgbCycleSlow,
		RgbCycleMedium,
		RgbCycleFast,
		Custom
	}
	internal static class ColorConfig
	{
		private const float LineAlpha = 0.85f;

		private const float MarkerAlpha = 0.9f;

		private const float CycleSlowSeconds = 7f;

		private const float CycleMediumSeconds = 3.5f;

		private const float CycleFastSeconds = 1.25f;

		internal const float EndCyclePhaseOffset = 0.15f;

		internal static readonly string[] PresetDisplayNames = new string[14]
		{
			"White", "Red", "Green", "Blue", "Yellow", "Cyan", "Magenta", "Orange", "Purple", "Black",
			"RGB Cycle Slow", "RGB Cycle Medium", "RGB Cycle Fast", "Custom"
		};

		internal static float DefaultLineAlpha => 0.85f;

		internal static float DefaultMarkerAlpha => 0.9f;

		internal static string ToDisplayName(ColorPreset preset)
		{
			if (preset >= ColorPreset.White && (int)preset < PresetDisplayNames.Length)
			{
				return PresetDisplayNames[(int)preset];
			}
			return PresetDisplayNames[0];
		}

		internal static ColorPreset ParsePreset(string raw)
		{
			if (TryParsePresetName(raw, out var preset))
			{
				return preset;
			}
			return ColorPreset.White;
		}

		internal static bool TryParsePresetName(string raw, out ColorPreset preset)
		{
			preset = ColorPreset.White;
			if (string.IsNullOrWhiteSpace(raw))
			{
				return false;
			}
			string text = raw.Trim();
			for (int i = 0; i < PresetDisplayNames.Length; i++)
			{
				if (string.Equals(PresetDisplayNames[i], text, StringComparison.OrdinalIgnoreCase))
				{
					preset = (ColorPreset)i;
					return true;
				}
			}
			if (Enum.TryParse<ColorPreset>(text, ignoreCase: true, out var result) && Enum.IsDefined(typeof(ColorPreset), result))
			{
				preset = result;
				return true;
			}
			string b = Compact(text);
			int num = 0;
			while (num < PresetDisplayNames.Length)
			{
				if (!string.Equals(Compact(PresetDisplayNames[num]), b, StringComparison.OrdinalIgnoreCase))
				{
					ColorPreset colorPreset = (ColorPreset)num;
					if (!string.Equals(Compact(colorPreset.ToString()), b, StringComparison.OrdinalIgnoreCase))
					{
						num++;
						continue;
					}
				}
				preset = (ColorPreset)num;
				return true;
			}
			return false;
		}

		internal static Color Resolve(string presetName, string hex, float fallbackAlpha, float huePhaseOffset = 0f)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return Resolve(ParsePreset(presetName), hex, fallbackAlpha, huePhaseOffset);
		}

		internal static Color Resolve(ColorPreset preset, string hex, float fallbackAlpha, float huePhaseOffset = 0f)
		{
			//IL_0027: 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_0053: 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_004b: 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)
			if (TryGetCyclePeriod(preset, out var periodSeconds))
			{
				return WithAlpha(Color.HSVToRGB(Mathf.Repeat(Time.time / periodSeconds + huePhaseOffset, 1f), 1f, 1f), fallbackAlpha);
			}
			if (preset == ColorPreset.Custom)
			{
				if (TryParseHex(hex, fallbackAlpha, out var color))
				{
					return color;
				}
				return WithAlpha(Color.white, fallbackAlpha);
			}
			return FromPreset(preset, fallbackAlpha);
		}

		internal static bool TryGetCyclePeriod(ColorPreset preset, out float periodSeconds)
		{
			switch (preset)
			{
			case ColorPreset.RgbCycleSlow:
				periodSeconds = 7f;
				return true;
			case ColorPreset.RgbCycleMedium:
				periodSeconds = 3.5f;
				return true;
			case ColorPreset.RgbCycleFast:
				periodSeconds = 1.25f;
				return true;
			default:
				periodSeconds = 0f;
				return false;
			}
		}

		internal static Color FromPreset(ColorPreset preset, float alpha)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			Color white = default(Color);
			switch (preset)
			{
			case ColorPreset.White:
				white = Color.white;
				break;
			case ColorPreset.Red:
				((Color)(ref white))..ctor(1f, 0.25f, 0.2f);
				break;
			case ColorPreset.Green:
				((Color)(ref white))..ctor(0.2f, 0.9f, 0.3f);
				break;
			case ColorPreset.Blue:
				((Color)(ref white))..ctor(0.25f, 0.45f, 1f);
				break;
			case ColorPreset.Yellow:
				((Color)(ref white))..ctor(1f, 0.92f, 0.2f);
				break;
			case ColorPreset.Cyan:
				((Color)(ref white))..ctor(0.2f, 0.95f, 0.95f);
				break;
			case ColorPreset.Magenta:
				((Color)(ref white))..ctor(1f, 0.3f, 0.9f);
				break;
			case ColorPreset.Orange:
				((Color)(ref white))..ctor(1f, 0.55f, 0.1f);
				break;
			case ColorPreset.Purple:
				((Color)(ref white))..ctor(0.7f, 0.3f, 1f);
				break;
			case ColorPreset.Black:
				((Color)(ref white))..ctor(0.05f, 0.05f, 0.05f);
				break;
			default:
				white = Color.white;
				break;
			}
			return WithAlpha(white, alpha);
		}

		internal static string ToHex(Color color)
		{
			//IL_0000: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			byte b = (byte)Mathf.Clamp(Mathf.RoundToInt(color.r * 255f), 0, 255);
			byte b2 = (byte)Mathf.Clamp(Mathf.RoundToInt(color.g * 255f), 0, 255);
			byte b3 = (byte)Mathf.Clamp(Mathf.RoundToInt(color.b * 255f), 0, 255);
			byte b4 = (byte)Mathf.Clamp(Mathf.RoundToInt(color.a * 255f), 0, 255);
			return $"#{b:X2}{b2:X2}{b3:X2}{b4:X2}";
		}

		internal static string NormalizeHexString(string hex)
		{
			if (!TryParseHex(hex, 1f, out var _))
			{
				return null;
			}
			string text = hex.Trim();
			if (!text.StartsWith("#", StringComparison.Ordinal))
			{
				text = "#" + text;
			}
			return text.ToUpperInvariant();
		}

		internal static bool TryParseHex(string hex, float fallbackAlpha, out Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			color = default(Color);
			if (string.IsNullOrWhiteSpace(hex))
			{
				return false;
			}
			string text = hex.Trim();
			if (text.StartsWith("#", StringComparison.Ordinal))
			{
				text = text.Substring(1);
			}
			if (text.Length != 6 && text.Length != 8)
			{
				return false;
			}
			if (!uint.TryParse(text, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))
			{
				return false;
			}
			if (text.Length == 6)
			{
				float num = (float)((result >> 16) & 0xFF) / 255f;
				float num2 = (float)((result >> 8) & 0xFF) / 255f;
				float num3 = (float)(result & 0xFF) / 255f;
				color = new Color(num, num2, num3, fallbackAlpha);
				return true;
			}
			float num4 = (float)((result >> 24) & 0xFF) / 255f;
			float num5 = (float)((result >> 16) & 0xFF) / 255f;
			float num6 = (float)((result >> 8) & 0xFF) / 255f;
			float num7 = (float)(result & 0xFF) / 255f;
			color = new Color(num4, num5, num6, num7);
			return true;
		}

		internal static bool TryParseUnityColor(string raw, out Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			color = default(Color);
			if (string.IsNullOrWhiteSpace(raw))
			{
				return false;
			}
			string[] array = raw.Split(new char[1] { ',' });
			if (array.Length < 3)
			{
				return false;
			}
			if (!float.TryParse(array[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || !float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) || !float.TryParse(array[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
			{
				return false;
			}
			float num = 1f;
			if (array.Length >= 4 && float.TryParse(array[3].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result4))
			{
				num = result4;
			}
			color = new Color(result, result2, result3, num);
			return true;
		}

		private static string Compact(string value)
		{
			char[] array = new char[value.Length];
			int length = 0;
			foreach (char c in value)
			{
				if (char.IsLetterOrDigit(c))
				{
					array[length++] = char.ToLowerInvariant(c);
				}
			}
			return new string(array, 0, length);
		}

		private static Color WithAlpha(Color rgb, float alpha)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			rgb.a = alpha;
			return rgb;
		}
	}
	internal static class ConfigMigration
	{
		private const string LegacyFileName = "dev.modded.bowtrajectory.cfg";

		private static readonly PropertyInfo OrphanedEntriesProperty = typeof(ConfigFile).GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);

		internal static void MigrateFromLegacy(ConfigFile current, ManualLogSource logger, ConfigEntry<bool> enabled, ConfigEntry<KeyboardShortcut> toggleKey, ConfigEntry<float> minDrawPercent, ConfigEntry<bool> showForCrossbows, ConfigEntry<bool> stopAtCharacters, ConfigEntry<string> startColor, ConfigEntry<string> startColorHex, ConfigEntry<string> endColor, ConfigEntry<string> endColorHex, ConfigEntry<float> lineWidth, ConfigEntry<bool> showImpactMarker, ConfigEntry<string> impactColor, ConfigEntry<string> impactColorHex, ConfigEntry<float> impactMarkerSize, ConfigEntry<int> maxPoints)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, "dev.modded.bowtrajectory.cfg");
			if (!File.Exists(text))
			{
				return;
			}
			try
			{
				ConfigFile legacy = new ConfigFile(text, true);
				int num = 0;
				num += Copy<bool>(legacy, enabled);
				num += Copy<KeyboardShortcut>(legacy, toggleKey);
				num += Copy<float>(legacy, minDrawPercent);
				num += Copy<bool>(legacy, showForCrossbows);
				num += Copy<bool>(legacy, stopAtCharacters);
				num += CopyColor(legacy, "Appearance", "StartColor", startColor, startColorHex);
				num += CopyColor(legacy, "Appearance", "EndColor", endColor, endColorHex);
				num += Copy<float>(legacy, lineWidth);
				num += Copy<bool>(legacy, showImpactMarker);
				num += CopyColor(legacy, "Appearance", "ImpactColor", impactColor, impactColorHex);
				num += Copy<float>(legacy, impactMarkerSize);
				num += Copy<int>(legacy, maxPoints);
				current.Save();
				logger.LogInfo((object)string.Format("Migrated {0} setting(s) from {1} to {2}.cfg", num, "dev.modded.bowtrajectory.cfg", "ModdedWolf.BowTrajectory"));
				try
				{
					ArchiveLegacyFile(text, logger);
				}
				catch (Exception ex)
				{
					logger.LogWarning((object)("Migrated settings but could not archive dev.modded.bowtrajectory.cfg: " + ex.Message + ". Rename or delete that file to prevent re-migration on next launch."));
				}
			}
			catch (Exception ex2)
			{
				logger.LogWarning((object)("Could not migrate legacy config (dev.modded.bowtrajectory.cfg): " + ex2.Message));
			}
		}

		internal static bool ScrubLegacyColorPreset(ConfigFile config, string section, string presetKey, string hexKey, string defaultDisplayName)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<ConfigDefinition, string> orphanedEntries = GetOrphanedEntries(config);
			if (orphanedEntries == null)
			{
				return false;
			}
			bool result = false;
			ConfigDefinition key = new ConfigDefinition(section, presetKey);
			if (orphanedEntries.TryGetValue(key, out var value) && !string.IsNullOrWhiteSpace(value))
			{
				string text = value.Trim();
				Color color;
				Color color2;
				if (ColorConfig.TryParsePresetName(text, out var preset))
				{
					string text2 = ColorConfig.ToDisplayName(preset);
					if (!string.Equals(text, text2, StringComparison.Ordinal))
					{
						orphanedEntries[key] = text2;
						result = true;
					}
				}
				else if (ColorConfig.TryParseHex(text, 1f, out color))
				{
					orphanedEntries[key] = ColorConfig.ToDisplayName(ColorPreset.Custom);
					if (EnsureHexOrphan(orphanedEntries, section, hexKey, ColorConfig.ToHex(color)))
					{
						result = true;
					}
					result = true;
				}
				else if (ColorConfig.TryParseUnityColor(text, out color2))
				{
					orphanedEntries[key] = ColorConfig.ToDisplayName(ColorPreset.Custom);
					if (EnsureHexOrphan(orphanedEntries, section, hexKey, ColorConfig.ToHex(color2)))
					{
						result = true;
					}
					result = true;
				}
				else
				{
					orphanedEntries[key] = defaultDisplayName;
					result = true;
				}
			}
			if (NormalizeHexOrphan(orphanedEntries, section, hexKey))
			{
				result = true;
			}
			return result;
		}

		private static bool EnsureHexOrphan(Dictionary<ConfigDefinition, string> orphans, string section, string hexKey, string fallbackHex)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ConfigDefinition key = new ConfigDefinition(section, hexKey);
			if (orphans.TryGetValue(key, out var value) && ColorConfig.TryParseHex(value, 1f, out var _))
			{
				string text = ColorConfig.NormalizeHexString(value);
				if (text != null && !string.Equals(value.Trim(), text, StringComparison.Ordinal))
				{
					orphans[key] = text;
					return true;
				}
				return false;
			}
			orphans[key] = fallbackHex;
			return true;
		}

		private static bool NormalizeHexOrphan(Dictionary<ConfigDefinition, string> orphans, string section, string hexKey)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ConfigDefinition key = new ConfigDefinition(section, hexKey);
			if (!orphans.TryGetValue(key, out var value) || string.IsNullOrWhiteSpace(value))
			{
				return false;
			}
			string text = ColorConfig.NormalizeHexString(value);
			if (text == null || string.Equals(value.Trim(), text, StringComparison.Ordinal))
			{
				return false;
			}
			orphans[key] = text;
			return true;
		}

		private static Dictionary<ConfigDefinition, string> GetOrphanedEntries(ConfigFile config)
		{
			if (OrphanedEntriesProperty == null)
			{
				return null;
			}
			return OrphanedEntriesProperty.GetValue(config) as Dictionary<ConfigDefinition, string>;
		}

		private static void ArchiveLegacyFile(string legacyPath, ManualLogSource logger)
		{
			string text = legacyPath + ".migrated";
			if (File.Exists(text))
			{
				File.Delete(text);
			}
			File.Move(legacyPath, text);
			logger.LogInfo((object)("Archived legacy config as " + Path.GetFileName(text) + " (migration will not re-run)"));
		}

		private static int Copy<T>(ConfigFile legacy, ConfigEntry<T> target)
		{
			ConfigEntry<T> val = default(ConfigEntry<T>);
			if (!legacy.TryGetEntry<T>(((ConfigEntryBase)target).Definition.Section, ((ConfigEntryBase)target).Definition.Key, ref val))
			{
				return 0;
			}
			target.Value = val.Value;
			return 1;
		}

		private static int CopyColor(ConfigFile legacy, string section, string key, ConfigEntry<string> preset, ConfigEntry<string> hex)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<Color> val = default(ConfigEntry<Color>);
			if (!legacy.TryGetEntry<Color>(section, key, ref val))
			{
				return 0;
			}
			preset.Value = ColorConfig.ToDisplayName(ColorPreset.Custom);
			hex.Value = ColorConfig.ToHex(val.Value);
			return 1;
		}
	}
	[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
	[HarmonyPriority(0)]
	internal static class HudCrosshairPatch
	{
		private static void Postfix(Hud __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && TrajectoryRenderer.ShouldHideVanillaAimHud())
			{
				if ((Object)(object)__instance.m_crosshair != (Object)null)
				{
					((Component)__instance.m_crosshair).gameObject.SetActive(false);
				}
				if ((Object)(object)__instance.m_crosshairBow != (Object)null)
				{
					((Component)__instance.m_crosshairBow).gameObject.SetActive(false);
				}
			}
		}
	}
	public class TrajectoryRenderer : MonoBehaviour
	{
		private LineRenderer _line;

		private LineRenderer _marker;

		private int _solidMask;

		private int _solidWithCharMask;

		private bool _masksReady;

		private Vector3[] _points;

		private readonly RaycastHit[] _hitBuffer = (RaycastHit[])(object)new RaycastHit[32];

		private Color _lastStart;

		private Color _lastEnd;

		private Color _lastImpact;

		private float _lastWidth = -1f;

		internal static bool UserPreviewEnabled { get; private set; } = true;

		private void Awake()
		{
			_line = CreateLineRenderer("BowTrajectory_Line", loop: false);
			_marker = CreateLineRenderer("BowTrajectory_Marker", loop: true);
			SetVisible(visible: false);
		}

		private LineRenderer CreateLineRenderer(string name, bool loop)
		{
			//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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(((Component)this).transform, false);
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.useWorldSpace = true;
			val2.loop = loop;
			val2.numCapVertices = 4;
			val2.numCornerVertices = 2;
			val2.textureMode = (LineTextureMode)0;
			((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)val2).receiveShadows = false;
			val2.alignment = (LineAlignment)0;
			val2.positionCount = 0;
			Shader val3 = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Particles/Standard Unlit");
			if ((Object)(object)val3 != (Object)null)
			{
				((Renderer)val2).material = new Material(val3);
			}
			if ((Object)(object)((Renderer)val2).material != (Object)null)
			{
				((Renderer)val2).material.renderQueue = 3100;
			}
			return val2;
		}

		private void EnsureMasks()
		{
			if (!_masksReady)
			{
				_solidMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" });
				_solidWithCharMask = _solidMask | LayerMask.GetMask(new string[5] { "character", "character_net", "character_ghost", "hitbox", "character_noenv" });
				_masksReady = true;
			}
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (IsToggleDown(BowTrajectoryPlugin.ToggleKey.Value) && !IsTextFieldFocused())
			{
				UserPreviewEnabled = !UserPreviewEnabled;
			}
		}

		private void LateUpdate()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (!BowTrajectoryPlugin.Enabled.Value || !UserPreviewEnabled)
			{
				SetVisible(visible: false);
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			Vector3 spawn;
			Vector3 dir;
			float speed;
			float gravity;
			float drag;
			float ttl;
			if ((Object)(object)localPlayer == (Object)null || !IsAimingForPreview(localPlayer, out var weapon, out var isBow, out var drawPct))
			{
				SetVisible(visible: false);
			}
			else if (!ResolveLaunch(localPlayer, weapon, isBow, drawPct, out spawn, out dir, out speed, out gravity, out drag, out ttl))
			{
				SetVisible(visible: false);
			}
			else
			{
				Simulate(localPlayer, spawn, dir, speed, gravity, drag, ttl);
			}
		}

		private bool ResolveLaunch(Player player, ItemData weapon, bool isBow, float drawPct, out Vector3 spawn, out Vector3 dir, out float speed, out float gravity, out float drag, out float ttl)
		{
			//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_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_0071: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
			spawn = Vector3.zero;
			dir = Vector3.forward;
			speed = 0f;
			gravity = 0f;
			drag = 0f;
			ttl = 4f;
			Attack attack = weapon.m_shared.m_attack;
			ItemData val = FindAmmo(player, weapon);
			GameObject attackProjectile = attack.m_attackProjectile;
			float num = attack.m_projectileVel;
			float num2 = attack.m_projectileVelMin;
			AnimationCurve drawVelocityCurve = attack.m_drawVelocityCurve;
			float gravity2 = 0f;
			Vector3 aimDir = Vector3.zero;
			bool flag = BetterArcheryCompat.AppliesTo(player) && BetterArcheryCompat.TryGetImprovements(out gravity2, out aimDir);
			bool betterArcheryStableAim = isBow && flag;
			if (flag && BetterArcheryCompat.TryGetBowVelocity(out var velocity))
			{
				num = velocity;
			}
			if (val != null && val.m_shared != null && val.m_shared.m_attack != null && (Object)(object)val.m_shared.m_attack.m_attackProjectile != (Object)null)
			{
				attackProjectile = val.m_shared.m_attack.m_attackProjectile;
				num += val.m_shared.m_attack.m_projectileVel;
				num2 += val.m_shared.m_attack.m_projectileVelMin;
				drawVelocityCurve = val.m_shared.m_attack.m_drawVelocityCurve;
			}
			if ((Object)(object)attackProjectile == (Object)null)
			{
				return false;
			}
			if (isBow)
			{
				float num3 = ((drawVelocityCurve != null && drawVelocityCurve.length > 0) ? drawVelocityCurve.Evaluate(drawPct) : drawPct);
				speed = Mathf.Lerp(num2, num, num3);
			}
			else
			{
				speed = num;
			}
			if (speed <= 0.01f)
			{
				return false;
			}
			Projectile component = attackProjectile.GetComponent<Projectile>();
			if ((Object)(object)component != (Object)null)
			{
				gravity = component.m_gravity;
				drag = component.m_drag;
				ttl = ((component.m_ttl > 0f) ? component.m_ttl : 4f);
			}
			if (flag)
			{
				gravity = gravity2;
			}
			GetSpawnAndAim(player, weapon, attack, betterArcheryStableAim, flag, aimDir, out spawn, out dir);
			return true;
		}

		private static ItemData FindAmmo(Player player, ItemData weapon)
		{
			if (weapon?.m_shared == null || string.IsNullOrEmpty(weapon.m_shared.m_ammoType))
			{
				return null;
			}
			string ammoType = weapon.m_shared.m_ammoType;
			ItemData ammoItem = ((Humanoid)player).GetAmmoItem();
			if (ammoItem != null && ammoItem.m_shared != null && ammoItem.m_shared.m_ammoType == ammoType)
			{
				return ammoItem;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return null;
			}
			return inventory.GetAmmoItem(ammoType, (string)null);
		}

		private void GetSpawnAndAim(Player player, ItemData weapon, Attack shared, bool betterArcheryStableAim, bool applyBetterArcheryAim, Vector3 betterArcheryAimOffset, out Vector3 spawn, out Vector3 dir)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0030: 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)
			//IL_0037: 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)
			Attack currentAttack = ((Humanoid)player).m_currentAttack;
			Attack val = shared;
			if (currentAttack != null && currentAttack.GetWeapon() == weapon)
			{
				val = currentAttack;
			}
			if (applyBetterArcheryAim && !betterArcheryStableAim && TryBetterArcheryLeftHandSpawn(player, val, out spawn, out dir))
			{
				dir += betterArcheryAimOffset;
				ApplyLaunchAngle(val, ref dir);
				return;
			}
			ReplicateVanillaSpawnAndAim(player, val, betterArcheryStableAim, out spawn, out dir);
			if (applyBetterArcheryAim)
			{
				dir += betterArcheryAimOffset;
			}
			ApplyLaunchAngle(val, ref dir);
		}

		private static bool TryBetterArcheryLeftHandSpawn(Player player, Attack source, out Vector3 spawn, out Vector3 dir)
		{
			//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_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_0044: 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_0051: 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_005b: 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_0085: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			spawn = Vector3.zero;
			dir = Vector3.forward;
			VisEquipment visEquipment = ((Humanoid)player).m_visEquipment;
			if ((Object)(object)visEquipment == (Object)null || (Object)(object)visEquipment.m_leftHand == (Object)null)
			{
				return false;
			}
			Transform transform = ((Component)player).transform;
			spawn = visEquipment.m_leftHand.position;
			dir = ((Humanoid)player).GetAimDir(spawn);
			if (source.m_useCharacterFacing)
			{
				Vector3 forward = Vector3.forward;
				if (source.m_useCharacterFacingYAim)
				{
					forward.y = dir.y;
				}
				dir = transform.TransformDirection(forward);
			}
			return true;
		}

		private static void ReplicateVanillaSpawnAndAim(Player player, Attack source, bool stableOrigin, out Vector3 spawn, out Vector3 dir)
		{
			//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_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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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)
			Transform transform = ((Component)player).transform;
			Transform val = transform;
			if (!stableOrigin)
			{
				string attackOriginJoint = source.m_attackOriginJoint;
				if (!string.IsNullOrEmpty(attackOriginJoint))
				{
					GameObject visual = ((Character)player).GetVisual();
					Transform val2 = Utils.FindChild(((Object)(object)visual != (Object)null) ? visual.transform : transform, attackOriginJoint, (IterativeSearchType)0);
					if ((Object)(object)val2 != (Object)null)
					{
						val = val2;
					}
				}
			}
			GetLookAxes(player, out var lookFwd, out var lookRight);
			spawn = val.position + Vector3.up * source.m_attackHeight + lookFwd * source.m_attackRange + lookRight * source.m_attackOffset;
			dir = ((Humanoid)player).GetAimDir(spawn);
			if (source.m_useCharacterFacing)
			{
				Vector3 forward = Vector3.forward;
				if (source.m_useCharacterFacingYAim)
				{
					forward.y = dir.y;
				}
				dir = transform.TransformDirection(forward);
			}
		}

		private static void ApplyLaunchAngle(Attack attack, ref Vector3 aimDir)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_002a: 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)
			float launchAngle = attack.m_launchAngle;
			if (launchAngle != 0f)
			{
				Vector3 val = Vector3.Cross(Vector3.up, aimDir);
				aimDir = Quaternion.AngleAxis(launchAngle, val) * aimDir;
			}
		}

		private static void GetLookAxes(Player player, out Vector3 lookFwd, out Vector3 lookRight)
		{
			//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_0027: 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_0057: 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_005c: 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_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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Character)player).GetLookDir();
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
			{
				val = ((Component)player).transform.forward;
				val.y = 0f;
			}
			lookFwd = ((((Vector3)(ref val)).sqrMagnitude > 1E-06f) ? ((Vector3)(ref val)).normalized : ((Component)player).transform.forward);
			lookRight = Vector3.Cross(Vector3.up, lookFwd);
			if (((Vector3)(ref lookRight)).sqrMagnitude < 1E-06f)
			{
				lookRight = ((Component)player).transform.right;
			}
			else
			{
				((Vector3)(ref lookRight)).Normalize();
			}
		}

		private void Simulate(Player owner, Vector3 spawn, Vector3 dir, float speed, float gravity, float drag, float ttl)
		{
			//IL_005f: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_00cc: 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_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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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)
			EnsureMasks();
			int value = BowTrajectoryPlugin.MaxPoints.Value;
			if (_points == null || _points.Length != value)
			{
				_points = (Vector3[])(object)new Vector3[value];
			}
			float num = Time.fixedDeltaTime;
			if (num <= 0f)
			{
				num = 0.02f;
			}
			int mask = (BowTrajectoryPlugin.StopAtCharacters.Value ? _solidWithCharMask : _solidMask);
			Vector3 val = spawn;
			Vector3 val2 = ((Vector3)(ref dir)).normalized * speed;
			_points[0] = val;
			int num2 = 1;
			float num3 = 0f;
			bool flag = false;
			Vector3 val3 = Vector3.zero;
			Vector3 normal = Vector3.up;
			while (num2 < value && num3 < ttl)
			{
				val2 += Vector3.down * (gravity * num);
				if (drag != 0f)
				{
					float num4 = ((Vector3)(ref val2)).sqrMagnitude * drag * num;
					val2 -= ((Vector3)(ref val2)).normalized * num4;
				}
				Vector3 val4 = val + val2 * num;
				Vector3 val5 = val4 - val;
				float magnitude = ((Vector3)(ref val5)).magnitude;
				if (magnitude > 0.0001f && SegmentCast(val, ((Vector3)(ref val5)).normalized, magnitude, mask, owner, out var best))
				{
					val3 = ((RaycastHit)(ref best)).point;
					normal = ((RaycastHit)(ref best)).normal;
					_points[num2++] = val3;
					flag = true;
					break;
				}
				val = val4;
				_points[num2++] = val;
				num3 += num;
			}
			ApplyStyleIfChanged();
			_line.positionCount = num2;
			_line.SetPositions(_points);
			((Renderer)_line).enabled = true;
			if (flag && BowTrajectoryPlugin.ShowImpactMarker.Value)
			{
				DrawMarker(val3, normal);
				((Renderer)_marker).enabled = true;
			}
			else
			{
				((Renderer)_marker).enabled = false;
			}
		}

		private bool SegmentCast(Vector3 origin, Vector3 dirNorm, float dist, int mask, Player owner, out RaycastHit best)
		{
			//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_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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			best = default(RaycastHit);
			int num = Physics.RaycastNonAlloc(origin, dirNorm, _hitBuffer, dist, mask, (QueryTriggerInteraction)1);
			bool result = false;
			float num2 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = _hitBuffer[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && (!((Object)(object)owner != (Object)null) || !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Character>() == (Object)(object)owner)) && ((RaycastHit)(ref val)).distance < num2)
				{
					num2 = ((RaycastHit)(ref val)).distance;
					best = val;
					result = true;
				}
			}
			return result;
		}

		private void DrawMarker(Vector3 point, Vector3 normal)
		{
			//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_0009: 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_0013: 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)
			//IL_0036: 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_003c: 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_0049: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_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_009d: 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)
			//IL_00aa: 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)
			//IL_00b5: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			Vector3 normalized = ((Vector3)(ref normal)).normalized;
			Vector3 val = Vector3.Cross(normalized, Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.Cross(normalized, Vector3.forward);
			}
			((Vector3)(ref val)).Normalize();
			Vector3 val2 = Vector3.Cross(normalized, val);
			float value = BowTrajectoryPlugin.ImpactMarkerSize.Value;
			Vector3 val3 = point + normalized * 0.03f;
			if (_marker.positionCount != 28)
			{
				_marker.positionCount = 28;
			}
			for (int i = 0; i < 28; i++)
			{
				float num = (float)i / 28f * (float)Math.PI * 2f;
				Vector3 val4 = val3 + (val * Mathf.Cos(num) + val2 * Mathf.Sin(num)) * value;
				_marker.SetPosition(i, val4);
			}
		}

		private void ApplyStyleIfChanged()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0016: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_006c: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_008f: 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_00a1: 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_00ac: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00db: 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_0109: 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_002b: 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_0039: 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_0047: 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)
			float value = BowTrajectoryPlugin.LineWidth.Value;
			Color val = BowTrajectoryPlugin.ResolveStartColor();
			Color val2 = BowTrajectoryPlugin.ResolveEndColor();
			Color val3 = BowTrajectoryPlugin.ResolveImpactColor();
			if (!Mathf.Approximately(value, _lastWidth) || !(val == _lastStart) || !(val2 == _lastEnd) || !(val3 == _lastImpact))
			{
				_lastWidth = value;
				_lastStart = val;
				_lastEnd = val2;
				_lastImpact = val3;
				_line.widthMultiplier = value;
				Gradient val4 = new Gradient();
				val4.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
				{
					new GradientColorKey(val, 0f),
					new GradientColorKey(val2, 1f)
				}, (GradientAlphaKey[])(object)new GradientAlphaKey[2]
				{
					new GradientAlphaKey(val.a, 0f),
					new GradientAlphaKey(val2.a, 1f)
				});
				_line.colorGradient = val4;
				_marker.widthMultiplier = value;
				_marker.startColor = val3;
				_marker.endColor = val3;
			}
		}

		private void SetVisible(bool visible)
		{
			if ((Object)(object)_line != (Object)null)
			{
				((Renderer)_line).enabled = visible;
			}
			if ((Object)(object)_marker != (Object)null)
			{
				((Renderer)_marker).enabled = visible;
			}
		}

		internal static bool ShouldHideVanillaAimHud()
		{
			if (!BowTrajectoryPlugin.HideVanillaCrosshair.Value)
			{
				return false;
			}
			if (!BowTrajectoryPlugin.Enabled.Value || !UserPreviewEnabled)
			{
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			ItemData weapon;
			bool isBow;
			float drawPct;
			if ((Object)(object)localPlayer != (Object)null)
			{
				return IsAimingForPreview(localPlayer, out weapon, out isBow, out drawPct);
			}
			return false;
		}

		private static bool IsAimingForPreview(Player player, out ItemData weapon, out bool isBow, out float drawPct)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			weapon = ((Humanoid)player).GetCurrentWeapon();
			isBow = false;
			drawPct = 0f;
			if (weapon == null || weapon.m_shared == null || weapon.m_shared.m_attack == null)
			{
				return false;
			}
			isBow = weapon.m_shared.m_attack.m_bowDraw;
			bool flag = (int)weapon.m_shared.m_skillType == 14;
			if (!isBow && (!flag || !BowTrajectoryPlugin.ShowForCrossbows.Value))
			{
				return false;
			}
			drawPct = ((Humanoid)player).GetAttackDrawPercentage();
			if (isBow && drawPct < BowTrajectoryPlugin.MinDrawPercent.Value)
			{
				return false;
			}
			if (flag && !IsCrossbowReady(player, weapon))
			{
				return false;
			}
			return true;
		}

		private static bool IsCrossbowReady(Player player, ItemData weapon)
		{
			if (weapon?.m_shared?.m_attack != null && !weapon.m_shared.m_attack.m_requiresReload)
			{
				return true;
			}
			if (!((Humanoid)player).IsWeaponLoaded())
			{
				return ((Character)player).InAttack();
			}
			return true;
		}

		private static bool IsToggleDown(KeyboardShortcut shortcut)
		{
			//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_000b: 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)
			KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey;
			if ((int)mainKey == 0 || !Input.GetKeyDown(mainKey))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return true;
		}

		private static bool IsTextFieldFocused()
		{
			try
			{
				if (Console.IsVisible())
				{
					return true;
				}
				if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}