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 RunicPrecisionBuildTool v2.0.9
plugins/RunicPrecisionBuildTool/RunicPrecisionBuildTool.dll
Decompiled 12 minutes ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Serialization.Json; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using QuietBuildRotation.Integration; using QuietBuildRotation.UI; using Runic.Localization; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyProduct("Runic Precision Build Tool")] [assembly: AssemblyFileVersion("2.0.9.0")] [assembly: AssemblyInformationalVersion("2.0.9")] [assembly: InternalsVisibleTo("RunicPrecisionBuildTool.Tests")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("2.0.9.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Runic.Localization { internal sealed class LanguageCatalog { private readonly Dictionary<string, string> _english; private Dictionary<string, string> _selected = new Dictionary<string, string>(); private readonly Func<string, string> _read; private string _language; internal LanguageCatalog(string english, Func<string, string> read) { _english = Parse(english); _read = read; } internal static Dictionary<string, string> Parse(string json) { if (string.IsNullOrWhiteSpace(json)) { return new Dictionary<string, string>(); } if (json.Length > 2097152) { throw new InvalidDataException("Language file exceeds 2 MiB."); } DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(Dictionary<string, string>), new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true }); using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json.TrimStart('\ufeff'))); return ((Dictionary<string, string>)dataContractJsonSerializer.ReadObject(stream)) ?? new Dictionary<string, string>(); } internal void Select(string language) { language = (string.IsNullOrWhiteSpace(language) ? "English" : language); if (string.Equals(language, _language, StringComparison.Ordinal)) { return; } _language = language; _selected = new Dictionary<string, string>(); if (language.IndexOfAny(new char[4] { '/', '\\', ':', '\0' }) >= 0 || language == "." || language == "..") { return; } try { _selected = Parse(_read(language)); } catch (Exception) { } } internal string Get(string key) { _english.TryGetValue(key, out var value); if (_selected.TryGetValue(key, out var value2) && !string.IsNullOrWhiteSpace(value2) && (value == null || SameFields(value, value2))) { return value2; } return value ?? key; } internal string English(string key) { if (!_english.TryGetValue(key, out var value)) { return key; } return value; } internal string TranslateEnglish(string text) { foreach (KeyValuePair<string, string> item in _english) { if (item.Value == text) { return Get(item.Key); } } return text; } internal string Format(string key, params object[] args) { _english.TryGetValue(key, out var value); string text = Get(key); if (value != null && !SameFields(value, text)) { text = value; } try { return string.Format(CultureInfo.CurrentCulture, text, args); } catch (FormatException) { try { return string.Format(CultureInfo.CurrentCulture, value ?? key, args); } catch (FormatException) { return value ?? key; } } } private static bool SameFields(string a, string b) { try { return Fields(a).SetEquals(Fields(b)); } catch (FormatException) { return false; } } private static HashSet<int> Fields(string text) { HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < text.Length; i++) { if (text[i] == '}') { if (i + 1 >= text.Length || text[i + 1] != '}') { throw new FormatException(); } i++; } else { if (text[i] != '{') { continue; } if (i + 1 < text.Length && text[i + 1] == '{') { i++; continue; } int num = ++i; for (; i < text.Length && char.IsDigit(text[i]); i++) { } if (num == i || !int.TryParse(text.Substring(num, i - num), out var result)) { throw new FormatException(); } hashSet.Add(result); for (; i < text.Length && text[i] != '}'; i++) { if (text[i] == '{') { throw new FormatException(); } } if (i == text.Length) { throw new FormatException(); } } } return hashSet; } } internal static class RunicText { private static readonly Assembly Owner = typeof(RunicText).Assembly; private static readonly string Module = Owner.GetName().Name; private static readonly LanguageCatalog Catalog = Create(); private static LanguageCatalog Create() { using Stream stream = Owner.GetManifestResourceStream("Runic.Localization.English.json"); using StreamReader streamReader = ((stream == null) ? null : new StreamReader(stream)); return new LanguageCatalog(streamReader?.ReadToEnd() ?? "{}", ReadLanguage); } private static string ReadLanguage(string language) { string path = Path.Combine(Path.Combine(Path.GetDirectoryName(Owner.Location), "Translations", Module), language + ".json"); if (!File.Exists(path)) { return null; } return File.ReadAllText(path); } private static void SelectLanguage() { string language = "English"; try { Localization instance = Localization.instance; language = ((instance != null) ? instance.GetSelectedLanguage() : null) ?? "English"; } catch { } Catalog.Select(language); } internal static string Get(string key) { SelectLanguage(); return Catalog.Get(key); } internal static string English(string key) { return Catalog.English(key); } internal static string TranslateEnglish(string text) { SelectLanguage(); return Catalog.TranslateEnglish(text); } internal static string Format(string key, params object[] args) { SelectLanguage(); return Catalog.Format(key, args); } } } namespace QuietBuildRotation { internal static class CompatibilityGuard { internal const string PerfectPlacementGuid = "Azumatt_and_ValheimPlusDevs.PerfectPlacement"; private const string PerfectPlacementSection = "1 - General"; private const string PerfectPlacementKey = "Enable Free Placement Rotation"; internal static bool ShouldDisableForPerfectPlacement(out string reason) { reason = null; if (!Chainloader.PluginInfos.TryGetValue("Azumatt_and_ValheimPlusDevs.PerfectPlacement", out var value)) { return false; } if ((Object)(object)((value != null) ? value.Instance : null) == (Object)null) { reason = RunicText.Get("text_028fa4e52762"); return true; } foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in value.Instance.Config) { if (string.Equals(item.Key.Section, "1 - General", StringComparison.Ordinal) && string.Equals(item.Key.Key, "Enable Free Placement Rotation", StringComparison.Ordinal)) { if (IsEnabled(item.Value.BoxedValue?.ToString())) { reason = RunicText.Get("text_348c02bee289"); return true; } return false; } } reason = RunicText.Get("text_654ca6093c3e"); return true; } private static bool IsEnabled(string value) { if (!string.Equals(value, "On", StringComparison.OrdinalIgnoreCase) && !string.Equals(value, "True", StringComparison.OrdinalIgnoreCase) && !string.Equals(value, "Enabled", StringComparison.OrdinalIgnoreCase)) { return string.Equals(value, "1", StringComparison.OrdinalIgnoreCase); } return true; } } internal static class PluginConfig { private sealed class ResolvedGesture { internal string Name { get; } internal HashSet<KeyCode> Keys { get; } internal ResolvedGesture(string name, HashSet<KeyCode> keys) { Name = name; Keys = keys; } } private const int DefaultRotationIncrements = 16; private const int DefaultFineRotationIncrements = 360; private const int CurrentWheelBindingSchemaVersion = 1; internal static ConfigEntry<bool> Enabled { get; private set; } internal static ConfigEntry<bool> RequirePrecisionMode { get; private set; } internal static ConfigEntry<int> WheelBindingSchemaVersion { get; private set; } internal static ConfigEntry<KeyboardShortcut> YawWheelChord { get; private set; } internal static ConfigEntry<KeyboardShortcut> PitchWheelChord { get; private set; } internal static ConfigEntry<KeyboardShortcut> RollWheelChord { get; private set; } internal static ConfigEntry<KeyboardShortcut> FineYawWheelChord { get; private set; } internal static ConfigEntry<KeyboardShortcut> FinePitchWheelChord { get; private set; } internal static ConfigEntry<KeyboardShortcut> FineRollWheelChord { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchRotation { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchPitch { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchRoll { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchYaw { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchPositionX { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchPositionY { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchPositionZ { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchPosition { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchTransform { get; private set; } internal static ConfigEntry<KeyboardShortcut> MatchSnapSide { get; private set; } internal static ConfigEntry<KeyboardShortcut> RepeatTransform { get; private set; } internal static ConfigEntry<KeyboardShortcut> ResetPitch { get; private set; } internal static ConfigEntry<KeyboardShortcut> ResetRoll { get; private set; } internal static ConfigEntry<KeyboardShortcut> ResetYaw { get; private set; } internal static ConfigEntry<KeyboardShortcut> ResetSway { get; private set; } internal static ConfigEntry<KeyboardShortcut> ResetHeave { get; private set; } internal static ConfigEntry<KeyboardShortcut> ResetSurge { get; private set; } internal static ConfigEntry<KeyboardShortcut> PrecisionModeToggle { get; private set; } internal static ConfigEntry<KeyboardShortcut> RotationFrameToggle { get; private set; } internal static ConfigEntry<PlacementReferenceFrame> RotationReferenceFrame { get; private set; } internal static ConfigEntry<KeyboardShortcut> AxisGuides { get; private set; } internal static ConfigEntry<KeyboardShortcut> Reset { get; private set; } internal static ConfigEntry<KeyboardShortcut> SearchNext { get; private set; } internal static ConfigEntry<KeyboardShortcut> ToggleFavorite { get; private set; } internal static ConfigEntry<KeyboardShortcut> NextFavorite { get; private set; } internal static ConfigEntry<KeyboardShortcut> NextRecent { get; private set; } internal static ConfigEntry<KeyboardShortcut> UndoLastPlacement { get; private set; } internal static ConfigEntry<KeyboardShortcut> AreaRepair { get; private set; } internal static ConfigEntry<string> BuildSearchQuery { get; private set; } internal static ConfigEntry<string> FavoritePieceIds { get; private set; } internal static ConfigEntry<string> RecentPieceIds { get; private set; } internal static ConfigEntry<KeyboardShortcut> MoveUp { get; private set; } internal static ConfigEntry<KeyboardShortcut> MoveDown { get; private set; } internal static ConfigEntry<KeyboardShortcut> MoveLeft { get; private set; } internal static ConfigEntry<KeyboardShortcut> MoveRight { get; private set; } internal static ConfigEntry<KeyboardShortcut> MoveForward { get; private set; } internal static ConfigEntry<KeyboardShortcut> MoveBackward { get; private set; } internal static ConfigEntry<KeyboardShortcut> FineMoveUp { get; private set; } internal static ConfigEntry<KeyboardShortcut> FineMoveDown { get; private set; } internal static ConfigEntry<KeyboardShortcut> FineMoveLeft { get; private set; } internal static ConfigEntry<KeyboardShortcut> FineMoveRight { get; private set; } internal static ConfigEntry<KeyboardShortcut> FineMoveForward { get; private set; } internal static ConfigEntry<KeyboardShortcut> FineMoveBackward { get; private set; } internal static ConfigEntry<int> RotationIncrementsPerCircle { get; private set; } internal static ConfigEntry<int> FineRotationIncrementsPerCircle { get; private set; } internal static ConfigEntry<float> SideStepMeters { get; private set; } internal static ConfigEntry<float> UpDownStepMeters { get; private set; } internal static ConfigEntry<float> ForwardBackStepMeters { get; private set; } internal static ConfigEntry<float> FineSideStepMeters { get; private set; } internal static ConfigEntry<float> FineUpDownStepMeters { get; private set; } internal static ConfigEntry<float> FineForwardBackStepMeters { get; private set; } internal static ConfigEntry<PlacementReferenceFrame> ReferenceFrame { get; private set; } internal static ConfigEntry<float> AreaRepairRadiusMeters { get; private set; } internal static ConfigEntry<int> AreaRepairMaximumPieces { get; private set; } internal static ConfigEntry<bool> ShowPlacementAngles { get; private set; } internal static ConfigEntry<bool> ShowTargetAngles { get; private set; } internal static ConfigEntry<bool> ShowPositionReadout { get; private set; } internal static ConfigEntry<int> ReadoutFontSize { get; private set; } internal static ConfigEntry<bool> VerboseLogging { get; private set; } internal static float RotationStepDegrees => DegreesPerIncrement(RotationIncrementsPerCircle?.Value ?? 16); internal static float FineRotationStepDegrees => DegreesPerIncrement(FineRotationIncrementsPerCircle?.Value ?? 360); internal static event Action Changed; internal static void Bind(ConfigFile config) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_052a: Unknown result type (might be due to invalid IL or missing references) //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_0624: Unknown result type (might be due to invalid IL or missing references) //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_0680: Unknown result type (might be due to invalid IL or missing references) //IL_06ae: Unknown result type (might be due to invalid IL or missing references) //IL_08dd: Unknown result type (might be due to invalid IL or missing references) //IL_08e7: Expected O, but got Unknown //IL_0925: Unknown result type (might be due to invalid IL or missing references) //IL_092f: Expected O, but got Unknown //IL_0a3c: Unknown result type (might be due to invalid IL or missing references) //IL_0a46: Expected O, but got Unknown //IL_0a6f: Unknown result type (might be due to invalid IL or missing references) //IL_0a79: Expected O, but got Unknown //IL_0b03: Unknown result type (might be due to invalid IL or missing references) //IL_0b0d: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, RunicText.Get("text_686cd5312a0d")); RequirePrecisionMode = config.Bind<bool>("General", "RequirePrecisionMode", true, RunicText.Get("text_593e5f623381")); WheelBindingSchemaVersion = config.Bind<int>("Compatibility", "WheelBindingSchemaVersion", 0, RunicText.Get("text_381ef2b5ee71")); YawWheelChord = BindWheelChord(config, "YawWheelChord", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), RunicText.Get("text_3c8d78f45760")); PitchWheelChord = BindWheelChord(config, "PitchWheelChord", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), RunicText.Get("text_341839140f70")); RollWheelChord = BindWheelChord(config, "RollWheelChord", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), RunicText.Get("text_88403d015643")); FineYawWheelChord = BindWheelChord(config, "FineYawWheelChord", new KeyboardShortcut((KeyCode)118, Array.Empty<KeyCode>()), RunicText.Get("text_08e4af7bc38f")); FinePitchWheelChord = BindWheelChord(config, "FinePitchWheelChord", new KeyboardShortcut((KeyCode)118, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), RunicText.Get("text_337d41b9d1a7")); FineRollWheelChord = BindWheelChord(config, "FineRollWheelChord", new KeyboardShortcut((KeyCode)118, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), RunicText.Get("text_d20c1bddc354")); MatchRotation = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchRotation", new KeyboardShortcut((KeyCode)256, Array.Empty<KeyCode>()), RunicText.Get("text_b0c791cfce88")); MatchPitch = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchPitch", new KeyboardShortcut((KeyCode)257, Array.Empty<KeyCode>()), RunicText.Get("text_3b7629265310")); MatchRoll = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchRoll", new KeyboardShortcut((KeyCode)258, Array.Empty<KeyCode>()), RunicText.Get("text_e19640ed7d6d")); MatchYaw = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchYaw", new KeyboardShortcut((KeyCode)259, Array.Empty<KeyCode>()), RunicText.Get("text_e3b0031d47ac")); MatchPositionX = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchPositionX", new KeyboardShortcut((KeyCode)260, Array.Empty<KeyCode>()), RunicText.Get("text_969a1ec228f6")); MatchPositionY = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchPositionY", new KeyboardShortcut((KeyCode)261, Array.Empty<KeyCode>()), RunicText.Get("text_49d70f25d41a")); MatchPositionZ = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchPositionZ", new KeyboardShortcut((KeyCode)262, Array.Empty<KeyCode>()), RunicText.Get("text_152ae390a3fc")); MatchPosition = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchPosition", new KeyboardShortcut((KeyCode)263, Array.Empty<KeyCode>()), RunicText.Get("text_20fc45da7f7e")); MatchTransform = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchTransform", new KeyboardShortcut((KeyCode)264, Array.Empty<KeyCode>()), RunicText.Get("text_7a7414cf3c26")); MatchSnapSide = config.Bind<KeyboardShortcut>("Controls - Actions", "MatchSnapSide", new KeyboardShortcut((KeyCode)265, Array.Empty<KeyCode>()), RunicText.Get("text_a6ecca97892b")); RepeatTransform = config.Bind<KeyboardShortcut>("Controls - Actions", "RepeatTransform", new KeyboardShortcut((KeyCode)266, Array.Empty<KeyCode>()), RunicText.Get("text_f992e7fdf7fe")); ResetPitch = config.Bind<KeyboardShortcut>("Controls - Axis Reset", "ResetPitch", new KeyboardShortcut((KeyCode)257, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), RunicText.Get("text_4e236f0f08c8")); ResetRoll = config.Bind<KeyboardShortcut>("Controls - Axis Reset", "ResetRoll", new KeyboardShortcut((KeyCode)258, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), RunicText.Get("text_bf503ab4dd93")); ResetYaw = config.Bind<KeyboardShortcut>("Controls - Axis Reset", "ResetYaw", new KeyboardShortcut((KeyCode)259, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), RunicText.Get("text_ddcc6b33d257")); ResetSway = config.Bind<KeyboardShortcut>("Controls - Axis Reset", "ResetSway", new KeyboardShortcut((KeyCode)260, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), RunicText.Get("text_73c1e6b04b3c")); ResetHeave = config.Bind<KeyboardShortcut>("Controls - Axis Reset", "ResetHeave", new KeyboardShortcut((KeyCode)261, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), RunicText.Get("text_77d5a3a865e7")); ResetSurge = config.Bind<KeyboardShortcut>("Controls - Axis Reset", "ResetSurge", new KeyboardShortcut((KeyCode)262, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), RunicText.Get("text_baa2395294a3")); PrecisionModeToggle = config.Bind<KeyboardShortcut>("Controls - Actions", "PrecisionModeToggle", new KeyboardShortcut((KeyCode)112, Array.Empty<KeyCode>()), RunicText.Get("text_b2e2c85df348")); RotationFrameToggle = config.Bind<KeyboardShortcut>("Controls - Actions", "RotationFrameToggle", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), RunicText.Get("text_8c4fbf900f6b")); RotationReferenceFrame = config.Bind<PlacementReferenceFrame>("Rotation", "ReferenceFrame", PlacementReferenceFrame.Local, RunicText.Get("text_566ea73df41d")); AxisGuides = config.Bind<KeyboardShortcut>("Controls - Actions", "AxisGuides", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), RunicText.Get("text_7a79ac6ac181") + RunicText.Get("text_c0850b137c0b") + RunicText.Get("text_45f0113b3c17") + RunicText.Get("text_ef8dce7b206c") + RunicText.Get("text_29f8f8461c85")); Reset = config.Bind<KeyboardShortcut>("Controls - Actions", "Reset", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), RunicText.Get("text_4789fbc5e2c9")); SearchNext = config.Bind<KeyboardShortcut>("Controls - Build Catalog", "SearchNext", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), RunicText.Get("text_df9b528dff32")); ToggleFavorite = config.Bind<KeyboardShortcut>("Controls - Build Catalog", "ToggleFavorite", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), RunicText.Get("text_e92b76fbb4ea")); NextFavorite = config.Bind<KeyboardShortcut>("Controls - Build Catalog", "NextFavorite", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), RunicText.Get("text_ea93c881a191")); NextRecent = config.Bind<KeyboardShortcut>("Controls - Build Catalog", "NextRecent", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), RunicText.Get("text_afbad8b2b885")); UndoLastPlacement = config.Bind<KeyboardShortcut>("Controls - Safe Utilities", "UndoLastPlacement", new KeyboardShortcut((KeyCode)292, Array.Empty<KeyCode>()), RunicText.Get("text_aa13d0d1ab9d")); AreaRepair = config.Bind<KeyboardShortcut>("Controls - Safe Utilities", "AreaRepair", new KeyboardShortcut((KeyCode)293, Array.Empty<KeyCode>()), RunicText.Get("text_97a95c90cc89")); BuildSearchQuery = config.Bind<string>("Build Catalog", "SearchQuery", string.Empty, RunicText.Get("text_7185394aecf0")); FavoritePieceIds = config.Bind<string>("Build Catalog", "Favorites", string.Empty, RunicText.Get("text_2de194be734f")); RecentPieceIds = config.Bind<string>("Build Catalog", "Recents", string.Empty, RunicText.Get("text_b4c407c0d3a6")); MoveUp = BindMovementChord(config, "MoveUp", (KeyCode)273, RunicText.Get("text_05a32a590ece")); MoveDown = BindMovementChord(config, "MoveDown", (KeyCode)274, RunicText.Get("text_b44845e538bb")); MoveLeft = BindMovementChord(config, "MoveLeft", (KeyCode)276, RunicText.Get("text_53132963ef68")); MoveRight = BindMovementChord(config, "MoveRight", (KeyCode)275, RunicText.Get("text_03c4defb3b50")); MoveForward = BindMovementChord(config, "MoveForward", (KeyCode)280, RunicText.Get("text_9f36706d3557")); MoveBackward = BindMovementChord(config, "MoveBackward", (KeyCode)281, RunicText.Get("text_04fe0535d549")); FineMoveUp = BindFineMovementChord(config, "FineMoveUp", (KeyCode)273, RunicText.Get("text_408ce21b3d2d")); FineMoveDown = BindFineMovementChord(config, "FineMoveDown", (KeyCode)274, RunicText.Get("text_f2d35e591aa4")); FineMoveLeft = BindFineMovementChord(config, "FineMoveLeft", (KeyCode)276, RunicText.Get("text_5f8cc456cfd8")); FineMoveRight = BindFineMovementChord(config, "FineMoveRight", (KeyCode)275, RunicText.Get("text_fd981ecea312")); FineMoveForward = BindFineMovementChord(config, "FineMoveForward", (KeyCode)280, RunicText.Get("text_20a0616161e9")); FineMoveBackward = BindFineMovementChord(config, "FineMoveBackward", (KeyCode)281, RunicText.Get("text_5ae378e3f395")); RotationIncrementsPerCircle = config.Bind<int>("Rotation", "IncrementsPerCircle", 16, new ConfigDescription(RunicText.Get("text_012a2e304cdf") + RunicText.Get("text_58da38ee7127"), (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 36000), Array.Empty<object>())); FineRotationIncrementsPerCircle = config.Bind<int>("Rotation", "FineIncrementsPerCircle", 360, new ConfigDescription(RunicText.Get("text_1552507550a5") + RunicText.Get("text_4458b65b04b0"), (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 36000), Array.Empty<object>())); SideStepMeters = BindDistance(config, "SideStepMeters", 0.25f, RunicText.Get("text_b3ea4b3126b5")); UpDownStepMeters = BindDistance(config, "UpDownStepMeters", 0.25f, RunicText.Get("text_c999ce6ebd94")); ForwardBackStepMeters = BindDistance(config, "ForwardBackStepMeters", 0.25f, RunicText.Get("text_ca0fd42ff029")); FineSideStepMeters = BindDistance(config, "FineSideStepMeters", 0.05f, RunicText.Get("text_148262651e13")); FineUpDownStepMeters = BindDistance(config, "FineUpDownStepMeters", 0.05f, RunicText.Get("text_17e2c2afb665")); FineForwardBackStepMeters = BindDistance(config, "FineForwardBackStepMeters", 0.05f, RunicText.Get("text_78bdc0d3b916")); ReferenceFrame = config.Bind<PlacementReferenceFrame>("Movement", "ReferenceFrame", PlacementReferenceFrame.World, RunicText.Get("text_e2b5387ec726")); AreaRepairRadiusMeters = config.Bind<float>("Safe Utilities", "AreaRepairRadiusMeters", 5f, new ConfigDescription(RunicText.Get("text_4e6ad63a795e"), (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 12f), Array.Empty<object>())); AreaRepairMaximumPieces = config.Bind<int>("Safe Utilities", "AreaRepairMaximumPieces", 16, new ConfigDescription(RunicText.Get("text_ac0258a29263"), (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 64), Array.Empty<object>())); ShowPlacementAngles = config.Bind<bool>("UI", "ShowPlacementAngles", true, RunicText.Get("text_39d4c5088ada")); ShowTargetAngles = config.Bind<bool>("UI", "ShowTargetAngles", true, RunicText.Get("text_14296ead0976")); ShowPositionReadout = config.Bind<bool>("UI", "ShowPositionReadout", true, RunicText.Get("text_cffb02a1d883")); ReadoutFontSize = config.Bind<int>("UI", "ReadoutFontSize", 36, new ConfigDescription(RunicText.Get("text_fc34718ecbba"), (AcceptableValueBase)(object)new AcceptableValueRange<int>(22, 54), Array.Empty<object>())); VerboseLogging = config.Bind<bool>("Diagnostics", "VerboseLogging", false, RunicText.Get("text_df78c8084db7")); MigrateLegacyWheelBindings(); HookChanges(); } internal static float DegreesPerIncrement(int incrementsPerCircle) { if (incrementsPerCircle <= 0) { return 0f; } return 360f / (float)incrementsPerCircle; } internal static string FindExactChordConflicts() { List<string> list = new List<string>(); List<ResolvedGesture> gestures = new List<ResolvedGesture> { Resolve("YawWheelChord", YawWheelChord) }; AddIfConfigured(gestures, "PitchWheelChord", PitchWheelChord); AddIfConfigured(gestures, "RollWheelChord", RollWheelChord); AddIfConfigured(gestures, "FineYawWheelChord", FineYawWheelChord); AddIfConfigured(gestures, "FinePitchWheelChord", FinePitchWheelChord); AddIfConfigured(gestures, "FineRollWheelChord", FineRollWheelChord); AddDuplicateGestures(gestures, list); List<ResolvedGesture> gestures2 = new List<ResolvedGesture>(); AddIfConfigured(gestures2, "MatchRotation", MatchRotation); AddIfConfigured(gestures2, "MatchPitch", MatchPitch); AddIfConfigured(gestures2, "MatchRoll", MatchRoll); AddIfConfigured(gestures2, "MatchYaw", MatchYaw); AddIfConfigured(gestures2, "MatchPositionX", MatchPositionX); AddIfConfigured(gestures2, "MatchPositionY", MatchPositionY); AddIfConfigured(gestures2, "MatchPositionZ", MatchPositionZ); AddIfConfigured(gestures2, "MatchPosition", MatchPosition); AddIfConfigured(gestures2, "MatchTransform", MatchTransform); AddIfConfigured(gestures2, "MatchSnapSide", MatchSnapSide); AddIfConfigured(gestures2, "RepeatTransform", RepeatTransform); AddIfConfigured(gestures2, "ResetPitch", ResetPitch); AddIfConfigured(gestures2, "ResetRoll", ResetRoll); AddIfConfigured(gestures2, "ResetYaw", ResetYaw); AddIfConfigured(gestures2, "ResetSway", ResetSway); AddIfConfigured(gestures2, "ResetHeave", ResetHeave); AddIfConfigured(gestures2, "ResetSurge", ResetSurge); AddIfConfigured(gestures2, "PrecisionModeToggle", PrecisionModeToggle); AddIfConfigured(gestures2, "RotationFrameToggle", RotationFrameToggle); AddIfConfigured(gestures2, "Reset", Reset); AddIfConfigured(gestures2, "SearchNext", SearchNext); AddIfConfigured(gestures2, "ToggleFavorite", ToggleFavorite); AddIfConfigured(gestures2, "NextFavorite", NextFavorite); AddIfConfigured(gestures2, "NextRecent", NextRecent); AddIfConfigured(gestures2, "UndoLastPlacement", UndoLastPlacement); AddIfConfigured(gestures2, "AreaRepair", AreaRepair); AddIfConfigured(gestures2, "MoveUp", MoveUp); AddIfConfigured(gestures2, "MoveDown", MoveDown); AddIfConfigured(gestures2, "MoveLeft", MoveLeft); AddIfConfigured(gestures2, "MoveRight", MoveRight); AddIfConfigured(gestures2, "MoveForward", MoveForward); AddIfConfigured(gestures2, "MoveBackward", MoveBackward); AddIfConfigured(gestures2, "FineMoveUp", FineMoveUp); AddIfConfigured(gestures2, "FineMoveDown", FineMoveDown); AddIfConfigured(gestures2, "FineMoveLeft", FineMoveLeft); AddIfConfigured(gestures2, "FineMoveRight", FineMoveRight); AddIfConfigured(gestures2, "FineMoveForward", FineMoveForward); AddIfConfigured(gestures2, "FineMoveBackward", FineMoveBackward); AddDuplicateGestures(gestures2, list); if (list.Count != 0) { return string.Join(", ", list); } return null; } internal static KeyboardShortcut MigrateLegacyRollShortcut(KeyboardShortcut shortcut, bool fine, int schemaVersion) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (schemaVersion >= 1) { return shortcut; } KeyboardShortcut right = (fine ? new KeyboardShortcut((KeyCode)118, (KeyCode[])(object)new KeyCode[2] { (KeyCode)308, (KeyCode)306 }) : new KeyboardShortcut((KeyCode)306, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 })); if (!ShortcutHasExactKeys(shortcut, right)) { return shortcut; } if (!fine) { return new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()); } return new KeyboardShortcut((KeyCode)118, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }); } internal static bool ShortcutHasExactKeys(KeyboardShortcut left, KeyboardShortcut right) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) HashSet<KeyCode> hashSet = new HashSet<KeyCode>(); HashSet<KeyCode> hashSet2 = new HashSet<KeyCode>(); AddShortcutKeys(hashSet, left); AddShortcutKeys(hashSet2, right); return hashSet.SetEquals(hashSet2); } private static void MigrateLegacyWheelBindings() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) if (WheelBindingSchemaVersion != null && WheelBindingSchemaVersion.Value < 1) { int value = WheelBindingSchemaVersion.Value; RollWheelChord.Value = MigrateLegacyRollShortcut(RollWheelChord.Value, fine: false, value); FineRollWheelChord.Value = MigrateLegacyRollShortcut(FineRollWheelChord.Value, fine: true, value); WheelBindingSchemaVersion.Value = 1; } } private static ConfigEntry<KeyboardShortcut> BindWheelChord(ConfigFile config, string key, KeyboardShortcut defaultValue, string description) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return config.Bind<KeyboardShortcut>("Controls - Rotation Wheel", key, defaultValue, description); } private static ConfigEntry<KeyboardShortcut> BindMovementChord(ConfigFile config, string key, KeyCode directionKey, string description) { //IL_0007: 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) return config.Bind<KeyboardShortcut>("Controls - Movement", key, new KeyboardShortcut(directionKey, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), description + RunicText.Get("text_1dfd2bc98927")); } private static ConfigEntry<KeyboardShortcut> BindFineMovementChord(ConfigFile config, string key, KeyCode directionKey, string description) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return config.Bind<KeyboardShortcut>("Controls - Movement Fine", key, new KeyboardShortcut(directionKey, (KeyCode[])(object)new KeyCode[2] { (KeyCode)308, (KeyCode)118 }), description + RunicText.Get("text_1dfd2bc98927")); } private static ConfigEntry<float> BindDistance(ConfigFile config, string key, float defaultValue, string description) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown return config.Bind<float>("Movement", key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 10f), Array.Empty<object>())); } private static void HookChanges() { Enabled.SettingChanged += OnSettingChanged; RequirePrecisionMode.SettingChanged += OnSettingChanged; YawWheelChord.SettingChanged += OnSettingChanged; PitchWheelChord.SettingChanged += OnSettingChanged; RollWheelChord.SettingChanged += OnSettingChanged; FineYawWheelChord.SettingChanged += OnSettingChanged; FinePitchWheelChord.SettingChanged += OnSettingChanged; FineRollWheelChord.SettingChanged += OnSettingChanged; MatchRotation.SettingChanged += OnSettingChanged; MatchPitch.SettingChanged += OnSettingChanged; MatchRoll.SettingChanged += OnSettingChanged; MatchYaw.SettingChanged += OnSettingChanged; MatchPositionX.SettingChanged += OnSettingChanged; MatchPositionY.SettingChanged += OnSettingChanged; MatchPositionZ.SettingChanged += OnSettingChanged; MatchPosition.SettingChanged += OnSettingChanged; MatchTransform.SettingChanged += OnSettingChanged; MatchSnapSide.SettingChanged += OnSettingChanged; RepeatTransform.SettingChanged += OnSettingChanged; ResetPitch.SettingChanged += OnSettingChanged; ResetRoll.SettingChanged += OnSettingChanged; ResetYaw.SettingChanged += OnSettingChanged; ResetSway.SettingChanged += OnSettingChanged; ResetHeave.SettingChanged += OnSettingChanged; ResetSurge.SettingChanged += OnSettingChanged; PrecisionModeToggle.SettingChanged += OnSettingChanged; AxisGuides.SettingChanged += OnSettingChanged; RotationFrameToggle.SettingChanged += OnSettingChanged; RotationReferenceFrame.SettingChanged += OnSettingChanged; Reset.SettingChanged += OnSettingChanged; SearchNext.SettingChanged += OnSettingChanged; ToggleFavorite.SettingChanged += OnSettingChanged; NextFavorite.SettingChanged += OnSettingChanged; NextRecent.SettingChanged += OnSettingChanged; UndoLastPlacement.SettingChanged += OnSettingChanged; AreaRepair.SettingChanged += OnSettingChanged; BuildSearchQuery.SettingChanged += OnSettingChanged; FavoritePieceIds.SettingChanged += OnSettingChanged; RecentPieceIds.SettingChanged += OnSettingChanged; MoveUp.SettingChanged += OnSettingChanged; MoveDown.SettingChanged += OnSettingChanged; MoveLeft.SettingChanged += OnSettingChanged; MoveRight.SettingChanged += OnSettingChanged; MoveForward.SettingChanged += OnSettingChanged; MoveBackward.SettingChanged += OnSettingChanged; FineMoveUp.SettingChanged += OnSettingChanged; FineMoveDown.SettingChanged += OnSettingChanged; FineMoveLeft.SettingChanged += OnSettingChanged; FineMoveRight.SettingChanged += OnSettingChanged; FineMoveForward.SettingChanged += OnSettingChanged; FineMoveBackward.SettingChanged += OnSettingChanged; RotationIncrementsPerCircle.SettingChanged += OnSettingChanged; FineRotationIncrementsPerCircle.SettingChanged += OnSettingChanged; SideStepMeters.SettingChanged += OnSettingChanged; UpDownStepMeters.SettingChanged += OnSettingChanged; ForwardBackStepMeters.SettingChanged += OnSettingChanged; FineSideStepMeters.SettingChanged += OnSettingChanged; FineUpDownStepMeters.SettingChanged += OnSettingChanged; FineForwardBackStepMeters.SettingChanged += OnSettingChanged; ReferenceFrame.SettingChanged += OnSettingChanged; AreaRepairRadiusMeters.SettingChanged += OnSettingChanged; AreaRepairMaximumPieces.SettingChanged += OnSettingChanged; ShowPlacementAngles.SettingChanged += OnSettingChanged; ShowTargetAngles.SettingChanged += OnSettingChanged; ShowPositionReadout.SettingChanged += OnSettingChanged; ReadoutFontSize.SettingChanged += OnSettingChanged; VerboseLogging.SettingChanged += OnSettingChanged; } private static void OnSettingChanged(object sender, EventArgs args) { PluginConfig.Changed?.Invoke(); } private static bool IsConfigured(ConfigEntry<KeyboardShortcut> entry) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if (entry != null) { KeyboardShortcut value = entry.Value; return (int)((KeyboardShortcut)(ref value)).MainKey > 0; } return false; } private static void AddIfConfigured(List<ResolvedGesture> gestures, string name, ConfigEntry<KeyboardShortcut> entry) { if (IsConfigured(entry)) { gestures.Add(Resolve(name, entry)); } } private static ResolvedGesture Resolve(string name, ConfigEntry<KeyboardShortcut> entry) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) HashSet<KeyCode> keys = new HashSet<KeyCode>(); if (entry != null) { AddShortcutKeys(keys, entry.Value); } return new ResolvedGesture(name, keys); } private static void AddShortcutKeys(HashSet<KeyCode> keys, KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0) { keys.Add(((KeyboardShortcut)(ref shortcut)).MainKey); } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if ((int)modifier != 0) { keys.Add(modifier); } } } private static void AddDuplicateGestures(List<ResolvedGesture> gestures, List<string> conflicts) { for (int i = 0; i < gestures.Count; i++) { for (int j = i + 1; j < gestures.Count; j++) { if (gestures[i].Keys.SetEquals(gestures[j].Keys)) { conflicts.Add(gestures[i].Name + " and " + gestures[j].Name); } } } } } internal static class AxisGuideRadialSuppressionPolicy { internal static bool IsGuideReservationActive(InputChord chord, IInputSource input) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (input == null || chord.IsEmpty || !chord.Contains((KeyCode)103) || !input.IsPressed((KeyCode)103)) { return false; } for (int i = 0; i < chord.ModifierCount; i++) { KeyCode modifier = chord.GetModifier(i); if ((int)modifier != 0 && (int)modifier != 103 && !input.IsPressed(modifier)) { return false; } } return true; } internal static bool ShouldSuppress(bool canRun, bool isLocalPlayer, bool isInPlaceMode, bool hasActiveRotatableGhost, bool displayGateOpen, bool inputGateOpen, bool configuredGuideReservesG, bool guideReservationIsActive) { return canRun && isLocalPlayer && isInPlaceMode && hasActiveRotatableGhost && displayGateOpen && inputGateOpen && configuredGuideReservesG && guideReservationIsActive; } } internal readonly struct BuildCatalogEntry { internal string StableId { get; } internal string DisplayName { get; } internal int Category { get; } internal int X { get; } internal int Y { get; } internal int GridWidth { get; } internal bool IsValid { get { if (!string.IsNullOrEmpty(StableId)) { return !string.IsNullOrEmpty(DisplayName); } return false; } } internal BuildCatalogEntry(string stableId, string displayName, int category, int x, int y, int gridWidth = 0) { StableId = stableId; DisplayName = displayName; Category = category; X = x; Y = y; GridWidth = gridWidth; } } internal sealed class BoundedBuildCatalog { internal const int EntryCapacity = 256; internal const int CandidateInspectionCapacity = 1024; internal const int FavoriteCapacity = 64; internal const int RecentCapacity = 16; internal const int MaximumIdLength = 96; internal const int MaximumDisplayLength = 96; internal const int MaximumQueryLength = 64; internal const int MaximumPersistedFavoritesLength = 6208; internal const int MaximumPersistedRecentsLength = 1552; private readonly BuildCatalogEntry[] _entries = new BuildCatalogEntry[256]; private readonly string[] _favorites = new string[64]; private readonly string[] _recents = new string[16]; private int _entryCount; private int _favoriteCount; private int _recentCount; internal int EntryCount => _entryCount; internal int FavoriteCount => _favoriteCount; internal int RecentCount => _recentCount; internal void Rebuild(IEnumerable<BuildCatalogEntry> candidates) { Array.Clear(_entries, 0, _entries.Length); _entryCount = 0; if (candidates == null) { return; } int num = 0; foreach (BuildCatalogEntry candidate in candidates) { if (_entryCount >= 256 || num++ >= 1024) { break; } if (TryBoundId(candidate.StableId, out var bounded) && TryBoundDisplay(candidate.DisplayName, out var bounded2) && IndexOfEntry(bounded) < 0) { _entries[_entryCount++] = new BuildCatalogEntry(bounded, bounded2, candidate.Category, candidate.X, candidate.Y, candidate.GridWidth); } } CompactKnown(_favorites, ref _favoriteCount, 64); CompactKnown(_recents, ref _recentCount, 16); } internal bool TryFindNext(string query, string currentId, out BuildCatalogEntry result) { result = default(BuildCatalogEntry); string text = BoundQuery(query); if (_entryCount == 0) { return false; } int num = IndexOfEntry(currentId); for (int i = 1; i <= _entryCount; i++) { int num2 = (num + i + _entryCount) % _entryCount; BuildCatalogEntry buildCatalogEntry = _entries[num2]; if (text.Length == 0 || buildCatalogEntry.DisplayName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0 || buildCatalogEntry.StableId.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) { result = buildCatalogEntry; return true; } } return false; } internal bool TryCycleFavorite(string currentId, out BuildCatalogEntry result) { return TryCycleList(_favorites, _favoriteCount, currentId, out result); } internal bool TryCycleRecent(string currentId, out BuildCatalogEntry result) { return TryCycleList(_recents, _recentCount, currentId, out result); } internal bool ToggleFavorite(string stableId, out bool isFavorite) { isFavorite = false; if (!TryBoundId(stableId, out var bounded) || IndexOfEntry(bounded) < 0) { return false; } int num = IndexOf(_favorites, _favoriteCount, bounded); if (num >= 0) { RemoveAt(_favorites, ref _favoriteCount, num); return true; } if (_favoriteCount >= 64) { return false; } _favorites[_favoriteCount++] = bounded; isFavorite = true; return true; } internal void RecordRecent(string stableId) { if (TryBoundId(stableId, out var bounded) && IndexOfEntry(bounded) >= 0) { int num = IndexOf(_recents, _recentCount, bounded); if (num >= 0) { RemoveAt(_recents, ref _recentCount, num); } else if (_recentCount == 16) { _recentCount--; } for (int num2 = _recentCount; num2 > 0; num2--) { _recents[num2] = _recents[num2 - 1]; } _recents[0] = bounded; _recentCount++; } } internal string SerializeFavorites() { return Serialize(_favorites, _favoriteCount); } internal string SerializeRecents() { return Serialize(_recents, _recentCount); } internal void LoadFavorites(string value) { Load(value, _favorites, ref _favoriteCount, 64, 6208); } internal void LoadRecents(string value) { Load(value, _recents, ref _recentCount, 16, 1552); } internal BuildCatalogEntry EntryAt(int index) { if (index < 0 || index >= _entryCount) { return default(BuildCatalogEntry); } return _entries[index]; } internal static string BoundQuery(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } string text = value[..Math.Min(value.Length, 64)].Trim(); if (text.Length == 0) { return string.Empty; } foreach (char c in text) { if (char.IsControl(c) || char.GetUnicodeCategory(c) == UnicodeCategory.Format || c == '<' || c == '>') { return string.Empty; } } if (text.Length > 64) { return text.Substring(0, 64); } return text; } private bool TryCycleList(string[] values, int count, string currentId, out BuildCatalogEntry result) { result = default(BuildCatalogEntry); if (count == 0) { return false; } int num = IndexOf(values, count, currentId); for (int i = 1; i <= count; i++) { int num2 = (num + i + count) % count; int num3 = IndexOfEntry(values[num2]); if (num3 >= 0) { result = _entries[num3]; return true; } } return false; } private int IndexOfEntry(string stableId) { if (string.IsNullOrEmpty(stableId)) { return -1; } for (int i = 0; i < _entryCount; i++) { if (string.Equals(_entries[i].StableId, stableId, StringComparison.Ordinal)) { return i; } } return -1; } private void CompactKnown(string[] values, ref int count, int capacity) { int num = 0; for (int i = 0; i < count; i++) { if (num >= capacity) { break; } string text = values[i]; if (IndexOfEntry(text) >= 0 && IndexOf(values, num, text) < 0) { values[num++] = text; } } for (int j = num; j < count; j++) { values[j] = null; } count = num; } private static void Load(string value, string[] target, ref int count, int capacity, int maximumSerializedLength) { Array.Clear(target, 0, target.Length); count = 0; if (string.IsNullOrEmpty(value) || value.Length > maximumSerializedLength) { return; } string[] array = value.Split('|'); for (int i = 0; i < array.Length; i++) { if (count >= capacity) { break; } if (TryBoundId(array[i], out var bounded) && IndexOf(target, count, bounded) < 0) { target[count++] = bounded; } } } private static string Serialize(string[] values, int count) { if (count <= 0) { return string.Empty; } return string.Join("|", values, 0, count); } private static bool TryBoundId(string value, out string bounded) { bounded = null; if (string.IsNullOrEmpty(value) || value.Length > 96) { return false; } string text = value.Trim(); if (text.Length == 0 || text.Length > 96) { return false; } foreach (char c in text) { if (!char.IsLetterOrDigit(c) && c != '_' && c != '-' && c != '.' && c != '$') { return false; } } bounded = text; return true; } private static bool TryBoundDisplay(string value, out string bounded) { bounded = null; if (string.IsNullOrEmpty(value)) { return false; } string text = value[..Math.Min(value.Length, 96)].Trim(); if (text.Length == 0) { return false; } for (int i = 0; i < text.Length; i++) { if (char.IsControl(text[i]) || char.GetUnicodeCategory(text[i]) == UnicodeCategory.Format || text[i] == '<' || text[i] == '>') { return false; } } bounded = text; return true; } private static int IndexOf(string[] values, int count, string value) { if (string.IsNullOrEmpty(value)) { return -1; } for (int i = 0; i < count; i++) { if (string.Equals(values[i], value, StringComparison.Ordinal)) { return i; } } return -1; } private static void RemoveAt(string[] values, ref int count, int index) { if (index >= 0 && index < count) { for (int i = index + 1; i < count; i++) { values[i - 1] = values[i]; } values[--count] = null; } } } internal interface IInputSource { bool IsPressed(KeyCode key); bool WasPressedThisFrame(KeyCode key); float ReadScrollDelta(); } internal readonly struct InputChord { private static readonly KeyCode[] EmptyModifiers = Array.Empty<KeyCode>(); private readonly KeyCode[] _modifiers; internal KeyCode MainKey { get; } internal int ModifierCount { get { KeyCode[] modifiers = _modifiers; if (modifiers == null) { return 0; } return modifiers.Length; } } internal bool IsEmpty => (int)MainKey == 0; internal InputChord(KeyCode mainKey) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) MainKey = mainKey; _modifiers = EmptyModifiers; } internal InputChord(KeyCode mainKey, KeyCode[] modifiers) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) MainKey = mainKey; _modifiers = ((modifiers == null || modifiers.Length == 0) ? EmptyModifiers : ((KeyCode[])modifiers.Clone())); } internal KeyCode GetModifier(int index) { return _modifiers[index]; } internal bool Contains(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between I4 and Unknown if ((int)key == 0) { return false; } if (MainKey == key) { return true; } int modifierCount = ModifierCount; for (int i = 0; i < modifierCount; i++) { if ((int)_modifiers[i] == (int)key) { return true; } } return false; } } internal readonly struct RotationInputBindings { internal static RotationInputBindings Default => new RotationInputBindings(new InputChord((KeyCode)0), new InputChord((KeyCode)308), new InputChord((KeyCode)304), new InputChord((KeyCode)118), new InputChord((KeyCode)118, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new InputChord((KeyCode)118, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 })); internal InputChord Yaw { get; } internal InputChord Pitch { get; } internal InputChord Roll { get; } internal InputChord FineYaw { get; } internal InputChord FinePitch { get; } internal InputChord FineRoll { get; } internal RotationInputBindings(InputChord yaw, InputChord pitch, InputChord roll, InputChord fineYaw, InputChord finePitch, InputChord fineRoll) { Yaw = yaw; Pitch = pitch; Roll = roll; FineYaw = fineYaw; FinePitch = finePitch; FineRoll = fineRoll; } } internal readonly struct MovementInputBindings { internal static MovementInputBindings Default => new MovementInputBindings(Chord((KeyCode)273, fine: false), Chord((KeyCode)274, fine: false), Chord((KeyCode)276, fine: false), Chord((KeyCode)275, fine: false), Chord((KeyCode)280, fine: false), Chord((KeyCode)281, fine: false), Chord((KeyCode)273, fine: true), Chord((KeyCode)274, fine: true), Chord((KeyCode)276, fine: true), Chord((KeyCode)275, fine: true), Chord((KeyCode)280, fine: true), Chord((KeyCode)281, fine: true)); internal InputChord Up { get; } internal InputChord Down { get; } internal InputChord Left { get; } internal InputChord Right { get; } internal InputChord Forward { get; } internal InputChord Backward { get; } internal InputChord FineUp { get; } internal InputChord FineDown { get; } internal InputChord FineLeft { get; } internal InputChord FineRight { get; } internal InputChord FineForward { get; } internal InputChord FineBackward { get; } internal MovementInputBindings(InputChord up, InputChord down, InputChord left, InputChord right, InputChord forward, InputChord backward, InputChord fineUp, InputChord fineDown, InputChord fineLeft, InputChord fineRight, InputChord fineForward, InputChord fineBackward) { Up = up; Down = down; Left = left; Right = right; Forward = forward; Backward = backward; FineUp = fineUp; FineDown = fineDown; FineLeft = fineLeft; FineRight = fineRight; FineForward = fineForward; FineBackward = fineBackward; } private static InputChord Chord(KeyCode mainKey, bool fine) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (!fine) { return new InputChord(mainKey, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }); } return new InputChord(mainKey, (KeyCode[])(object)new KeyCode[2] { (KeyCode)308, (KeyCode)118 }); } } internal readonly struct InputBindings { internal static InputBindings Default => new InputBindings(RotationInputBindings.Default, new InputChord((KeyCode)256), new InputChord((KeyCode)257), new InputChord((KeyCode)258), new InputChord((KeyCode)259), new InputChord((KeyCode)260), new InputChord((KeyCode)261), new InputChord((KeyCode)262), new InputChord((KeyCode)263), new InputChord((KeyCode)264), new InputChord((KeyCode)265), new InputChord((KeyCode)266), new InputChord((KeyCode)257, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)258, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)259, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)260, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)261, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)262, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)112), new InputChord((KeyCode)103), new InputChord((KeyCode)291), MovementInputBindings.Default); internal RotationInputBindings Rotation { get; } internal InputChord Match { get; } internal InputChord MatchPitch { get; } internal InputChord MatchRoll { get; } internal InputChord MatchYaw { get; } internal InputChord MatchPositionX { get; } internal InputChord MatchPositionY { get; } internal InputChord MatchPositionZ { get; } internal InputChord MatchPosition { get; } internal InputChord MatchTransform { get; } internal InputChord MatchSnapSide { get; } internal InputChord RepeatTransform { get; } internal InputChord ResetPitch { get; } internal InputChord ResetRoll { get; } internal InputChord ResetYaw { get; } internal InputChord ResetSway { get; } internal InputChord ResetHeave { get; } internal InputChord ResetSurge { get; } internal InputChord PrecisionModeToggle { get; } internal InputChord AxisGuides { get; } internal InputChord Reset { get; } internal MovementInputBindings Movement { get; } internal InputBindings(RotationInputBindings rotation, InputChord match, InputChord matchPitch, InputChord matchRoll, InputChord matchYaw, InputChord axisGuides, InputChord reset, MovementInputBindings movement) : this(rotation, match, matchPitch, matchRoll, matchYaw, new InputChord((KeyCode)260), new InputChord((KeyCode)261), new InputChord((KeyCode)262), new InputChord((KeyCode)263), new InputChord((KeyCode)264), new InputChord((KeyCode)265), new InputChord((KeyCode)266), new InputChord((KeyCode)257, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)258, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)259, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)260, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)261, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)262, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new InputChord((KeyCode)112), axisGuides, reset, movement) { } internal InputBindings(RotationInputBindings rotation, InputChord match, InputChord matchPitch, InputChord matchRoll, InputChord matchYaw, InputChord matchPositionX, InputChord matchPositionY, InputChord matchPositionZ, InputChord matchPosition, InputChord matchTransform, InputChord matchSnapSide, InputChord repeatTransform, InputChord resetPitch, InputChord resetRoll, InputChord resetYaw, InputChord resetSway, InputChord resetHeave, InputChord resetSurge, InputChord precisionModeToggle, InputChord axisGuides, InputChord reset, MovementInputBindings movement) { Rotation = rotation; Match = match; MatchPitch = matchPitch; MatchRoll = matchRoll; MatchYaw = matchYaw; MatchPositionX = matchPositionX; MatchPositionY = matchPositionY; MatchPositionZ = matchPositionZ; MatchPosition = matchPosition; MatchTransform = matchTransform; MatchSnapSide = matchSnapSide; RepeatTransform = repeatTransform; ResetPitch = resetPitch; ResetRoll = resetRoll; ResetYaw = resetYaw; ResetSway = resetSway; ResetHeave = resetHeave; ResetSurge = resetSurge; PrecisionModeToggle = precisionModeToggle; AxisGuides = axisGuides; Reset = reset; Movement = movement; } } internal readonly struct InputContext { internal bool Enabled { get; } internal bool RuntimeAvailable { get; } internal bool IsFocused { get; } internal bool TakeInput { get; } internal bool HasActiveGhost { get; } internal bool CanRotate { get; } internal bool CanTranslate { get; } internal int RotationIncrementsPerCircle { get; } internal int FineRotationIncrementsPerCircle { get; } internal float RotationStepDegrees => StepDegrees(RotationIncrementsPerCircle); internal float FineRotationStepDegrees => StepDegrees(FineRotationIncrementsPerCircle); internal float SideStepMetres { get; } internal float UpDownStepMetres { get; } internal float ForwardBackStepMetres { get; } internal float FineSideStepMetres { get; } internal float FineUpDownStepMetres { get; } internal float FineForwardBackStepMetres { get; } internal bool AcceptsRunicInput { get { if (Enabled && RuntimeAvailable && IsFocused && TakeInput) { return HasActiveGhost; } return false; } } internal InputContext(bool enabled, bool runtimeAvailable, bool isFocused, bool takeInput, bool hasActiveGhost, bool canRotate, bool canTranslate, int rotationIncrementsPerCircle, int fineRotationIncrementsPerCircle, float sideStepMetres, float upDownStepMetres, float forwardBackStepMetres, float fineSideStepMetres, float fineUpDownStepMetres, float fineForwardBackStepMetres) { Enabled = enabled; RuntimeAvailable = runtimeAvailable; IsFocused = isFocused; TakeInput = takeInput; HasActiveGhost = hasActiveGhost; CanRotate = canRotate; CanTranslate = canTranslate; RotationIncrementsPerCircle = rotationIncrementsPerCircle; FineRotationIncrementsPerCircle = fineRotationIncrementsPerCircle; SideStepMetres = sideStepMetres; UpDownStepMetres = upDownStepMetres; ForwardBackStepMetres = forwardBackStepMetres; FineSideStepMetres = fineSideStepMetres; FineUpDownStepMetres = fineUpDownStepMetres; FineForwardBackStepMetres = fineForwardBackStepMetres; } private static float StepDegrees(int incrementsPerCircle) { if (incrementsPerCircle <= 0) { return 0f; } return 360f / (float)incrementsPerCircle; } } internal readonly struct InputFrameResult { internal SemanticCommand WheelCommand { get; } internal SemanticCommand DiscreteCommand { get; } internal bool ConsumeWheel { get; } internal RotationAxis ActiveAxis { get; } internal float ActiveStep { get; } internal bool ActiveStepIsFine { get; } internal bool AxisGuidesHeld { get; } internal InputFrameResult(SemanticCommand wheelCommand, SemanticCommand discreteCommand, bool consumeWheel, RotationAxis activeAxis, float activeStep, bool activeStepIsFine, bool axisGuidesHeld) { WheelCommand = wheelCommand; DiscreteCommand = discreteCommand; ConsumeWheel = consumeWheel; ActiveAxis = activeAxis; ActiveStep = activeStep; ActiveStepIsFine = activeStepIsFine; AxisGuidesHeld = axisGuidesHeld; } } internal sealed class InputRouter { private readonly struct WheelSelection { internal RotationAxis Axis { get; } internal float Step { get; } internal bool IsRecognized { get; } internal bool IsFine { get; } internal WheelSelection(RotationAxis axis, float step, bool isFine) { Axis = axis; Step = step; IsRecognized = true; IsFine = isFine; } } private const float ScrollEpsilon = 0.0001f; private readonly IInputSource _input; internal InputRouter(IInputSource input) { _input = input ?? throw new ArgumentNullException("input"); } internal InputFrameResult ProcessFrame(in InputContext context, in InputBindings bindings) { float num = _input.ReadScrollDelta(); if (!context.AcceptsRunicInput) { return default(InputFrameResult); } WheelSelection wheelSelection = ResolveWheelSelection(in context, in bindings); SemanticCommand wheelCommand = SemanticCommand.None; bool consumeWheel = false; if (context.CanRotate && wheelSelection.IsRecognized && Math.Abs(num) > 0.0001f && QuaternionMath.IsFinite(num) && QuaternionMath.IsFinite(wheelSelection.Step) && wheelSelection.Step > 0f) { float degrees = ((num > 0f) ? wheelSelection.Step : (0f - wheelSelection.Step)); wheelCommand = SemanticCommand.Rotation(wheelSelection.Axis, degrees); consumeWheel = !wheelCommand.IsNone; } SemanticCommand discreteCommand = ResolveDiscreteCommand(in context, in bindings); bool axisGuidesHeld = context.CanRotate && IsControlChordHeld(bindings.AxisGuides); return new InputFrameResult(wheelCommand, discreteCommand, consumeWheel, (context.CanRotate && wheelSelection.IsRecognized) ? wheelSelection.Axis : RotationAxis.None, (context.CanRotate && wheelSelection.IsRecognized) ? wheelSelection.Step : 0f, context.CanRotate && wheelSelection.IsRecognized && wheelSelection.IsFine, axisGuidesHeld); } internal bool WasExactActionPressed(InputChord chord, in InputBindings bindings) { return IsExactChordDown(chord, in bindings); } private WheelSelection ResolveWheelSelection(in InputContext context, in InputBindings bindings) { float fineRotationStepDegrees = context.FineRotationStepDegrees; if (IsExactHeldChord(bindings.Rotation.FineRoll, bindings.Rotation.FinePitch, in bindings, allowEmpty: false)) { return new WheelSelection(RotationAxis.Roll, fineRotationStepDegrees, isFine: true); } if (IsExactHeldChord(bindings.Rotation.FinePitch, in bindings, allowEmpty: false)) { return new WheelSelection(RotationAxis.Pitch, fineRotationStepDegrees, isFine: true); } if (IsExactHeldChord(bindings.Rotation.FineYaw, in bindings, allowEmpty: false)) { return new WheelSelection(RotationAxis.Yaw, fineRotationStepDegrees, isFine: true); } float rotationStepDegrees = context.RotationStepDegrees; if (IsExactHeldChord(bindings.Rotation.Roll, bindings.Rotation.Pitch, in bindings, allowEmpty: false)) { return new WheelSelection(RotationAxis.Roll, rotationStepDegrees, isFine: false); } if (IsExactHeldChord(bindings.Rotation.Pitch, in bindings, allowEmpty: false)) { return new WheelSelection(RotationAxis.Pitch, rotationStepDegrees, isFine: false); } if (IsExactHeldChord(bindings.Rotation.Yaw, in bindings, allowEmpty: true)) { return new WheelSelection(RotationAxis.Yaw, rotationStepDegrees, isFine: false); } return default(WheelSelection); } private SemanticCommand ResolveDiscreteCommand(in InputContext context, in InputBindings bindings) { if (IsExactChordDown(bindings.Reset, in bindings)) { return SemanticCommand.Reset; } if (IsExactChordDown(bindings.ResetPitch, in bindings)) { return SemanticCommand.ResetPitch; } if (IsExactChordDown(bindings.ResetRoll, in bindings)) { return SemanticCommand.ResetRoll; } if (IsExactChordDown(bindings.ResetYaw, in bindings)) { return SemanticCommand.ResetYaw; } if (IsExactChordDown(bindings.ResetSway, in bindings)) { return SemanticCommand.ResetSway; } if (IsExactChordDown(bindings.ResetHeave, in bindings)) { return SemanticCommand.ResetHeave; } if (IsExactChordDown(bindings.ResetSurge, in bindings)) { return SemanticCommand.ResetSurge; } if (IsExactChordDown(bindings.MatchTransform, in bindings)) { return SemanticCommand.MatchTransform; } if (IsExactChordDown(bindings.MatchSnapSide, in bindings)) { return SemanticCommand.MatchSnapSide; } if (IsExactChordDown(bindings.RepeatTransform, in bindings)) { return SemanticCommand.RepeatTransform; } if (IsExactChordDown(bindings.MatchPosition, in bindings)) { return SemanticCommand.MatchPosition; } if (IsExactChordDown(bindings.MatchPositionX, in bindings)) { return SemanticCommand.MatchPositionX; } if (IsExactChordDown(bindings.MatchPositionY, in bindings)) { return SemanticCommand.MatchPositionY; } if (IsExactChordDown(bindings.MatchPositionZ, in bindings)) { return SemanticCommand.MatchPositionZ; } if (context.CanRotate) { if (IsExactChordDown(bindings.MatchPitch, in bindings)) { return SemanticCommand.MatchPitch; } if (IsExactChordDown(bindings.MatchRoll, in bindings)) { return SemanticCommand.MatchRoll; } if (IsExactChordDown(bindings.MatchYaw, in bindings)) { return SemanticCommand.MatchYaw; } if (IsExactChordDown(bindings.Match, in bindings)) { return SemanticCommand.MatchOrientation; } } if (!context.CanTranslate) { return SemanticCommand.None; } MovementInputBindings movement = bindings.Movement; SemanticCommand result = TranslationIfDown(movement.FineUp, SemanticCommandKind.MoveHeave, context.FineUpDownStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.FineDown, SemanticCommandKind.MoveHeave, 0f - context.FineUpDownStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.FineLeft, SemanticCommandKind.MoveSway, 0f - context.FineSideStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.FineRight, SemanticCommandKind.MoveSway, context.FineSideStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.FineForward, SemanticCommandKind.MoveSurge, context.FineForwardBackStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.FineBackward, SemanticCommandKind.MoveSurge, 0f - context.FineForwardBackStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.Up, SemanticCommandKind.MoveHeave, context.UpDownStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.Down, SemanticCommandKind.MoveHeave, 0f - context.UpDownStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.Left, SemanticCommandKind.MoveSway, 0f - context.SideStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.Right, SemanticCommandKind.MoveSway, context.SideStepMetres, in bindings); if (!result.IsNone) { return result; } result = TranslationIfDown(movement.Forward, SemanticCommandKind.MoveSurge, context.ForwardBackStepMetres, in bindings); if (!result.IsNone) { return result; } return TranslationIfDown(movement.Backward, SemanticCommandKind.MoveSurge, 0f - context.ForwardBackStepMetres, in bindings); } private SemanticCommand TranslationIfDown(InputChord chord, SemanticCommandKind kind, float signedStep, in InputBindings bindings) { if (!QuaternionMath.IsFinite(signedStep) || Math.Abs(signedStep) <= 0.0001f) { return SemanticCommand.None; } if (!IsExactChordDown(chord, in bindings)) { return SemanticCommand.None; } return SemanticCommand.Translation(kind, signedStep); } private bool IsExactChordDown(InputChord chord, in InputBindings bindings) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!chord.IsEmpty && AreChordKeysHeld(chord) && HasOnlyAllowedControlKeys(in bindings, chord)) { return _input.WasPressedThisFrame(chord.MainKey); } return false; } private bool IsControlChordHeld(InputChord chord) { if (!chord.IsEmpty) { return AreChordKeysHeld(chord); } return false; } private bool IsExactHeldChord(InputChord chord, in InputBindings bindings, bool allowEmpty) { return IsExactHeldChord(chord, default(InputChord), in bindings, allowEmpty); } private bool IsExactHeldChord(InputChord chord, InputChord supplementalAllowed, in InputBindings bindings, bool allowEmpty) { if (chord.IsEmpty) { if (allowEmpty && SupplementalChordIsFullyHeldOrReleased(supplementalAllowed, chord)) { return HasOnlyAllowedWheelKeys(in bindings, chord, supplementalAllowed); } return false; } if (AreChordKeysHeld(chord) && SupplementalChordIsFullyHeldOrReleased(supplementalAllowed, chord)) { return HasOnlyAllowedWheelKeys(in bindings, chord, supplementalAllowed); } return false; } private bool SupplementalChordIsFullyHeldOrReleased(InputChord supplemental, InputChord primary) { //IL_000e: 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 (supplemental.IsEmpty) { return true; } bool flag = SupplementalOnlyKeyIsHeld(supplemental.MainKey, primary); int modifierCount = supplemental.ModifierCount; for (int i = 0; i < modifierCount; i++) { if (flag) { break; } flag = SupplementalOnlyKeyIsHeld(supplemental.GetModifier(i), primary); } if (flag) { return AreChordKeysHeld(supplemental); } return true; } private bool SupplementalOnlyKeyIsHeld(KeyCode key, InputChord primary) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0 && !primary.Contains(key)) { return _input.IsPressed(key); } return false; } private bool AreChordKeysHeld(InputChord chord) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (chord.IsEmpty || !_input.IsPressed(chord.MainKey)) { return false; } int modifierCount = chord.ModifierCount; for (int i = 0; i < modifierCount; i++) { KeyCode modifier = chord.GetModifier(i); if ((int)modifier == 0 || !_input.IsPressed(modifier)) { return false; } } return true; } private bool HasOnlyAllowedControlKeys(in InputBindings bindings, InputChord allowed) { InputChord overlay = (IsControlChordHeld(bindings.AxisGuides) ? bindings.AxisGuides : default(InputChord)); if (KeyIsAllowedOrReleased((KeyCode)308, allowed, overlay) && KeyIsAllowedOrReleased((KeyCode)307, allowed, overlay) && KeyIsAllowedOrReleased((KeyCode)306, allowed, overlay) && KeyIsAllowedOrReleased((KeyCode)305, allowed, overlay) && KeyIsAllowedOrReleased((KeyCode)304, allowed, overlay) && KeyIsAllowedOrReleased((KeyCode)303, allowed, overlay) && ChordKeysAreAllowedOrReleased(bindings.Rotation.Yaw, allowed, overlay) && ChordKeysAreAllowedOrReleased(bindings.Rotation.Pitch, allowed, overlay) && ChordKeysAreAllowedOrReleased(bindings.Rotation.Roll, allowed, overlay) && ChordKeysAreAllowedOrReleased(bindings.Rotation.FineYaw, allowed, overlay) && ChordKeysAreAllowedOrReleased(bindings.Rotation.FinePitch, allowed, overlay) && ChordKeysAreAllowedOrReleased(bindings.Rotation.FineRoll, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Match, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.MatchPitch, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.MatchRoll, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.MatchYaw, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.MatchPositionX, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.MatchPositionY, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.MatchPositionZ, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.MatchPosition, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.MatchTransform, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.MatchSnapSide, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.RepeatTransform, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.ResetPitch, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.ResetRoll, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.ResetYaw, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.ResetSway, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.ResetHeave, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.ResetSurge, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.PrecisionModeToggle, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Reset, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.Up, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.Down, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.Left, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.Right, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.Forward, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.Backward, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.FineUp, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.FineDown, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.FineLeft, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.FineRight, allowed, overlay) && ChordModifiersAreAllowedOrReleased(bindings.Movement.FineForward, allowed, overlay)) { return ChordModifiersAreAllowedOrReleased(bindings.Movement.FineBackward, allowed, overlay); } return false; } private bool HasOnlyAllowedWheelKeys(in InputBindings bindings, InputChord allowed, InputChord supplementalAllowed) { InputChord overlay = (IsControlChordHeld(bindings.AxisGuides) ? bindings.AxisGuides : default(InputChord)); if (WheelKeyIsAllowedOrReleased((KeyCode)308, allowed, supplementalAllowed, overlay) && WheelKeyIsAllowedOrReleased((KeyCode)307, allowed, supplementalAllowed, overlay) && WheelKeyIsAllowedOrReleased((KeyCode)304, allowed, supplementalAllowed, overlay) && WheelKeyIsAllowedOrReleased((KeyCode)303, allowed, supplementalAllowed, overlay) && WheelChordKeysAreAllowedOrReleased(bindings.Rotation.Yaw, allowed, supplementalAllowed, overlay) && WheelChordKeysAreAllowedOrReleased(bindings.Rotation.Pitch, allowed, supplementalAllowed, overlay) && WheelChordKeysAreAllowedOrReleased(bindings.Rotation.Roll, allowed, supplementalAllowed, overlay) && WheelChordKeysAreAllowedOrReleased(bindings.Rotation.FineYaw, allowed, supplementalAllowed, overlay) && WheelChordKeysAreAllowedOrReleased(bindings.Rotation.FinePitch, allowed, supplementalAllowed, overlay)) { return WheelChordKeysAreAllowedOrReleased(bindings.Rotation.FineRoll, allowed, supplementalAllowed, overlay); } return false; } private bool WheelChordKeysAreAllowedOrReleased(InputChord candidate, InputChord allowed, InputChord supplementalAllowed, InputChord overlay) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!WheelKeyIsAllowedOrReleased(candidate.MainKey, allowed, supplementalAllowed, overlay)) { return false; } int modifierCount = candidate.ModifierCount; for (int i = 0; i < modifierCount; i++) { if (!WheelKeyIsAllowedOrReleased(candidate.GetModifier(i), allowed, supplementalAllowed, overlay)) { return false; } } return true; } private bool WheelKeyIsAllowedOrReleased(KeyCode key, InputChord allowed, InputChord supplementalAllowed, InputChord overlay) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0 && !allowed.Contains(key) && !supplementalAllowed.Contains(key) && !overlay.Contains(key)) { return !_input.IsPressed(key); } return true; } private bool ChordKeysAreAllowedOrReleased(InputChord candidate, InputChord allowed, InputChord overlay) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (!KeyIsAllowedOrReleased(candidate.MainKey, allowed, overlay)) { return false; } return ChordModifiersAreAllowedOrReleased(candidate, allowed, overlay); } private bool ChordModifiersAreAllowedOrReleased(InputChord candidate, InputChord allowed, InputChord overlay) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) int modifierCount = candidate.ModifierCount; for (int i = 0; i < modifierCount; i++) { if (!KeyIsAllowedOrReleased(candidate.GetModifier(i), allowed, overlay)) { return false; } } return true; } private bool KeyIsAllowedOrReleased(KeyCode key, InputChord allowed, InputChord overlay) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_001d: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0 && !allowed.Contains(key) && !overlay.Contains(key)) { return !_input.IsPressed(key); } return true; } } internal enum MutationDenial : byte { None, RuntimeUnavailable, NotLocalPlayer, ObjectAuthorityUnavailable, WrongCreator, WardDenied, OutOfRange, NoBuildZone, Changed, Damaged, AccessedOrInteractive, StructurallyDependedUpon, NativePolicyDenied, ToolUnavailable, CapacityExceeded } internal readonly struct MutationEvidence { internal bool RuntimeAvailable { get; } internal bool LocalPlayer { get; } internal bool ObjectOwner { get; } internal bool Creator { get; } internal bool WardAccess { get; } internal bool InRange { get; } internal bool OutsideNoBuildZone { get; } internal bool Unchanged { get; } internal bool FullHealth { get; } internal bool Inert { get; } internal bool StructurallyIndependent { get; } internal bool NativePolicy { get; } internal bool ToolAvailable { get; } internal bool WithinCapacity { get; } internal MutationEvidence(bool runtimeAvailable, bool localPlayer, bool objectOwner, bool creator, bool wardAccess, bool inRange, bool outsideNoBuildZone, bool unchanged, bool fullHealth, bool inert, bool structurallyIndependent, bool nativePolicy, bool toolAvailable, bool withinCapacity) { RuntimeAvailable = runtimeAvailable; LocalPlayer = localPlayer; ObjectOwner = objectOwner; Creator = creator; WardAccess = wardAccess; InRange = inRange; OutsideNoBuildZone = outsideNoBuildZone; Unchanged = unchanged; FullHealth = fullHealth; Inert = inert; StructurallyIndependent = structurallyIndependent; NativePolicy = nativePolicy; ToolAvailable = toolAvailable; WithinCapacity = withinCapacity; } } internal static class MutationPolicy { internal static MutationDenial EvaluateUndo(in MutationEvidence evidence) { MutationDenial mutationDenial = EvaluateCommon(in evidence); if (mutationDenial != MutationDenial.None) { return mutationDenial; } if (!evidence.Unchanged) { return MutationDenial.Changed; } if (!evidence.FullHealth) { return MutationDenial.Damaged; } if (!evidence.Inert) { return MutationDenial.AccessedOrInteractive; } if (!evidence.StructurallyIndependent) { return MutationDenial.StructurallyDependedUpon; } if (!evidence.NativePolicy) { return MutationDenial.NativePolicyDenied; } return MutationDenial.None; } internal static MutationDenial EvaluateRepair(in MutationEvidence evidence) { MutationDenial mutationDenial = EvaluateCommon(in evidence); if (mutationDenial != MutationDenial.None) { return mutationDenial; } if (!evidence.NativePolicy) { return MutationDenial.NativePolicyDenied; } if (!evidence.ToolAvailable) { return MutationDenial.ToolUnavailable; } if (!evidence.WithinCapacity) { return MutationDenial.CapacityExceeded; } return MutationDenial.None; } private static MutationDenial EvaluateCommon(in MutationEvidence evidence) { if (!evidence.RuntimeAvailable) { return MutationDenial.RuntimeUnavailable; } if (!evidence.LocalPlayer) { return MutationDenial.NotLocalPlayer; } if (!evidence.ObjectOwner) { return MutationDenial.ObjectAuthorityUnavailable; } if (!evidence.Creator) { return MutationDenial.WrongCreator; } if (!evidence.WardAccess) { return MutationDenial.WardDenied; } if (!evidence.InRange) { return MutationDenial.OutOfRange; } if (!evidence.OutsideNoBuildZone) { return MutationDenial.NoBuildZone; } return MutationDenial.None; } } internal readonly struct OrientationAngles { internal const float SingularityThresholdDegrees = 89.95f; internal const float DisplayZeroThresholdDegrees = 0.05f; private const float IntegralDisplayTolerance = 0.005f; private const double ProjectedForwardEpsilonSquared = 1E-10; private const double SingularityThresholdProjection = 0.0008726645152351496; private const double MatchSingularityProjectionSquared = 1E-12; internal float Pitch { get; } internal float Roll { get; } internal float Yaw { get; } private OrientationAngles(float pitch, float roll, float yaw) { Pitch = pitch; Roll = roll; Yaw = yaw; } internal static OrientationAngles FromQuaternion(Quaternion rotation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!QuaternionMath.TryNormalize(rotation, out var normalized)) { return default(OrientationAngles); } return FromNormalizedQuaternion(normalized); } internal static bool TryDecomposeForMatch(Quaternion rotation, out OrientationAngles angles) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_002b: Unknown result type (might be due to invalid IL or missing references) if (!QuaternionMath.TryNormalize(rotation, out var normalized)) { angles = default(OrientationAngles); return false; } double num = normalized.x; double num2 = normalized.y; double num3 = normalized.z; double num4 = normalized.w; double x = 1.0 - 2.0 * (num2 * num2 + num3 * num3); double num5 = 2.0 * (num * num3 + num2 * num4); double y = 2.0 * (num * num2 + num3 * num4); double x2 = 1.0 - 2.0 * (num * num + num3 * num3); double num6 = 2.0 * (num2 * num3 - num * num4); double num7 = 2.0 * (num * num3 - num2 * num4); double num8 = 1.0 - 2.0 * (num * num + num2 * num2); double num9 = Clamp(0.0 - num6, -1.0, 1.0); double num10; double num11; double num12; if (num5 * num5 + num8 * num8 <= 1E-12) { num10 = ((num9 < 0.0) ? (-90.0) : 90.0); num11 = Math.Atan2(0.0 - num7, x) * (180.0 / Math.PI); num12 = 0.0; } else { num10 = Math.Asin(num9) * (180.0 / Math.PI); num11 = Math.Atan2(num5, num8) * (180.0 / Math.PI); num12 = Math.Atan2(y, x2) * (180.0 / Math.PI); } angles = new OrientationAngles(NormalizeSignedForMatch((float)num10), NormalizeSignedForMatch((float)num12), NormalizeSignedForMatch((float)num11)); return true; } internal static bool TryRecompose(float pitch, float roll, float yaw, out Quaternion rotation) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (!QuaternionMath.IsFinite(pitch) || !QuaternionMath.IsFinite(roll) || !QuaternionMath.IsFinite(yaw)) { rotation = Quaternion.identity; return false; } Quaternion val = QuaternionMath.AngleAxis(yaw, 0f, 1f, 0f); Quaternion val2 = QuaternionMath.AngleAxis(pitch, 1f, 0f, 0f); Quaternion val3 = QuaternionMath.AngleAxis(roll, 0f, 0f, 1f); return QuaternionMath.TryNormalize(val * val2 * val3, out rotation); } private static OrientationAngles FromNormalizedQuaternion(Quaternion q) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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) double num = q.x; double num2 = q.y; double num3 = q.z; double num4 = q.w; double x = 1.0 - 2.0 * (num2 * num2 + num3 * num3); double num5 = 2.0 * (num * num3 + num2 * num4); double y = 2.0 * (num * num2 + num3 * num4); double x2 = 1.0 - 2.0 * (num * num + num3 * num3); double num6 = 2.0 * (num2 * num3 - num * num4); double num7 = 2.0 * (num * num3 - num2 * num4); double num8 = 1.0 - 2.0 * (num * num + num2 * num2); double num9 = Clamp(0.0 - num6, -1.0, 1.0); double num10 = Math.Asin(num9) * (180.0 / Math.PI); double num11 = num5 * num5 + num8 * num8; double num12; double num13; if (Math.Abs(num10) >= 89.94999694824219 && num11 <= 1E-10) { num10 = ((num9 < 0.0) ? (-90.0) : 90.0); num12 = Math.Atan2(0.0 - num7, x) * (180.0 / Math.PI); num13 = 0.0; } else if (Math.Abs(num10) >= 89.94999694824219) { double num14 = Math.Atan2(num5, num8) * (180.0 / Math.PI); double num15 = Math.Atan2(y, x2) * (180.0 / Math.PI); if (num15 > 90.0 || num15 < -90.0) { num14 = NormalizeSignedDouble(num14 + 180.0); num15 = NormalizeSignedDouble(num15 + 180.0); num10 = ((num10 >= 0.0) ? (180.0 - num10) : (-180.0 - num10)); } double value = Math.Sqrt(num11) / 0.0008726645152351496; value = Clamp(value, 0.0, 1.0); num13 = num15 * value; double num16 = Math.Atan2(0.0 - num7, x) * (180.0 / Math.PI); num12 = ((num10 >= 0.0) ? (num16 + num13) : (num16 - num13)); } else { num12 = Math.Atan2(num5, num8) * (180.0 / Math.PI); num13 = Math.Atan2(y, x2) * (180.0 / Math.PI); } return new OrientationAngles(NormalizeSigned((float)num10), NormalizeSigned((float)num13), NormalizeSigned((float)num12)); } internal static float NormalizeSigned(float degrees) { if (!QuaternionMath.IsFinite(degrees)) { return 0f; } degrees %= 360f; if (degrees < -180f) { degrees += 360f; } else if (degrees >= 180f) { degrees -= 360f; } if (!(Math.Abs(degrees) <= 0.05f)) { return degrees; } return 0f; } internal static string FormatDegrees(float degrees) { degrees = NormalizeSigned(degrees); float num = (float)Math.Round(degrees); if (Math.Abs(degrees - num) < 0.005f) { return NormalizeSigned(num).ToString("0", CultureInfo.InvariantCulture) + "°"; } return degrees.ToString("0.##", CultureInfo.InvariantCulture) + "°"; } internal static string FormatValue(float value) { if (!QuaternionMath.IsFinite(value)) { return "0"; } float num = (float)Math.Round(value); if (Math.Abs(value - num) < 0.005f) { return num.ToString("0", CultureInfo.InvariantCulture); } return value.ToString("0.##", CultureInfo.InvariantCulture); } private static double Clamp(double value, double minimum, double maximum) { if (value < minimum) { return minimum; } if (!(value > maximum)) { return value; } return maximum; } private static double NormalizeSignedDouble(double degrees) { degrees %= 360.0; if (degrees < -180.0) { degrees += 360.0; } else if (degrees >= 180.0) { degrees -= 360.0; } return degrees; } private static float NormalizeSignedForMatch(float degrees) { if (!QuaternionMath.IsFinite(degrees)) { return 0f; } degrees %= 360f; if (degrees < -180f) { degrees += 360f; } else if (degrees >= 180f) { degrees -= 360f; } return degrees; } } internal sealed class PlacementSession { internal bool IsActive { get; private set; } internal int SelectedPrefabId { get; private set; } internal Quaternion BaseRotation { get; private set; } = Quaternion.identity; internal Quaternion DesiredRotation { get; private set; } = Quaternion.identity; internal bool HasAbsoluteRotation { get; private set; } internal bool HasRunicRotation { get; private set; } internal Vector3 SwayOffset { get; private set; } = Vector3.zero; internal Vector3 HeaveOffset { get; private set; } = Vector3.zero; internal Vector3 SurgeOffset { get; private set; } = Vector3.zero; internal Vector3 WorldOffset => SwayOffset + HeaveOffset + SurgeOffset; internal Vector3 DesiredPosition { get; private set; } = Vector3.zero; internal bool LocksPositionX { get; private set; } internal bool LocksPositionY { get; private set; } internal bool LocksPositionZ { get; private set; } internal bool HasAbsolutePosition { get { if (!LocksPositionX && !LocksPositionY) { return LocksPositionZ; } return true; } } internal int LastVanillaYawIndex { get; private set; } internal uint Generation { get; private set; } internal RotationAxis ActiveAxis { get; private set; } internal float ActiveStep { get; private set; } internal bool ActiveStepIsFine { get; private set; } internal float MatchFeedbackUntil { get; private set; } internal bool ObserveSelection(int selectedPrefabId, Quaternion baseRotation, int vanillaYawIndex) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (IsActive && SelectedPrefabId == selectedPrefabId) { return false; } AdvanceGeneration(); IsActive = true; SelectedPrefabId = selectedPrefabId; ResetPose(baseRotation, vanillaYawIndex); return true; } internal bool Exit() { //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 (!IsActive) { return false; } AdvanceGeneration(); IsActive = false; SelectedPrefabId = 0; BaseRotation = Quaternion.identity; DesiredRotation = Quaternion.identity; HasAbsoluteRotation = false; HasRunicRotation = false; ClearTranslation(); ClearPositionLocks(); LastVanillaYawIndex = 0; ActiveAxis = RotationAxis.None; ActiveStep = 0f; ActiveStepIsFine = false; MatchFeedbackUntil = 0f; return true; } internal void ResetPose(Quaternion baseRotation, int vanillaYawIndex) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) BaseRotation = QuaternionMath.NormalizeSafe(baseRotation); DesiredRotation = BaseRotation; HasAbsoluteRotation = false; HasRunicRotation = false; ClearTranslation(); ClearPositionLocks(); LastVanillaYawIndex = vanillaYawIndex; ActiveAxis = RotationAxis.None; ActiveStep = 0f; ActiveStepIsFine = false; MatchFeedbackUntil = 0f; } internal void SetBaseRotation(Quaternion rotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) BaseRotation = QuaternionMath.NormalizeSafe(rotation); } internal void SetDesiredRotation(Quaternion rotation, bool absolute) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) DesiredRotation = QuaternionMath.NormalizeSafe(rotation); HasAbsoluteRotation = absolute; } internal void SetRunicRotation(bool isDirty) { HasRunicRotation = isDirty; } internal void SetLastVanillaYawIndex(int yawIndex) { LastVanillaYawIndex = yawIndex; } internal void AddAxisOffset(SemanticCommandKind axis, Vector3 worldDelta) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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) switch (axis) { case SemanticCommandKind.MoveSway: SwayOffset += worldDelta; break; case SemanticCommandKind.MoveHeave: HeaveOffset += worldDelta; break; case SemanticCommandKind.MoveSurge: SurgeO