Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SilksongTrueAim v1.0.4
TrueAim/TrueAim.dll
Decompiled 7 months ago
The result has been truncated due to the large size, download it to view full contents!
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.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HutongGames.PlayMaker; using InControl; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [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.4")] 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] = "充填アニメーション完了後に攻撃ゾーンをハイライト表示す