Decompiled source of SilksongTrueAim v1.0.3

BepInEx/Plugins/TrueAim/TrueAim.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HutongGames.PlayMaker;
using InControl;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.CacheObject;
using UnityExplorer.CacheObject.Views;
using UniverseLib.Utility;

[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: AssemblyCompany("TrueAim")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+c6044e4fea45ea190d41ab56f6874704e73c7e81")]
[assembly: AssemblyProduct("TrueAim")]
[assembly: AssemblyTitle("TrueAim")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace SilksongTrueAim
{
	public enum ZoneType
	{
		Horizontal,
		DiagonalDown,
		DiagonalUp
	}
	public struct ActionZone
	{
		public string name;

		public float startAngle;

		public float endAngle;

		public Color color;

		public ZoneType type;

		public ActionZone(string n, float start, float end, Color c, ZoneType t)
		{
			//IL_0016: 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)
			name = n;
			startAngle = start;
			endAngle = end;
			color = c;
			type = t;
		}

		public bool ContainsAngle(float angle)
		{
			angle = (angle % 360f + 360f) % 360f;
			if (startAngle <= endAngle)
			{
				if (angle >= startAngle)
				{
					return angle <= endAngle;
				}
				return false;
			}
			if (!(angle >= startAngle))
			{
				return angle <= endAngle;
			}
			return true;
		}
	}
	public static class EasingCurves
	{
		public static float EaseOutExpo(float t, float strength = 10f)
		{
			if (t != 1f)
			{
				return 1f - Mathf.Pow(2f, (0f - strength) * t);
			}
			return 1f;
		}

		public static float EaseInExpo(float t, float strength = 10f)
		{
			if (t != 0f)
			{
				return Mathf.Pow(2f, strength * (t - 1f));
			}
			return 0f;
		}

		public static float EaseInOutExpo(float t, float strength = 10f)
		{
			if (t == 0f)
			{
				return 0f;
			}
			if (t == 1f)
			{
				return 1f;
			}
			if (!(t < 0.5f))
			{
				return (2f - Mathf.Pow(2f, (0f - strength) * (2f * t - 1f))) / 2f;
			}
			return Mathf.Pow(2f, strength * (2f * t - 1f)) / 2f;
		}

		public static float EaseOutCubic(float t)
		{
			return 1f - Mathf.Pow(1f - t, 3f);
		}

		public static float EaseInCubic(float t)
		{
			return t * t * t;
		}

		public static float EaseInOutCubic(float t)
		{
			if (!(t < 0.5f))
			{
				return 1f - Mathf.Pow(-2f * t + 2f, 3f) / 2f;
			}
			return 4f * t * t * t;
		}

		public static float EaseOutQuart(float t)
		{
			return 1f - Mathf.Pow(1f - t, 4f);
		}

		public static float EaseOutQuint(float t)
		{
			return 1f - Mathf.Pow(1f - t, 5f);
		}

		public static float EaseOutCirc(float t)
		{
			return Mathf.Sqrt(1f - Mathf.Pow(t - 1f, 2f));
		}

		public static float EaseInCirc(float t)
		{
			return 1f - Mathf.Sqrt(1f - Mathf.Pow(t, 2f));
		}

		public static float EaseOutBack(float t, float overshoot = 1.70158f)
		{
			float num = overshoot + 1f;
			return 1f + num * Mathf.Pow(t - 1f, 3f) + overshoot * Mathf.Pow(t - 1f, 2f);
		}

		public static float EaseInBack(float t, float overshoot = 1.70158f)
		{
			return (overshoot + 1f) * t * t * t - overshoot * t * t;
		}

		public static float EaseOutElastic(float t, float oscillations = 3f, float springiness = 10f)
		{
			if (t == 0f)
			{
				return 0f;
			}
			if (t == 1f)
			{
				return 1f;
			}
			float num = (float)Math.PI * 2f / oscillations;
			return Mathf.Pow(2f, (0f - springiness) * t) * Mathf.Sin((t * 10f - 0.75f) * num) + 1f;
		}

		public static float EaseOutSine(float t)
		{
			return Mathf.Sin(t * (float)Math.PI / 2f);
		}

		public static float EaseInOutSine(float t)
		{
			return (0f - (Mathf.Cos((float)Math.PI * t) - 1f)) / 2f;
		}

		public static float EaseOutQuad(float t)
		{
			return 1f - (1f - t) * (1f - t);
		}

		public static float EaseInOutQuad(float t)
		{
			if (!(t < 0.5f))
			{
				return 1f - Mathf.Pow(-2f * t + 2f, 2f) / 2f;
			}
			return 2f * t * t;
		}
	}
	public class AttackDetector
	{
		private TrueAimPlugin plugin;

		private ManualLogSource? Logger;

		private FieldInfo? wallSlashingField;

		private FieldInfo? attackCooldownField;

		private FieldInfo? nailChargeTimerField;

		private PlayMakerFSM? nailArtsFSM;

		private string previousSprintState = "";

		private string previousCrestState = "";

		private string previousNailArtsState = "";

		private bool previousAttacking;

		private bool wasNailCharging;

		private Action<float, float, string> onAttackDetected;

		public PlayMakerFSM? NailArtsFSM => nailArtsFSM;

		public AttackDetector(ManualLogSource logger, Action<float, float, string> attackCallback, TrueAimPlugin pluginRef)
		{
			Logger = logger;
			onAttackDetected = attackCallback;
			if ((Object)(object)pluginRef != (Object)null)
			{
				plugin = pluginRef;
			}
			CacheReflectionFields();
		}

		private void CacheReflectionFields()
		{
			try
			{
				wallSlashingField = typeof(HeroController).GetField("wallSlashing", BindingFlags.Instance | BindingFlags.NonPublic);
				attackCooldownField = typeof(HeroController).GetField("attack_cooldown", BindingFlags.Instance | BindingFlags.NonPublic);
				nailChargeTimerField = typeof(HeroController).GetField("nailChargeTimer", BindingFlags.Instance | BindingFlags.NonPublic);
				if (wallSlashingField != null && attackCooldownField != null && nailChargeTimerField != null)
				{
					ManualLogSource? logger = Logger;
					if (logger != null)
					{
						logger.LogInfo((object)Localization.Get("attack_detection_cached"));
					}
				}
				else
				{
					ManualLogSource? logger2 = Logger;
					if (logger2 != null)
					{
						logger2.LogError((object)"Failed to cache some reflection fields");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource? logger3 = Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)("Reflection cache error: " + ex.Message));
				}
			}
		}

		public void Update(HeroController hero, bool effectsEnabled)
		{
			if ((Object)(object)hero == (Object)null || !((Component)hero).gameObject.activeInHierarchy)
			{
				ManualLogSource? logger = Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"HeroController is null or inactive, skipping update");
				}
				return;
			}
			try
			{
				if ((Object)(object)nailArtsFSM == (Object)null || !((Component)nailArtsFSM).gameObject.activeInHierarchy)
				{
					PlayMakerFSM[] components = ((Component)hero).GetComponents<PlayMakerFSM>();
					if (components != null)
					{
						nailArtsFSM = Array.Find(components, (PlayMakerFSM fsm) => (Object)(object)fsm != (Object)null && fsm.FsmName == "Nail Arts");
						if ((Object)(object)nailArtsFSM != (Object)null)
						{
							plugin.VerboseLogger.LogDebug(Localization.Get("found_nail_arts_fsm"));
						}
					}
				}
				if ((Object)(object)hero.sprintFSM != (Object)null)
				{
					MonitorSprintFSM(hero);
				}
				if ((Object)(object)hero.crestAttacksFSM != (Object)null)
				{
					MonitorCrestFSM(hero);
				}
				if ((Object)(object)nailArtsFSM != (Object)null)
				{
					MonitorNailArtsFSM();
				}
				DetectCStateAttacks(hero, plugin.AttackEffectToggle);
				TrackChargeState(hero);
			}
			catch (Exception ex)
			{
				ManualLogSource? logger2 = Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("AttackDetector.Update error: " + ex.Message + "\n" + ex.StackTrace));
				}
			}
		}

		private void DetectCStateAttacks(HeroController hero, bool effectsEnabled)
		{
			bool attacking = hero.cState.attacking;
			bool upAttacking = hero.cState.upAttacking;
			bool downAttacking = hero.cState.downAttacking;
			bool downSpikeAntic = hero.cState.downSpikeAntic;
			bool isScrewDownAttacking = hero.cState.isScrewDownAttacking;
			bool parryAttack = hero.cState.parryAttack;
			bool whipLashing = hero.cState.whipLashing;
			bool flag = wallSlashingField != null && (bool)wallSlashingField.GetValue(hero);
			bool isToolThrowing = hero.cState.isToolThrowing;
			bool flag2 = attacking || upAttacking || downAttacking || downSpikeAntic || isScrewDownAttacking || parryAttack || whipLashing || flag || isToolThrowing;
			if (flag2 && !previousAttacking)
			{
				string text = (parryAttack ? "Parry" : (whipLashing ? "Whip" : (flag ? "Wall" : (downAttacking ? "Down" : (isScrewDownAttacking ? "Screw" : (downSpikeAntic ? "Downspike" : (upAttacking ? "Up" : (isToolThrowing ? "Tool" : "Normal"))))))));
				plugin.VerboseLogger.LogDebug("\ud83c\udfaf " + text + " attack detected");
				if (effectsEnabled)
				{
					float arg = 1f;
					float arg2 = 1f;
					if (downSpikeAntic || isScrewDownAttacking)
					{
						arg = 1.2f;
						arg2 = 1.2f;
					}
					else if (parryAttack)
					{
						arg = 1.5f;
						arg2 = 1.5f;
					}
					else if (whipLashing)
					{
						arg = 0.9f;
						arg2 = 0.9f;
					}
					else if (isToolThrowing)
					{
						arg = 0.8f;
						arg2 = 0.8f;
					}
					onAttackDetected(arg, arg2, text);
				}
			}
			previousAttacking = flag2;
		}

		private void MonitorSprintFSM(HeroController hero)
		{
			if (!((Object)(object)hero.sprintFSM == (Object)null))
			{
				string activeStateName = hero.sprintFSM.ActiveStateName;
				if (activeStateName != previousSprintState && !string.IsNullOrEmpty(activeStateName))
				{
					CheckSprintAttackStates(activeStateName);
					previousSprintState = activeStateName;
				}
			}
		}

		private void CheckSprintAttackStates(string stateName)
		{
			if (!plugin.AttackEffectToggle || stateName == null)
			{
				return;
			}
			switch (stateName.Length)
			{
			case 12:
				switch (stateName[0])
				{
				case 'A':
					if (stateName == "Attack Antic")
					{
						onAttackDetected(1.4f, 1.4f, "Dash Stab");
					}
					break;
				case 'R':
					if (stateName == "Reaper Antic")
					{
						onAttackDetected(1.6f, 1.6f, "Reaper Sprint");
					}
					break;
				}
				break;
			case 18:
				switch (stateName[0])
				{
				case 'W':
					if (stateName == "Wanderer Attacking")
					{
						onAttackDetected(1.4f, 1.4f, "Wanderer Sprint");
					}
					break;
				case 'D':
					if (stateName == "Drill Charge Start")
					{
						onAttackDetected(1.6f, 1.6f, "Architect Sprint Drill");
					}
					break;
				}
				break;
			case 16:
				if (stateName == "RecoilStab Antic")
				{
					onAttackDetected(1.4f, 1.4f, "Recoil Stab");
				}
				break;
			case 13:
				if (stateName == "Warrior Antic")
				{
					onAttackDetected(1.6f, 1.6f, "Warrior");
				}
				break;
			case 15:
				if (stateName == "Drill Attack Ch")
				{
					onAttackDetected(1.8f, 1.8f, "Architect Sprint Drill Charged");
				}
				break;
			case 11:
				if (stateName == "Shaman Leap")
				{
					onAttackDetected(1.5f, 1.5f, "Shaman Sprint");
				}
				break;
			case 14:
			case 17:
				break;
			}
		}

		private void MonitorCrestFSM(HeroController hero)
		{
			if (!((Object)(object)hero.crestAttacksFSM == (Object)null))
			{
				string activeStateName = hero.crestAttacksFSM.ActiveStateName;
				if (activeStateName != previousCrestState && !string.IsNullOrEmpty(activeStateName))
				{
					CheckCrestAttackStates(activeStateName);
					previousCrestState = activeStateName;
				}
			}
		}

		private void CheckCrestAttackStates(string stateName)
		{
			if (plugin.AttackEffectToggle)
			{
				switch (stateName)
				{
				case "SpinBall Antic":
					onAttackDetected(1.6f, 1.6f, "Beast Crest Spin");
					break;
				case "Rpr Downslash Antic":
					onAttackDetected(1.6f, 1.6f, "Reaper Downslash");
					break;
				case "Witch Downslash Antic":
					onAttackDetected(1.5f, 1.5f, "Witch Downslash");
					break;
				case "Shaman Downslash Antic":
					onAttackDetected(1.5f, 1.5f, "Shaman Downslash");
					break;
				case "ToolM Antic":
					onAttackDetected(1.6f, 1.6f, "Toolmaster Drill");
					break;
				}
			}
		}

		private void MonitorNailArtsFSM()
		{
			if (!((Object)(object)nailArtsFSM == (Object)null))
			{
				string activeStateName = nailArtsFSM.ActiveStateName;
				if (activeStateName != previousNailArtsState && !string.IsNullOrEmpty(activeStateName))
				{
					plugin.VerboseLogger.LogDebug("⚔\ufe0f Nail Arts: " + previousNailArtsState + " → " + activeStateName);
					CheckNailArtsStates(activeStateName);
					previousNailArtsState = activeStateName;
				}
			}
		}

		private void CheckNailArtsStates(string stateName)
		{
			if (!plugin.AttackEffectToggle || stateName == null)
			{
				return;
			}
			switch (stateName.Length)
			{
			case 5:
				if (stateName == "Antic")
				{
					onAttackDetected(1.5f, 1.5f, "Charged Attack");
				}
				break;
			case 9:
				if (stateName == "Antic Rpr")
				{
					onAttackDetected(1.6f, 1.7f, "Reaper Charged");
				}
				break;
			case 12:
				if (stateName == "Wander Antic")
				{
					onAttackDetected(1.5f, 1.6f, "Wanderer Charged");
				}
				break;
			case 14:
				if (stateName == "Warrior2 Antic")
				{
					onAttackDetected(1.5f, 1.6f, "Beast Charged");
				}
				break;
			case 7:
				if (stateName == "Do Spin")
				{
					onAttackDetected(1.4f, 1.5f, "Witch Spin");
				}
				break;
			case 11:
				if (stateName == "Antic Drill")
				{
					onAttackDetected(1.5f, 1.6f, "Toolmaster Charged");
				}
				break;
			case 10:
				if (stateName == "Antic Wrrr")
				{
					onAttackDetected(1.7f, 1.8f, "Warrior Charged");
				}
				break;
			case 6:
			case 8:
			case 13:
				break;
			}
		}

		private void TrackChargeState(HeroController hero)
		{
			bool nailCharging = hero.cState.nailCharging;
			if (nailCharging && !wasNailCharging)
			{
				plugin.VerboseLogger.LogDebug("\ud83d\udd0b Nail charging STARTED");
			}
			else if (!nailCharging && wasNailCharging)
			{
				plugin.VerboseLogger.LogDebug("⚡ Nail charge RELEASED");
			}
			wasNailCharging = nailCharging;
		}

		public float GetAttackCooldown(HeroController hero)
		{
			if (!(attackCooldownField != null))
			{
				return 0.35f;
			}
			return (float)attackCooldownField.GetValue(hero);
		}

		public float GetChargeTime(HeroController hero)
		{
			if (!(nailChargeTimerField != null))
			{
				return 0f;
			}
			return (float)nailChargeTimerField.GetValue(hero);
		}

		public bool GetWallSlashing(HeroController hero)
		{
			if (wallSlashingField != null)
			{
				return (bool)wallSlashingField.GetValue(hero);
			}
			return false;
		}
	}
	public static class ColorPresets
	{
		public struct ZonePalette
		{
			public Color Primary;

			public Color Secondary;

			public Color Tertiary;

			public ZonePalette(float r1, float g1, float b1, float r2, float g2, float b2, float r3, float g3, float b3)
			{
				//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_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_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				Primary = new Color(r1, g1, b1, 1f);
				Secondary = new Color(r2, g2, b2, 1f);
				Tertiary = new Color(r3, g3, b3, 1f);
			}
		}

		public static readonly Dictionary<string, ZonePalette> Presets = new Dictionary<string, ZonePalette>
		{
			["Silk (Default)"] = new ZonePalette(1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f),
			["Monochrome"] = new ZonePalette(0.8f, 0.8f, 0.8f, 1f, 1f, 1f, 0.6f, 0.6f, 0.6f),
			["Ember"] = new ZonePalette(1f, 0.7f, 0.2f, 1f, 0.4f, 0.1f, 1f, 0.85f, 0.5f),
			["Bilewater"] = new ZonePalette(0.8f, 1f, 0.2f, 0.6f, 0.85f, 0.2f, 0.9f, 1f, 0.6f),
			["Mount Fay"] = new ZonePalette(0.85f, 0.95f, 1f, 0.6f, 0.8f, 0.95f, 0.95f, 0.98f, 1f),
			["Abyss"] = new ZonePalette(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f),
			["Crimson"] = new ZonePalette(1f, 0.2f, 0.25f, 0.65f, 0.05f, 0.08f, 1f, 0.4f, 0.45f),
			["Red Maiden"] = new ZonePalette(0.545f, 0.141f, 0.22f, 0.33f, 0f, 0.14f, 1f, 1f, 1f),
			["Ocean"] = new ZonePalette(0f, 0.6f, 0.85f, 0f, 0.35f, 0.65f, 0.3f, 0.8f, 0.9f),
			["Jade"] = new ZonePalette(0.2f, 0.7f, 0.4f, 0.15f, 0.5f, 0.3f, 0.5f, 0.85f, 0.6f),
			["Teal"] = new ZonePalette(0.2f, 0.9f, 0.8f, 0.15f, 0.65f, 0.6f, 0.5f, 1f, 0.9f),
			["Neon"] = new ZonePalette(0f, 1f, 1f, 1f, 0f, 1f, 1f, 1f, 0f),
			["Cinderlight"] = new ZonePalette(0.949f, 0.361f, 0.098f, 0.373f, 0.067f, 0.239f, 1f, 0.851f, 0.78f),
			["Verdigris"] = new ZonePalette(0.184f, 0.639f, 0.604f, 0.478f, 0.306f, 0.114f, 0.749f, 0.906f, 0.839f),
			["Eclipse"] = new ZonePalette(0.043f, 0.043f, 0.078f, 0.765f, 0.58f, 0.133f, 0.29f, 0.435f, 0.682f),
			["Wispfire"] = new ZonePalette(0.914f, 0.953f, 1f, 1f, 0.478f, 0.682f, 0.718f, 0.612f, 1f),
			["Moth Silk"] = new ZonePalette(0.941f, 0.929f, 0.902f, 0.812f, 0.902f, 0.788f, 0.549f, 0.494f, 0.416f),
			["Glassheart"] = new ZonePalette(0.247f, 0.82f, 1f, 1f, 0.357f, 0.541f, 0.682f, 0.878f, 1f),
			["Iron Bloom"] = new ZonePalette(0.494f, 0.557f, 0.639f, 0.898f, 0.322f, 0.18f, 1f, 0.82f, 0.329f),
			["Shroudglow"] = new ZonePalette(0f, 0.24f, 0.3f, 0.718f, 0.976f, 0.294f, 0.42f, 0.878f, 1f)
		};

		private static readonly Dictionary<string, ZonePalette> SpoilerPresets = new Dictionary<string, ZonePalette> { ["Shade"] = new ZonePalette(0.25f, 0.15f, 0.35f, 0.15f, 0.1f, 0.2f, 0.3f, 0.25f, 0.45f) };

		public static string[] GetPresetNames(bool includeSpoilers = false)
		{
			List<string> list = Presets.Keys.ToList();
			if (includeSpoilers)
			{
				list.AddRange(SpoilerPresets.Keys);
			}
			return list.ToArray();
		}

		public static ZonePalette GetPreset(string name)
		{
			if (Presets.TryGetValue(name, out var value))
			{
				return value;
			}
			if (SpoilerPresets.TryGetValue(name, out value))
			{
				return value;
			}
			return Presets["Silk (Default)"];
		}

		public static bool PresetExists(string name)
		{
			if (!Presets.ContainsKey(name))
			{
				return SpoilerPresets.ContainsKey(name);
			}
			return true;
		}

		public static bool IsSpoilerPreset(string name)
		{
			return SpoilerPresets.ContainsKey(name);
		}

		public static string GetLocalizedPresetName(string internalName)
		{
			return Localization.Get("preset_" + internalName.ToLower().Replace(" ", "_").Replace("(", "")
				.Replace(")", ""));
		}

		public static string GetInternalPresetName(string localizedName)
		{
			foreach (string key in Presets.Keys)
			{
				if (GetLocalizedPresetName(key) == localizedName)
				{
					return key;
				}
			}
			return localizedName;
		}
	}
	public static class ConfigLocalizedLanguagePilot
	{
		private static Vector2 _scrollPos;

		public static ConfigEntry<Localization.Language> BindLocalizedLanguageDropdown(ConfigFile cfg, string section, string key, Localization.Language defaultLanguage)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			Localization.Language[] allLanguages = Enum.GetValues(typeof(Localization.Language)).Cast<Localization.Language>().ToArray();
			return cfg.Bind<Localization.Language>(section, key, defaultLanguage, new ConfigDescription(Localization.Get("config_language"), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = delegate(ConfigEntryBase entryBase)
					{
						Draw(entryBase, allLanguages);
					}
				}
			}));
		}

		private static void Draw(ConfigEntryBase entryBase, Localization.Language[] allLanguages)
		{
			//IL_006d: 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)
			ConfigEntry<Localization.Language> val = (ConfigEntry<Localization.Language>)(object)entryBase;
			string[] array = allLanguages.Select((Localization.Language lang) => Localization.GetLanguageDisplayName(lang)).ToArray();
			int num = Array.IndexOf(allLanguages, val.Value);
			if (num < 0)
			{
				num = 0;
			}
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Label(Localization.Get("setting_language"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			_scrollPos = GUILayout.BeginScrollView(_scrollPos, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(120f),
				GUILayout.Width(280f)
			});
			int num2 = GUILayout.SelectionGrid(num, array, 2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) });
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
			if (num2 != num && num2 >= 0 && num2 < allLanguages.Length)
			{
				val.Value = allLanguages[num2];
			}
		}
	}
	public static class ConfigLocalizedPresetPilot
	{
		private static Vector2 _scrollPos;

		public static ConfigEntry<string> BindLocalizedPresetDropdown(ConfigFile cfg, string section, string key, string defaultInternalPreset, Func<string[]> getOrderedInternalNames)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			Func<string[]> getOrderedInternalNames2 = getOrderedInternalNames;
			if (!ColorPresets.PresetExists(defaultInternalPreset))
			{
				defaultInternalPreset = "Silk (Default)";
			}
			return cfg.Bind<string>(section, key, defaultInternalPreset, new ConfigDescription(Localization.Get("config_color_preset"), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = delegate(ConfigEntryBase entryBase)
					{
						Draw(entryBase, getOrderedInternalNames2);
					}
				}
			}));
		}

		private static void Draw(ConfigEntryBase entryBase, Func<string[]> getOrderedInternalNames)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<string> val = (ConfigEntry<string>)(object)entryBase;
			string[] array = getOrderedInternalNames?.Invoke() ?? ColorPresets.GetPresetNames();
			string[] array2 = array.Select(ColorPresets.GetLocalizedPresetName).ToArray();
			int num = Array.IndexOf(array, val.Value);
			if (num < 0)
			{
				num = 0;
			}
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Label(Localization.Get("setting_color_preset"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			_scrollPos = GUILayout.BeginScrollView(_scrollPos, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(140f),
				GUILayout.Width(280f)
			});
			int num2 = GUILayout.SelectionGrid(num, array2, 2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) });
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
			if (num2 != num && num2 >= 0 && num2 < array.Length)
			{
				val.Value = array[num2];
			}
		}
	}
	public class DebugOverlay
	{
		private ManualLogSource? Logger;

		private bool showDebugOverlay;

		private TrueAimPlugin plugin;

		public DebugOverlay(TrueAimPlugin plugin, ManualLogSource logger)
		{
			this.plugin = plugin;
			Logger = logger;
		}

		public void OnGUI()
		{
			if (showDebugOverlay)
			{
				HeroController instance = HeroController.instance;
				if (!((Object)(object)instance == (Object)null))
				{
					RenderDebugUI(instance);
				}
			}
		}

		public void Toggle()
		{
			showDebugOverlay = !showDebugOverlay;
			ManualLogSource? logger = Logger;
			if (logger != null)
			{
				logger.LogInfo((object)(showDebugOverlay ? Localization.Get("debug_overlay_on") : Localization.Get("debug_overlay_off")));
			}
		}

		public bool IsActive()
		{
			return showDebugOverlay;
		}

		private void RenderDebugUI(HeroController hero)
		{
			//IL_0040: 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_0063: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			float num = 1920f;
			float num2 = (float)Screen.width / num;
			num2 = Mathf.Clamp(num2, 0.5f, 2f);
			GUIStyle val = CreateBoxStyle((int)(16f * num2), (int)(10f * num2));
			GUIStyle val2 = CreateLabelStyle((int)(14f * num2), Color.white);
			GUIStyle headerStyle = CreateHeaderStyle((int)(18f * num2));
			GUIStyle stateStyle = new GUIStyle(val2);
			float num3 = 420f * num2;
			float num4 = 960f * num2;
			float num5 = (float)Screen.width - num3 - 10f;
			float num6 = 10f * num2;
			int num7 = (int)(num5 + 10f * num2);
			int num8 = (int)(25f * num2);
			int sectionGap = (int)(15f * num2);
			int num9 = (int)(380f * num2);
			GUI.Box(new Rect(num5, num6, num3, num4), "TRUE AIM DEBUG", val);
			int y = (int)(num6 + 40f * num2);
			RenderConfigSection(hero, num7, ref y, num8, sectionGap, num9, headerStyle, val2);
			RenderHeroStateSection(hero, num7, ref y, num8, sectionGap, num9, headerStyle, val2, stateStyle);
			RenderEffectsSection(hero, num7, ref y, num8, sectionGap, num9, headerStyle, val2, stateStyle);
			RenderChargeSection(hero, num7, ref y, num8, sectionGap, num9, headerStyle, val2, stateStyle);
			RenderControllerSection(hero, num7, ref y, num8, sectionGap, num9, headerStyle, val2);
			RenderFSMSection(hero, num7, ref y, num8, num9, headerStyle, val2, stateStyle);
			int num10 = (int)(num6 + num4 - 35f * num2);
			GUI.Label(new Rect((float)num7, (float)num10, (float)num9, (float)num8), "F11: Toggle | F9: Log FSMs | F12: Scan All", val2);
		}

		private void RenderConfigSection(HeroController hero, int leftMargin, ref int y, int lineHeight, int sectionGap, int labelWidth, GUIStyle headerStyle, GUIStyle labelStyle)
		{
			//IL_000b: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "=== CONFIG ===", headerStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Effects Toggle: {plugin.AttackEffectToggle}", labelStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Show Guide: {plugin.ShowInputGuide}", labelStyle);
			y += lineHeight + sectionGap;
		}

		private void RenderHeroStateSection(HeroController hero, int leftMargin, ref int y, int lineHeight, int sectionGap, int labelWidth, GUIStyle headerStyle, GUIStyle labelStyle, GUIStyle stateStyle)
		{
			//IL_000b: 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_0037: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "=== HERO STATE ===", headerStyle);
			y += lineHeight;
			stateStyle.normal.textColor = (hero.cState.nailCharging ? Color.yellow : Color.white);
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Nail Charging: {hero.cState.nailCharging}", stateStyle);
			y += lineHeight;
			stateStyle.normal.textColor = (hero.cState.attacking ? Color.red : Color.white);
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Attacking: {hero.cState.attacking}", stateStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Up Attack: {hero.cState.upAttacking}", labelStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Down Attack: {hero.cState.downAttacking}", labelStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Tool Throwing: {hero.cState.isToolThrowing}", labelStyle);
			y += lineHeight;
			bool wallSlashing = plugin.GetWallSlashing(hero);
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Wall Slashing: {wallSlashing}", labelStyle);
			y += lineHeight + sectionGap;
		}

		private void RenderEffectsSection(HeroController hero, int leftMargin, ref int y, int lineHeight, int sectionGap, int labelWidth, GUIStyle headerStyle, GUIStyle labelStyle, GUIStyle stateStyle)
		{
			//IL_000b: 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_003c: 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_00a5: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "=== EFFECTS ===", headerStyle);
			y += lineHeight;
			stateStyle.normal.textColor = ((plugin.AttackFlashTimer > 0f) ? Color.green : Color.gray);
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Flash Timer: {plugin.AttackFlashTimer:F3}s", stateStyle);
			y += lineHeight;
			stateStyle.normal.textColor = ((plugin.AttackCooldownTimer > 0f) ? Color.cyan : Color.gray);
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Cooldown Timer: {plugin.AttackCooldownTimer:F3}s", stateStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Flash Multiplier: {plugin.BaseFlashMultiplier:F2}x", labelStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Pulse Multiplier: {plugin.BasePulseMultiplier:F2}x", labelStyle);
			y += lineHeight + sectionGap;
		}

		private void RenderChargeSection(HeroController hero, int leftMargin, ref int y, int lineHeight, int sectionGap, int labelWidth, GUIStyle headerStyle, GUIStyle labelStyle, GUIStyle stateStyle)
		{
			//IL_000b: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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)
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "=== CHARGE ===", headerStyle);
			y += lineHeight;
			float chargeTime = plugin.GetChargeTime(hero);
			float nAIL_CHARGE_TIME = hero.NAIL_CHARGE_TIME;
			float num = Mathf.Clamp01(chargeTime / nAIL_CHARGE_TIME);
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Charge Time: {chargeTime:F2}s / {nAIL_CHARGE_TIME:F2}s", labelStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Progress: {num:P0}", labelStyle);
			y += lineHeight;
			stateStyle.normal.textColor = ((plugin.ChargeSwellMultiplier > 1.01f) ? Color.magenta : Color.gray);
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Swell Multiplier: {plugin.ChargeSwellMultiplier:F2}x", stateStyle);
			y += lineHeight + sectionGap;
		}

		private void RenderControllerSection(HeroController hero, int leftMargin, ref int y, int lineHeight, int sectionGap, int labelWidth, GUIStyle headerStyle, GUIStyle labelStyle)
		{
			//IL_000b: 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_0039: 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)
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "=== CONTROLLER ===", headerStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), $"Actor: {hero.hero_state}", labelStyle);
			y += lineHeight;
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "Flags: " + GetCStateDescription(hero.cState), labelStyle);
			y += lineHeight + sectionGap;
		}

		private void RenderFSMSection(HeroController hero, int leftMargin, ref int y, int lineHeight, int labelWidth, GUIStyle headerStyle, GUIStyle labelStyle, GUIStyle stateStyle)
		{
			//IL_000b: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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_01b0: 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_014b: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: 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_02c1: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "=== FSM ===", headerStyle);
			y += lineHeight;
			if ((Object)(object)hero.sprintFSM != (Object)null)
			{
				stateStyle.normal.textColor = ((hero.sprintFSM.ActiveStateName == "Attack Antic") ? Color.red : Color.white);
				GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "Sprint: " + hero.sprintFSM.ActiveStateName, stateStyle);
				y += lineHeight;
			}
			if ((Object)(object)hero.crestAttacksFSM != (Object)null)
			{
				stateStyle.normal.textColor = (hero.crestAttacksFSM.ActiveStateName.Contains("Antic") ? Color.red : Color.white);
				GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "Crest: " + hero.crestAttacksFSM.ActiveStateName, stateStyle);
				y += lineHeight;
			}
			if ((Object)(object)hero.toolsFSM != (Object)null)
			{
				stateStyle.normal.textColor = ((hero.toolsFSM.ActiveStateName != "Idle") ? Color.cyan : Color.white);
				GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "Tools: " + hero.toolsFSM.ActiveStateName, stateStyle);
				y += lineHeight;
			}
			if ((Object)(object)plugin.NailArtsFSM != (Object)null)
			{
				stateStyle.normal.textColor = ((plugin.NailArtsFSM.ActiveStateName != "Inactive") ? Color.magenta : Color.white);
				GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "NailArts: " + plugin.NailArtsFSM.ActiveStateName, stateStyle);
				y += lineHeight;
			}
			if ((Object)(object)hero.superJumpFSM != (Object)null)
			{
				stateStyle.normal.textColor = ((hero.superJumpFSM.ActiveStateName != "Idle" && hero.superJumpFSM.ActiveStateName != "Inactive") ? Color.green : Color.white);
				GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "SuperJump: " + hero.superJumpFSM.ActiveStateName, stateStyle);
				y += lineHeight;
			}
			if ((Object)(object)hero.wallScrambleFSM != (Object)null)
			{
				stateStyle.normal.textColor = ((hero.wallScrambleFSM.ActiveStateName != "Idle") ? Color.yellow : Color.white);
				GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "WallScramble: " + hero.wallScrambleFSM.ActiveStateName, stateStyle);
				y += lineHeight;
			}
			if ((Object)(object)hero.harpoonDashFSM != (Object)null)
			{
				GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "Harpoon: " + hero.harpoonDashFSM.ActiveStateName, labelStyle);
				y += lineHeight;
			}
			if ((Object)(object)hero.bellBindFSM != (Object)null)
			{
				GUI.Label(new Rect((float)leftMargin, (float)y, (float)labelWidth, (float)lineHeight), "Bell: " + hero.bellBindFSM.ActiveStateName, labelStyle);
				y += lineHeight;
			}
		}

		private string GetCStateDescription(HeroControllerStates cState)
		{
			List<string> list = new List<string>();
			if (cState.onGround)
			{
				list.Add("Ground");
			}
			if (cState.jumping)
			{
				list.Add("Jump");
			}
			if (cState.falling)
			{
				list.Add("Fall");
			}
			if (cState.dashing)
			{
				list.Add("Dash");
			}
			if (cState.wallSliding)
			{
				list.Add("WallSlide");
			}
			if (cState.wallClinging)
			{
				list.Add("WallCling");
			}
			if (cState.attacking)
			{
				list.Add("Attack");
			}
			if (cState.upAttacking)
			{
				list.Add("UpAtk");
			}
			if (cState.downAttacking)
			{
				list.Add("DownAtk");
			}
			if (cState.nailCharging)
			{
				list.Add("Charge");
			}
			if (cState.invulnerable)
			{
				list.Add("Invuln");
			}
			if (cState.recoiling)
			{
				list.Add("Recoil");
			}
			if (cState.parrying)
			{
				list.Add("Parry");
			}
			if (list.Count <= 0)
			{
				return "None";
			}
			return string.Join(", ", list);
		}

		private GUIStyle CreateBoxStyle(int fontSize, int padding)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0026: 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_0035: Expected O, but got Unknown
			//IL_0036: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.box)
			{
				fontSize = fontSize
			};
			val.normal.textColor = Color.white;
			val.padding = new RectOffset(padding, padding, padding, padding);
			return val;
		}

		private GUIStyle CreateLabelStyle(int fontSize, Color color)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0023: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = fontSize
			};
			val.normal.textColor = color;
			return val;
		}

		private GUIStyle CreateHeaderStyle(int fontSize)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = fontSize,
				fontStyle = (FontStyle)1
			};
			val.normal.textColor = Color.yellow;
			return val;
		}
	}
	public class GameplayHandler
	{
		private ManualLogSource? Logger;

		private TrueAimPlugin plugin;

		private string lastKnownCrestID = "";

		private bool lastKnownLongclawEquipped;

		private float cachedRadius = 2.5f;

		private Type? gameplayType;

		private PropertyInfo? longNeedleToolProperty;

		private PropertyInfo? longNeedleMultiplierProperty;

		private bool hasTriedReflectionSetup;

		private static readonly Dictionary<string, float> CrestRadiusMap = new Dictionary<string, float>
		{
			{ "Hunter", 2.95f },
			{ "Reaper", 3.75f },
			{ "Wanderer", 3.1f },
			{ "Warrior", 3.2f },
			{ "Witch", 4f },
			{ "Toolmaster", 4.1f },
			{ "Spell", 5.6f }
		};

		public GameplayHandler(ManualLogSource logger, TrueAimPlugin pluginRef)
		{
			Logger = logger;
			plugin = pluginRef;
		}

		private void EnsureReflectionSetup()
		{
			if (hasTriedReflectionSetup)
			{
				return;
			}
			hasTriedReflectionSetup = true;
			try
			{
				gameplayType = Type.GetType("GlobalSettings.Gameplay, Assembly-CSharp");
				if (gameplayType != null)
				{
					longNeedleToolProperty = gameplayType.GetProperty("LongNeedleTool", BindingFlags.Static | BindingFlags.Public);
					longNeedleMultiplierProperty = gameplayType.GetProperty("LongNeedleMultiplier", BindingFlags.Static | BindingFlags.Public);
					if (longNeedleToolProperty != null)
					{
						ManualLogSource? logger = Logger;
						if (logger != null)
						{
							logger.LogInfo((object)"✅ Longclaw detection initialized");
						}
					}
				}
				else
				{
					ManualLogSource? logger2 = Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)"⚠\ufe0f GlobalSettings.Gameplay not found");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource? logger3 = Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)("Reflection setup failed: " + ex.Message));
				}
			}
		}

		private bool IsLongclawEquipped(HeroController hero)
		{
			if ((Object)(object)hero == (Object)null)
			{
				return false;
			}
			EnsureReflectionSetup();
			if (longNeedleToolProperty == null)
			{
				return false;
			}
			try
			{
				object value = longNeedleToolProperty.GetValue(null);
				if (value == null)
				{
					return false;
				}
				PropertyInfo property = value.GetType().GetProperty("IsEquipped");
				if (property == null)
				{
					return false;
				}
				return (bool)property.GetValue(value);
			}
			catch
			{
				return false;
			}
		}

		private float GetLongNeedleMultiplier()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (longNeedleMultiplierProperty != null)
			{
				try
				{
					object value = longNeedleMultiplierProperty.GetValue(null);
					if (value is Vector2)
					{
						Vector2 val = (Vector2)value;
						return val.x;
					}
				}
				catch
				{
				}
			}
			return 1.25f;
		}

		private void UpdateCachedRadius(string crestID, bool hasLongNeedle)
		{
			string text = crestID.Split(new char[1] { '_' })[0];
			float value;
			float num = (CrestRadiusMap.TryGetValue(text, out value) ? value : 2.5f);
			if (hasLongNeedle)
			{
				float longNeedleMultiplier = GetLongNeedleMultiplier();
				cachedRadius = num * longNeedleMultiplier;
				ManualLogSource? logger = Logger;
				if (logger != null)
				{
					logger.LogInfo((object)$"\ud83d\udccf {text} + Longclaw: {cachedRadius:F2} (base={num:F2}, mult={longNeedleMultiplier:F2})");
				}
			}
			else
			{
				cachedRadius = num;
				ManualLogSource? logger2 = Logger;
				if (logger2 != null)
				{
					logger2.LogInfo((object)$"\ud83d\udccf {text}: {cachedRadius:F2}");
				}
			}
		}

		public bool TryGetUpdatedRadius(HeroController hero, out float newRadius)
		{
			if ((Object)(object)hero == (Object)null || hero.playerData == null)
			{
				newRadius = cachedRadius;
				return false;
			}
			string currentCrestID = hero.playerData.CurrentCrestID;
			bool flag = IsLongclawEquipped(hero);
			if (currentCrestID != lastKnownCrestID || flag != lastKnownLongclawEquipped)
			{
				ManualLogSource? logger = Logger;
				if (logger != null)
				{
					logger.LogInfo((object)("⚔\ufe0f Loadout: " + currentCrestID + (flag ? " + Longclaw" : "")));
				}
				UpdateCachedRadius(currentCrestID, flag);
				lastKnownCrestID = currentCrestID;
				lastKnownLongclawEquipped = flag;
				newRadius = cachedRadius;
				return true;
			}
			newRadius = cachedRadius;
			return false;
		}

		public void ForceRefresh(HeroController hero)
		{
			lastKnownCrestID = "";
			lastKnownLongclawEquipped = false;
			TryGetUpdatedRadius(hero, out var _);
		}

		private bool IsHunterCrestEquipped()
		{
			HeroController instance = HeroController.instance;
			if ((Object)(object)instance == (Object)null || instance.playerData == null)
			{
				return false;
			}
			string currentCrestID = instance.playerData.CurrentCrestID;
			if (!(currentCrestID == "Hunter") && !(currentCrestID == "Hunter_v2"))
			{
				return currentCrestID == "Hunter_v3";
			}
			return true;
		}
	}
	public class HaloRenderer
	{
		private GameObject haloObject;

		private LineRenderer indicatorRenderer;

		private GameObject arrowheadObject;

		private MeshRenderer arrowheadRenderer;

		private MeshFilter arrowheadFilter;

		private List<LineRenderer> segmentBaseRenderers = new List<LineRenderer>();

		private List<LineRenderer> segmentFillRenderers = new List<LineRenderer>();

		private static Material? _sharedSpriteMat;

		private float radius;

		private List<ActionZone> zones = new List<ActionZone>();

		private bool isAnimating;

		private float animationProgress = 1f;

		private bool targetVisible = true;

		private const float ANIMATION_DURATION = 0.25f;

		private const float SHRINK_SCALE = 0.6f;

		private float currentActiveOpacity = 1f;

		public bool IsCreated
		{
			get
			{
				if ((Object)(object)haloObject != (Object)null && segmentBaseRenderers != null && segmentBaseRenderers.Count > 0 && segmentFillRenderers != null && segmentFillRenderers.Count > 0)
				{
					return (Object)(object)indicatorRenderer != (Object)null;
				}
				return false;
			}
		}

		public void Create(float haloRadius, List<ActionZone> actionZones)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)haloObject != (Object)null))
			{
				radius = haloRadius;
				zones = actionZones;
				haloObject = new GameObject("TrueAimHalo");
				Object.DontDestroyOnLoad((Object)(object)haloObject);
				haloObject.layer = LayerMask.NameToLayer("UI");
				haloObject.transform.localScale = Vector3.one;
				CreateSegments(actionZones);
				CreateIndicator();
			}
		}

		private void CreateSegments(List<ActionZone> zones)
		{
			//IL_0029: 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_005b: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			foreach (ActionZone zone in zones)
			{
				GameObject val = new GameObject("Segment_" + zone.name + "_Base");
				val.transform.SetParent(haloObject.transform);
				LineRenderer val2 = val.AddComponent<LineRenderer>();
				val2.useWorldSpace = false;
				val2.alignment = (LineAlignment)0;
				SetupLineRenderer(val2, zone.color, 0.08f);
				DrawArc(val2, zone.startAngle, zone.endAngle, radius);
				segmentBaseRenderers.Add(val2);
				GameObject val3 = new GameObject("Segment_" + zone.name + "_Fill");
				val3.transform.SetParent(haloObject.transform);
				LineRenderer val4 = val3.AddComponent<LineRenderer>();
				val4.useWorldSpace = false;
				val4.alignment = (LineAlignment)0;
				SetupLineRenderer(val4, zone.color, 0.2f);
				((Renderer)val4).enabled = false;
				segmentFillRenderers.Add(val4);
			}
		}

		private void CreateIndicator()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0034: 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_008b: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("InputIndicator");
			val.transform.SetParent(haloObject.transform);
			indicatorRenderer = val.AddComponent<LineRenderer>();
			SetupLineRenderer(indicatorRenderer, Color.white, 0.08f);
			indicatorRenderer.positionCount = 2;
			((Renderer)indicatorRenderer).enabled = false;
			indicatorRenderer.startWidth = 0.08f;
			indicatorRenderer.endWidth = 0.08f;
			arrowheadObject = new GameObject("Arrowhead");
			arrowheadObject.transform.SetParent(haloObject.transform);
			arrowheadFilter = arrowheadObject.AddComponent<MeshFilter>();
			arrowheadRenderer = arrowheadObject.AddComponent<MeshRenderer>();
			((Renderer)arrowheadRenderer).material = (Material)(((object)_sharedSpriteMat) ?? ((object)new Material(Shader.Find("Sprites/Default"))));
			((Renderer)arrowheadRenderer).sortingOrder = 32767;
			CreateArrowheadMesh();
			arrowheadObject.SetActive(false);
		}

		private void CreateArrowheadMesh()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Mesh val = new Mesh();
			float num = 0.2f;
			float num2 = 0.2f;
			Vector3[] vertices = (Vector3[])(object)new Vector3[3]
			{
				new Vector3(num, 0f, 0f),
				new Vector3(0f, num2 / 2f, 0f),
				new Vector3(0f, (0f - num2) / 2f, 0f)
			};
			int[] triangles = new int[3] { 0, 1, 2 };
			Vector2[] uv = (Vector2[])(object)new Vector2[3]
			{
				new Vector2(1f, 0.5f),
				new Vector2(0f, 1f),
				new Vector2(0f, 0f)
			};
			val.vertices = vertices;
			val.triangles = triangles;
			val.uv = uv;
			val.RecalculateNormals();
			arrowheadFilter.mesh = val;
		}

		public void UpdateRadius(float newRadius)
		{
			if (!IsCreated || Mathf.Abs(radius - newRadius) < 0.01f)
			{
				return;
			}
			radius = newRadius;
			for (int i = 0; i < segmentBaseRenderers.Count && i < zones.Count; i++)
			{
				if ((Object)(object)segmentBaseRenderers[i] != (Object)null)
				{
					DrawArc(segmentBaseRenderers[i], zones[i].startAngle, zones[i].endAngle, radius);
				}
			}
		}

		public void UpdatePosition(Vector3 position)
		{
			//IL_0019: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)haloObject != (Object)null)
			{
				haloObject.transform.position = new Vector3(position.x, position.y, -0.1f);
			}
			if (isAnimating)
			{
				UpdateAnimation();
			}
		}

		public void UpdateSegmentHighlights(int activeSegment, List<ActionZone> zones, float activeOpacity, float inactiveOpacity, float flashIntensity, float fillProgress, float pulseIntensity, float swellMultiplier = 1f)
		{
			//IL_0047: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00da: 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_007b: 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_008a: 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_00f4: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			currentActiveOpacity = activeOpacity;
			for (int i = 0; i < segmentBaseRenderers.Count && i < zones.Count; i++)
			{
				LineRenderer val = segmentBaseRenderers[i];
				LineRenderer val2 = segmentFillRenderers[i];
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Color color = zones[i].color;
				if (i == activeSegment)
				{
					((Renderer)val).enabled = true;
					Color val3 = color * 1.2f;
					val3.a = activeOpacity;
					if (flashIntensity > 0f)
					{
						val3 = Color.Lerp(val3, Color.white, flashIntensity * 0.6f);
					}
					float num = pulseIntensity * 0.3f;
					DrawArc(val, zones[i].startAngle, zones[i].endAngle, radius + num);
					val.startColor = val3;
					val.endColor = val3;
					((Renderer)val2).enabled = true;
					Color val4 = color;
					val4.a = activeOpacity * 0.4f;
					if (flashIntensity > 0f)
					{
						val4 = Color.Lerp(val4, Color.white, flashIntensity * 0.6f);
					}
					if (fillProgress >= 0.99f)
					{
						val4.a = activeOpacity;
					}
					float num2 = 0.2f + pulseIntensity * 0.15f;
					num2 = (val2.startWidth = num2 * swellMultiplier);
					val2.endWidth = num2;
					float num4 = 0.14f + pulseIntensity * 0.3f;
					num4 *= swellMultiplier;
					DrawPartialArcOffset(val2, zones[i], fillProgress, num4);
					val2.startColor = val4;
					val2.endColor = val4;
				}
				else
				{
					((Renderer)val).enabled = true;
					color.a = inactiveOpacity;
					DrawArc(val, zones[i].startAngle, zones[i].endAngle, radius);
					val.startColor = color;
					val.endColor = color;
					((Renderer)val2).enabled = false;
				}
			}
		}

		public void UpdateIndicator(Vector2 input, int activeSegment, List<ActionZone> zones, float currentRadius, float startOffset, float activeOpacity)
		{
			//IL_0046: 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_00b0: 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_00f9: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)indicatorRenderer == (Object)null) && !((Object)(object)arrowheadObject == (Object)null))
			{
				if (((Vector2)(ref input)).magnitude > 0.1f)
				{
					((Renderer)indicatorRenderer).enabled = true;
					arrowheadObject.SetActive(true);
					float num = Mathf.Atan2(input.y, input.x);
					float num2 = num * 57.29578f;
					Vector3 val = default(Vector3);
					((Vector3)(ref val))..ctor(Mathf.Cos(num) * currentRadius * startOffset, Mathf.Sin(num) * currentRadius * startOffset, 0f);
					float num3 = currentRadius - 0.32f;
					Vector3 val2 = default(Vector3);
					((Vector3)(ref val2))..ctor(Mathf.Cos(num) * num3, Mathf.Sin(num) * num3, 0f);
					indicatorRenderer.SetPosition(0, val);
					indicatorRenderer.SetPosition(1, val2);
					Vector3 localPosition = default(Vector3);
					((Vector3)(ref localPosition))..ctor(Mathf.Cos(num) * (currentRadius - 0.28f), Mathf.Sin(num) * (currentRadius - 0.28f), 0f);
					arrowheadObject.transform.localPosition = localPosition;
					arrowheadObject.transform.localRotation = Quaternion.Euler(0f, 0f, num2);
					Color startColor;
					Color val3 = (startColor = ((activeSegment >= 0 && activeSegment < zones.Count) ? zones[activeSegment].color : Color.white));
					startColor.a = activeOpacity * 0.3f;
					Color endColor = val3;
					endColor.a = activeOpacity;
					indicatorRenderer.startColor = startColor;
					indicatorRenderer.endColor = endColor;
					Color color = val3;
					color.a = activeOpacity;
					((Renderer)arrowheadRenderer).material.color = color;
				}
				else
				{
					((Renderer)indicatorRenderer).enabled = false;
					arrowheadObject.SetActive(false);
				}
			}
		}

		public void SetActive(bool active, bool animated = false)
		{
			//IL_007b: 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_004f: 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)
			if ((Object)(object)haloObject == (Object)null)
			{
				return;
			}
			targetVisible = active;
			if (animated)
			{
				isAnimating = true;
				if (active)
				{
					haloObject.SetActive(true);
					animationProgress = 0f;
					haloObject.transform.localScale = Vector3.one * 0.6f;
					ApplyGlobalAlpha(0f);
				}
				else
				{
					animationProgress = 1f;
					haloObject.transform.localScale = Vector3.one;
				}
			}
			else
			{
				isAnimating = false;
				animationProgress = (active ? 1f : 0f);
				haloObject.SetActive(active);
				haloObject.transform.localScale = Vector3.one;
				if (active)
				{
					ApplyGlobalAlpha(1f);
				}
			}
		}

		public void ResetAnimationState()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			isAnimating = false;
			animationProgress = (targetVisible ? 1f : 0f);
			if ((Object)(object)haloObject != (Object)null)
			{
				haloObject.SetActive(targetVisible);
				haloObject.transform.localScale = Vector3.one;
				if (targetVisible)
				{
					ApplyGlobalAlpha(1f);
				}
			}
		}

		public void Destroy()
		{
			if ((Object)(object)haloObject != (Object)null)
			{
				Object.Destroy((Object)(object)haloObject);
				haloObject = null;
				indicatorRenderer = null;
				arrowheadObject = null;
				arrowheadRenderer = null;
				arrowheadFilter = null;
				segmentBaseRenderers?.Clear();
				segmentFillRenderers?.Clear();
				if ((Object)(object)_sharedSpriteMat != (Object)null)
				{
					Object.Destroy((Object)(object)_sharedSpriteMat);
					_sharedSpriteMat = null;
				}
			}
		}

		public bool IsAnimating()
		{
			return isAnimating;
		}

		private void UpdateAnimation()
		{
			if (targetVisible)
			{
				animationProgress += Time.deltaTime / 0.25f;
				if (animationProgress >= 1f)
				{
					animationProgress = 1f;
					isAnimating = false;
				}
			}
			else
			{
				animationProgress -= Time.deltaTime / 0.25f;
				if (animationProgress <= 0f)
				{
					animationProgress = 0f;
					isAnimating = false;
					if ((Object)(object)haloObject != (Object)null)
					{
						haloObject.SetActive(false);
					}
				}
			}
			float num = EasingCurves.EaseOutExpo(animationProgress);
			ApplyGlobalAlpha(num);
			ApplyGlobalScale(num);
		}

		private void ApplyGlobalAlpha(float multiplier)
		{
			//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_002e: 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_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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_00d5: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < segmentBaseRenderers.Count; i++)
			{
				LineRenderer val = segmentBaseRenderers[i];
				if (!((Object)(object)val == (Object)null))
				{
					Color startColor = val.startColor;
					startColor.a *= multiplier;
					val.startColor = startColor;
					val.endColor = startColor;
				}
			}
			for (int j = 0; j < segmentFillRenderers.Count; j++)
			{
				LineRenderer val2 = segmentFillRenderers[j];
				if (!((Object)(object)val2 == (Object)null))
				{
					Color startColor2 = val2.startColor;
					startColor2.a *= multiplier;
					val2.startColor = startColor2;
					val2.endColor = startColor2;
				}
			}
			if ((Object)(object)indicatorRenderer != (Object)null && ((Renderer)indicatorRenderer).enabled)
			{
				Color startColor3 = indicatorRenderer.startColor;
				Color endColor = indicatorRenderer.endColor;
				startColor3.a *= multiplier;
				endColor.a *= multiplier;
				indicatorRenderer.startColor = startColor3;
				indicatorRenderer.endColor = endColor;
			}
			if ((Object)(object)arrowheadRenderer != (Object)null && arrowheadObject.activeSelf)
			{
				Color color = ((Renderer)arrowheadRenderer).material.color;
				color.a *= multiplier;
				((Renderer)arrowheadRenderer).material.color = color;
			}
		}

		private void ApplyGlobalScale(float easedProgress)
		{
			//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)
			if ((Object)(object)haloObject != (Object)null)
			{
				float num = ((!targetVisible) ? Mathf.Lerp(0.6f, 1f, easedProgress) : Mathf.Lerp(0.6f, 1f, easedProgress));
				haloObject.transform.localScale = Vector3.one * num;
			}
		}

		private void SetupLineRenderer(LineRenderer lr, Color color, float width)
		{
			//IL_0035: 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_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_0029: Expected O, but got Unknown
			if ((Object)(object)_sharedSpriteMat == (Object)null)
			{
				_sharedSpriteMat = new Material(Shader.Find("Sprites/Default"))
				{
					hideFlags = (HideFlags)32
				};
			}
			((Renderer)lr).material = _sharedSpriteMat;
			lr.startColor = color;
			lr.endColor = color;
			lr.startWidth = width;
			lr.endWidth = width;
			lr.useWorldSpace = false;
			((Renderer)lr).sortingOrder = 32767;
		}

		private void DrawCircle(LineRenderer lr, float circleRadius)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			int num = 64;
			lr.positionCount = num + 1;
			for (int i = 0; i <= num; i++)
			{
				float num2 = (float)i / (float)num * 2f * (float)Math.PI;
				lr.SetPosition(i, new Vector3(Mathf.Cos(num2) * circleRadius, Mathf.Sin(num2) * circleRadius, 0f));
			}
		}

		private void DrawArc(LineRenderer lr, float startAngle, float endAngle, float arcRadius)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			startAngle = (startAngle % 360f + 360f) % 360f;
			endAngle = (endAngle % 360f + 360f) % 360f;
			float num = ((startAngle <= endAngle) ? (endAngle - startAngle) : (360f - startAngle + endAngle));
			int num2 = Mathf.Max(64, (int)(num / 1f));
			lr.positionCount = num2 + 1;
			for (int i = 0; i <= num2; i++)
			{
				float num3 = (float)i / (float)num2;
				float num4 = (startAngle + num * num3) * ((float)Math.PI / 180f);
				lr.SetPosition(i, new Vector3(Mathf.Cos(num4) * arcRadius, Mathf.Sin(num4) * arcRadius, 0f));
			}
		}

		private void DrawPartialArcOffset(LineRenderer lr, ActionZone zone, float fillProgress, float radiusOffset)
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			float num = (zone.startAngle % 360f + 360f) % 360f;
			float num2 = (zone.endAngle % 360f + 360f) % 360f;
			float num3 = ((num <= num2) ? (num2 - num) : (360f - num + num2));
			float num4 = num + num3 / 2f;
			float num5 = num3 / 2f * fillProgress;
			float num6 = num4 - num5;
			float num7 = num4 + num5;
			int num8 = Mathf.Max(32, (int)(num3 * fillProgress / 1f));
			lr.positionCount = num8 + 1;
			float num9 = radius + radiusOffset;
			for (int i = 0; i <= num8; i++)
			{
				float num10 = (float)i / (float)num8;
				float num11 = Mathf.Lerp(num6, num7, num10) * ((float)Math.PI / 180f);
				lr.SetPosition(i, new Vector3(Mathf.Cos(num11) * num9, Mathf.Sin(num11) * num9, 0f));
			}
		}

		public bool IsActive()
		{
			if ((Object)(object)haloObject != (Object)null)
			{
				return haloObject.activeSelf;
			}
			return false;
		}

		public void DebugState()
		{
			Debug.Log((object)$"Halo State: Created={IsCreated}, Active={IsActive()}, Animating={isAnimating}, Progress={animationProgress}, TargetVisible={targetVisible}");
		}

		public void DebugAnimationState()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)haloObject == (Object)null)
			{
				Debug.Log((object)"HaloObject is null");
				return;
			}
			Debug.Log((object)("Animation State: " + $"Active: {haloObject.activeSelf}, " + $"Animating: {isAnimating}, " + $"Progress: {animationProgress:F2}, " + $"TargetVisible: {targetVisible}, " + $"Scale: {haloObject.transform.localScale}"));
		}
	}
	[BepInPlugin("com.trueaim.silksong", "Silksong True Aim", "1.0.2")]
	public static class Localization
	{
		public enum Language
		{
			English,
			SimplifiedChinese,
			Japanese,
			Korean,
			Spanish,
			French,
			German,
			Russian
		}

		private static Language currentLanguage = Language.English;

		private static readonly Dictionary<string, Dictionary<Language, string>> strings = new Dictionary<string, Dictionary<Language, string>>
		{
			["plugin_loaded"] = new Dictionary<Language, string>
			{
				[Language.English] = "Plugin {0} loaded!",
				[Language.SimplifiedChinese] = "插件 {0} 已加载!",
				[Language.Japanese] = "プラグイン {0} をロードしました!",
				[Language.Korean] = "플러그인 {0} 로드 완료!",
				[Language.Spanish] = "¡Plugin {0} cargado!",
				[Language.French] = "Plugin {0} chargé !",
				[Language.German] = "Plugin {0} geladen!",
				[Language.Russian] = "Плагин {0} загружен!"
			},
			["press_key_toggle"] = new Dictionary<Language, string>
			{
				[Language.English] = "Press {0} to toggle True Aim",
				[Language.SimplifiedChinese] = "按 {0} 切换真准",
				[Language.Japanese] = "{0} を押してTrue Aimを切り替え",
				[Language.Korean] = "{0} 키로 True Aim 전환",
				[Language.Spanish] = "Pulsa {0} para activar/desactivar True Aim",
				[Language.French] = "Appuyez sur {0} pour activer/désactiver True Aim",
				[Language.German] = "Drücke {0} um True Aim umzuschalten",
				[Language.Russian] = "Нажмите {0} для переключения True Aim"
			},
			["category_general"] = new Dictionary<Language, string>
			{
				[Language.English] = "General",
				[Language.SimplifiedChinese] = "常规",
				[Language.Japanese] = "一般",
				[Language.Korean] = "일반",
				[Language.Spanish] = "General",
				[Language.French] = "Général",
				[Language.German] = "Allgemein",
				[Language.Russian] = "Общие"
			},
			["category_visual"] = new Dictionary<Language, string>
			{
				[Language.English] = "Visual",
				[Language.SimplifiedChinese] = "视觉效果",
				[Language.Japanese] = "ビジュアル",
				[Language.Korean] = "시각 효과",
				[Language.Spanish] = "Visual",
				[Language.French] = "Visuel",
				[Language.German] = "Visuell",
				[Language.Russian] = "Визуальные"
			},
			["category_controls"] = new Dictionary<Language, string>
			{
				[Language.English] = "Controls",
				[Language.SimplifiedChinese] = "控制",
				[Language.Japanese] = "操作",
				[Language.Korean] = "조작",
				[Language.Spanish] = "Controles",
				[Language.French] = "Contrôles",
				[Language.German] = "Steuerung",
				[Language.Russian] = "Управление"
			},
			["category_gameplay"] = new Dictionary<Language, string>
			{
				[Language.English] = "Gameplay",
				[Language.SimplifiedChinese] = "游戏性",
				[Language.Japanese] = "ゲームプレイ",
				[Language.Korean] = "게임플레이",
				[Language.Spanish] = "Jugabilidad",
				[Language.French] = "Gameplay",
				[Language.German] = "Gameplay",
				[Language.Russian] = "Геймплей"
			},
			["category_colors"] = new Dictionary<Language, string>
			{
				[Language.English] = "Colors",
				[Language.SimplifiedChinese] = "颜色自定义",
				[Language.Japanese] = "色設定",
				[Language.Korean] = "색상 커스터마이징",
				[Language.Spanish] = "Colores",
				[Language.French] = "Couleurs",
				[Language.German] = "Farben",
				[Language.Russian] = "Цвета"
			},
			["category_debug"] = new Dictionary<Language, string>
			{
				[Language.English] = "Debug",
				[Language.SimplifiedChinese] = "调试",
				[Language.Japanese] = "デバッグ",
				[Language.Korean] = "디버그",
				[Language.Spanish] = "Depuración",
				[Language.French] = "Débogage",
				[Language.German] = "Debug",
				[Language.Russian] = "Отладка"
			},
			["setting_language"] = new Dictionary<Language, string>
			{
				[Language.English] = "Language",
				[Language.SimplifiedChinese] = "语言选项",
				[Language.Japanese] = "言語",
				[Language.Korean] = "언어 설정",
				[Language.Spanish] = "Idioma",
				[Language.French] = "Langue",
				[Language.German] = "Sprache",
				[Language.Russian] = "Язык"
			},
			["setting_show_guide"] = new Dictionary<Language, string>
			{
				[Language.English] = "Show Input Guide Toggle",
				[Language.SimplifiedChinese] = "显示输入指引开关",
				[Language.Japanese] = "入力ガイド表示切替",
				[Language.Korean] = "입력 가이드 표시 토글",
				[Language.Spanish] = "Mostrar Guía de Entrada",
				[Language.French] = "Afficher le Guide d'Entrée",
				[Language.German] = "Eingabehilfe Anzeigen",
				[Language.Russian] = "Показать Гид Ввода"
			},
			["setting_halo_radius"] = new Dictionary<Language, string>
			{
				[Language.English] = "Halo Radius",
				[Language.SimplifiedChinese] = "光环半径",
				[Language.Japanese] = "ハロー半径",
				[Language.Korean] = "후광 반경",
				[Language.Spanish] = "Radio del Halo",
				[Language.French] = "Rayon du Halo",
				[Language.German] = "Halo-Radius",
				[Language.Russian] = "Радиус Ореола"
			},
			["setting_active_opacity"] = new Dictionary<Language, string>
			{
				[Language.English] = "Active Zone Opacity",
				[Language.SimplifiedChinese] = "激活区域不透明度",
				[Language.Japanese] = "アクティブゾーン不透明度",
				[Language.Korean] = "활성 구역 불투명도",
				[Language.Spanish] = "Opacidad de Zona Activa",
				[Language.French] = "Opacité de Zone Active",
				[Language.German] = "Aktive Zonen-Deckkraft",
				[Language.Russian] = "Непрозрачность Активной Зоны"
			},
			["setting_inactive_opacity"] = new Dictionary<Language, string>
			{
				[Language.English] = "Inactive Zone Opacity",
				[Language.SimplifiedChinese] = "未激活区域不透明度",
				[Language.Japanese] = "非アクティブゾーン不透明度",
				[Language.Korean] = "비활성 구역 불투명도",
				[Language.Spanish] = "Opacidad de Zona Inactiva",
				[Language.French] = "Opacité de Zone Inactive",
				[Language.German] = "Inaktive Zonen-Deckkraft",
				[Language.Russian] = "Непрозрачность Неактивной Зоны"
			},
			["setting_indicator_offset"] = new Dictionary<Language, string>
			{
				[Language.English] = "Indicator Start Offset",
				[Language.SimplifiedChinese] = "指示器起始偏移值",
				[Language.Japanese] = "インジケーター開始オフセット",
				[Language.Korean] = "표시기 시작 오프셋",
				[Language.Spanish] = "Desplazamiento del Indicador",
				[Language.French] = "Décalage de l'Indicateur",
				[Language.German] = "Indikator-Startversatz",
				[Language.Russian] = "Смещение Индикатора"
			},
			["setting_adaptive_halo"] = new Dictionary<Language, string>
			{
				[Language.English] = "Adaptive Halo Radius Toggle",
				[Language.SimplifiedChinese] = "自适应光环半径开关",
				[Language.Japanese] = "適応ハロー半径切替",
				[Language.Korean] = "적응형 후광 반경 토글",
				[Language.Spanish] = "Radio de Halo Adaptativo",
				[Language.French] = "Rayon de Halo Adaptatif",
				[Language.German] = "Adaptiver Halo-Radius",
				[Language.Russian] = "Адаптивный Радиус Ореола"
			},
			["setting_attack_effects"] = new Dictionary<Language, string>
			{
				[Language.English] = "Attack Visual Effects Toggle",
				[Language.SimplifiedChinese] = "攻击视觉特效开关",
				[Language.Japanese] = "攻撃ビジュアルエフェクト切替",
				[Language.Korean] = "공격 시각 효과 토글",
				[Language.Spanish] = "Efectos Visuales de Ataque",
				[Language.French] = "Effets Visuels d'Attaque",
				[Language.German] = "Angriffs-Visuelle Effekte",
				[Language.Russian] = "Визуальные Эффекты Атаки"
			},
			["setting_show_facing"] = new Dictionary<Language, string>
			{
				[Language.English] = "Always Show Facing Arc Zone Toggle",
				[Language.SimplifiedChinese] = "总是显示面向弧形区域开关",
				[Language.Japanese] = "向いている方向の弧を常に表示",
				[Language.Korean] = "향하는 방향 호 항상 표시",
				[Language.Spanish] = "Mostrar Siempre Zona de Arco Frontal",
				[Language.French] = "Toujours Afficher la Zone d'Arc Frontal",
				[Language.German] = "Blickrichtungs-Bogen Immer Anzeigen",
				[Language.Russian] = "Всегда Показывать Дугу Направления"
			},
			["setting_attack_persist"] = new Dictionary<Language, string>
			{
				[Language.English] = "Attack Zone Persist Time",
				[Language.SimplifiedChinese] = "攻击区域保持时长",
				[Language.Japanese] = "攻撃ゾーン持続時間",
				[Language.Korean] = "공격 구역 지속 시간",
				[Language.Spanish] = "Tiempo de Persistencia de Zona",
				[Language.French] = "Durée de Persistance de Zone",
				[Language.German] = "Angriffszonen-Anzeigedauer",
				[Language.Russian] = "Время Сохранения Зоны Атаки"
			},
			["setting_toggle_key"] = new Dictionary<Language, string>
			{
				[Language.English] = "Toggle Key",
				[Language.SimplifiedChinese] = "切换键",
				[Language.Japanese] = "切替キー",
				[Language.Korean] = "전환 키",
				[Language.Spanish] = "Tecla de Activación",
				[Language.French] = "Touche de Basculement",
				[Language.German] = "Umschalttaste",
				[Language.Russian] = "Клавиша Переключения"
			},
			["setting_toggle_key_alt"] = new Dictionary<Language, string>
			{
				[Language.English] = "Secondary Toggle Key",
				[Language.SimplifiedChinese] = "备用切换键",
				[Language.Japanese] = "サブ切替キー",
				[Language.Korean] = "보조 전환 키",
				[Language.Spanish] = "Tecla Alternativa",
				[Language.French] = "Touche Alternative",
				[Language.German] = "Alternative Umschalttaste",
				[Language.Russian] = "Дополнительная Клавиша"
			},
			["setting_input_hold"] = new Dictionary<Language, string>
			{
				[Language.English] = "Input Hold Duration",
				[Language.SimplifiedChinese] = "输入保持时长",
				[Language.Japanese] = "入力保持時間",
				[Language.Korean] = "입력 유지 시간",
				[Language.Spanish] = "Duración de Retención",
				[Language.French] = "Durée de Maintien",
				[Language.German] = "Eingabe-Haltedauer",
				[Language.Russian] = "Длительность Удержания"
			},
			["setting_color_primary"] = new Dictionary<Language, string>
			{
				[Language.English] = "Primary (Horizontal)",
				[Language.SimplifiedChinese] = "主要颜色(水平)",
				[Language.Japanese] = "プライマリ(水平)",
				[Language.Korean] = "주 색상(수평)",
				[Language.Spanish] = "Primario (Horizontal)",
				[Language.French] = "Primaire (Horizontal)",
				[Language.German] = "Primär (Horizontal)",
				[Language.Russian] = "Основной (Горизонталь)"
			},
			["setting_color_secondary"] = new Dictionary<Language, string>
			{
				[Language.English] = "Secondary (Down)",
				[Language.SimplifiedChinese] = "次要颜色(向下)",
				[Language.Japanese] = "セカンダリ(下)",
				[Language.Korean] = "보조 색상(하)",
				[Language.Spanish] = "Secundario (Abajo)",
				[Language.French] = "Secondaire (Bas)",
				[Language.German] = "Sekundär (Unten)",
				[Language.Russian] = "Вторичный (Вниз)"
			},
			["setting_color_tertiary"] = new Dictionary<Language, string>
			{
				[Language.English] = "Tertiary (Up)",
				[Language.SimplifiedChinese] = "第三颜色(向上)",
				[Language.Japanese] = "ターシャリ(上)",
				[Language.Korean] = "3차 색상(상)",
				[Language.Spanish] = "Terciario (Arriba)",
				[Language.French] = "Tertiaire (Haut)",
				[Language.German] = "Tertiär (Oben)",
				[Language.Russian] = "Третичный (Вверх)"
			},
			["setting_color_preset"] = new Dictionary<Language, string>
			{
				[Language.English] = "Color Preset",
				[Language.SimplifiedChinese] = "颜色预设",
				[Language.Japanese] = "カラープリセット",
				[Language.Korean] = "색상 프리셋",
				[Language.Spanish] = "Preset de Color",
				[Language.French] = "Préréglage de Couleur",
				[Language.German] = "Farbvoreinstellung",
				[Language.Russian] = "Цветовая Предустановка"
			},
			["setting_developer_mode"] = new Dictionary<Language, string>
			{
				[Language.English] = "Developer Mode",
				[Language.SimplifiedChinese] = "开发者模式",
				[Language.Japanese] = "開発者モード",
				[Language.Korean] = "개발자 모드",
				[Language.Spanish] = "Modo Desarrollador",
				[Language.French] = "Mode Développeur",
				[Language.German] = "Entwicklermodus",
				[Language.Russian] = "Режим Разработчика"
			},
			["setting_verbose_logging"] = new Dictionary<Language, string>
			{
				[Language.English] = "Verbose Logging",
				[Language.SimplifiedChinese] = "详细日志",
				[Language.Japanese] = "詳細ログ",
				[Language.Korean] = "상세 로그",
				[Language.Spanish] = "Registro Detallado",
				[Language.French] = "Journalisation Détaillée",
				[Language.German] = "Ausführliche Protokollierung",
				[Language.Russian] = "Подробное Логирование"
			},
			["true_aim_on"] = new Dictionary<Language, string>
			{
				[Language.English] = "True Aim Overlay: ON",
				[Language.SimplifiedChinese] = "真准显示:开启",
				[Language.Japanese] = "True Aimオーバーレイ:ON",
				[Language.Korean] = "True Aim 오버레이: 켜짐",
				[Language.Spanish] = "Overlay True Aim: ACTIVADO",
				[Language.French] = "Overlay True Aim: ACTIVÉ",
				[Language.German] = "True Aim Overlay: AN",
				[Language.Russian] = "Оверлей True Aim: ВКЛ"
			},
			["true_aim_off"] = new Dictionary<Language, string>
			{
				[Language.English] = "True Aim Overlay: OFF",
				[Language.SimplifiedChinese] = "真准显示:关闭",
				[Language.Japanese] = "True Aimオーバーレイ:OFF",
				[Language.Korean] = "True Aim 오버레이: 꺼짐",
				[Language.Spanish] = "Overlay True Aim: DESACTIVADO",
				[Language.French] = "Overlay True Aim: DÉSACTIVÉ",
				[Language.German] = "True Aim Overlay: AUS",
				[Language.Russian] = "Оверлей True Aim: ВЫКЛ"
			},
			["attack_effects_on"] = new Dictionary<Language, string>
			{
				[Language.English] = "True Aim Attack Effects: ON",
				[Language.SimplifiedChinese] = "真准攻击特效:开启",
				[Language.Japanese] = "True Aim攻撃エフェクト:ON",
				[Language.Korean] = "True Aim 공격 효과: 켜짐",
				[Language.Spanish] = "Efectos de Ataque: ACTIVADO",
				[Language.French] = "Effets d'Attaque: ACTIVÉ",
				[Language.German] = "Angriffseffekte: AN",
				[Language.Russian] = "Эффекты Атаки: ВКЛ"
			},
			["attack_effects_off"] = new Dictionary<Language, string>
			{
				[Language.English] = "True Aim Attack Effects: OFF",
				[Language.SimplifiedChinese] = "真准攻击特效:关闭",
				[Language.Japanese] = "True Aim攻撃エフェクト:OFF",
				[Language.Korean] = "True Aim 공격 효과: 꺼짐",
				[Language.Spanish] = "Efectos de Ataque: DESACTIVADO",
				[Language.French] = "Effets d'Attaque: DÉSACTIVÉ",
				[Language.German] = "Angriffseffekte: AUS",
				[Language.Russian] = "Эффекты Атаки: ВЫКЛ"
			},
			["debug_overlay_on"] = new Dictionary<Language, string>
			{
				[Language.English] = "Debug Overlay: ON",
				[Language.SimplifiedChinese] = "调试面板:开启",
				[Language.Japanese] = "デバッグオーバーレイ:ON",
				[Language.Korean] = "디버그 오버레이: 켜짐",
				[Language.Spanish] = "Overlay de Depuración: ACTIVADO",
				[Language.French] = "Overlay de Débogage: ACTIVÉ",
				[Language.German] = "Debug-Overlay: AN",
				[Language.Russian] = "Отладочный Оверлей: ВКЛ"
			},
			["debug_overlay_off"] = new Dictionary<Language, string>
			{
				[Language.English] = "Debug Overlay: OFF",
				[Language.SimplifiedChinese] = "调试面板:关闭",
				[Language.Japanese] = "デバッグオーバーレイ:OFF",
				[Language.Korean] = "디버그 오버레이: 꺼짐",
				[Language.Spanish] = "Overlay de Depuración: DESACTIVADO",
				[Language.French] = "Overlay de Débogage: DÉSACTIVÉ",
				[Language.German] = "Debug-Overlay: AUS",
				[Language.Russian] = "Отладочный Оверлей: ВЫКЛ"
			},
			["found_nail_arts_fsm"] = new Dictionary<Language, string>
			{
				[Language.English] = "Found Nail Arts FSM!",
				[Language.SimplifiedChinese] = "已找到钉刺技能状态机!",
				[Language.Japanese] = "ネイルアーツFSMを発見!",
				[Language.Korean] = "네일 아츠 FSM 발견!",
				[Language.Spanish] = "¡FSM de Artes de Aguja encontrado!",
				[Language.French] = "FSM des Arts de l'Aiguille trouvé !",
				[Language.German] = "Nagel-Künste FSM gefunden!",
				[Language.Russian] = "FSM Искусств Иглы найден!"
			},
			["attack_detection_cached"] = new Dictionary<Language, string>
			{
				[Language.English] = "Attack detection fields cached via reflection",
				[Language.SimplifiedChinese] = "已通过反射缓存攻击检测字段",
				[Language.Japanese] = "リフレクションで攻撃検出フィールドをキャッシュ",
				[Language.Korean] = "리플렉션으로 공격 감지 필드 캐시됨",
				[Language.Spanish] = "Campos de detección de ataque almacenados por reflexión",
				[Language.French] = "Champs de détection d'attaque mis en cache par réflexion",
				[Language.German] = "Angriffserkennungsfelder via Reflection gecacht",
				[Language.Russian] = "Поля обнаружения атак кэшированы через рефлексию"
			},
			["zones_initialized"] = new Dictionary<Language, string>
			{
				[Language.English] = "Initialized {0} zones with configured colors",
				[Language.SimplifiedChinese] = "已初始化 {0} 个区域并配置颜色",
				[Language.Japanese] = "{0}個のゾーンを色設定付きで初期化",
				[Language.Korean] = "{0}개 구역을 색상과 함께 초기화",
				[Language.Spanish] = "Inicializadas {0} zonas con colores configurados",
				[Language.French] = "{0} zones initialisées avec couleurs configurées",
				[Language.German] = "{0} Zonen mit konfigurierten Farben initialisiert",
				[Language.Russian] = "Инициализировано {0} зон с настроенными цветами"
			},
			["config_developer_mode"] = new Dictionary<Language, string>
			{
				[Language.English] = "Enable developer debug tools (F9, F11, F12, logging). Hidden feature for development.",
				[Language.SimplifiedChinese] = "启用开发者调试工具(F9, F11, F12, 日志记录)。开发用隐藏功能。",
				[Language.Japanese] = "開発者デバッグツールを有効化(F9, F11, F12, ログ)。開発用隠し機能。",
				[Language.Korean] = "개발자 디버그 도구 활성화(F9, F11, F12, 로깅). 개발용 숨겨진 기능.",
				[Language.Spanish] = "Activar herramientas de depuración (F9, F11, F12, registro). Función oculta para desarrollo.",
				[Language.French] = "Activer les outils de débogage (F9, F11, F12, journaux). Fonction cachée pour le développement.",
				[Language.German] = "Entwickler-Debug-Tools aktivieren (F9, F11, F12, Protokollierung). Versteckte Funktion für Entwicklung.",
				[Language.Russian] = "Включить инструменты отладки разработчика (F9, F11, F12, логирование). Скрытая функция для разработки."
			},
			["config_verbose_logging"] = new Dictionary<Language, string>
			{
				[Language.English] = "Enable detailed attack detection logging. Creates large log files. Use F11 debug overlay for temporary verbose logging instead.",
				[Language.SimplifiedChinese] = "启用详细的攻击检测日志。会创建大型日志文件。建议使用 F11 调试面板进行临时详细日志记录。",
				[Language.Japanese] = "詳細な攻撃検出ログを有効化。大きなログファイルが作成されます。代わりにF11デバッグオーバーレイで一時的な詳細ログを使用してください。",
				[Language.Korean] = "상세 공격 감지 로그 활성화. 큰 로그 파일을 생성합니다. 대신 F11 디버그 오버레이로 임시 상세 로그를 사용하세요.",
				[Language.Spanish] = "Activar registro detallado de detección de ataques. Crea archivos de registro grandes. Use F11 para registro temporal en su lugar.",
				[Language.French] = "Activer la journalisation détaillée de détection d'attaque. Crée de gros fichiers journaux. Utilisez F11 pour la journalisation temporaire à la place.",
				[Language.German] = "Detaillierte Angriffserkennung aktivieren. Erstellt große Protokolldateien. Verwenden Sie stattdessen F11 für temporäre Protokollierung.",
				[Language.Russian] = "Включить подробное логирование обнаружения атак. Создает большие файлы логов. Используйте F11 для временного подробного логирования."
			},
			["config_show_guide"] = new Dictionary<Language, string>
			{
				[Language.English] = "Show the input guide halo around Hornet",
				[Language.SimplifiedChinese] = "以大黄蜂为中心显示输入指引光环",
				[Language.Japanese] = "ホーネットの周りに入力ガイドハローを表示",
				[Language.Korean] = "호넷 주위에 입력 가이드 후광 표시",
				[Language.Spanish] = "Mostrar el halo de guía de entrada alrededor de Hornet",
				[Language.French] = "Afficher le halo de guide d'entrée autour de Hornet",
				[Language.German] = "Eingabehilfe-Halo um Hornet anzeigen",
				[Language.Russian] = "Показать ореол гида ввода вокруг Хорнет"
			},
			["config_halo_radius"] = new Dictionary<Language, string>
			{
				[Language.English] = "Radius of the halo around Hornet",
				[Language.SimplifiedChinese] = "设置输入指引光环的半径",
				[Language.Japanese] = "ホーネット周りのハローの半径",
				[Language.Korean] = "호넷 주위 후광의 반경",
				[Language.Spanish] = "Radio del halo alrededor de Hornet",
				[Language.French] = "Rayon du halo autour de Hornet",
				[Language.German] = "Radius des Halos um Hornet",
				[Language.Russian] = "Радиус ореола вокруг Хорнет"
			},
			["config_active_opacity"] = new Dictionary<Language, string>
			{
				[Language.English] = "Opacity when zone is active (default 0.6)",
				[Language.SimplifiedChinese] = "区域激活时的不透明度(默认0.6)",
				[Language.Japanese] = "ゾーンアクティブ時の不透明度(デフォルト0.6)",
				[Language.Korean] = "구역 활성 시 불투명도(기본값 0.6)",
				[Language.Spanish] = "Opacidad cuando la zona está activa (predeterminado 0.6)",
				[Language.French] = "Opacité lorsque la zone est active (par défaut 0.6)",
				[Language.German] = "Deckkraft bei aktiver Zone (Standard 0.6)",
				[Language.Russian] = "Непрозрачность при активной зоне (по умолчанию 0.6)"
			},
			["config_inactive_opacity"] = new Dictionary<Language, string>
			{
				[Language.English] = "Opacity when zone is inactive (default 0.2)",
				[Language.SimplifiedChinese] = "区域未激活时的不透明度(默认0.2)",
				[Language.Japanese] = "ゾーン非アクティブ時の不透明度(デフォルト0.2)",
				[Language.Korean] = "구역 비활성 시 불투명도(기본값 0.2)",
				[Language.Spanish] = "Opacidad cuando la zona está inactiva (predeterminado 0.2)",
				[Language.French] = "Opacité lorsque la zone est inactive (par défaut 0.2)",
				[Language.German] = "Deckkraft bei inaktiver Zone (Standard 0.2)",
				[Language.Russian] = "Непрозрачность при неактивной зоне (по умолчанию 0.2)"
			},
			["config_indicator_offset"] = new Dictionary<Language, string>
			{
				[Language.English] = "How far from center the indicator arrow starts (0=center, 1=edge)",
				[Language.SimplifiedChinese] = "指示箭头从中心开始的距离(0=中心,1=边缘)",
				[Language.Japanese] = "インジケーター矢印の開始位置(0=中心, 1=端)",
				[Language.Korean] = "표시기 화살표 시작 거리(0=중심, 1=가장자리)",
				[Language.Spanish] = "Distancia desde el centro donde comienza la flecha (0=centro, 1=borde)",
				[Language.French] = "Distance du centre où commence la flèche (0=centre, 1=bord)",
				[Language.German] = "Startposition des Indikatorpfeils vom Zentrum (0=Zentrum, 1=Rand)",
				[Language.Russian] = "Расстояние от центра для стрелки индикатора (0=центр, 1=край)"
			},
			["config_adaptive_halo"] = new Dictionary<Language, string>
			{
				[Language.English] = "Automatically adjust halo radius based on equipped crest and Longclaw tool to match attack range visually. Updates when changing equipment at a bench.",
				[Language.SimplifiedChinese] = "启用自适应光环半径功能,根据现装备的纹章(和钉爪工具)调整光环视觉大小来预示攻击距离, 仅在坐长椅并切换纹章后更新!",
				[Language.Japanese] = "装備中のクレストとロングクロー道具に基づいてハロー半径を自動調整し、攻撃範囲を視覚的に一致させます。ベンチで装備変更時に更新されます。",
				[Language.Korean] = "장착된 문장과 롱클로 도구에 따라 후광 반경을 자동 조정하여 공격 범위를 시각적으로 일치시킵니다. 벤치에서 장비 변경 시 업데이트됩니다.",
				[Language.Spanish] = "Ajustar automáticamente el radio del halo según la cresta equipada y la herramienta Longclaw para coincidir visualmente con el rango de ataque. Se actualiza al cambiar equipo en un banco.",
				[Language.French] = "Ajuster automatiquement le rayon du halo en fonction de la crête équipée et de l'outil Longclaw pour correspondre visuellement à la portée d'attaque. Se met à jour lors du changement d'équipement sur un banc.",
				[Language.German] = "Halo-Radius automatisch an ausgerüsteten Wappen und Longclaw-Werkzeug anpassen, um die Angriffsreichweite visuell anzuzeigen. Aktualisiert sich beim Ausrüstungswechsel auf einer Bank.",
				[Language.Russian] = "Автоматически настраивать радиус ореола в зависимости от экипированного герба и инструмента Длинный Коготь для визуального соответствия дальности атаки. Обновляется при смене экипировки на скамье."
			},
			["config_attack_effects"] = new Dictionary<Language, string>
			{
				[Language.English] = "Enable attack flash and pulse effects",
				[Language.SimplifiedChinese] = "启用攻击闪光和脉冲效果",
				[Language.Japanese] = "攻撃フラッシュとパルスエフェクトを有効化",
				[Language.Korean] = "공격 플래시 및 펄스 효과 활성화",
				[Language.Spanish] = "Activar efectos de destello y pulso de ataque",
				[Language.French] = "Activer les effets de flash et de pulsation d'attaque",
				[Language.German] = "Angriffsblitz- und Pulseffekte aktivieren",
				[Language.Russian] = "Включить эффекты вспышки и пульсации атаки"
			},
			["config_show_facing"] = new Dictionary<Language, string>
			{
				[Language.English] = "Always highlight horizontal zone based on facing direction (even without input)",
				[Language.SimplifiedChinese] = "始终根据面向方向高亮显示水平区域(即使没有输入)",
				[Language.Japanese] = "向いている方向に基づいて水平ゾーンを常にハイライト表示(入力なしでも)",
				[Language.Korean] = "향하는 방향에 따라 수평 구역을 항상 강조 표시(입력 없이도)",
				[Language.Spanish] = "Resaltar siempre la zona horizontal según la dirección frontal (incluso sin entrada)",
				[Language.French] = "Toujours mettre en surbrillance la zone horizontale selon la direction (même sans entrée)",
				[Language.German] = "Horizontale Zone basierend auf Blickrichtung immer hervorheben (auch ohne Eingabe)",
				[Language.Russian] = "Всегда подсвечивать горизонтальную зону в зависимости от направления взгляда (даже без ввода)"
			},
			["config_attack_persist"] = new Dictionary<Language, string>
			{
				[Language.English] = "How long (seconds) to keep attack zone highlighted after fill animation completes",
				[Language.SimplifiedChinese] = "填充动画完成后保持攻击区域高亮的时长(秒)",
				[Language.Japanese] = "充填