Decompiled source of BetterBuilderTools v2.0.0
plugins/BetterBuilderTools/BetterBuildBackout.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Lamb.UI; using Lamb.UI.BuildMenu; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Better Build Backout")] [assembly: AssemblyProduct("Better Build Backout")] [assembly: ComVisible(false)] [assembly: Guid("ce3ea138-0f05-4b72-88a5-e0493434a508")] [assembly: AssemblyFileVersion("0.1.10.0")] [assembly: AssemblyVersion("0.1.10.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 BetterBuildBackout { [BepInPlugin("com.cotl.betterbuildertools.betterbuildbackout", "Better Build Backout", "0.1.11")] public sealed class BetterBuildBackoutPlugin : BaseUnityPlugin { public const string PluginGuid = "com.cotl.betterbuildertools.betterbuildbackout"; public const string PluginName = "Better Build Backout"; public const string PluginVersion = "0.1.11"; private Harmony _harmony; private bool _hasLastChosen; private float _lastReopenTime; private float _nextAutoCleanupCheck; private float _staleSince; private bool _sawBuildActivity; private bool _reconciledAfterBuild; private float _lastBuildActivityAt; private bool _preservingCameraForCatalogue; private float _suspendAutoCleanupUntil; private int _lastCancelFrame = -1; private KeyCode _reopenKey; private Interaction_PlacementRegion _lastBuilderInteraction; private static readonly MethodInfo OpenBuildMenuMethod = AccessTools.Method(typeof(Interaction_PlacementRegion), "OpenBuildMenu", (Type[])null, (Type[])null); private static readonly MethodInfo ClearPrefabsMethod = AccessTools.Method(typeof(PlacementRegion), "ClearPrefabs", (Type[])null, (Type[])null); private static readonly FieldInfo TilesField = AccessTools.Field(typeof(PlacementRegion), "Tiles"); private static readonly FieldInfo TilesInitiatedField = AccessTools.Field(typeof(PlacementRegion), "tilesInitiated"); private static readonly FieldInfo PlacementObjectField = AccessTools.Field(typeof(PlacementRegion), "placementObject"); private static readonly FieldInfo PlacementUiField = AccessTools.Field(typeof(PlacementRegion), "placementUI"); private static readonly FieldInfo IsEditingBuildingsField = AccessTools.Field(typeof(PlacementRegion), "isEditingBuildings"); internal static ManualLogSource Log { get; private set; } internal static BetterBuildBackoutPlugin Instance { get; private set; } private void Awake() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; BetterBuildBackoutConfig.Bind(((BaseUnityPlugin)this).Config); _reopenKey = ParseKey(BetterBuildBackoutConfig.ReopenKey.Value, (KeyCode)114); _harmony = new Harmony("com.cotl.betterbuildertools.betterbuildbackout"); _harmony.PatchAll(typeof(BetterBuildBackoutPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Better Build Backout 0.1.11 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; Instance = null; } internal void RememberChoice(TYPES structureType) { _hasLastChosen = true; } internal void RememberBuilderInteraction(Interaction_PlacementRegion interaction) { if ((Object)(object)interaction != (Object)null) { _lastBuilderInteraction = interaction; } } internal void QueueReopen() { if (BetterBuildBackoutConfig.Enabled.Value && _hasLastChosen && BetterBuildBackoutConfig.AutoReopenAfterPlacement.Value && !(Time.unscaledTime - _lastReopenTime < 0.25f)) { _lastReopenTime = Time.unscaledTime; ((MonoBehaviour)this).StartCoroutine(ReopenRoutine()); } } private void Update() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (BetterBuildBackoutConfig.Enabled.Value) { bool num = IsActiveBuildPlacement(); if (num) { _sawBuildActivity = true; _staleSince = 0f; } if (num && Input.GetKeyDown(_reopenKey)) { ((MonoBehaviour)this).StartCoroutine(ReopenRoutine()); } if (EditModeTogglePressed()) { _suspendAutoCleanupUntil = Time.unscaledTime + 2.5f; _staleSince = 0f; } if (BetterBuildBackoutConfig.AutoCleanup.Value) { CheckAutoCleanup(); } } } internal bool TryHandleCancelBackout() { if (!BetterBuildBackoutConfig.Enabled.Value || !BetterBuildBackoutConfig.CancelReopensBuildMenu.Value || !IsActiveBuildPlacement()) { return false; } if ((Object)(object)PlacementRegion.Instance != (Object)null && IsEditBuildingsMode(PlacementRegion.Instance)) { return false; } if (_lastCancelFrame == Time.frameCount) { return true; } _lastCancelFrame = Time.frameCount; ((MonoBehaviour)this).StartCoroutine(ReopenRoutine()); return true; } private IEnumerator ReopenRoutine() { if (!IsActiveBuildPlacement() || Time.unscaledTime - _lastReopenTime < 0.25f) { yield break; } _lastReopenTime = Time.unscaledTime; if (!CancelActivePlacementIfNeeded(BetterBuildBackoutConfig.PreserveCameraForCatalogue.Value)) { yield break; } _preservingCameraForCatalogue = BetterBuildBackoutConfig.PreserveCameraForCatalogue.Value; yield return (object)new WaitForSecondsRealtime(BetterBuildBackoutConfig.ReopenDelay.Value); if ((Object)(object)_lastBuilderInteraction != (Object)null && OpenBuildMenuMethod != null && OpenBuildMenuMethod.Invoke(_lastBuilderInteraction, null) is IEnumerator enumerator) { ((MonoBehaviour)_lastBuilderInteraction).StartCoroutine(enumerator); yield break; } Log.LogWarning((object)"Could not reopen through Interaction_PlacementRegion; falling back to UIManager."); if ((Object)(object)MonoSingleton<UIManager>.Instance != (Object)null && (Object)(object)MonoSingleton<UIManager>.Instance.BuildMenuTemplate != (Object)null) { Time.timeScale = 0f; MonoSingleton<UIManager>.Instance.ShowBuildMenu((TYPES)0); } } internal void MarkBuildMenuSelection() { _preservingCameraForCatalogue = false; } internal void HandleBuildMenuCancel() { if (_preservingCameraForCatalogue) { _preservingCameraForCatalogue = false; RestoreWorldState(resetCameraToPlayer: true); } } private static bool CancelActivePlacementIfNeeded(bool preserveCamera) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 PlacementRegion instance = PlacementRegion.Instance; if ((Object)(object)instance == (Object)null || (int)instance.CurrentMode == 0) { return true; } if ((int)instance.CurrentMode == 4 || (int)instance.CurrentMode == 2) { Log.LogWarning((object)"Backout ignored while moving/upgrading a structure to avoid losing that edit."); return false; } ((MonoBehaviour)instance).StopAllCoroutines(); GameObject val = (((Object)(object)PlacementObject.Instance != (Object)null) ? ((Component)PlacementObject.Instance).gameObject : null); try { DestroyPlacementTiles(instance); ClearPrefabsMethod?.Invoke(instance, null); DestroyPrivateObject<PlacementObject>(instance, PlacementObjectField); DestroyPrivateObject<PlacementObjectUI>(instance, PlacementUiField); } catch (Exception ex) { Log.LogWarning((object)("Placement cleanup failed: " + ex.Message)); } instance.CurrentMode = (Mode)0; instance.PlacementPosition = Vector3.zero; TilesInitiatedField?.SetValue(instance, false); if ((Object)(object)DLCLandController.Instance != (Object)null) { DLCLandController.Instance.ShowBridge(); } if ((Object)(object)HUD_Manager.Instance != (Object)null) { HUD_Manager.Instance.Show(1, false); HUD_Manager.Instance.ShowEditMode(false); } if ((Object)(object)WeatherSystemController.Instance != (Object)null) { WeatherSystemController.Instance.ShowWeather(false, true); } if ((Object)(object)LightingManager.Instance != (Object)null) { LightingManager.Instance.inOverride = false; LightingManager.Instance.overrideSettings = null; LightingManager.Instance.transitionDurationMultiplier = 0.2f; LightingManager.Instance.lerpActive = false; LightingManager.Instance.UpdateLighting(true, false, false); LightingManager.Instance.PrepareLightingSettings(false); } if ((Object)(object)GameManager.GetInstance() != (Object)null) { if ((Object)(object)GameManager.GetInstance().CamFollowTarget != (Object)null) { ((Behaviour)GameManager.GetInstance().CamFollowTarget).enabled = !preserveCamera; } if ((Object)(object)val != (Object)null) { GameManager.GetInstance().RemoveFromCamera(val); } if (!preserveCamera) { GameManager.GetInstance().RemoveAllFromCamera(); GameManager.GetInstance().AddPlayerToCamera(); GameManager.GetInstance().CameraResetTargetZoom(); } } GameManager.overridePlayerPosition = false; Time.timeScale = 1f; return true; } private void CheckAutoCleanup() { if (Time.unscaledTime < _suspendAutoCleanupUntil) { _staleSince = 0f; } else { if (Time.unscaledTime < _nextAutoCleanupCheck) { return; } _nextAutoCleanupCheck = Time.unscaledTime + 0.25f; if (IsActiveBuildPlacement()) { _sawBuildActivity = true; _reconciledAfterBuild = false; _lastBuildActivityAt = Time.unscaledTime; _staleSince = 0f; return; } if (_sawBuildActivity && !_reconciledAfterBuild && !AnyMenuOpen() && Time.unscaledTime - _lastBuildActivityAt >= 0.4f) { int num = RepairOrphanBuildTiles(); _reconciledAfterBuild = true; if (num > 0) { Log.LogWarning((object)("Cleared " + num + " orphaned build-grid tile(s) after placement ended.")); } } if (!_sawBuildActivity || _preservingCameraForCatalogue || AnyMenuOpen() || !HasStaleBuildSymptoms()) { _staleSince = 0f; } else if (_staleSince <= 0f) { _staleSince = Time.unscaledTime; } else if (!(Time.unscaledTime - _staleSince < BetterBuildBackoutConfig.AutoCleanupDelay.Value)) { RecoverStaleBuildState(); _sawBuildActivity = false; _staleSince = 0f; Log.LogInfo((object)"Auto-cleaned stale build placement state."); } } } private static void RecoverStaleBuildState() { PlacementRegion[] array = PlacementRegion.PlacementRegions.ToArray(); for (int i = 0; i < array.Length; i++) { RecoverPlacementRegion(array[i]); } if ((Object)(object)PlacementObject.Instance != (Object)null) { Object.Destroy((Object)(object)((Component)PlacementObject.Instance).gameObject); } RestoreWorldState(resetCameraToPlayer: true); RestorePlayers(); } private static void RecoverPlacementRegion(PlacementRegion region) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)region == (Object)null)) { ((MonoBehaviour)region).StopAllCoroutines(); try { DestroyPlacementTiles(region); DestroyPrivateObject<PlacementObject>(region, PlacementObjectField); DestroyPrivateObject<PlacementObjectUI>(region, PlacementUiField); ClearPrefabsMethod?.Invoke(region, null); } catch (Exception ex) { Log.LogWarning((object)("Auto cleanup placement-region recovery failed: " + ex.Message)); } region.CurrentMode = (Mode)0; region.PlacementPosition = Vector3.zero; TilesInitiatedField?.SetValue(region, false); } } private static void RestoreWorldState(bool resetCameraToPlayer) { GameManager.overridePlayerPosition = false; Time.timeScale = 1f; if ((Object)(object)DLCLandController.Instance != (Object)null) { DLCLandController.Instance.ShowBridge(); } if ((Object)(object)HUD_Manager.Instance != (Object)null) { HUD_Manager.Instance.Show(1, false); HUD_Manager.Instance.ShowEditMode(false); } if ((Object)(object)WeatherSystemController.Instance != (Object)null) { WeatherSystemController.Instance.ShowWeather(false, true); } if ((Object)(object)LightingManager.Instance != (Object)null) { LightingManager.Instance.inOverride = false; LightingManager.Instance.overrideSettings = null; LightingManager.Instance.transitionDurationMultiplier = 0.2f; LightingManager.Instance.lerpActive = false; LightingManager.Instance.UpdateLighting(true, false, false); LightingManager.Instance.PrepareLightingSettings(false); } if ((Object)(object)GameManager.GetInstance() != (Object)null) { if ((Object)(object)GameManager.GetInstance().CamFollowTarget != (Object)null) { ((Behaviour)GameManager.GetInstance().CamFollowTarget).enabled = true; } if (resetCameraToPlayer) { GameManager.GetInstance().RemoveAllFromCamera(); GameManager.GetInstance().AddPlayerToCamera(); GameManager.GetInstance().CameraResetTargetZoom(); } } } private static void RestorePlayers() { foreach (PlayerFarming player in PlayerFarming.players) { if (!((Object)(object)player == (Object)null)) { ((Component)player).gameObject.SetActive(true); player.GoToAndStopping = false; if ((Object)(object)player.state != (Object)null) { player.state.CURRENT_STATE = (State)0; } if ((Object)(object)player.interactor != (Object)null) { player.interactor.CurrentInteraction = null; player.interactor.PreviousInteraction = null; } if ((Object)(object)player.indicator != (Object)null) { ((TMP_Text)player.indicator.text).text = ""; ((TMP_Text)player.indicator.SecondaryText).text = ""; ((TMP_Text)player.indicator.Thirdtext).text = ""; ((TMP_Text)player.indicator.Fourthtext).text = ""; player.indicator.Reset(); player.indicator.HideTopInfo(); } } } } private static int RepairOrphanBuildTiles() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if ((int)PlayerFarming.Location != 1 || (Object)(object)PlacementRegion.Instance == (Object)null || PlacementRegion.Instance.Grid == null) { return 0; } HashSet<int> hashSet = new HashSet<int>(); Structure[] array = Structure.Structures.ToArray(); foreach (Structure val in array) { if ((Object)(object)val != (Object)null && val.Brain != null && val.Brain.Data != null && (int)val.Brain.Data.Location == 1) { hashSet.Add(val.Brain.Data.ID); } } int num = 0; foreach (TileGridTile item in PlacementRegion.Instance.Grid) { if (item != null && item.ObjectID >= 0 && !hashSet.Contains(item.ObjectID) && IsBuildSiteTile(item.ObjectOnTile)) { item.Occupied = false; item.Obstructed = false; item.ReservedForWaste = false; item.IsUpgrade = false; item.Collapsed = false; item.ObjectID = -1; item.ObjectOnTile = (TYPES)0; num++; } } return num; } private static bool IsBuildSiteTile(TYPES type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)type != 31) { return (int)type == 118; } return true; } private static void DestroyPlacementTiles(PlacementRegion region) { if (!(TilesField?.GetValue(region) is List<PlacementTile> list)) { return; } PlacementTile[] array = list.ToArray(); foreach (PlacementTile val in array) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } list.Clear(); } private static void DestroyPrivateObject<T>(PlacementRegion region, FieldInfo field) where T : Component { object? obj = field?.GetValue(region); T val = (T)((obj is T) ? obj : null); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); field.SetValue(region, null); } } private static bool IsActiveBuildPlacement() { //IL_0011: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 PlacementRegion instance = PlacementRegion.Instance; if ((Object)(object)instance == (Object)null) { return false; } if (GameManager.IsDungeon(PlayerFarming.Location)) { return false; } if (IsEditBuildingsMode(instance)) { return true; } if ((int)instance.CurrentMode == 0) { return false; } Mode currentMode = instance.CurrentMode; if ((int)currentMode != 1 && (int)currentMode != 5) { return (int)currentMode == 3; } return true; } private static bool IsEditBuildingsMode(PlacementRegion region) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 if ((Object)(object)region == (Object)null) { return false; } if ((int)region.StructureType == 215) { return true; } try { if (IsEditingBuildingsField != null && (bool)IsEditingBuildingsField.GetValue(region)) { return true; } } catch { } return (int)region.CurrentMode == 3; } private static bool EditModeTogglePressed() { if (Input.GetKeyDown((KeyCode)99)) { return true; } try { return InputManager.UI.GetEditBuildingsButtonDown((PlayerFarming)null); } catch { return false; } } private static bool AnyMenuOpen() { if (UIMenuBase.ActiveMenus != null) { return UIMenuBase.ActiveMenus.Count > 0; } return false; } private static bool HasStaleBuildSymptoms() { if (GameManager.overridePlayerPosition || Time.timeScale == 0f) { return true; } if ((Object)(object)LightingManager.Instance != (Object)null && LightingManager.Instance.inOverride) { return true; } if ((Object)(object)PlayerFarming.Instance == (Object)null || (Object)(object)PlayerFarming.Instance.CameraBone == (Object)null || (Object)(object)GameManager.GetInstance() == (Object)null) { return false; } return !GameManager.GetInstance().CameraContains(PlayerFarming.Instance.CameraBone); } private static KeyCode ParseKey(string raw, KeyCode fallback) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references) try { return (KeyCode)Enum.Parse(typeof(KeyCode), raw, ignoreCase: true); } catch { return fallback; } } } [HarmonyPatch(typeof(Interaction_PlacementRegion), "OnInteract")] internal static class InteractionPlacementRegionOnInteractPatch { private static void Prefix(Interaction_PlacementRegion __instance) { BetterBuildBackoutPlugin.Instance?.RememberBuilderInteraction(__instance); } } internal static class BetterBuildBackoutConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> AutoReopenAfterPlacement; internal static ConfigEntry<string> ReopenKey; internal static ConfigEntry<float> ReopenDelay; internal static ConfigEntry<bool> CancelReopensBuildMenu; internal static ConfigEntry<bool> ShowToolPrompt; internal static ConfigEntry<bool> AutoCleanup; internal static ConfigEntry<float> AutoCleanupDelay; internal static ConfigEntry<bool> PreserveCameraForCatalogue; internal static void Bind(ConfigFile config) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Better Build Backout."); AutoReopenAfterPlacement = config.Bind<bool>("Build Menu", "ReopenAfterPlacement", false, "Automatically reopen the build catalogue after successfully placing a structure. This is off by default; use ReopenKey for manual return."); if (AutoReopenAfterPlacement.Value) { AutoReopenAfterPlacement.Value = false; } ReopenKey = config.Bind<string>("Controls", "ReopenKey", "R", "KeyCode used to reopen the build catalogue after placing a structure."); ReopenDelay = config.Bind<float>("Build Menu", "ReopenDelay", 0.15f, new ConfigDescription("Delay before reopening the build catalogue.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 1f), Array.Empty<object>())); CancelReopensBuildMenu = config.Bind<bool>("Controls", "CancelReopensBuildMenu", true, "When placing a structure, the first UI cancel/back press returns to the build catalogue instead of leaving build mode."); AutoCleanup = config.Bind<bool>("Cleanup", "AutoCleanup", true, "Automatically recover stale build tint/camera/player-lock state after leaving build placement."); AutoCleanupDelay = config.Bind<float>("Cleanup", "AutoCleanupDelay", 0.75f, new ConfigDescription("Seconds stale build symptoms must persist before auto cleanup runs.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>())); PreserveCameraForCatalogue = config.Bind<bool>("Build Menu", "PreserveCameraForCatalogue", true, "Keep the current build camera position when returning to the catalogue for a quick structure swap."); ShowToolPrompt = config.Bind<bool>("UI", "ShowToolPrompt", false, "Deprecated. Better Build Backout no longer appends text to the vanilla placement indicator."); } } [HarmonyPatch(typeof(RewiredUIInputSource), "GetCancelButtonDown")] internal static class RewiredUICancelButtonDownPatch { private static void Postfix(ref bool __result) { if (__result && (Object)(object)BetterBuildBackoutPlugin.Instance != (Object)null && BetterBuildBackoutPlugin.Instance.TryHandleCancelBackout()) { __result = false; } } } [HarmonyPatch(typeof(UIBuildMenuController), "ChosenBuilding")] internal static class BuildMenuChosenBuildingPatch { private static void Prefix(TYPES structure) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) BetterBuildBackoutPlugin.Instance?.RememberChoice(structure); BetterBuildBackoutPlugin.Instance?.MarkBuildMenuSelection(); } } [HarmonyPatch(typeof(UIBuildMenuController), "OnCancelButtonInput")] internal static class BuildMenuCancelButtonInputPatch { private static void Prefix() { BetterBuildBackoutPlugin.Instance?.HandleBuildMenuCancel(); } } [HarmonyPatch(typeof(PlacementRegion), "Play", new Type[] { typeof(Vector3) })] internal static class PlacementRegionPlayVectorPatch { private static void Prefix() { BetterBuildBackoutPlugin.Instance?.MarkBuildMenuSelection(); } } [HarmonyPatch(typeof(PlacementRegion), "Play", new Type[] { typeof(int) })] internal static class PlacementRegionPlayIntPatch { private static void Prefix() { BetterBuildBackoutPlugin.Instance?.MarkBuildMenuSelection(); } } [HarmonyPatch(typeof(PlacementRegion), "Build")] internal static class PlacementRegionBuildPatch { private static void Postfix() { BetterBuildBackoutPlugin.Instance?.QueueReopen(); } } }
plugins/BetterBuilderTools/BuildCameraFocus.dll
Decompiled 2 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Build Camera Focus")] [assembly: AssemblyProduct("Build Camera Focus")] [assembly: ComVisible(false)] [assembly: Guid("8a83b49b-7176-4d1e-8515-dca4b8737746")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyVersion("0.1.0.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 BuildCameraFocus { [BepInPlugin("com.cotl.betterbuildertools.buildcamerafocus", "Build Camera Focus", "0.1.0")] public sealed class BuildCameraFocusPlugin : BaseUnityPlugin { public const string PluginGuid = "com.cotl.betterbuildertools.buildcamerafocus"; public const string PluginName = "Build Camera Focus"; public const string PluginVersion = "0.1.0"; private Harmony _harmony; internal static ManualLogSource Log { get; private set; } internal static BuildCameraFocusPlugin Instance { get; private set; } private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; BuildCameraFocusConfig.Bind(((BaseUnityPlugin)this).Config); _harmony = new Harmony("com.cotl.betterbuildertools.buildcamerafocus"); _harmony.PatchAll(typeof(BuildCameraFocusPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Build Camera Focus 0.1.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; Instance = null; } internal void Focus(CameraFollowTarget followTarget) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if (BuildCameraFocusConfig.Enabled.Value && !((Object)(object)followTarget == (Object)null) && !((Object)(object)PlacementObject.Instance == (Object)null)) { Vector3 val = ((Component)PlacementObject.Instance).transform.position + Vector3.back * 0.5f; float value = BuildCameraFocusConfig.CameraDistance.Value; float num = BuildCameraFocusConfig.CameraAngle.Value * ((float)Math.PI / 180f); Vector3 val2 = val + new Vector3(0f, value * Mathf.Sin(num), (0f - value) * Mathf.Cos(num)); float num2 = 1f - Mathf.Exp((0f - BuildCameraFocusConfig.FollowSharpness.Value) * Time.unscaledDeltaTime); Vector3 val3 = Vector3.Lerp(((Component)followTarget).transform.position, val2, num2); ((Component)followTarget).transform.position = val3; ((Component)followTarget).transform.rotation = Quaternion.Euler(BuildCameraFocusConfig.CameraAngle.Value, 0f, 0f); followTarget.CurrentPosition = val3; followTarget.CurrentTargetCameraPosition = val3; } } } internal static class BuildCameraFocusConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> CameraDistance; internal static ConfigEntry<float> CameraAngle; internal static ConfigEntry<float> FollowSharpness; internal static void Bind(ConfigFile config) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Build Camera Focus."); CameraDistance = config.Bind<float>("Camera", "CameraDistance", 11f, new ConfigDescription("Camera distance while following the placement object.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(4f, 30f), Array.Empty<object>())); CameraAngle = config.Bind<float>("Camera", "CameraAngle", -45f, new ConfigDescription("Camera pitch while following the placement object.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-80f, -15f), Array.Empty<object>())); FollowSharpness = config.Bind<float>("Camera", "FollowSharpness", 16f, new ConfigDescription("How quickly the camera follows placement.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 80f), Array.Empty<object>())); } } [HarmonyPatch(typeof(CameraFollowTarget), "LateUpdate")] internal static class CameraFollowTargetLateUpdatePatch { private static void Postfix(CameraFollowTarget __instance) { BuildCameraFocusPlugin.Instance?.Focus(__instance); } } }
plugins/BetterBuilderTools/ClearThisType.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using src.UINavigator; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Clear This Type")] [assembly: AssemblyProduct("Clear This Type")] [assembly: ComVisible(false)] [assembly: Guid("042701eb-e714-4929-96aa-a7f4e71e6630")] [assembly: AssemblyFileVersion("0.1.7.0")] [assembly: AssemblyVersion("0.1.7.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 ClearThisType { [BepInPlugin("com.cotl.betterbuildertools.clearthistype", "Clear This Type", "0.1.9")] public sealed class ClearThisTypePlugin : BaseUnityPlugin { public const string PluginGuid = "com.cotl.betterbuildertools.clearthistype"; public const string PluginName = "Clear This Type"; public const string PluginVersion = "0.1.9"; private Harmony _harmony; private KeyCode _clearKey; private KeyCode _controllerConfirmKey; private KeyCode _controllerCancelKey; private string _statusText = ""; private float _statusUntil; private TYPES _pendingType; private float _pendingUntil; private string _pendingName = ""; private int _pendingCount; private GUIStyle _boxStyle; private GUIStyle _titleStyle; private GUIStyle _bodyStyle; private GUIStyle _confirmStyle; private GUIStyle _cancelStyle; private Texture2D _boxBackground; private Texture2D _confirmBackground; private Texture2D _cancelBackground; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ClearThisTypeConfig.Bind(((BaseUnityPlugin)this).Config); _clearKey = ParseKey(ClearThisTypeConfig.ClearKey.Value, (KeyCode)289); _controllerConfirmKey = ParseKey(ClearThisTypeConfig.ControllerConfirmKey.Value, (KeyCode)330); _controllerCancelKey = ParseKey(ClearThisTypeConfig.ControllerCancelKey.Value, (KeyCode)331); _harmony = new Harmony("com.cotl.betterbuildertools.clearthistype"); _harmony.PatchAll(typeof(ClearThisTypePlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Clear This Type 0.1.9 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; DestroyTexture(ref _boxBackground); DestroyTexture(ref _confirmBackground); DestroyTexture(ref _cancelBackground); } private void Update() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) bool allowNearestFallback; if (!ClearThisTypeConfig.Enabled.Value || (Object)(object)PlacementRegion.Instance == (Object)null || !IsActiveBuildPlacement()) { ClearPending(); } else if (HasPendingConfirmation() && (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown((KeyCode)324))) { ClearPending(); ShowStatus("Remove all cancelled"); } else if (HasPendingConfirmation() && ControllerCancelPressed()) { ClearPending(); ShowStatus("Remove all cancelled"); } else if (HasPendingConfirmation() && ControllerConfirmPressed()) { ClearMatchingType(_pendingType); } else if (ClearPressed(out allowNearestFallback)) { QueueOrClearHoveredType(allowNearestFallback); } } private bool ClearPressed(out bool allowNearestFallback) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) allowNearestFallback = false; if (Input.GetKeyDown(_clearKey)) { allowNearestFallback = true; return true; } if (!ClearThisTypeConfig.EnableVanillaClearButton.Value) { return false; } try { return InputManager.Gameplay.GetInteract3ButtonDown(MonoSingleton<UINavigatorNew>.Instance.AllowInputOnlyFromPlayer); } catch { return false; } } private bool ControllerConfirmPressed() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(_controllerConfirmKey)) { return true; } try { return InputManager.UI.GetAcceptButtonDown((PlayerFarming)null); } catch { return false; } } private bool ControllerCancelPressed() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(_controllerCancelKey)) { return true; } try { return InputManager.UI.GetCancelButtonDown((PlayerFarming)null); } catch { return false; } } private unsafe void QueueOrClearHoveredType(bool allowNearestFallback) { //IL_001b: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Structure val = PlacementRegion.Instance.GetHoveredStructure(); if ((Object)(object)val == (Object)null && allowNearestFallback) { val = GetNearestStructureAtPlacement(PlacementRegion.Instance.PlacementPosition, ClearThisTypeConfig.TargetRadius.Value); } StructureBrain val2 = (((Object)(object)val != (Object)null) ? val.Brain : null); if (val2 == null || val2.Data == null) { Log.LogInfo((object)"Clear This Type: no hovered structure found."); ShowStatus("No matching structure under cursor"); return; } TYPES type = val2.Data.Type; if (!ClearThisTypeConfig.AllowCriticalStructures.Value && IsCritical(type)) { Log.LogWarning((object)("Blocked Clear This Type for protected structure type " + ((object)(*(TYPES*)(&type))/*cast due to .constrained prefix*/).ToString() + ".")); ShowStatus("Protected structure type"); } else if (ClearThisTypeConfig.RequireConfirmation.Value && (_pendingType != type || Time.unscaledTime > _pendingUntil)) { SetPendingConfirmation(type); } else { ClearMatchingType(type); } } private void SetPendingConfirmation(TYPES type) { //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_001e: 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) _pendingType = type; _pendingUntil = Time.unscaledTime + ClearThisTypeConfig.ConfirmationSeconds.Value; _pendingName = StructuresData.LocalizedName(type); _pendingCount = GetStructuresOfType(type).Count; ShowStatus("Remove all " + _pendingName + "? Press again"); } private unsafe void ClearMatchingType(TYPES type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) List<Structure> structuresOfType = GetStructuresOfType(type); int value = ClearThisTypeConfig.MaxClearCount.Value; int num = 0; int num2 = 0; int num3 = structuresOfType.Count - 1; while (num3 >= 0 && num < value) { Structure val = structuresOfType[num3]; if ((Object)(object)val != (Object)null && val.Brain != null && val.Brain.Data != null) { TYPES toBuildType = val.Brain.Data.ToBuildType; if (RemoveStructureCleanly(val)) { num++; num2 += RefundBuildSiteMaterials(type, toBuildType); } } num3--; } Log.LogInfo((object)("Cleared " + num + " structure(s) of type " + ((object)(*(TYPES*)(&type))/*cast due to .constrained prefix*/).ToString() + ".")); ShowStatus((num2 > 0) ? ("Cleared " + num + "x " + ((object)(*(TYPES*)(&type))/*cast due to .constrained prefix*/).ToString() + " and refunded " + num2 + " item(s)") : ("Cleared " + num + "x " + ((object)(*(TYPES*)(&type))/*cast due to .constrained prefix*/).ToString())); ClearPending(); } private static int RefundBuildSiteMaterials(TYPES type, TYPES toBuildType) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_001e: 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_0042: Unknown result type (might be due to invalid IL or missing references) if (!ClearThisTypeConfig.RefundBuildSiteMaterials.Value || ((int)type != 31 && (int)type != 118)) { return 0; } List<ItemCost> cost = StructuresData.GetCost(((int)toBuildType != 0) ? toBuildType : type); if (cost == null) { return 0; } int num = 0; for (int i = 0; i < cost.Count; i++) { ItemCost val = cost[i]; if (val.CostValue > 0) { Inventory.AddItem(val.CostItem, val.CostValue, true); num += val.CostValue; } } return num; } private void LateUpdate() { UpdateVanillaPrompt(); } private void OnGUI() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) if (ClearThisTypeConfig.ShowConfirmationOverlay.Value && ClearThisTypeConfig.Enabled.Value && HasPendingConfirmation() && IsActiveBuildPlacement()) { EnsureStyles(); float num = Mathf.Min(540f, (float)Screen.width - 48f); float num2 = 168f; Rect val = default(Rect); ((Rect)(ref val))..ctor(((float)Screen.width - num) * 0.5f, Mathf.Max(56f, (float)Screen.height * 0.18f), num, num2); GUI.Box(val, GUIContent.none, _boxStyle); GUI.Label(new Rect(((Rect)(ref val)).x + 24f, ((Rect)(ref val)).y + 18f, ((Rect)(ref val)).width - 48f, 34f), "Remove all " + _pendingName + "?", _titleStyle); string text = "This will remove " + _pendingCount + " matching structure" + ((_pendingCount == 1) ? "" : "s") + " from the cult. Press " + ClearThisTypeConfig.ClearKey.Value + " again or use Confirm. Controller: Accept to confirm, Back to cancel."; GUI.Label(new Rect(((Rect)(ref val)).x + 24f, ((Rect)(ref val)).y + 58f, ((Rect)(ref val)).width - 48f, 44f), text, _bodyStyle); Rect val2 = new Rect(((Rect)(ref val)).x + ((Rect)(ref val)).width - 248f, ((Rect)(ref val)).y + ((Rect)(ref val)).height - 48f, 104f, 30f); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(((Rect)(ref val)).x + ((Rect)(ref val)).width - 132f, ((Rect)(ref val)).y + ((Rect)(ref val)).height - 48f, 84f, 30f); if (GUI.Button(val2, "Confirm", _confirmStyle)) { ClearMatchingType(_pendingType); } if (GUI.Button(val3, "Cancel", _cancelStyle)) { ClearPending(); ShowStatus("Remove all cancelled"); } } } private void UpdateVanillaPrompt() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (!ClearThisTypeConfig.ShowPrompt.Value || !ClearThisTypeConfig.Enabled.Value || (Object)(object)PlacementRegion.Instance == (Object)null || (Object)(object)PlacementObject.Instance == (Object)null || (Object)(object)PlayerFarming.Instance == (Object)null || (Object)(object)PlayerFarming.Instance.indicator == (Object)null || !IsActiveBuildPlacement()) { return; } Structure val = PlacementRegion.Instance.GetHoveredStructure(); if ((Object)(object)val == (Object)null) { val = GetNearestStructureAtPlacement(PlacementRegion.Instance.PlacementPosition, ClearThisTypeConfig.TargetRadius.Value); } if (!((Object)(object)val == (Object)null) || !(Time.unscaledTime >= _statusUntil)) { string text = (((int)_pendingType != 0 && Time.unscaledTime <= _pendingUntil) ? "Confirm Remove All" : "Remove All"); Indicator indicator = PlayerFarming.Instance.indicator; indicator.HasThirdInteraction = true; indicator.ThirdInteractable = true; if (ClearThisTypeConfig.UseVanillaPromptSlot.Value) { indicator.thirdControlPrompt.Category = 0; indicator.thirdControlPrompt.Action = 67; } string text2 = (((Object)(object)indicator.Thirdtext != (Object)null) ? ((TMP_Text)indicator.Thirdtext).text : string.Empty); string text3 = ((Time.unscaledTime < _statusUntil && !string.IsNullOrEmpty(_statusText)) ? _statusText : text); ((TMP_Text)indicator.Thirdtext).text = (ShouldReplacePrompt(text2) ? text3 : text2); indicator.Reset(); } } private void ClearVanillaPrompt() { if ((Object)(object)PlayerFarming.Instance != (Object)null && (Object)(object)PlayerFarming.Instance.indicator != (Object)null && (Object)(object)PlayerFarming.Instance.indicator.Fourthtext != (Object)null) { ((TMP_Text)PlayerFarming.Instance.indicator.Fourthtext).text = ""; PlayerFarming.Instance.indicator.HasFourthInteraction = false; } } private void ShowStatus(string text) { _statusText = text; _statusUntil = Time.unscaledTime + 2f; } private bool HasPendingConfirmation() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)_pendingType != 0) { return Time.unscaledTime <= _pendingUntil; } return false; } private void ClearPending() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) _pendingType = (TYPES)0; _pendingUntil = 0f; _pendingName = ""; _pendingCount = 0; } private void EnsureStyles() { //IL_001e: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00ae: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Expected O, but got Unknown if (_boxStyle == null) { _boxBackground = MakeTexture(new Color(0.02f, 0.015f, 0.012f, 0.92f)); _confirmBackground = MakeTexture(new Color(0.66f, 0.08f, 0.06f, 0.94f)); _cancelBackground = MakeTexture(new Color(0.16f, 0.14f, 0.12f, 0.94f)); GUIStyle val = new GUIStyle(GUI.skin.box); val.normal.background = _boxBackground; val.padding = new RectOffset(18, 18, 18, 18); _boxStyle = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 24, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; val2.normal.textColor = new Color(1f, 0.91f, 0.34f, 1f); _titleStyle = val2; GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = 16, wordWrap = true, alignment = (TextAnchor)0 }; val3.normal.textColor = Color.white; _bodyStyle = val3; GUIStyle val4 = new GUIStyle(GUI.skin.button) { fontSize = 16, fontStyle = (FontStyle)1 }; val4.normal.background = _confirmBackground; val4.normal.textColor = Color.white; val4.hover.background = _confirmBackground; val4.hover.textColor = Color.white; val4.active.background = _confirmBackground; val4.active.textColor = Color.white; _confirmStyle = val4; GUIStyle val5 = new GUIStyle(GUI.skin.button) { fontSize = 16, fontStyle = (FontStyle)1 }; val5.normal.background = _cancelBackground; val5.normal.textColor = Color.white; val5.hover.background = _cancelBackground; val5.hover.textColor = Color.white; val5.active.background = _cancelBackground; val5.active.textColor = Color.white; _cancelStyle = val5; } } private static Texture2D MakeTexture(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0017: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, color); val.Apply(); return val; } private static void DestroyTexture(ref Texture2D texture) { if (!((Object)(object)texture == (Object)null)) { Object.Destroy((Object)(object)texture); texture = null; } } private static Structure GetNearestStructureAtPlacement(Vector3 position, float radius) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Structure result = null; float num = radius; foreach (Structure structure in Structure.Structures) { if (!((Object)(object)structure == (Object)null) && structure.Brain != null && structure.Brain.Data != null) { float num2 = Vector3.Distance(position, ((Component)structure).transform.position); if (num2 <= num) { result = structure; num = num2; } } } return result; } private static List<Structure> GetStructuresOfType(TYPES type) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) List<Structure> list = new List<Structure>(); Structure[] array = Structure.Structures.ToArray(); foreach (Structure val in array) { if ((Object)(object)val != (Object)null && val.Brain != null && val.Brain.Data != null && val.Brain.Data.Type == type) { list.Add(val); } } return list; } private static bool RemoveStructureCleanly(Structure structure) { if ((Object)(object)structure == (Object)null || structure.Brain == null || structure.Brain.Data == null) { return false; } try { if ((Object)(object)PlacementRegion.Instance != (Object)null) { PlacementRegion.Instance.DestroyBuilding(structure); } else { structure.RemoveStructure(); Object.Destroy((Object)(object)((Component)structure).gameObject); } return true; } catch (Exception ex) { Log.LogWarning((object)("Clean removal failed for " + ((object)Unsafe.As<TYPES, TYPES>(ref structure.Type)/*cast due to .constrained prefix*/).ToString() + ": " + ex.Message)); return false; } } private unsafe static bool IsCritical(TYPES type) { string text = ((object)(*(TYPES*)(&type))/*cast due to .constrained prefix*/).ToString(); if (!text.Contains("TEMPLE") && !text.Contains("SHRINE") && !text.Contains("ALTAR")) { return text.Contains("BUILDER"); } return true; } private static bool IsActiveBuildPlacement() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 if ((Object)(object)PlacementObject.Instance == (Object)null || (Object)(object)PlacementRegion.Instance == (Object)null || (int)PlacementRegion.Instance.CurrentMode == 0) { return false; } Mode currentMode = PlacementRegion.Instance.CurrentMode; if ((int)currentMode != 1 && (int)currentMode != 5) { return (int)currentMode == 3; } return true; } private static bool ShouldReplacePrompt(string existing) { if (!string.IsNullOrEmpty(existing) && !existing.Contains("Clear this type") && !existing.Contains("Remove All") && !existing.Contains("Remove all ") && !existing.StartsWith("Cleared ") && !(existing == "Protected structure type") && !(existing == "No matching structure under cursor")) { return existing == "Remove all cancelled"; } return true; } private static KeyCode ParseKey(string raw, KeyCode fallback) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references) try { return (KeyCode)Enum.Parse(typeof(KeyCode), raw, ignoreCase: true); } catch { return fallback; } } } internal static class ClearThisTypeConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<string> ClearKey; internal static ConfigEntry<string> ControllerConfirmKey; internal static ConfigEntry<string> ControllerCancelKey; internal static ConfigEntry<int> MaxClearCount; internal static ConfigEntry<bool> AllowCriticalStructures; internal static ConfigEntry<float> TargetRadius; internal static ConfigEntry<bool> ShowPrompt; internal static ConfigEntry<bool> EnableVanillaClearButton; internal static ConfigEntry<bool> UseVanillaPromptSlot; internal static ConfigEntry<bool> ShowConfirmationOverlay; internal static ConfigEntry<bool> RequireConfirmation; internal static ConfigEntry<float> ConfirmationSeconds; internal static ConfigEntry<bool> RefundBuildSiteMaterials; internal static void Bind(ConfigFile config) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Clear This Type."); ClearKey = config.Bind<string>("Controls", "ClearKey", "F8", "KeyCode used to clear all structures matching the hovered structure type."); ControllerConfirmKey = config.Bind<string>("Controls", "ControllerConfirmKey", "JoystickButton0", "Fallback controller KeyCode used to confirm the custom Remove All prompt. JoystickButton0 is normally A/Cross."); ControllerCancelKey = config.Bind<string>("Controls", "ControllerCancelKey", "JoystickButton1", "Fallback controller KeyCode used to cancel the custom Remove All prompt. JoystickButton1 is normally B/Circle."); EnableVanillaClearButton = config.Bind<bool>("Controls", "EnableVanillaClearButton", true, "Also trigger Clear This Type from the vanilla third interaction button while actively placing/editing."); MaxClearCount = config.Bind<int>("Safety", "MaxClearCount", 250, new ConfigDescription("Maximum structures removed by one clear action.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), Array.Empty<object>())); AllowCriticalStructures = config.Bind<bool>("Safety", "AllowCriticalStructures", false, "Allow clearing temple/shrine/altar/builder style critical structures."); TargetRadius = config.Bind<float>("Targeting", "TargetRadius", 1.25f, new ConfigDescription("Fallback radius around the build cursor when vanilla hover targeting returns nothing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>())); ShowPrompt = config.Bind<bool>("UI", "ShowPrompt", true, "Show a small build-mode prompt for Clear This Type."); UseVanillaPromptSlot = config.Bind<bool>("UI", "UseVanillaPromptSlot", true, "Use the vanilla third interaction prompt slot/glyph for Clear This Type."); ShowConfirmationOverlay = config.Bind<bool>("UI", "ShowConfirmationOverlay", true, "Show a centered confirmation prompt before removing every matching structure."); RequireConfirmation = config.Bind<bool>("Safety", "RequireConfirmation", true, "Require pressing Clear Type twice before removing every matching structure."); ConfirmationSeconds = config.Bind<float>("Safety", "ConfirmationSeconds", 3f, new ConfigDescription("Seconds the remove-all confirmation remains active.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); RefundBuildSiteMaterials = config.Bind<bool>("Safety", "RefundBuildSiteMaterials", true, "Refund the full normal cost directly to inventory when Remove All clears unfinished build sites."); } } }
plugins/BetterBuilderTools/DragPlaceStructures.dll
Decompiled 2 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using src.UINavigator; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Drag Place Structures")] [assembly: AssemblyProduct("Drag Place Structures")] [assembly: ComVisible(false)] [assembly: Guid("abefcbd5-7fec-41fa-8ba5-b14640519f34")] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyVersion("0.1.1.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 DragPlaceStructures { [BepInPlugin("com.cotl.betterbuildertools.dragplacestructures", "Drag Place Structures", "0.1.4")] public sealed class DragPlaceStructuresPlugin : BaseUnityPlugin { public const string PluginGuid = "com.cotl.betterbuildertools.dragplacestructures"; public const string PluginName = "Drag Place Structures"; public const string PluginVersion = "0.1.4"; private Harmony _harmony; private KeyCode _modifierKey; private KeyCode _repeatKey; private float _lastPlaceTime; private Vector2Int _lastPlaceGrid = new Vector2Int(9999, 9999); private TYPES _lastStructureType; private Mode _lastMode; private int _lastCustomBuildFrame = -1; private bool _invokingBuild; private static readonly MethodInfo BuildMethod = AccessTools.Method(typeof(PlacementRegion), "Build", (Type[])null, (Type[])null); internal static ManualLogSource Log { get; private set; } internal static DragPlaceStructuresPlugin Instance { get; private set; } private void Awake() { //IL_002c: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; DragPlaceStructuresConfig.Bind(((BaseUnityPlugin)this).Config); _modifierKey = ParseKey(DragPlaceStructuresConfig.ModifierKey.Value, (KeyCode)304); _repeatKey = ParseKey(DragPlaceStructuresConfig.RepeatKey.Value, (KeyCode)323); _harmony = new Harmony("com.cotl.betterbuildertools.dragplacestructures"); _harmony.PatchAll(typeof(DragPlaceStructuresPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Drag Place Structures 0.1.4 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; Instance = null; } private void Update() { TryDragPlace(PlacementRegion.Instance); } internal void TryDragPlace(PlacementRegion region) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) if (!DragPlaceStructuresConfig.Enabled.Value || (Object)(object)region == (Object)null || (Object)(object)PlacementObject.Instance == (Object)null) { ResetPlacementSession(); return; } if ((int)region.CurrentMode != 5 && (int)region.CurrentMode != 1) { ResetPlacementSession(); return; } if (region.StructureType != _lastStructureType || region.CurrentMode != _lastMode) { _lastPlaceGrid = new Vector2Int(9999, 9999); _lastPlaceTime = -1f; _lastStructureType = region.StructureType; _lastMode = region.CurrentMode; } if ((DragPlaceStructuresConfig.RequireModifier.Value && !Input.GetKey(_modifierKey)) || !IsRepeatHeld() || Time.unscaledTime - _lastPlaceTime < DragPlaceStructuresConfig.PlaceInterval.Value) { return; } TYPES structureType = region.StructureType; if (!DragPlaceStructuresConfig.AllowPathsToo.Value && StructureBrain.IsPath(structureType)) { return; } TileGridTile gridTile = GetGridTile(region); if (gridTile != null && !(Vector2Int.Distance(gridTile.Position, _lastPlaceGrid) < DragPlaceStructuresConfig.MinDistance.Value)) { Vector2Int bounds = (((Object)(object)PlacementObject.Instance != (Object)null) ? PlacementObject.Instance.Bounds : Vector2Int.one); if (CanPlaceBounds(region, gridTile.Position, bounds) && InvokeVanillaBuild(region, structureType, gridTile, bounds)) { _lastPlaceGrid = gridTile.Position; _lastPlaceTime = Time.unscaledTime; } } } private void ResetPlacementSession() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) _lastPlaceGrid = new Vector2Int(9999, 9999); _lastPlaceTime = -1f; _lastStructureType = (TYPES)0; _lastMode = (Mode)0; _lastCustomBuildFrame = -1; } private bool IsRepeatHeld() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) if ((int)_repeatKey == 323 && Input.GetMouseButton(0)) { return true; } if (Input.GetKey(_repeatKey)) { return true; } try { return InputManager.Gameplay.GetPlaceMoveUpgradeButtonHeld(MonoSingleton<UINavigatorNew>.Instance.AllowInputOnlyFromPlayer); } catch { return false; } } private static TileGridTile GetGridTile(PlacementRegion region) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) try { return region.GetClosestTileGridTileAtWorldPosition(region.PlacementPosition); } catch { return null; } } private static bool CanPlaceBounds(PlacementRegion region, Vector2Int origin, Vector2Int bounds) { //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_0011: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < ((Vector2Int)(ref bounds)).x; i++) { for (int j = 0; j < ((Vector2Int)(ref bounds)).y; j++) { TileGridTile tileGridTile = region.GetTileGridTile(origin + new Vector2Int(i, j)); if (tileGridTile == null || !tileGridTile.CanPlaceStructure) { return false; } } } return true; } private bool InvokeVanillaBuild(PlacementRegion region, TYPES type, TileGridTile tile, Vector2Int bounds) { //IL_0033: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) try { _invokingBuild = true; if (BuildMethod == null) { region.PlaceStructureAtWorldPosition(type, tile.WorldPosition, bounds); } else { BuildMethod.Invoke(region, new object[6] { type, tile.WorldPosition, tile.Position, bounds, false, false }); } } catch (Exception ex) { Log.LogWarning((object)("Drag placement build failed: " + ex.GetBaseException().Message)); RepairFailedTile(tile); return false; } finally { _invokingBuild = false; } _lastCustomBuildFrame = Time.frameCount; if (tile == null || tile.ObjectID < 0 || (int)tile.ObjectOnTile == 0) { RepairFailedTile(tile); Log.LogWarning((object)"Drag placement did not commit a structure; restored the touched grid tile."); return false; } return true; } private static void RepairFailedTile(TileGridTile tile) { if (tile != null && tile.ObjectID < 0) { tile.Occupied = false; tile.Obstructed = false; tile.ReservedForWaste = false; tile.IsUpgrade = false; tile.Collapsed = false; } } internal bool ShouldSuppressNativeBuild() { if (!_invokingBuild) { return _lastCustomBuildFrame == Time.frameCount; } return false; } private static KeyCode ParseKey(string raw, KeyCode fallback) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references) try { return (KeyCode)Enum.Parse(typeof(KeyCode), raw, ignoreCase: true); } catch { return fallback; } } } [HarmonyPatch(typeof(PlacementRegion), "Build")] internal static class PlacementRegionBuildPatch { private static bool Prefix() { if (!((Object)(object)DragPlaceStructuresPlugin.Instance == (Object)null)) { return !DragPlaceStructuresPlugin.Instance.ShouldSuppressNativeBuild(); } return true; } } internal static class DragPlaceStructuresConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> RequireModifier; internal static ConfigEntry<string> ModifierKey; internal static ConfigEntry<string> RepeatKey; internal static ConfigEntry<float> PlaceInterval; internal static ConfigEntry<float> MinDistance; internal static ConfigEntry<bool> AllowPathsToo; internal static void Bind(ConfigFile config) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Drag Place Structures."); RequireModifier = config.Bind<bool>("Controls", "RequireModifier", false, "Require a modifier while dragging to place repeated structures."); ModifierKey = config.Bind<string>("Controls", "ModifierKey", "LeftShift", "KeyCode held while dragging to place repeated structures."); RepeatKey = config.Bind<string>("Controls", "RepeatKey", "Mouse0", "KeyCode held to place repeated structures. For controller confirm, try JoystickButton0."); PlaceInterval = config.Bind<float>("Behavior", "PlaceInterval", 0.16f, new ConfigDescription("Minimum seconds between drag placements. Matches Path Brush Plus by default.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>())); MinDistance = config.Bind<float>("Behavior", "MinDistance", 0.75f, new ConfigDescription("Minimum world distance from the last drag placement.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); AllowPathsToo = config.Bind<bool>("Behavior", "AllowPathsToo", false, "Also run for path types. Usually Path Brush Plus should handle paths instead."); } } }
plugins/BetterBuilderTools/PathBrushPlus.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MMTools; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using src.UINavigator; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Path Brush Plus")] [assembly: AssemblyProduct("Path Brush Plus")] [assembly: ComVisible(false)] [assembly: Guid("4e4da601-492e-4c50-bf01-530cf2e1ff4d")] [assembly: AssemblyFileVersion("0.1.6.0")] [assembly: AssemblyVersion("0.1.6.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 PathBrushPlus { [BepInPlugin("com.cotl.betterbuildertools.pathbrushplus", "Path Brush Plus", "0.1.6")] public sealed class PathBrushPlusPlugin : BaseUnityPlugin { public const string PluginGuid = "com.cotl.betterbuildertools.pathbrushplus"; public const string PluginName = "Path Brush Plus"; public const string PluginVersion = "0.1.6"; private Harmony _harmony; private float _lastBrushTime; private KeyCode _cycleModeKey; private KeyCode _controllerCycleModeKey; private BrushMode _currentMode; private string _statusText; private float _statusUntil; private readonly HashSet<Vector2Int> _paintedThisHold = new HashSet<Vector2Int>(); private readonly List<GameObject> _previewObjects = new List<GameObject>(); private GameObject _promptRowObject; private GameObject _promptCellObject; private MMControlPrompt _promptControlPrompt; private TMP_Text _promptText; private bool? _promptWasController; private static readonly MethodInfo BuildMethod = AccessTools.Method(typeof(PlacementRegion), "Build", (Type[])null, (Type[])null); internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; PathBrushPlusConfig.Bind(((BaseUnityPlugin)this).Config); _currentMode = ParseMode(PathBrushPlusConfig.DefaultMode.Value, BrushMode.ThreeByThree); _cycleModeKey = ParseKey(PathBrushPlusConfig.CycleModeKey.Value, (KeyCode)118); _controllerCycleModeKey = ParseKey(PathBrushPlusConfig.ControllerCycleModeKey.Value, (KeyCode)338); _harmony = new Harmony("com.cotl.betterbuildertools.pathbrushplus"); _harmony.PatchAll(typeof(PathBrushPlusPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Path Brush Plus 0.1.6 loaded."); } private void OnDestroy() { ClearPreview(); DestroyPromptUi(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; } private void Update() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) if (!PathBrushPlusConfig.Enabled.Value || (Object)(object)PlacementRegion.Instance == (Object)null || (Object)(object)PlacementObject.Instance == (Object)null) { _paintedThisHold.Clear(); ClearPreview(); return; } PlacementRegion instance = PlacementRegion.Instance; if (IsPathPlacement(instance)) { HandleModeToggle(); } if ((int)instance.CurrentMode != 5 && (int)instance.CurrentMode != 1) { _paintedThisHold.Clear(); return; } TYPES structureType = instance.StructureType; if (PathBrushPlusConfig.PathsOnly.Value && !StructureBrain.IsPath(structureType)) { _paintedThisHold.Clear(); return; } if (_currentMode == BrushMode.Vanilla) { _paintedThisHold.Clear(); return; } bool flag = IsPlaceHeld(); bool flag2 = IsRemoveHeld(); if (!flag && !flag2) { _paintedThisHold.Clear(); } else if (!(Time.unscaledTime - _lastBrushTime < PathBrushPlusConfig.BrushInterval.Value)) { _lastBrushTime = Time.unscaledTime; ApplyBrush(instance, structureType, flag, flag2); } } private void LateUpdate() { UpdatePreview(); UpdatePrompt(); } private void ApplyBrush(PlacementRegion region, TYPES type, bool placeHeld, bool removeHeld) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) List<Vector2Int> brushOffsets = GetBrushOffsets(); if (brushOffsets.Count == 0) { return; } TileGridTile centerTile = GetCenterTile(region); if (centerTile == null) { return; } for (int i = 0; i < brushOffsets.Count; i++) { Vector2Int val = brushOffsets[i]; if (val == Vector2Int.zero) { continue; } TileGridTile tileGridTile = region.GetTileGridTile(centerTile.Position + val); if (tileGridTile != null) { if (removeHeld) { PathTileManager.Instance.DeleteTile(tileGridTile.WorldPosition); _paintedThisHold.Remove(tileGridTile.Position); } else if (placeHeld && !_paintedThisHold.Contains(tileGridTile.Position)) { BuildPath(region, type, tileGridTile); _paintedThisHold.Add(tileGridTile.Position); } } } } private static TileGridTile GetCenterTile(PlacementRegion region) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) try { return region.GetClosestTileGridTileAtWorldPosition(region.PlacementPosition); } catch { return null; } } private static void BuildPath(PlacementRegion region, TYPES type, TileGridTile tile) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0025: 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_0040: Unknown result type (might be due to invalid IL or missing references) if (BuildMethod != null) { BuildMethod.Invoke(region, new object[6] { type, tile.WorldPosition, tile.Position, Vector2Int.one, true, false }); } else { PathTileManager.Instance.DeleteTile(tile.WorldPosition); PathTileManager.Instance.DisplayTile(type, tile.WorldPosition); PathTileManager.Instance.SetTile(type, tile.WorldPosition); } } private static bool IsPlaceHeld() { try { return InputManager.Gameplay.GetPlaceMoveUpgradeButtonHeld(MonoSingleton<UINavigatorNew>.Instance.AllowInputOnlyFromPlayer); } catch { return Input.GetMouseButton(0); } } private static bool IsRemoveHeld() { try { return InputManager.Gameplay.GetRemoveFlipButtonHeld(MonoSingleton<UINavigatorNew>.Instance.AllowInputOnlyFromPlayer); } catch { return Input.GetMouseButton(1); } } private void UpdatePreview() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) if (!PathBrushPlusConfig.ShowBrushPreview.Value || !PathBrushPlusConfig.Enabled.Value || (Object)(object)PlacementRegion.Instance == (Object)null || (Object)(object)PlacementObject.Instance == (Object)null || _currentMode == BrushMode.Vanilla) { ClearPreview(); return; } PlacementRegion instance = PlacementRegion.Instance; if (PathBrushPlusConfig.PathsOnly.Value && !StructureBrain.IsPath(instance.StructureType)) { ClearPreview(); return; } TileGridTile centerTile = GetCenterTile(instance); List<Vector2Int> brushOffsets = GetBrushOffsets(includeCenter: true); if (centerTile == null || brushOffsets.Count == 0 || (Object)(object)instance.PlacementSquare == (Object)null) { ClearPreview(); return; } EnsurePreviewCount(instance, brushOffsets.Count); int num = 0; for (int i = 0; i < brushOffsets.Count; i++) { Vector2Int val = brushOffsets[i]; TileGridTile tileGridTile = instance.GetTileGridTile(centerTile.Position + val); GameObject val2 = _previewObjects[num++]; if (tileGridTile == null) { val2.SetActive(false); continue; } val2.SetActive(true); val2.transform.SetParent(((Component)instance).transform, false); val2.transform.localPosition = new Vector3((float)((Vector2Int)(ref tileGridTile.Position)).x, (float)((Vector2Int)(ref tileGridTile.Position)).y, -0.05f); ApplyPreviewColor(val2, val == Vector2Int.zero); } for (int j = num; j < _previewObjects.Count; j++) { _previewObjects[j].SetActive(false); } } private void EnsurePreviewCount(PlacementRegion region, int needed) { while (_previewObjects.Count < needed) { GameObject val = Object.Instantiate<GameObject>(region.PlacementSquare, ((Component)region).transform); ((Object)val).name = "PathBrushPlusPreview"; Collider2D[] componentsInChildren = val.GetComponentsInChildren<Collider2D>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } _previewObjects.Add(val); } } private static void ApplyPreviewColor(GameObject preview, bool center) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) SpriteRenderer[] componentsInChildren = preview.GetComponentsInChildren<SpriteRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].color = (center ? new Color(0.1f, 1f, 0.1f, 0.9f) : new Color(0.1f, 0.85f, 1f, 0.55f)); } } private void ClearPreview() { for (int i = 0; i < _previewObjects.Count; i++) { if ((Object)(object)_previewObjects[i] != (Object)null) { Object.Destroy((Object)(object)_previewObjects[i]); } } _previewObjects.Clear(); } private void HandleModeToggle() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(_cycleModeKey) || (PathBrushPlusConfig.EnableControllerModeCycle.Value && Input.GetKeyDown(_controllerCycleModeKey))) { _currentMode = NextMode(_currentMode); _paintedThisHold.Clear(); ClearPreview(); ShowStatus("Path brush: " + ModeLabel(_currentMode)); } } private void UpdatePrompt() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (!PathBrushPlusConfig.ShowModePrompt.Value || !PathBrushPlusConfig.Enabled.Value || (Object)(object)PlacementRegion.Instance == (Object)null || (Object)(object)PlacementObject.Instance == (Object)null || (Object)(object)PlayerFarming.Instance == (Object)null || (Object)(object)PlayerFarming.Instance.indicator == (Object)null) { HidePrompt(); return; } PlacementRegion instance = PlacementRegion.Instance; if (!IsPathPlacement(instance) || (PathBrushPlusConfig.PathsOnly.Value && !StructureBrain.IsPath(instance.StructureType))) { HidePrompt(); } else if (EnsurePrompt(PlayerFarming.Instance.indicator)) { string text = ((Time.unscaledTime < _statusUntil && !string.IsNullOrEmpty(_statusText)) ? _statusText : ("Brush: " + ModeLabel(_currentMode))); bool flag = IsControllerInput(); _promptControlPrompt.playerFarming = PlayerFarming.Instance; _promptControlPrompt.PrioritizeMouse = false; _promptText.text = text; _promptCellObject.SetActive(true); SizePromptRow(_promptRowObject); _promptRowObject.SetActive(true); if (_promptWasController != flag) { _promptWasController = flag; RefreshPromptGlyph(flag); } } } private bool EnsurePrompt(Indicator indicator) { if ((Object)(object)_promptCellObject != (Object)null && (Object)(object)_promptControlPrompt != (Object)null && (Object)(object)_promptText != (Object)null) { return true; } if ((Object)(object)indicator == (Object)null || (Object)(object)indicator.FourthControlPrompt == (Object)null || (Object)(object)((Transform)indicator.FourthControlPrompt).parent == (Object)null || (Object)(object)indicator.Fourthtext == (Object)null) { return false; } EnsurePromptRow(indicator); if ((Object)(object)_promptRowObject == (Object)null) { return false; } CreatePromptCell(indicator); if ((Object)(object)_promptControlPrompt == (Object)null || (Object)(object)_promptText == (Object)null) { DestroyPromptUi(); return false; } _promptWasController = null; return true; } private void EnsurePromptRow(Indicator indicator) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown Transform promptParent = GetPromptParent(indicator); if (!((Object)(object)promptParent == (Object)null)) { Transform val = promptParent.Find("RemoteBuildCancel_BuilderToolsPromptRow"); if ((Object)(object)val != (Object)null) { ConfigurePromptRow(((Component)val).gameObject); AddVanillaPromptBackground(((Component)val).gameObject, indicator); _promptRowObject = ((Component)val).gameObject; _promptRowObject.SetActive(true); } else { GameObject val2 = new GameObject("RemoteBuildCancel_BuilderToolsPromptRow"); ((Transform)val2.AddComponent<RectTransform>()).SetParent(promptParent, false); ConfigurePromptRow(val2); AddVanillaPromptBackground(val2, indicator); val2.transform.SetAsLastSibling(); _promptRowObject = val2; } } } private static void ConfigurePromptRow(GameObject row) { //IL_001b: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown RectTransform obj = row.GetComponent<RectTransform>() ?? row.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0.5f, 0f); obj.anchorMax = new Vector2(0.5f, 0f); obj.pivot = new Vector2(0f, 0f); obj.anchoredPosition = new Vector2(240f, 112f); obj.sizeDelta = new Vector2(0f, 52f); LayoutElement obj2 = row.GetComponent<LayoutElement>() ?? row.AddComponent<LayoutElement>(); obj2.minWidth = 0f; obj2.preferredWidth = 0f; obj2.flexibleWidth = 0f; obj2.minHeight = 52f; obj2.preferredHeight = 52f; obj2.flexibleHeight = 0f; ContentSizeFitter obj3 = row.GetComponent<ContentSizeFitter>() ?? row.AddComponent<ContentSizeFitter>(); obj3.horizontalFit = (FitMode)2; obj3.verticalFit = (FitMode)0; ((Behaviour)obj3).enabled = false; HorizontalLayoutGroup obj4 = row.GetComponent<HorizontalLayoutGroup>() ?? row.AddComponent<HorizontalLayoutGroup>(); ((LayoutGroup)obj4).padding = new RectOffset(18, 18, 5, 5); ((HorizontalOrVerticalLayoutGroup)obj4).spacing = 18f; ((LayoutGroup)obj4).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = true; } private static void SizePromptRow(GameObject row) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)row == (Object)null) { return; } RectTransform component = row.GetComponent<RectTransform>(); HorizontalLayoutGroup component2 = row.GetComponent<HorizontalLayoutGroup>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { return; } float num = ((LayoutGroup)component2).padding.left + ((LayoutGroup)component2).padding.right; int num2 = 0; for (int i = 0; i < row.transform.childCount; i++) { GameObject gameObject = ((Component)row.transform.GetChild(i)).gameObject; if (!gameObject.activeSelf || ((Object)gameObject).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) >= 0) { continue; } LayoutElement component3 = gameObject.GetComponent<LayoutElement>(); float num3 = (((Object)(object)component3 != (Object)null) ? Mathf.Max(component3.minWidth, component3.preferredWidth) : 0f); if (num3 <= 0f) { RectTransform component4 = gameObject.GetComponent<RectTransform>(); float num4; if (!((Object)(object)component4 != (Object)null)) { num4 = 0f; } else { Rect rect = component4.rect; num4 = ((Rect)(ref rect)).width; } num3 = num4; } if (num3 <= 0f) { num3 = 40f; } if (num2 > 0) { num += ((HorizontalOrVerticalLayoutGroup)component2).spacing; } num += num3; num2++; } num = Mathf.Max(num, 1f); component.SetSizeWithCurrentAnchors((Axis)0, num); component.SetSizeWithCurrentAnchors((Axis)1, 52f); LayoutElement component5 = row.GetComponent<LayoutElement>(); if ((Object)(object)component5 != (Object)null) { component5.minWidth = num; component5.preferredWidth = num; } } private static Transform GetPromptParent(Indicator indicator) { Transform val = (((Object)(object)indicator != (Object)null && (Object)(object)indicator.ControlPromptUI != (Object)null) ? indicator.ControlPromptUI.transform : (((Object)(object)indicator != (Object)null) ? ((Component)indicator).transform : null)); if ((Object)(object)val == (Object)null) { return null; } Canvas val2 = ((Component)val).GetComponent<Canvas>() ?? ((Component)val).GetComponentInParent<Canvas>(); if (!((Object)(object)val2 != (Object)null)) { if (!((Object)(object)val.parent != (Object)null)) { return val; } return val.parent; } return ((Component)val2).transform; } private static void AddVanillaPromptBackground(GameObject row, Indicator indicator) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Image val = (((Object)(object)indicator != (Object)null && (Object)(object)indicator.BG != (Object)null) ? (((Component)indicator.BG).GetComponent<Image>() ?? ((Component)indicator.BG).GetComponentInChildren<Image>(true)) : null); Image val2 = row.GetComponent<Image>() ?? row.AddComponent<Image>(); ((Behaviour)val2).enabled = true; ((Graphic)val2).raycastTarget = false; val2.sprite = (((Object)(object)val != (Object)null) ? val.sprite : null); val2.type = (Type)(((Object)(object)val != (Object)null) ? ((int)val.type) : 0); if ((Object)(object)val2.sprite == (Object)null) { val2.sprite = Sprite.Create(Texture2D.whiteTexture, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); val2.type = (Type)0; } ((Graphic)val2).color = new Color(0f, 0f, 0f, 0.88f); ((Graphic)val2).canvasRenderer.SetColor(((Graphic)val2).color); for (int i = 0; i < row.transform.childCount; i++) { Transform child = row.transform.GetChild(i); if (((Object)child).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) >= 0) { ((Component)child).gameObject.SetActive(false); } } } private void CreatePromptCell(Indicator indicator) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("PathBrushPlus_ModeCell"); ((Transform)val.AddComponent<RectTransform>()).SetParent(_promptRowObject.transform, false); LayoutElement obj = val.AddComponent<LayoutElement>(); obj.preferredWidth = 150f; obj.minWidth = 150f; HorizontalLayoutGroup obj2 = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f; ((LayoutGroup)obj2).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true; GameObject val2 = Object.Instantiate<GameObject>(((Component)indicator.FourthControlPrompt).gameObject, val.transform, false); ((Object)val2).name = "PathBrushPlus_ModeKey"; val2.SetActive(true); val2.transform.localScale = Vector3.one; _promptControlPrompt = val2.GetComponent<MMControlPrompt>() ?? val2.GetComponentInChildren<MMControlPrompt>(true); LayoutElement obj3 = val2.GetComponent<LayoutElement>() ?? val2.AddComponent<LayoutElement>(); obj3.preferredWidth = 50f; obj3.minWidth = 42f; obj3.preferredHeight = 40f; TMP_Text val3 = (TMP_Text)(object)Object.Instantiate<TextMeshProUGUI>(indicator.Fourthtext, val.transform, false); ((Object)((Component)val3).gameObject).name = "PathBrushPlus_ModeLabel"; ((Component)val3).gameObject.SetActive(true); val3.transform.localScale = Vector3.one; val3.alignment = (TextAlignmentOptions)4097; val3.enableAutoSizing = true; val3.fontSizeMin = 12f; val3.fontSizeMax = 22f; LayoutElement obj4 = ((Component)val3).GetComponent<LayoutElement>() ?? ((Component)val3).gameObject.AddComponent<LayoutElement>(); obj4.preferredWidth = 90f; obj4.minWidth = 90f; Behaviour[] components = ((Component)val3).GetComponents<Behaviour>(); foreach (Behaviour val4 in components) { if ((Object)(object)val4 != (Object)null && ((object)val4).GetType().FullName == "I2.Loc.Localize") { val4.enabled = false; } } _promptCellObject = val; _promptText = val3; } private void RefreshPromptGlyph(bool controller) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_promptControlPrompt == (Object)null)) { SetCustomPromptKey(_promptControlPrompt, controller ? ControllerButtonLabel(_controllerCycleModeKey) : PathBrushPlusConfig.CycleModeKey.Value); } } private unsafe static string ControllerButtonLabel(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_0034: Expected I4, but got Unknown return (key - 330) switch { 0 => "A", 1 => "B", 2 => "X", 3 => "Y", 4 => "LB", 5 => "RB", 6 => "Back", 7 => "Start", 8 => "LS", 9 => "RS", _ => ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString().Replace("JoystickButton", "Pad "), }; } private static void SetCustomPromptKey(MMControlPrompt prompt, string label) { prompt.IgnoreControllerChange = true; object? obj = AccessTools.Field(typeof(MMControlPrompt), "_text")?.GetValue(prompt); TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); object? obj2 = AccessTools.Field(typeof(MMControlPrompt), "_iconText")?.GetValue(prompt); TMP_Text val2 = (TMP_Text)((obj2 is TMP_Text) ? obj2 : null); object? obj3 = AccessTools.Field(typeof(MMControlPrompt), "_icon")?.GetValue(prompt); Image val3 = (Image)((obj3 is Image) ? obj3 : null); if ((Object)(object)val != (Object)null) { val.text = label; val.fontSize = 20f; val.enableAutoSizing = true; val.fontSizeMin = 8f; val.fontSizeMax = 20f; ((Component)val).gameObject.SetActive(true); } if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(false); } if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(true); } } private static bool IsControllerInput() { try { return (Object)(object)PlayerFarming.Instance != (Object)null && InputManager.General.InputIsController(PlayerFarming.Instance); } catch { return false; } } private void HidePrompt() { if ((Object)(object)_promptCellObject != (Object)null) { _promptCellObject.SetActive(false); } RefreshPromptRowVisibility(_promptRowObject); } private static void RefreshPromptRowVisibility(GameObject row) { if ((Object)(object)row == (Object)null) { return; } bool active = false; for (int i = 0; i < row.transform.childCount; i++) { GameObject gameObject = ((Component)row.transform.GetChild(i)).gameObject; if (gameObject.activeSelf && ((Object)gameObject).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) < 0) { active = true; break; } } SizePromptRow(row); row.SetActive(active); } private void DestroyPromptUi() { if ((Object)(object)_promptCellObject != (Object)null) { Object.Destroy((Object)(object)_promptCellObject); } _promptCellObject = null; _promptControlPrompt = null; _promptText = null; _promptWasController = null; _promptRowObject = null; } private static bool IsPathPlacement(PlacementRegion region) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if ((Object)(object)region != (Object)null) { if ((int)region.CurrentMode != 5) { return (int)region.CurrentMode == 1; } return true; } return false; } private List<Vector2Int> GetBrushOffsets(bool includeCenter = false) { if (_currentMode == BrushMode.Vanilla) { return new List<Vector2Int>(); } if (_currentMode == BrushMode.Fill) { return GetSquareOffsets(PathBrushPlusConfig.FillSize.Value, includeCenter); } int value = PathBrushPlusConfig.BrushRadius.Value; if (value <= 0) { return new List<Vector2Int>(); } return GetSquareOffsets(value * 2 + 1, includeCenter); } private static List<Vector2Int> GetSquareOffsets(int size, bool includeCenter) { //IL_003c: 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_002f: Unknown result type (might be due to invalid IL or missing references) List<Vector2Int> list = new List<Vector2Int>(); if (size <= 1) { return list; } int num = -(size / 2); int num2 = num + size - 1; Vector2Int val = default(Vector2Int); for (int i = num; i <= num2; i++) { for (int j = num; j <= num2; j++) { ((Vector2Int)(ref val))..ctor(i, j); if (includeCenter || !(val == Vector2Int.zero)) { list.Add(val); } } } return list; } private void ShowStatus(string text) { _statusText = text; _statusUntil = Time.unscaledTime + 1.5f; } private static BrushMode NextMode(BrushMode mode) { return mode switch { BrushMode.Vanilla => BrushMode.ThreeByThree, BrushMode.ThreeByThree => BrushMode.Fill, _ => BrushMode.Vanilla, }; } private static string ModeLabel(BrushMode mode) { switch (mode) { case BrushMode.Vanilla: return "1x1"; case BrushMode.Fill: return PathBrushPlusConfig.FillSize.Value + "x" + PathBrushPlusConfig.FillSize.Value; default: { int num = PathBrushPlusConfig.BrushRadius.Value * 2 + 1; return num + "x" + num; } } } private static BrushMode ParseMode(string raw, BrushMode fallback) { try { return (BrushMode)Enum.Parse(typeof(BrushMode), raw, ignoreCase: true); } catch { return fallback; } } private static KeyCode ParseKey(string raw, KeyCode fallback) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references) try { return (KeyCode)Enum.Parse(typeof(KeyCode), raw, ignoreCase: true); } catch { return fallback; } } } internal enum BrushMode { Vanilla, ThreeByThree, Fill } internal static class PathBrushPlusConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<string> DefaultMode; internal static ConfigEntry<string> CycleModeKey; internal static ConfigEntry<bool> EnableControllerModeCycle; internal static ConfigEntry<string> ControllerCycleModeKey; internal static ConfigEntry<int> BrushRadius; internal static ConfigEntry<int> FillSize; internal static ConfigEntry<bool> PathsOnly; internal static ConfigEntry<float> BrushInterval; internal static ConfigEntry<bool> ShowBrushPreview; internal static ConfigEntry<bool> ShowModePrompt; internal static ConfigEntry<bool> UseVanillaPromptSlot; internal static void Bind(ConfigFile config) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Path Brush Plus."); DefaultMode = config.Bind<string>("Brush", "DefaultMode", "ThreeByThree", "Starting brush mode: Vanilla, ThreeByThree, or Fill."); CycleModeKey = config.Bind<string>("Controls", "CycleModeKey", "V", "KeyCode used while placing paths to cycle Vanilla, 3x3, and Fill brush modes."); EnableControllerModeCycle = config.Bind<bool>("Controls", "EnableControllerModeCycle", true, "Enable the configured controller KeyCode for cycling path brush modes."); ControllerCycleModeKey = config.Bind<string>("Controls", "ControllerCycleModeKey", "JoystickButton8", "Controller KeyCode used while placing paths to cycle brush modes."); BrushRadius = config.Bind<int>("Brush", "BrushRadius", 1, new ConfigDescription("Extra path radius. 1 makes a 3x3 brush.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 4), Array.Empty<object>())); FillSize = config.Bind<int>("Brush", "FillSize", 10, new ConfigDescription("Square brush width/height used by Fill mode.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 20), Array.Empty<object>())); PathsOnly = config.Bind<bool>("Brush", "PathsOnly", true, "Only apply the brush to StructureBrain path types."); BrushInterval = config.Bind<float>("Brush", "BrushInterval", 0.16f, new ConfigDescription("Minimum seconds between brush applications while holding place/remove.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 0.5f), Array.Empty<object>())); ShowBrushPreview = config.Bind<bool>("UI", "ShowBrushPreview", true, "Show a separate preview overlay for the full brush area."); ShowModePrompt = config.Bind<bool>("UI", "ShowModePrompt", true, "Show the current path brush mode on the vanilla placement indicator."); UseVanillaPromptSlot = config.Bind<bool>("UI", "UseVanillaPromptSlot", false, "Use the deprecated vanilla fourth prompt slot for brush mode. This slot uses vanilla's back/cancel glyph, so leave this off unless you want the old text-only prompt behavior."); if (BrushInterval.Value < 0.16f) { BrushInterval.Value = 0.16f; } } } }
plugins/BetterBuilderTools/RemoteBuildCancel.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Lamb.UI; using MMTools; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Remote Build Cancel")] [assembly: AssemblyProduct("Remote Build Cancel")] [assembly: ComVisible(false)] [assembly: Guid("04fd6213-8fb5-4236-8792-8e002100f026")] [assembly: AssemblyFileVersion("0.1.6.0")] [assembly: AssemblyVersion("0.1.6.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 RemoteBuildCancel { [BepInPlugin("com.cotl.betterbuildertools.remotebuildcancel", "Remote Build Cancel", "0.1.9")] public sealed class RemoteBuildCancelPlugin : BaseUnityPlugin { public const string PluginGuid = "com.cotl.betterbuildertools.remotebuildcancel"; public const string PluginName = "Remote Build Cancel"; public const string PluginVersion = "0.1.9"; private Harmony _harmony; private KeyCode _cancelKey; private KeyCode _mouseCancelKey; private KeyCode _controllerCancelKey; private KeyCode _editModeKey; private int _lastBuiltId = -1; private bool _hasCachedBuildMode; private TYPES _cachedBuildType; private GameObject _cachedPlacementPrefab; private Mode _cachedBuildMode = (Mode)5; private bool _hasLastBuildSelection; private TYPES _lastBuildType; private GameObject _lastBuildPlacementPrefab; private Mode _lastBuildMode = (Mode)5; private float _preserveCachedModeUntil; private Indicator _promptOwner; private GameObject _modePromptObject; private GameObject _modePromptTextObject; private MMControlPrompt _modeControlPrompt; private TMP_Text _modePromptText; private GameObject _cancelPromptObject; private GameObject _cancelPromptTextObject; private MMControlPrompt _cancelControlPrompt; private TMP_Text _cancelPromptText; private GameObject _promptRowObject; private GameObject _modePromptCellObject; private GameObject _cancelPromptCellObject; private bool _promptCreationWarningLogged; private bool? _modePromptWasController; private bool? _cancelPromptWasController; private static readonly MethodInfo ClearPrefabsMethod = AccessTools.Method(typeof(PlacementRegion), "ClearPrefabs", (Type[])null, (Type[])null); private static readonly FieldInfo TilesField = AccessTools.Field(typeof(PlacementRegion), "Tiles"); private static readonly FieldInfo TilesInitiatedField = AccessTools.Field(typeof(PlacementRegion), "tilesInitiated"); private static readonly FieldInfo IsEditingBuildingsField = AccessTools.Field(typeof(PlacementRegion), "isEditingBuildings"); private static readonly FieldInfo PreviousEditingPositionField = AccessTools.Field(typeof(PlacementRegion), "previousEditingPosition"); private static readonly FieldInfo CurrentStructureToMoveField = AccessTools.Field(typeof(PlacementRegion), "CurrentStructureToMove"); private static readonly FieldInfo CurrentStructureToUpgradeField = AccessTools.Field(typeof(PlacementRegion), "CurrentStructureToUpgrade"); private static readonly FieldInfo PlacementObjectField = AccessTools.Field(typeof(PlacementRegion), "placementObject"); private static readonly FieldInfo PlacementUiField = AccessTools.Field(typeof(PlacementRegion), "placementUI"); internal static ManualLogSource Log { get; private set; } internal static RemoteBuildCancelPlugin Instance { get; private set; } private void Awake() { //IL_002c: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; RemoteBuildCancelConfig.Bind(((BaseUnityPlugin)this).Config); _cancelKey = ParseKey(RemoteBuildCancelConfig.CancelKey.Value, (KeyCode)290); _mouseCancelKey = ParseKey(RemoteBuildCancelConfig.MouseCancelKey.Value, (KeyCode)325); _controllerCancelKey = ParseKey(RemoteBuildCancelConfig.ControllerCancelKey.Value, (KeyCode)332); _editModeKey = ParseKey(RemoteBuildCancelConfig.EditModeKey.Value, (KeyCode)99); _harmony = new Harmony("com.cotl.betterbuildertools.remotebuildcancel"); _harmony.PatchAll(typeof(RemoteBuildCancelPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Remote Build Cancel 0.1.9 loaded."); } private void OnDestroy() { DestroyAllPromptUi(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; Instance = null; } private unsafe void Update() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) if (!RemoteBuildCancelConfig.Enabled.Value) { HideModePrompt(); HideCancelPrompt(); return; } RememberActiveBuildSelection(); if (!IsActiveBuildPlacement()) { if (((Object)(object)PlacementRegion.Instance == (Object)null || (int)PlacementRegion.Instance.CurrentMode == 0) && Time.unscaledTime >= _preserveCachedModeUntil) { ClearCachedBuildMode(); } HideModePrompt(); HideCancelPrompt(); } else if (RemoteBuildCancelConfig.EnableEditModeToggle.Value && EditModePressed()) { ToggleBuildEditMode(); } else { if (!CancelPressed()) { return; } Structure val = GetHoveredStructure(); if ((Object)(object)val == (Object)null && RemoteBuildCancelConfig.FallbackToLastPlaced.Value) { val = FindStructureById(_lastBuiltId); } if ((Object)(object)val == (Object)null || val.Brain == null || val.Brain.Data == null) { Log.LogInfo((object)"Remote cancel: no hovered/latest structure found."); return; } if (RemoteBuildCancelConfig.OnlyCancelBuildSites.Value && !IsBuildSite(val.Brain.Data.Type)) { Log.LogInfo((object)("Remote cancel ignored non-build-site structure " + ((object)Unsafe.As<TYPES, TYPES>(ref val.Brain.Data.Type)/*cast due to .constrained prefix*/).ToString() + ".")); return; } if (!RemoteBuildCancelConfig.AllowCriticalStructures.Value && IsCritical(val.Brain.Data.Type)) { Log.LogWarning((object)("Blocked remote cancel for protected structure type " + ((object)Unsafe.As<TYPES, TYPES>(ref val.Brain.Data.Type)/*cast due to .constrained prefix*/).ToString() + ".")); return; } TYPES type = val.Brain.Data.Type; if (RemoveStructureCleanly(val)) { Log.LogInfo((object)("Remote canceled " + ((object)(*(TYPES*)(&type))/*cast due to .constrained prefix*/).ToString() + ".")); } } } private void LateUpdate() { UpdateEditModePrompt(); UpdateCancelPrompt(); } private bool CancelPressed() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(_cancelKey) || Input.GetKeyDown(_mouseCancelKey)) { return true; } if (RemoteBuildCancelConfig.EnableControllerCancel.Value) { return Input.GetKeyDown(_controllerCancelKey); } return false; } private bool EditModePressed() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(_editModeKey) || Input.GetKeyDown((KeyCode)99)) { return true; } if (!RemoteBuildCancelConfig.UseVanillaEditModeAction.Value) { return false; } try { return InputManager.UI.GetEditBuildingsButtonDown((PlayerFarming)null); } catch { return false; } } private void ToggleBuildEditMode() { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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) PlacementRegion instance = PlacementRegion.Instance; if ((Object)(object)instance == (Object)null) { return; } Log.LogInfo((object)("Edit toggle request: mode=" + ((object)Unsafe.As<Mode, Mode>(ref instance.CurrentMode)/*cast due to .constrained prefix*/).ToString() + ", type=" + ((object)Unsafe.As<TYPES, TYPES>(ref instance.StructureType)/*cast due to .constrained prefix*/).ToString() + ", edit=" + IsEditBuildingsMode(instance) + ", cached=" + _hasCachedBuildMode + ", remembered=" + _hasLastBuildSelection + ".")); if (IsEditBuildingsMode(instance)) { if (!_hasCachedBuildMode && _hasLastBuildSelection) { _cachedBuildType = _lastBuildType; _cachedPlacementPrefab = _lastBuildPlacementPrefab; _cachedBuildMode = _lastBuildMode; _hasCachedBuildMode = true; } if (_hasCachedBuildMode) { SwitchToBuildMode(instance); } else { OpenBuildCatalogueFromEditMode(instance); } } else { SwitchToEditMode(instance); } } private void SwitchToEditMode(PlacementRegion region) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)region == (Object)null || (int)region.CurrentMode == 0 || (int)region.CurrentMode == 3 || (int)region.CurrentMode == 4 || (int)region.CurrentMode == 2) { return; } _cachedBuildType = region.StructureType; _cachedPlacementPrefab = region.PlacementGameObject; _cachedBuildMode = region.CurrentMode; _hasCachedBuildMode = (int)_cachedBuildType != 0 && (int)_cachedBuildType != 215 && (Object)(object)_cachedPlacementPrefab != (Object)null; if (!_hasCachedBuildMode) { Log.LogWarning((object)"Could not cache the active building before entering Edit mode."); return; } _hasLastBuildSelection = true; _lastBuildType = _cachedBuildType; _lastBuildPlacementPrefab = _cachedPlacementPrefab; _lastBuildMode = _cachedBuildMode; Vector3 val = (((Object)(object)PlacementObject.Instance != (Object)null) ? ((Component)PlacementObject.Instance).transform.position : region.PlacementPosition); if (val == Vector3.zero && (Object)(object)PlayerFarming.Instance != (Object)null) { val = ((Component)PlayerFarming.Instance).transform.position; } try { HideModePrompt(); PreserveCachedModeDuringTransition(); PrepareRegionForModeSwitch(region, enteringEditMode: true); region.StructureType = (TYPES)215; region.PlacementGameObject = TypeAndPlacementObjects.GetByType((TYPES)215).PlacementObject; region.CurrentMode = (Mode)3; region.Play(val); Log.LogInfo((object)"Switched active placement to Edit Buildings mode."); } catch (Exception ex) { Log.LogWarning((object)("Could not switch active placement to Edit Buildings mode: " + ex.Message)); } } private void SwitchToBuildMode(PlacementRegion region) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Invalid comparison between Unknown and I4 //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) if (!_hasCachedBuildMode || (int)_cachedBuildType == 0 || (int)_cachedBuildType == 215) { Log.LogInfo((object)"Build mode toggle ignored because there is no previous building selection to restore."); return; } GameObject val = _cachedPlacementPrefab; if ((Object)(object)val == (Object)null) { TypeAndPlacementObject byType = TypeAndPlacementObjects.GetByType(_cachedBuildType); val = ((byType != null) ? byType.PlacementObject : null); } if ((Object)(object)val == (Object)null) { Log.LogWarning((object)"Could not restore Build mode because the cached placement prefab is unavailable."); return; } Vector3 val2 = (((Object)(object)PlacementObject.Instance != (Object)null) ? ((Component)PlacementObject.Instance).transform.position : region.PlacementPosition); if (val2 == Vector3.zero) { val2 = GameManager.GetInstance().CamFollowTarget.GetCameraTargetWorldPosition(); } try { HideModePrompt(); PreserveCachedModeDuringTransition(); PrepareRegionForModeSwitch(region, enteringEditMode: false); region.StructureType = _cachedBuildType; region.PlacementGameObject = val; region.CurrentMode = (Mode)(((int)_cachedBuildMode == 1) ? 1 : 5); region.Play(val2); Log.LogInfo((object)("Restored Build mode with " + ((object)Unsafe.As<TYPES, TYPES>(ref _cachedBuildType)/*cast due to .constrained prefix*/).ToString() + ".")); } catch (Exception ex) { Log.LogWarning((object)("Could not restore Build mode: " + ex.Message)); } } private void OpenBuildCatalogueFromEditMode(PlacementRegion region) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)region == (Object)null || (Object)(object)MonoSingleton<UIManager>.Instance == (Object)null || (Object)(object)MonoSingleton<UIManager>.Instance.BuildMenuTemplate == (Object)null) { Log.LogWarning((object)"Could not return to the build catalogue because the build menu is unavailable."); return; } try { ((MonoBehaviour)region).StopAllCoroutines(); DestroyPlacementTiles(region); ClearPrefabsMethod?.Invoke(region, null); DestroyPrivateObject<PlacementObject>(region, PlacementObjectField); DestroyPrivateObject<PlacementObjectUI>(region, PlacementUiField); TilesInitiatedField?.SetValue(region, false); IsEditingBuildingsField?.SetValue(region, false); CurrentStructureToMoveField?.SetValue(region, null); CurrentStructureToUpgradeField?.SetValue(region, null); region.StructureType = (TYPES)0; region.CurrentMode = (Mode)0; region.PlacementPosition = Vector3.zero; GameManager.overridePlayerPosition = false; ClearCachedBuildMode(); HideModePrompt(); HideCancelPrompt(); Time.timeScale = 0f; MonoSingleton<UIManager>.Instance.ShowBuildMenu((TYPES)0); Log.LogInfo((object)"Returned from externally opened Edit Buildings mode to the build catalogue."); } catch (Exception ex) { Log.LogWarning((object)("Could not return from Edit Buildings mode to the build catalogue: " + ex.Message)); } } private static void PrepareRegionForModeSwitch(PlacementRegion region, bool enteringEditMode) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviour)region).StopAllCoroutines(); DestroyPlacementTiles(region); ClearPrefabsMethod?.Invoke(region, null); TilesInitiatedField?.SetValue(region, false); IsEditingBuildingsField?.SetValue(region, enteringEditMode); PreviousEditingPositionField?.SetValue(region, Vector3.zero); CurrentStructureToMoveField?.SetValue(region, null); CurrentStructureToUpgradeField?.SetValue(region, null); } private static void DestroyPlacementTiles(PlacementRegion region) { if (!(TilesField?.GetValue(region) is List<PlacementTile> list)) { return; } PlacementTile[] array = list.ToArray(); foreach (PlacementTile val in array) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } list.Clear(); } private static void DestroyPrivateObject<T>(PlacementRegion region, FieldInfo field) where T : Component { object? obj = field?.GetValue(region); T val = (T)((obj is T) ? obj : null); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); field.SetValue(region, null); } } private void UpdateEditModePrompt() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Invalid comparison between Unknown and I4 if (!RemoteBuildCancelConfig.ShowEditModePrompt.Value || !RemoteBuildCancelConfig.Enabled.Value || !RemoteBuildCancelConfig.EnableEditModeToggle.Value || (Object)(object)PlacementRegion.Instance == (Object)null || (Object)(object)PlayerFarming.Instance == (Object)null || (Object)(object)PlayerFarming.Instance.indicator == (Object)null || !IsActiveBuildPlacement()) { HideModePrompt(); return; } Mode currentMode = PlacementRegion.Instance.CurrentMode; bool flag = IsEditBuildingsMode(PlacementRegion.Instance); if (!flag && (int)currentMode != 1 && (int)currentMode != 5) { HideModePrompt(); return; } Indicator indicator = PlayerFarming.Instance.indicator; if (EnsureModePrompt(indicator)) { _modeControlPrompt.playerFarming = PlayerFarming.Instance; bool flag2 = IsControllerInput(); _modeControlPrompt.PrioritizeMouse = false; _modePromptText.text = (flag ? "Build" : "Edit"); _modePromptCellObject.SetActive(true); SizePromptRow(_promptRowObject); _promptRowObject.SetActive(true); _modePromptObject.SetActive(true); _modePromptTextObject.SetActive(true); if (_modePromptWasController != flag2) { _modePromptWasController = flag2; RefreshModePromptGlyph(flag2); } } } private bool EnsureModePrompt(Indicator indicator) { if ((Object)(object)_promptOwner != (Object)null && (Object)(object)_promptOwner != (Object)(object)indicator) { DestroyAllPromptUi(); } if ((Object)(object)_promptOwner == (Object)(object)indicator && (Object)(object)_modePromptCellObject != (Object)null && (Object)(object)_modeControlPrompt != (Object)null && (Object)(object)_modePromptText != (Object)null) { return true; } EnsurePromptRow(indicator); if ((Object)(object)_promptRowObject == (Object)null) { return false; } CreatePromptCell(indicator, "RemoteBuildCancel_ModeToggleCell", 120f, out _modePromptCellObject, out _modePromptObject, out _modeControlPrompt, out _modePromptTextObject, out _modePromptText); if ((Object)(object)_modeControlPrompt == (Object)null || (Object)(object)_modePromptText == (Object)null) { DestroyModePrompt(); return false; } _modePromptWasController = null; return true; } private void RefreshModePromptGlyph(bool controller) { if (!((Object)(object)_modeControlPrompt == (Object)null)) { if (controller) { _modeControlPrompt.IgnoreControllerChange = false; _modeControlPrompt.Category = 1; _modeControlPrompt.Action = 51; _modeControlPrompt.ForceUpdate(); } else { SetCustomPromptKey(_modeControlPrompt, "C"); } } } private void UpdateCancelPrompt() { if (!RemoteBuildCancelConfig.ShowCancelPrompt.Value || !RemoteBuildCancelConfig.Enabled.Value || !IsActiveBuildPlacement() || (Object)(object)PlayerFarming.Instance == (Object)null || (Object)(object)PlayerFarming.Instance.indicator == (Object)null) { HideCancelPrompt(); return; } Structure val = GetHoveredStructure(); if ((Object)(object)val == (Object)null && RemoteBuildCancelConfig.FallbackToLastPlaced.Value) { val = FindStructureById(_lastBuiltId); } if (!CanRemoteCancel(val)) { HideCancelPrompt(); return; } Indicator indicator = PlayerFarming.Instance.indicator; if (EnsureCancelPrompt(indicator)) { bool flag = IsControllerInput(); _cancelControlPrompt.playerFarming = PlayerFarming.Instance; _cancelControlPrompt.PrioritizeMouse = false; _cancelPromptText.text = "Cancel Build"; _cancelPromptCellObject.SetActive(true); SizePromptRow(_promptRowObject); _promptRowObject.SetActive(true); _cancelPromptObject.SetActive(true); _cancelPromptTextObject.SetActive(true); if (_cancelPromptWasController != flag) { _cancelPromptWasController = flag; RefreshCancelPromptGlyph(flag); } } } private bool EnsureCancelPrompt(Indicator indicator) { if ((Object)(object)_promptOwner != (Object)null && (Object)(object)_promptOwner != (Object)(object)indicator) { DestroyAllPromptUi(); } if ((Object)(object)_promptOwner == (Object)(object)indicator && (Object)(object)_cancelPromptCellObject != (Object)null && (Object)(object)_cancelControlPrompt != (Object)null && (Object)(object)_cancelPromptText != (Object)null) { return true; } EnsurePromptRow(indicator); if ((Object)(object)_promptRowObject == (Object)null) { return false; } CreatePromptCell(indicator, "RemoteBuildCancel_CancelCell", 165f, out _cancelPromptCellObject, out _cancelPromptObject, out _cancelControlPrompt, out _cancelPromptTextObject, out _cancelPromptText); if ((Object)(object)_cancelControlPrompt == (Object)null || (Object)(object)_cancelPromptText == (Object)null) { DestroyCancelPrompt(); return false; } _cancelPromptWasController = null; return true; } private void EnsurePromptRow(Indicator indicator) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown if ((Object)(object)_promptRowObject != (Object)null && (Object)(object)_promptOwner == (Object)(object)indicator) { return; } Transform promptParent = GetPromptParent(indicator); if (!((Object)(object)promptParent == (Object)null)) { Transform val = promptParent.Find("RemoteBuildCancel_BuilderToolsPromptRow"); if ((Object)(object)val != (Object)null) { EnsureExistingPromptRow(((Component)val).gameObject, indicator); _promptOwner = indicator; _promptRowObject = ((Component)val).gameObject; return; } GameObject val2 = new GameObject("RemoteBuildCancel_BuilderToolsPromptRow"); ((Transform)val2.AddComponent<RectTransform>()).SetParent(promptParent, false); ConfigurePromptRow(val2); AddVanillaPromptBackground(val2, indicator); val2.transform.SetAsLastSibling(); _promptOwner = indicator; _promptRowObject = val2; } } private static void ConfigurePromptRow(GameObject row) { //IL_001b: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown RectTransform obj = row.GetComponent<RectTransform>() ?? row.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0.5f, 0f); obj.anchorMax = new Vector2(0.5f, 0f); obj.pivot = new Vector2(0f, 0f); obj.anchoredPosition = new Vector2(240f, 112f); obj.sizeDelta = new Vector2(0f, 52f); LayoutElement obj2 = row.GetComponent<LayoutElement>() ?? row.AddComponent<LayoutElement>(); obj2.minWidth = 0f; obj2.preferredWidth = 0f; obj2.flexibleWidth = 0f; obj2.minHeight = 52f; obj2.preferredHeight = 52f; obj2.flexibleHeight = 0f; ContentSizeFitter obj3 = row.GetComponent<ContentSizeFitter>() ?? row.AddComponent<ContentSizeFitter>(); obj3.horizontalFit = (FitMode)2; obj3.verticalFit = (FitMode)0; ((Behaviour)obj3).enabled = false; HorizontalLayoutGroup obj4 = row.GetComponent<HorizontalLayoutGroup>() ?? row.AddComponent<HorizontalLayoutGroup>(); ((LayoutGroup)obj4).padding = new RectOffset(18, 18, 5, 5); ((HorizontalOrVerticalLayoutGroup)obj4).spacing = 18f; ((LayoutGroup)obj4).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = true; } private static void SizePromptRow(GameObject row) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)row == (Object)null) { return; } RectTransform component = row.GetComponent<RectTransform>(); HorizontalLayoutGroup component2 = row.GetComponent<HorizontalLayoutGroup>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { return; } float num = ((LayoutGroup)component2).padding.left + ((LayoutGroup)component2).padding.right; int num2 = 0; for (int i = 0; i < row.transform.childCount; i++) { GameObject gameObject = ((Component)row.transform.GetChild(i)).gameObject; if (!gameObject.activeSelf || ((Object)gameObject).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) >= 0) { continue; } LayoutElement component3 = gameObject.GetComponent<LayoutElement>(); float num3 = (((Object)(object)component3 != (Object)null) ? Mathf.Max(component3.minWidth, component3.preferredWidth) : 0f); if (num3 <= 0f) { RectTransform component4 = gameObject.GetComponent<RectTransform>(); float num4; if (!((Object)(object)component4 != (Object)null)) { num4 = 0f; } else { Rect rect = component4.rect; num4 = ((Rect)(ref rect)).width; } num3 = num4; } if (num3 <= 0f) { num3 = 40f; } if (num2 > 0) { num += ((HorizontalOrVerticalLayoutGroup)component2).spacing; } num += num3; num2++; } num = Mathf.Max(num, 1f); component.SetSizeWithCurrentAnchors((Axis)0, num); component.SetSizeWithCurrentAnchors((Axis)1, 52f); LayoutElement component5 = row.GetComponent<LayoutElement>(); if ((Object)(object)component5 != (Object)null) { component5.minWidth = num; component5.preferredWidth = num; } } private static Transform GetPromptParent(Indicator indicator) { Transform val = (((Object)(object)indicator != (Object)null && (Object)(object)indicator.ControlPromptUI != (Object)null) ? indicator.ControlPromptUI.transform : (((Object)(object)indicator != (Object)null) ? ((Component)indicator).transform : null)); if ((Object)(object)val == (Object)null) { return null; } Canvas val2 = ((Component)val).GetComponent<Canvas>() ?? ((Component)val).GetComponentInParent<Canvas>(); if (!((Object)(object)val2 != (Object)null)) { if (!((Object)(object)val.parent != (Object)null)) { return val; } return val.parent; } return ((Component)val2).transform; } private static void EnsureExistingPromptRow(GameObject row, Indicator indicator) { if (!((Object)(object)row == (Object)null)) { ConfigurePromptRow(row); AddVanillaPromptBackground(row, indicator); } } private static void AddVanillaPromptBackground(GameObject row, Indicator indicator) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Image val = (((Object)(object)indicator != (Object)null && (Object)(object)indicator.BG != (Object)null) ? (((Component)indicator.BG).GetComponent<Image>() ?? ((Component)indicator.BG).GetComponentInChildren<Image>(true)) : null); Image val2 = row.GetComponent<Image>() ?? row.AddComponent<Image>(); ((Behaviour)val2).enabled = true; ((Graphic)val2).raycastTarget = false; val2.sprite = (((Object)(object)val != (Object)null) ? val.sprite : null); val2.type = (Type)(((Object)(object)val != (Object)null) ? ((int)val.type) : 0); if ((Object)(object)val2.sprite == (Object)null) { val2.sprite = Sprite.Create(Texture2D.whiteTexture, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); val2.type = (Type)0; } ((Graphic)val2).color = new Color(0f, 0f, 0f, 0.88f); ((Graphic)val2).canvasRenderer.SetColor(((Graphic)val2).color); for (int i = 0; i < row.transform.childCount; i++) { Transform child = row.transform.GetChild(i); if (((Object)child).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) >= 0) { ((Component)child).gameObject.SetActive(false); } } } private void CreatePromptCell(Indicator indicator, string cellName, float preferredWidth, out GameObject cellObject, out GameObject promptObject, out MMControlPrompt controlPrompt, out GameObject textObject, out TMP_Text promptText) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) cellObject = null; promptObject = null; controlPrompt = null; textObject = null; promptText = null; RectTransform val = (((Object)(object)indicator.FourthControlPrompt != (Object)null) ? indicator.FourthControlPrompt : indicator.ThirdControlPrompt); if ((Object)(object)val == (Object)null) { val = (((Object)(object)indicator.SecondaryControlPrompt != (Object)null) ? indicator.SecondaryControlPrompt : indicator.ControlPrompt); } TMP_Text val2 = (TMP_Text)(object)(((Object)(object)indicator.Fourthtext != (Object)null) ? indicator.Fourthtext : indicator.Thirdtext); if ((Object)(object)val2 == (Object)null) { val2 = (TMP_Text)(object)(((Object)(object)indicator.SecondaryText != (Object)null) ? indicator.SecondaryText : indicator.text); } if ((Object)(object)_promptRowObject == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return; } GameObject val3 = new GameObject(cellName); ((Transform)val3.AddComponent<RectTransform>()).SetParent(_promptRowObject.transform, false); LayoutElement obj = val3.AddComponent<LayoutElement>(); obj.preferredWidth = preferredWidth; obj.minWidth = preferredWidth; HorizontalLayoutGroup obj2 = val3.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f; ((LayoutGroup)obj2).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true; GameObject val4 = Object.Instantiate<GameObject>(((Component)val).gameObject, val3.transform, false); ((Object)val4).name = cellName + "_Key"; val4.SetActive(true); val4.transform.localScale = Vector3.one; controlPrompt = val4.GetComponent<MMControlPrompt>() ?? val4.GetComponentInChildren<MMControlPrompt>(true); LayoutElement obj3 = val4.GetComponent<LayoutElement>() ?? val4.AddComponent<LayoutElement>(); obj3.preferredWidth = 50f; obj3.minWidth = 42f; obj3.preferredHeight = 40f; TMP_Text val5 = Object.Instantiate<TMP_Text>(val2, val3.transform, false); ((Object)((Component)val5).gameObject).name = cellName + "_Label"; ((Component)val5).gameObject.SetActive(true); val5.transform.localScale = Vector3.one; val5.alignment = (TextAlignmentOptions)4097; val5.enableAutoSizing = true; val5.fontSizeMin = 12f; val5.fontSizeMax = 22f; LayoutElement obj4 = ((Component)val5).GetComponent<LayoutElement>() ?? ((Component)val5).gameObject.AddComponent<LayoutElement>(); obj4.preferredWidth = preferredWidth - 58f; obj4.minWidth = preferredWidth - 58f; Behaviour[] components = ((Component)val5).GetComponents<Behaviour>(); foreach (Behaviour val6 in components) { if ((Object)(object)val6 != (Object)null && ((object)val6).GetType().FullName == "I2.Loc.Localize") { val6.enabled = false; } } cellObject = val3; promptObject = val4; textObject = ((Component)val5).gameObject; promptText = val5; } private void RefreshCancelPromptGlyph(bool controller) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_cancelControlPrompt == (Object)null)) { SetCustomPromptKey(_cancelControlPrompt, controller ? ControllerButtonLabel(_controllerCancelKey) : "MMB"); } } private static void SetCustomPromptKey(MMControlPrompt prompt, string label) { prompt.IgnoreControllerChange = true; object? obj = AccessTools.Field(typeof(MMControlPrompt), "_text")?.GetValue(prompt); TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); object? obj2 = AccessTools.Field(typeof(MMControlPrompt), "_iconText")?.GetValue(prompt); TMP_Text val2 = (TMP_Text)((obj2 is TMP_Text) ? obj2 : null); object? obj3 = AccessTools.Field(typeof(MMControlPrompt), "_icon")?.GetValue(prompt); Image val3 = (Image)((obj3 is Image) ? obj3 : null); if ((Object)(object)val != (Object)null) { val.text = label; val.fontSize = 20f; val.enableAutoSizing = true; val.fontSizeMin = 8f; val.fontSizeMax = 20f; ((Component)val).gameObject.SetActive(true); } if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(false); } if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(true); } } private void HideCancelPrompt() { if ((Object)(object)_cancelPromptCellObject != (Object)null) { _cancelPromptCellObject.SetActive(false); } RefreshPromptRowVisibility(_promptRowObject); } private void DestroyCancelPrompt() { if ((Object)(object)_cancelPromptCellObject != (Object)null) { Object.Destroy((Object)(object)_cancelPromptCellObject); } else { if ((Object)(object)_cancelPromptObject != (Object)null) { Object.Destroy((Object)(object)_cancelPromptObject); } if ((Object)(object)_cancelPromptTextObject != (Object)null) { Object.Destroy((Object)(object)_cancelPromptTextObject); } } _cancelPromptCellObject = null; _cancelPromptObject = null; _cancelPromptTextObject = null; _cancelControlPrompt = null; _cancelPromptText = null; _cancelPromptWasController = null; } private void HideModePrompt() { if ((Object)(object)_modePromptCellObject != (Object)null && _modePromptCellObject.activeSelf) { _modePromptCellObject.SetActive(false); } RefreshPromptRowVisibility(_promptRowObject); } private static void RefreshPromptRowVisibility(GameObject row) { if ((Object)(object)row == (Object)null) { return; } bool active = false; for (int i = 0; i < row.transform.childCount; i++) { GameObject gameObject = ((Component)row.transform.GetChild(i)).gameObject; if (gameObject.activeSelf && ((Object)gameObject).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) < 0) { active = true; break; } } SizePromptRow(row); row.SetActive(active); } private void DestroyModePrompt() { if ((Object)(object)_modePromptCellObject != (Object)null) { Object.Destroy((Object)(object)_modePromptCellObject); } else { if ((Object)(object)_modePromptObject != (Object)null) { Object.Destroy((Object)(object)_modePromptObject); } if ((Object)(object)_modePromptTextObject != (Object)null) { Object.Destroy((Object)(object)_modePromptTextObject); } } _modePromptCellObject = null; _modePromptObject = null; _modePromptTextObject = null; _modeControlPrompt = null; _modePromptText = null; _modePromptWasController = null; } private void DestroyAllPromptUi() { DestroyModePrompt(); DestroyCancelPrompt(); if ((Object)(object)_promptRowObject != (Object)null) { Object.Destroy((Object)(object)_promptRowObject); } _promptRowObject = null; _promptOwner = null; } private static bool IsControllerInput() { try { return (Object)(object)PlayerFarming.Instance != (Object)null && InputManager.General.InputIsController(PlayerFarming.Instance); } catch { return false; } } private bool CanRemoteCancel(Structure target) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null || target.Brain == null || target.Brain.Data == null) { return false; } if (RemoteBuildCancelConfig.OnlyCancelBuildSites.Value && !IsBuildSite(target.Brain.Data.Type)) { return false; } if (!RemoteBuildCancelConfig.AllowCriticalStructures.Value) { return !IsCritical(target.Brain.Data.Type); } return true; } private unsafe static string ControllerButtonLabel(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_0034: Expected I4, but got Unknown return (key - 330) switch { 0 => "A", 1 => "B", 2 => "X", 3 => "Y", 4 => "LB", 5 => "RB", 6 => "Back", 7 => "Start", 8 => "LS", 9 => "RS", _ => ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString().Replace("JoystickButton", "Pad "), }; } private void ClearCachedBuildMode() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) _hasCachedBuildMode = false; _cachedBuildType = (TYPES)0; _cachedPlacementPrefab = null; _cachedBuildMode = (Mode)5; _preserveCachedModeUntil = 0f; } private void PreserveCachedModeDuringTransition() { _preserveCachedModeUntil = Time.unscaledTime + 0.75f; } private void RememberActiveBuildSelection() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0023: 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_001f: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_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) PlacementRegion instance = PlacementRegion.Instance; if (!((Object)(object)instance == (Object)null) && ((int)instance.CurrentMode == 1 || (int)instance.CurrentMode == 5) && (int)instance.StructureType != 0 && (int)instance.StructureType != 215 && !((Object)(object)instance.PlacementGameObject == (Object)null)) { _hasLastBuildSelection = true; _lastBuildType = instance.StructureType; _lastBuildPlacementPrefab = instance.PlacementGameObject; _lastBuildMode = instance.CurrentMode; } } internal void RememberLatest(StructureBrain brain) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (brain != null && brain.Data != null && IsActiveBuildPlacement() && (!RemoteBuildCancelConfig.OnlyCancelBuildSites.Value || IsBuildSite(brain.Data.Type))) { _lastBuiltId = brain.Data.ID; } } private static Structure GetHoveredStructure() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) Structure val = (((Object)(object)PlacementRegion.Instance != (Object)null) ? PlacementRegion.Instance.GetHoveredStructure() : null); if ((Object)(object)val != (Object)null) { return val; } if ((Object)(object)PlacementRegion.Instance != (Object)null) { return GetNearestStructureAtPlacement(PlacementRegion.Instance.PlacementPosition, RemoteBuildCancelConfig.TargetRadius.Value); } return null; } private static Structure GetNearestStructureAtPlacement(Vector3 position, float radius) { //IL_0039: 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) Structure result = null; float num = radius; Structure[] array = Structure.Structures.ToArray(); foreach (Structure val in array) { if (!((Object)(object)val == (Object)null) && val.Brain != null && val.Brain.Data != null) { float num2 = Vector3.Distance(position, ((Component)val).transform.position); if (num2 <= num) { result = val; num = num2; } } } return result; } private static Structure FindStructureById(int id) { if (id < 0) { return null; } Structure[] array = Structure.Structures.ToArray(); foreach (Structure val in array) { if ((Object)(object)val != (Object)null && val.Brain != null && val.Brain.Data != null && val.Brain.Data.ID == id) { return val; } } return null; } private static bool RemoveStructureCleanly(Structure structure) { //IL_002b: 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_003c: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)structure == (Object)null || structure.Brain == null || structure.Brain.Data == null) { return false; } TYPES type = structure.Brain.Data.Type; TYPES toBuildType = structure.Brain.Data.ToBuildType; try { if ((Object)(object)PlacementRegion.Instance != (Object)null) { PlacementRegion.Instance.DestroyBuilding(structure); } else { structure.RemoveStructure(); Object.Destroy((Object)(object)((Component)structure).gameObject); } RefundBuildSiteMaterials(type, toBuildType); return true; } catch (Exception ex) { Log.LogWarning((object)("Remote cancel clean removal failed: " + ex.Message)); return false; } } private static void RefundBuildSiteMaterials(TYPES type, TYPES toBuildType) { //IL_0000: 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_000f: 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_0030: Unknown result type (might be due to invalid IL or missing references) if (!IsBuildSite(type)) { return; } List<ItemCost> cost = StructuresData.GetCost(((int)toBuildType != 0) ? toBuildType : type); if (cost == null) { return; } for (int i = 0; i < cost.Count; i++) { ItemCost val = cost[i]; if (val.CostValue > 0) { Inventory.AddItem(val.CostItem, val.CostValue, true); } } RefreshPlacementCostUi(); } private static void RefreshPlacementCostUi() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) PlacementRegion instance = PlacementRegion.Instance; if ((Object)(object)instance == (Object)null) { return; } try { object? obj = PlacementUiField?.GetValue(instance); PlacementObjectUI val = (PlacementObjectUI)((obj is PlacementObjectUI) ? obj : null); if ((Object)(object)val != (Object)null) { val.UpdateText(instance.StructureType); } } catch (Exception ex) { Log.LogDebug((object)("Could not refresh live placement cost UI: " + ex.Message)); } } private static bool IsActiveBuildPlacement() { //IL_0029: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 PlacementRegion instance = PlacementRegion.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)PlacementObject.Instance == (Object)null) { return false; } if (IsEditBuildingsMode(instance)) { return true; } if ((int)instance.CurrentMode == 0) { return false; } Mode currentMode = instance.CurrentMode; if ((int)currentMode != 1 && (int)currentMode != 5) { return (int)currentMode == 3; } return true; } private static bool IsEditBuildingsMode(PlacementRegion region) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 if ((Object)(object)region == (Object)null) { return false; } if ((int)region.StructureType == 215) { return true; } try { if (IsEditingBuildingsField != null && (bool)IsEditingBuildingsField.GetValue(region)) { return true; } } catch { } return (int)region.CurrentMode == 3; } private static bool IsBuildSite(TYPES type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)type != 31) { return (int)type == 118; } return true; } private unsafe static bool IsCritical(TYPES type) { string text = ((object)(*(TYPES*)(&type))/*cast due to .constrained prefix*/).ToString(); if (!text.Contains("TEMPLE") && !text.Contains("SHRINE") && !text.Contains("ALTAR")) { return text.Contains("BUILDER"); } return true; } private static KeyCode ParseKey(string raw, KeyCode fallback) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references) try { return (KeyCode)Enum.Parse(typeof(KeyCode), raw, ignoreCase: true); } catch { return fallback; } } } internal static class RemoteBuildCancelConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<string> CancelKey; internal static ConfigEntry<string> MouseCancelKey; internal static ConfigEntry<bool> EnableControllerCancel; internal static ConfigEntry<string> ControllerCancelKey; internal static ConfigEntry<bool> EnableEditModeToggle; internal static ConfigEntry<bool> UseVanillaEditModeAction; internal static ConfigEntry<string> EditModeKey; internal static ConfigEntry<bool> ShowEditModePrompt; internal static ConfigEntry<bool> ShowCancelPrompt; internal static ConfigEntry<bool> OnlyCancelBuildSites; internal static ConfigEntry<bool> FallbackToLastPlaced; internal static ConfigEntry<bool> AllowCriticalStructures; internal static ConfigEntry<float> TargetRadius; internal static void Bind(ConfigFile config) { //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Remote Build Cancel."); CancelKey = config.Bind<string>("Controls", "CancelKey", "F9", "KeyCode used to cancel the hovered or latest placed structure."); MouseCancelKey = config.Bind<string>("Controls", "MouseCancelKey", "Mouse2", "Mouse KeyCode used to cancel the hovered or latest placed structure. Mouse2 is middle mouse."); EnableControllerCancel = config.Bind<bool>("Controls", "EnableControllerCancel", true, "Enable the configured controller KeyCode for canceling the hovered or latest placed structure."); ControllerCancelKey = config.Bind<string>("Controls", "ControllerCancelKey", "JoystickButton2", "Controller KeyCode used to cancel the hovered or latest placed structure."); EnableEditModeToggle = config.Bind<bool>("Controls", "EnableEditModeToggle", true, "Allow switching from active placement into Edit Buildings mode without reopening the build catalogue."); UseVanillaEditModeAction = config.Bind<bool>("Controls", "UseVanillaEditModeAction", true, "Use the game's normal Edit Buildings input action while actively placing a structure."); EditModeKey = config.Bind<string>("Controls", "EditModeKey", "F7", "Fallback keyboard KeyCode used to switch active placement into Edit Buildings mode."); ShowEditModePrompt = config.Bind<bool>("UI", "ShowEditModePrompt", true, "Show a vanilla bottom-bar prompt for switching active placement into Edit Buildings mode."); ShowCancelPrompt = config.Bind<bool>("UI", "ShowCancelPrompt", true, "Show a vanilla bottom-bar prompt for the middle-mouse or controller remote-cancel action."); OnlyCancelBuildSites = config.Bind<bool>("Behavior", "OnlyCancelBuildSites", true, "Only allow remote cancel for unbuilt BUILD_SITE / BUILDSITE_BUILDINGPROJECT structures."); FallbackToLastPlaced = config.Bind<bool>("Behavior", "FallbackToLastPlaced", true, "Cancel the most recently placed structure if no hovered structure is found."); AllowCriticalStructures = config.Bind<bool>("Safety", "AllowCriticalStructures", false, "Allow remote cancel for temple/shrine/altar/builder style critical structures."); TargetRadius = config.Bind<float>("Targeting", "TargetRadius", 1.25f, new ConfigDescription("Fallback radius around the build cursor when vanilla hover targeting returns nothing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>())); } } [HarmonyPatch(typeof(StructureManager), "AddStructure")] internal static class StructureManagerAddStructurePatch { private static void Postfix(StructureBrain __result) { RemoteBuildCancelPlugin.Instance?.RememberLatest(__result); } } }
plugins/BetterBuilderTools/UndoBuildAction.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MMTools; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Undo Build Action")] [assembly: AssemblyProduct("Undo Build Action")] [assembly: ComVisible(false)] [assembly: Guid("eac82e42-17ee-466e-a457-6b853a2699ca")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyVersion("0.2.0.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 UndoBuildAction { [BepInPlugin("com.cotl.betterbuildertools.undobuildaction", "Undo Build Action", "0.2.1")] public sealed class UndoBuildActionPlugin : BaseUnityPlugin { public const string PluginGuid = "com.cotl.betterbuildertools.undobuildaction"; public const string PluginName = "Undo Build Action"; public const string PluginVersion = "0.2.1"; private readonly List<int> _undoStack = new List<int>(); private Harmony _harmony; private KeyCode _undoKey; private Indicator _promptOwner; private GameObject _undoPromptObject; private GameObject _undoPromptTextObject; private MMControlPrompt _undoControlPrompt; private TMP_Text _undoPromptText; private GameObject _promptRowObject; private GameObject _undoPromptCellObject; private bool _promptCreationWarningLogged; private bool? _promptWasController; internal static ManualLogSource Log { get; private set; } internal static UndoBuildActionPlugin Instance { get; private set; } private void Awake() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; UndoBuildActionConfig.Bind(((BaseUnityPlugin)this).Config); _undoKey = ParseKey(UndoBuildActionConfig.UndoKey.Value, (KeyCode)122); _harmony = new Harmony("com.cotl.betterbuildertools.undobuildaction"); _harmony.PatchAll(typeof(UndoBuildActionPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Undo Build Action 0.2.1 loaded."); } private void OnDestroy() { DestroyUndoPrompt(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; Instance = null; } private void Update() { if (UndoBuildActionConfig.Enabled.Value && UndoPressed()) { UndoLatest(); } } private void LateUpdate() { UpdateUndoPrompt(); } private bool UndoPressed() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(_undoKey)) { if (UndoBuildActionConfig.RequireControl.Value && !Input.GetKey((KeyCode)306)) { return Input.GetKey((KeyCode)305); } return true; } if (!UndoBuildActionConfig.EnableControllerUndo.Value) { return false; } try { PlayerFarming instance = PlayerFarming.Instance; return (Object)(object)instance != (Object)null && InputManager.General.InputIsController(instance) && InputManager.UI.GetPageNavigateLeftDown(instance); } catch { return false; } } internal void RecordLatest(StructureBrain brain) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (brain != null && brain.Data != null && IsInPlacementFlow() && (UndoBuildActionConfig.AllowCriticalStructures.Value || !IsCritical(brain.Data.Type))) { _undoStack.Add(brain.Data.ID); while (_undoStack.Count > UndoBuildActionConfig.UndoDepth.Value) { _undoStack.RemoveAt(0); } } } internal void ClearSession() { _undoStack.Clear(); HideUndoPrompt(); } private unsafe void UndoLatest() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) while (_undoStack.Count > 0) { int index = _undoStack.Count - 1; int id = _undoStack[index]; _undoStack.RemoveAt(index); Structure val = FindStructureById(id); if ((Object)(object)val != (Object)null && val.Brain != null && val.Brain.Data != null) { TYPES type = val.Brain.Data.Type; if (RemoveStructureCleanly(val)) { Log.LogInfo((object)("Undid placement of " + ((object)(*(TYPES*)(&type))/*cast due to .constrained prefix*/).ToString() + ".")); } break; } } } private static Structure FindStructureById(int id) { Structure[] array = Structure.Structures.ToArray(); foreach (Structure val in array) { if ((Object)(object)val != (Object)null && val.Brain != null && val.Brain.Data != null && val.Brain.Data.ID == id) { return val; } } return null; } private static bool RemoveStructureCleanly(Structure structure) { //IL_002b: 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_003c: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)structure == (Object)null || structure.Brain == null || structure.Brain.Data == null) { return false; } TYPES type = structure.Brain.Data.Type; TYPES toBuildType = structure.Brain.Data.ToBuildType; Vector3 position = ((Component)structure).transform.position; try { if ((Object)(object)PlacementRegion.Instance != (Object)null) { PlacementRegion.Instance.DestroyBuilding(structure); } else { structure.RemoveStructure(); Object.Destroy((Object)(object)((Component)structure).gameObject); } RefundBuildSiteMaterials(type, toBuildType, position); return true; } catch (Exception ex) { Log.LogWarning((object)("Undo clean removal failed: " + ex.Message)); return false; } } private static void RefundBuildSiteMaterials(TYPES type, TYPES toBuildType, Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_000b: 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_0008: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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 ((int)type != 31 && (int)type != 118) { return; } List<ItemCost> cost = StructuresData.GetCost(((int)toBuildType != 0) ? toBuildType : type); if (cost == null) { return; } for (int i = 0; i < cost.Count; i++) { ItemCost val = cost[i]; if (val.CostValue > 0) { InventoryItem.Spawn(val.CostItem, val.CostValue, position, 4f, (Action<PickUp>)null); } } } private static bool IsInPlacementFlow() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 if (!((Object)(object)PlacementObject.Instance != (Object)null)) { if ((Object)(object)PlacementRegion.Instance != (Object)null) { return (int)PlacementRegion.Instance.CurrentMode > 0; } return false; } return true; } private unsafe static bool IsCritical(TYPES type) { string text = ((object)(*(TYPES*)(&type))/*cast due to .constrained prefix*/).ToString(); if (!text.Contains("TEMPLE") && !text.Contains("SHRINE") && !text.Contains("ALTAR")) { return text.Contains("BUILDER"); } return true; } private void UpdateUndoPrompt() { if (!UndoBuildActionConfig.ShowUndoPrompt.Value || !UndoBuildActionConfig.Enabled.Value || _undoStack.Count == 0 || !IsInPlacementFlow() || (Object)(object)PlayerFarming.Instance == (Object)null || (Object)(object)PlayerFarming.Instance.indicator == (Object)null) { HideUndoPrompt(); return; } Indicator indicator = PlayerFarming.Instance.indicator; if (EnsureUndoPrompt(indicator)) { bool flag = false; try { flag = InputManager.General.InputIsController(PlayerFarming.Instance); } catch { } _undoControlPrompt.playerFarming = PlayerFarming.Instance; _undoControlPrompt.PrioritizeMouse = false; _undoPromptCellObject.SetActive(true); SizePromptRow(_promptRowObject); _promptRowObject.SetActive(true); _undoPromptObject.SetActive(true); _undoPromptTextObject.SetActive(true); if (_promptWasController != flag) { _promptWasController = flag; RefreshPromptGlyph(flag); } _undoPromptText.text = "Undo"; } } private bool EnsureUndoPrompt(Indicator indicator) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_promptOwner == (Object)(object)indicator && (Object)(object)_undoPromptCellObject != (Object)null && (Object)(object)_undoControlPrompt != (Object)null && (Object)(object)_undoPromptText != (Object)null) { return true; } DestroyUndoPrompt(); if ((Object)(object)indicator.FourthControlPrompt == (Object)null || (Object)(object)((Transform)indicator.FourthControlPrompt).parent == (Object)null || (Object)(object)indicator.Fourthtext == (Object)null || (Object)(object)((TMP_Text)indicator.Fourthtext).transform.parent == (Object)null) { return false; } EnsurePromptRow(indicator); if ((Object)(object)_promptRowObject == (Object)null) { return false; } GameObject val = new GameObject("UndoBuildAction_UndoCell"); ((Transform)val.AddComponent<RectTransform>()).SetParent(_promptRowObject.transform, false); LayoutElement obj = val.AddComponent<LayoutElement>(); obj.preferredWidth = 110f; obj.minWidth = 110f; HorizontalLayoutGroup obj2 = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f; ((LayoutGroup)obj2).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true; GameObject val2 = Object.Instantiate<GameObject>(((Component)indicator.FourthControlPrompt).gameObject, val.transform, false); ((Object)val2).name = "UndoBuildAction_UndoPrompt"; val2.SetActive(true); val2.transform.localScale = Vector3.one; MMControlPrompt val3 = val2.GetComponent<MMControlPrompt>() ?? val2.GetComponentInChildren<MMControlPrompt>(true); LayoutElement obj3 = val2.GetComponent<LayoutElement>() ?? val2.AddComponent<LayoutElement>(); obj3.preferredWidth = 50f; obj3.minWidth = 42f; obj3.preferredHeight = 40f; TMP_Text val4 = (TMP_Text)(object)Object.Instantiate<TextMeshProUGUI>(indicator.Fourthtext, val.transform, false); ((Object)((Component)val4).gameObject).name = "UndoBuildAction_UndoText"; ((Component)val4).gameObject.SetActive(true); val4.transform.localScale = Vector3.one; val4.alignment = (TextAlignmentOptions)4097; val4.enableAutoSizing = true; val4.fontSizeMin = 12f; val4.fontSizeMax = 22f; LayoutElement obj4 = ((Component)val4).GetComponent<LayoutElement>() ?? ((Component)val4).gameObject.AddComponent<LayoutElement>(); obj4.preferredWidth = 52f; obj4.minWidth = 52f; Behaviour[] components = ((Component)val4).GetComponents<Behaviour>(); foreach (Behaviour val5 in components) { if ((Object)(object)val5 != (Object)null && ((object)val5).GetType().FullName == "I2.Loc.Localize") { val5.enabled = false; } } if ((Object)(object)val3 == (Object)null) { Object.Destroy((Object)(object)val); if (!_promptCreationWarningLogged) { _promptCreationWarningLogged = true; Log.LogWarning((object)"Could not create the standalone Undo control prompt."); } return false; } _promptOwner = indicator; _undoPromptCellObject = val; _undoPromptObject = val2; _undoPromptTextObject = ((Component)val4).gameObject; _undoControlPrompt = val3; _undoPromptText = val4; _promptCreationWarningLogged = false; _promptWasController = null; return true; } private void EnsurePromptRow(Indicator indicator) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown if ((Object)(object)_promptRowObject != (Object)null && (Object)(object)_promptOwner == (Object)(object)indicator) { return; } Transform promptParent = GetPromptParent(indicator); if (!((Object)(object)promptParent == (Object)null)) { Transform val = promptParent.Find("RemoteBuildCancel_BuilderToolsPromptRow"); if ((Object)(object)val != (Object)null) { ConfigurePromptRow(((Component)val).gameObject); AddVanillaPromptBackground(((Component)val).gameObject, indicator); _promptOwner = indicator; _promptRowObject = ((Component)val).gameObject; } else { GameObject val2 = new GameObject("RemoteBuildCancel_BuilderToolsPromptRow"); ((Transform)val2.AddComponent<RectTransform>()).SetParent(promptParent, false); ConfigurePromptRow(val2); AddVanillaPromptBackground(val2, indicator); val2.transform.SetAsLastSibling(); _promptOwner = indicator; _promptRowObject = val2; } } } private static void ConfigurePromptRow(GameObject row) { //IL_001b: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown RectTransform obj = row.GetComponent<RectTransform>() ?? row.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0.5f, 0f); obj.anchorMax = new Vector2(0.5f, 0f); obj.pivot = new Vector2(0f, 0f); obj.anchoredPosition = new Vector2(240f, 112f); obj.sizeDelta = new Vector2(0f, 52f); LayoutElement obj2 = row.GetComponent<LayoutElement>() ?? row.AddComponent<LayoutElement>(); obj2.minWidth = 0f; obj2.preferredWidth = 0f; obj2.flexibleWidth = 0f; obj2.minHeight = 52f; obj2.preferredHeight = 52f; obj2.flexibleHeight = 0f; ContentSizeFitter obj3 = row.GetComponent<ContentSizeFitter>() ?? row.AddComponent<ContentSizeFitter>(); obj3.horizontalFit = (FitMode)2; obj3.verticalFit = (FitMode)0; ((Behaviour)obj3).enabled = false; HorizontalLayoutGroup obj4 = row.GetComponent<HorizontalLayoutGroup>() ?? row.AddComponent<HorizontalLayoutGroup>(); ((LayoutGroup)obj4).padding = new RectOffset(18, 18, 5, 5); ((HorizontalOrVerticalLayoutGroup)obj4).spacing = 18f; ((LayoutGroup)obj4).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = true; } private static void SizePromptRow(GameObject row) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)row == (Object)null) { return; } RectTransform component = row.GetComponent<RectTransform>(); HorizontalLayoutGroup component2 = row.GetComponent<HorizontalLayoutGroup>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { return; } float num = ((LayoutGroup)component2).padding.left + ((LayoutGroup)component2).padding.right; int num2 = 0; for (int i = 0; i < row.transform.childCount; i++) { GameObject gameObject = ((Component)row.transform.GetChild(i)).gameObject; if (!gameObject.activeSelf || ((Object)gameObject).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) >= 0) { continue; } LayoutElement component3 = gameObject.GetComponent<LayoutElement>(); float num3 = (((Object)(object)component3 != (Object)null) ? Mathf.Max(component3.minWidth, component3.preferredWidth) : 0f); if (num3 <= 0f) { RectTransform component4 = gameObject.GetComponent<RectTransform>(); float num4; if (!((Object)(object)component4 != (Object)null)) { num4 = 0f; } else { Rect rect = component4.rect; num4 = ((Rect)(ref rect)).width; } num3 = num4; } if (num3 <= 0f) { num3 = 40f; } if (num2 > 0) { num += ((HorizontalOrVerticalLayoutGroup)component2).spacing; } num += num3; num2++; } num = Mathf.Max(num, 1f); component.SetSizeWithCurrentAnchors((Axis)0, num); component.SetSizeWithCurrentAnchors((Axis)1, 52f); LayoutElement component5 = row.GetComponent<LayoutElement>(); if ((Object)(object)component5 != (Object)null) { component5.minWidth = num; component5.preferredWidth = num; } } private static Transform GetPromptParent(Indicator indicator) { Transform val = (((Object)(object)indicator != (Object)null && (Object)(object)indicator.ControlPromptUI != (Object)null) ? indicator.ControlPromptUI.transform : (((Object)(object)indicator != (Object)null) ? ((Component)indicator).transform : null)); if ((Object)(object)val == (Object)null) { return null; } Canvas val2 = ((Component)val).GetComponent<Canvas>() ?? ((Component)val).GetComponentInParent<Canvas>(); if (!((Object)(object)val2 != (Object)null)) { if (!((Object)(object)val.parent != (Object)null)) { return val; } return val.parent; } return ((Component)val2).transform; } private static void AddVanillaPromptBackground(GameObject row, Indicator indicator) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Image val = (((Object)(object)indicator != (Object)null && (Object)(object)indicator.BG != (Object)null) ? (((Component)indicator.BG).GetComponent<Image>() ?? ((Component)indicator.BG).GetComponentInChildren<Image>(true)) : null); Image val2 = row.GetComponent<Image>() ?? row.AddComponent<Image>(); ((Behaviour)val2).enabled = true; ((Graphic)val2).raycastTarget = false; val2.sprite = (((Object)(object)val != (Object)null) ? val.sprite : null); val2.type = (Type)(((Object)(object)val != (Object)null) ? ((int)val.type) : 0); if ((Object)(object)val2.sprite == (Object)null) { val2.sprite = Sprite.Create(Texture2D.whiteTexture, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); val2.type = (Type)0; } ((Graphic)val2).color = new Color(0f, 0f, 0f, 0.88f); ((Graphic)val2).canvasRenderer.SetColor(((Graphic)val2).color); for (int i = 0; i < row.transform.childCount; i++) { Transform child = row.transform.GetChild(i); if (((Object)child).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) >= 0) { ((Component)child).gameObject.SetActive(false); } } } private void RefreshPromptGlyph(bool controller) { if ((Object)(object)_undoControlPrompt == (Object)null) { return; } if (controller) { _undoControlPrompt.IgnoreControllerChange = false; _undoControlPrompt.Category = 1; _undoControlPrompt.Action = 43; _undoControlPrompt.ForceUpdate(); return; } _undoControlPrompt.IgnoreControllerChange = true; object? obj = AccessTools.Field(typeof(MMControlPrompt), "_text")?.GetValue(_undoControlPrompt); TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); object? obj2 = AccessTools.Field(typeof(MMControlPrompt), "_iconText")?.GetValue(_undoControlPrompt); TMP_Text val2 = (TMP_Text)((obj2 is TMP_Text) ? obj2 : null); object? obj3 = AccessTools.Field(typeof(MMControlPrompt), "_icon")?.GetValue(_undoControlPrompt); Image val3 = (Image)((obj3 is Image) ? obj3 : null); if ((Object)(object)val != (Object)null) { val.text = (UndoBuildActionConfig.RequireControl.Value ? ("Ctrl+" + ((object)Unsafe.As<KeyCode, KeyCode>(ref _undoKey)/*cast due to .constrained prefix*/).ToString()) : ((object)Unsafe.As<KeyCode, KeyCode>(ref _undoKey)/*cast due to .constrained prefix*/).ToString()); val.fontSize = 20f; val.enableAutoSizing = true; val.fontSizeMin = 8f; val.fontSizeMax = 20f; ((Component)val).gameObject.SetActive(true); } if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(false); } if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(true); } } private void HideUndoPrompt() { if ((Object)(object)_undoPromptCellObject != (Object)null) { _undoPromptCellObject.SetActive(false); } RefreshPromptRowVisibility(_promptRowObject); } private static void RefreshPromptRowVisibility(GameObject row) { if ((Object)(object)row == (Object)null) { return; } bool active = false; for (int i = 0; i < row.transform.childCount; i++) { GameObject gameObject = ((Component)row.transform.GetChild(i)).gameObject; if (gameObject.activeSelf && ((Object)gameObject).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) < 0) { active = true; break; } } SizePromptRow(row); row.SetActive(active); } private void DestroyUndoPrompt() { if ((Object)(object)_undoPromptCellObject != (Object)null) { Object.Destroy((Object)(object)_undoPromptCellObject); } else { if ((Object)(object)_undoPromptObject != (Object)null) { Object.Destroy((Object)(object)_undoPromptObject); } if ((Object)(object)_undoPromptTextObject != (Object)null) { Object.Destroy((Object)(object)_undoPromptTextObject); } } _undoPromptCellObject = null; _undoPromptObject = null; _undoPromptTextObject = null; _undoControlPrompt = null; _undoPromptText = null; _promptWasController = null; } private static KeyCode ParseKey(string raw, KeyCode fallback) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references) try { return (KeyCode)Enum.Parse(typeof(KeyCode), raw, ignoreCase: true); } catch { return fallback; } } } internal static class UndoBuildActionConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<string> UndoKey; internal static ConfigEntry<bool> RequireControl; internal static ConfigEntry<bool> EnableControllerUndo; internal static ConfigEntry<bool> ShowUndoPrompt; internal static ConfigEntry<int> UndoDepth; internal static ConfigEntry<bool> AllowCriticalStructures; internal static void Bind(ConfigFile config) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Undo Build Action."); UndoKey = config.Bind<string>("Controls", "UndoKey", "Z", "KeyCode used for undo."); RequireControl = config.Bind<bool>("Controls", "RequireControl", true, "Require Ctrl plus UndoKey."); EnableControllerUndo = config.Bind<bool>("Controls", "EnableControllerUndo", true, "Allow the UI Page Left controller action (normally LB/L1) to undo during build placement."); ShowUndoPrompt = config.Bind<bool>("UI", "ShowUndoPrompt", true, "Show a vanilla bottom-bar Undo prompt while build placement has an action available to undo."); UndoDepth = config.Bind<int>("Undo", "UndoDepth", 10, new ConfigDescription("How many recent placements are kept.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>())); if (UndoDepth.Value < 10) { UndoDepth.Value = 10; } AllowCriticalStructures = config.Bind<bool>("Safety", "AllowCriticalStructures", false, "Allow undo removal of temple/shrine/altar/builder style critical structures."); } } [HarmonyPatch(typeof(Interaction_PlacementRegion), "OnInteract")] internal static class InteractionPlacementRegionOnInteractPatch { private static void Prefix() { UndoBuildActionPlugin.Instance?.ClearSession(); } } [HarmonyPatch(typeof(StructureManager), "AddStructure")] internal static class StructureManagerAddStructurePatch { private static void Postfix(StructureBrain __result) { UndoBuildActionPlugin.Instance?.RecordLatest(__result); } } }
plugins/BetterBuilderTools/UpgradeBuildTools.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Lamb.UI; using MMTools; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using src.UINavigator; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Upgrade Build Tools")] [assembly: AssemblyProduct("Upgrade Build Tools")] [assembly: AssemblyVersion("0.1.0.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 UpgradeBuildTools { [BepInPlugin("com.cotl.betterbuildertools.upgradebuildtools", "Upgrade Build Tools", "0.1.1")] public sealed class UpgradeBuildToolsPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(PlacementRegion), "Upgrade")] private static class PlacementRegionUpgradePatch { private static bool Prefix(PlacementRegion __instance) { if ((Object)(object)Instance == (Object)null) { return true; } if (Instance.ShouldSkipNativeUpgrade(__instance)) { return false; } Instance.ObserveNativeUpgrade(__instance); return true; } } public const string PluginGuid = "com.cotl.betterbuildertools.upgradebuildtools"; public const string PluginName = "Upgrade Build Tools"; public const string PluginVersion = "0.1.1"; private static readonly FieldInfo CurrentUpgradeField = AccessTools.Field(typeof(PlacementRegion), "CurrentStructureToUpgrade"); private static readonly FieldInfo PlacementObjectField = AccessTools.Field(typeof(PlacementRegion), "placementObject"); private static readonly FieldInfo PlacementUiField = AccessTools.Field(typeof(PlacementRegion), "placementUI"); private static readonly FieldInfo TilesField = AccessTools.Field(typeof(PlacementRegion), "Tiles"); private static readonly FieldInfo TilesInitiatedField = AccessTools.Field(typeof(PlacementRegion), "tilesInitiated"); private static readonly FieldInfo InputDelayField = AccessTools.Field(typeof(PlacementRegion), "InputDelay"); private static readonly MethodInfo ClearPrefabsMethod = AccessTools.Method(typeof(PlacementRegion), "ClearPrefabs", (Type[])null, (Type[])null); private static readonly MethodInfo UpgradeMethod = AccessTools.Method(typeof(PlacementRegion), "Upgrade", (Type[])null, (Type[])null); private static readonly MethodInfo GetMousePositionWorldMethod = AccessTools.Method(typeof(PlacementRegion), "GetMousePositionWorld", (Type[])null, (Type[])null); private Harmony _harmony; private KeyCode _upgradeAllKey; private KeyCode _controllerUpgradeAllKey; private Coroutine _batchRoutine; private float _lastHeldUpgradeTime; private int _suppressNativeUpgradeUntilFrame = -1; private bool _invokingCustomUpgrade; private PlacementRegion _activeRegion; private bool _awaitingMouseRelease; private readonly HashSet<int> _handledWhileHeld = new HashSet<int>(); private Indicator _promptOwner; private GameObject _promptRowObject; private GameObject _promptCellObject; private GameObject _promptObject; private MMControlPrompt _promptControl; private TMP_Text _promptText; private bool? _promptWasController; private bool _promptCreationWarningLogged; internal static ManualLogSource Log { get; private set; } internal static UpgradeBuildToolsPlugin Instance { get; private set; } private void Awake() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; UpgradeBuildToolsConfig.Bind(((BaseUnityPlugin)this).Config); _upgradeAllKey = ParseKey(UpgradeBuildToolsConfig.UpgradeAllKey.Value, (KeyCode)103); _controllerUpgradeAllKey = ParseKey(UpgradeBuildToolsConfig.ControllerUpgradeAllKey.Value, (KeyCode)333); _harmony = new Harmony("com.cotl.betterbuildertools.upgradebuildtools"); _harmony.PatchAll(typeof(UpgradeBuildToolsPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Upgrade Build Tools 0.1.1 loaded."); } private void OnDestroy() { if (_batchRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_batchRoutine); _batchRoutine = null; } DestroyPromptUi(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; Instance = null; } private void Update() { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (!UpgradeBuildToolsConfig.Enabled.Value) { ResetPlacementState(null); return; } PlacementRegion instance = PlacementRegion.Instance; if (!IsUpgradePlacement(instance, out var info)) { ResetPlacementState(instance); return; } if ((Object)(object)_activeRegion != (Object)(object)instance) { _activeRegion = instance; _handledWhileHeld.Clear(); _lastHeldUpgradeTime = 0f; _awaitingMouseRelease = true; } if (_awaitingMouseRelease) { if (Input.GetMouseButton(0)) { return; } _awaitingMouseRelease = false; } if (_batchRoutine == null && UpgradeAllPressed()) { _batchRoutine = ((MonoBehaviour)this).StartCoroutine(UpgradeAllRoutine(instance, info)); } if (_batchRoutine != null || !UpgradeBuildToolsConfig.EnableHoldToUpgrade.Value) { return; } if (!IsPlaceHeld()) { _handledWhileHeld.Clear(); } else { if (!Input.GetMouseButton(0)) { return; } bool mouseButtonDown = Input.GetMouseButtonDown(0); if (mouseButtonDown || !(Time.unscaledTime - _lastHeldUpgradeTime < UpgradeBuildToolsConfig.UpgradeInterval.Value)) { Structure val = FindCursorUpgradeTarget(instance, info.UpgradeFromType); if (!((Object)(object)val == (Object)null) && val.Brain != null && val.Brain.Data != null && !_handledWhileHeld.Contains(val.Brain.Data.ID) && TryUpgradeTarget(instance, val, mouseButtonDown)) { _handledWhileHeld.Add(val.Brain.Data.ID); _lastHeldUpgradeTime = Time.unscaledTime; } } } } private void LateUpdate() { UpdatePrompt(); if (_suppressNativeUpgradeUntilFrame >= 0 && Time.frameCount > _suppressNativeUpgradeUntilFrame) { _suppressNativeUpgradeUntilFrame = -1; } } private void ResetPlacementState(PlacementRegion region) { if (_batchRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_batchRoutine); _batchRoutine = null; } _activeRegion = null; _awaitingMouseRelease = false; _handledWhileHeld.Clear(); _lastHeldUpgradeTime = 0f; } private bool UpgradeAllPressed() { //IL_0001: 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) if (Input.GetKeyDown(_upgradeAllKey)) { return true; } if (UpgradeBuildToolsConfig.EnableControllerUpgradeAll.Value) { return Input.GetKeyDown(_controllerUpgradeAllKey); } return false; } private bool IsPlaceHeld() { if (Input.GetMouseButton(0)) { return true; } try { return InputManager.Gameplay.GetPlaceMoveUpgradeButtonHeld(MonoSingleton<UINavigatorNew>.Instance.AllowInputOnlyFromPlayer); } catch { return false; } } private static bool IsUpgradePlacement(PlacementRegion region, out StructuresData info) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_001a: 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_003b: Invalid comparison between Unknown and I4 info = null; if ((Object)(object)region == (Object)null || (int)region.CurrentMode != 2) { return false; } try { info = StructuresData.GetInfoByType(region.StructureType, 0); return info != null && info.IsUpgrade && (int)info.UpgradeFromType > 0; } catch { return false; } } private IEnumerator UpgradeAllRoutine(PlacementRegion region, StructuresData upgradeInfo) { _handledWhileHeld.Clear(); Structure currentUpgrade = GetCurrentUpgrade(region); if ((Object)(object)currentUpgrade != (Object)null && (Object)(object)((Component)currentUpgrade).gameObject != (Object)null && !((Component)currentUpgrade).gameObject.activeSelf) { ((Component)currentUpgrade).gameObject.SetActive(true); } List<Structure> targets = FindEligibleStructures(region, upgradeInfo.UpgradeFromType); if (IsEligibleUpgradeTarget(region, currentUpgrade, upgradeInfo.UpgradeFromType)) { targets.Remove(currentUpgrade); targets.Insert(0, currentUpgrade); } int upgraded = 0; if (targets.Count == 0 || !StructuresData.CanAfford(region.StructureType)) { _batchRoutine = null; yield break; } ((MonoBehaviour)region).StopAllCoroutines(); for (int i = 0; i < targets.Count; i++) { if ((Object)(object)PlacementRegion.Instance != (Object)(object)region) { break; } if ((int)region.CurrentMode != 2) { break; } Structure target = targets[i]; if (!IsEligibleUpgradeTarget(region, target, upgradeInfo.UpgradeFromType) || !StructuresData.CanAfford(region.StructureType)) { break; } if (TryUpgradeTarget(region, target, suppressNativeClick: false)) { upgraded++; } yield return null; } if (upgraded > 0) { Log.LogInfo((object)$"Upgraded {upgraded} {upgradeInfo.UpgradeFromType} structure(s) to {region.StructureType}."); } _handledWhileHeld.Clear(); _batchRoutine = null; FinishUpgradeBatch(region); } private static void FinishUpgradeBatch(PlacementRegion region) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Invalid comparison between Unknown and I4 if ((Object)(object)region == (Object)null) { Time.timeScale = 1f; return; } ((MonoBehaviour)region).StopAllCoroutines(); try { DestroyPlacementTiles(region); ClearPrefabsMethod?.Invoke(region, null); DestroyPrivateObject<PlacementObject>(region, PlacementObjectField); DestroyPrivateObject<PlacementObjectUI>(region, PlacementUiField); } catch (Exception ex) { Log.LogWarning((object)("Upgrade batch placement cleanup failed: " + ex.GetBaseException().Message)); } region.CurrentMode = (Mode)0; region.StructureType = (TYPES)0; region.PlacementPosition = Vector3.zero; TilesInitiatedField?.SetValue(region, false); GameManager.overridePlayerPosition = false; if ((Object)(object)DLCLandController.Instance != (Object)null) { DLCLandController.Instance.ShowBridge(); } if ((Object)(object)HUD_Manager.Instance != (Object)null) { HUD_Manager.Instance.Show(1, false); HUD_Manager.Instance.ShowEditMode(false); } if ((Object)(object)WeatherSystemController.Instance != (Object)null) { WeatherSystemController.Instance.ShowWeather(false, true); } if ((Object)(object)LightingManager.Instance != (Object)null) { LightingManager.Instance.inOverride = false; LightingManager.Instance.overrideSettings = null; LightingManager.Instance.transitionDurationMultiplier = 0.2f; LightingManager.Instance.lerpActive = false; LightingManager.Instance.UpdateLighting(true, false, false); LightingManager.Instance.PrepareLightingSettings(false); } if ((Object)(object)GameManager.GetInstance() != (Object)null) { if ((Object)(object)GameManager.GetInstance().CamFollowTarget != (Object)null) { ((Behaviour)GameManager.GetInstance().CamFollowTarget).enabled = true; } GameManager.GetInstance().RemoveAllFromCamera(); GameManager.GetInstance().AddPlayerToCamera(); GameManager.GetInstance().CameraResetTargetZoom(); } if (PlayerFarming.players != null) { for (int i = 0; i < PlayerFarming.players.Count; i++) { PlayerFarming val = PlayerFarming.players[i]; if ((Object)(object)val != (Object)null && (Object)(object)val.state != (Object)null && (int)val.state.CURRENT_STATE == 13) { val.state.CURRENT_STATE = (State)0; } } } if ((Object)(object)AudioManager.Instance != (Object)null) { AudioManager.Instance.SetBuildSnapshotEnabled(false); } Time.timeScale = 1f; if ((Object)(object)MonoSingleton<UIManager>.Instance != (Object)null && (Object)(object)MonoSingleton<UIManager>.Instance.BuildMenuTemplate != (Object)null) { Time.timeScale = 0f; MonoSingleton<UIManager>.Instance.ShowBuildMenu((TYPES)0); } } private static void DestroyPlacementTiles(PlacementRegion region) { if (!(TilesField?.GetValue(region) is List<PlacementTile> list)) { return; } PlacementTile[] array = list.ToArray(); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { Object.Destroy((Object)(object)((Component)array[i]).gameObject); } } list.Clear(); } private static void DestroyPrivateObject<T>(PlacementRegion region, FieldInfo field) where T : Component { object? obj = field?.GetValue(region); T val = (T)((obj is T) ? obj : null); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); field.SetValue(region, null); } } private bool TryUpgradeTarget(PlacementRegion region, Structure target, bool suppressNativeClick) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (UpgradeMethod == null || CurrentUpgradeField == null || PlacementObjectField == null || (Object)(object)target == (Object)null || target.Brain == null || target.Brain.Data == null) { Log.LogWarning((object)"Native upgrade members were not found; upgrade tools are unavailable for this game build."); return false; } StructuresData infoByType = StructuresData.GetInfoByType(region.StructureType, 0); if (infoByType == null || !IsEligibleUpgradeTarget(region, target, infoByType.UpgradeFromType) || !StructuresData.CanAfford(region.StructureType)) { return false; } Structure currentUpgrade = GetCurrentUpgrade(region); if ((Object)(object)currentUpgrade != (Object)null && (Object)(object)currentUpgrade != (Object)(object)target && (Object)(object)((Component)currentUpgrade).gameObject != (Object)null && !((Component)currentUpgrade).gameObject.activeSelf && !_handledWhileHeld.Contains(GetStructureId(currentUpgrade))) { ((Component)currentUpgrade).gameObject.SetActive(true); } CurrentUpgradeField.SetValue(region, target); ((Component)target).gameObject.SetActive(false); if (InputDelayField != null) { InputDelayField.SetValue(region, 0.2f); } if (suppressNativeClick) { _suppressNativeUpgradeUntilFrame = Time.frameCount + 1; } try { _invokingCustomUpgrade = true; UpgradeMethod.Invoke(region, null); _invokingCustomUpgrade = false; return true; } catch (Exception ex) { _invokingCustomUpgrade = false; if ((Object)(object)((Component)target).gameObject != (Object)null) { ((Component)target).gameObject.SetActive(true); } Log.LogWarning((object)("Upgrade action failed: " + ex.GetBaseException().Message)); return false; } } private Structure FindCursorUpgradeTarget(PlacementRegion region, TYPES fromType) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (GetMousePositionWorldMethod == null) { return null; } Vector3 val; try { val = (Vector3)GetMousePositionWorldMethod.Invoke(region, null); } catch { return null; } PlacementTile closestTileAtWorldPosition = region.GetClosestTileAtWorldPosition(val, -1f); if ((Object)(object)closestTileAtWorldPosition == (Object)null) { return null; } TileGridTile tileGridTile = region.GetTileGridTile(closestTileAtWorldPosition.GridPosition); if (tileGridTile != null && tileGridTile.ObjectID >= 0) { Structure val2 = FindStructureById(tileGridTile.ObjectID); if (IsEligibleUpgradeTarget(region, val2, fromType)) { return val2; } } Structure[] array = Structure.Structures.ToArray(); foreach (Structure val3 in array) { if (IsEligibleUpgradeTarget(region, val3, fromType)) { Vector2Int gridTilePosition = val3.Brain.Data.GridTilePosition; Vector2Int bounds = val3.Brain.Data.Bounds; if (((Vector2Int)(ref closestTileAtWorldPosition.GridPosition)).x >= ((Vector2Int)(ref gridTilePosition)).x && ((Vector2Int)(ref closestTileAtWorldPosition.GridPosition)).x < ((Vector2Int)(ref gridTilePosition)).x + ((Vector2Int)(ref bounds)).x && ((Vector2Int)(ref closestTileAtWorldPosition.GridPosition)).y >= ((Vector2Int)(ref gridTilePosition)).y && ((Vector2Int)(ref closestTileAtWorldPosition.GridPosition)).y < ((Vector2Int)(ref gridTilePosition)).y + ((Vector2Int)(ref bounds)).y) { return val3; } } } return null; } private static List<Structure> FindEligibleStructures(PlacementRegion region, TYPES fromType) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) List<Structure> list = new List<Structure>(); Structure[] array = Structure.Structures.ToArray(); foreach (Structure val in array) { if (IsEligibleUpgradeTarget(region, val, fromType)) { list.Add(val); } } return list; } private static bool IsEligibleUpgradeTarget(PlacementRegion region, Structure target, TYPES fromType) { //IL_002c: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Invalid comparison between Unknown and I4 if ((Object)(object)target == (Object)null || !((Component)target).gameObject.activeInHierarchy || target.Brain == null || target.Brain.Data == null || target.Type != fromType) { return false; } if ((Object)(object)region != (Object)null && region.StructureInfo != null && target.Structure_Info.Location != region.StructureInfo.Location) { return false; } TYPES type = target.Type; if (target.Structure_Info.ClaimedByPlayer && ((int)type == 2 || (int)type == 40 || (int)type == 41)) { return false; } return true; } private static Structure FindStructureById(int id) { Structure[] array = Structure.Structures.ToArray(); foreach (Structure val in array) { if ((Object)(object)val != (Object)null && val.Brain != null && val.Brain.Data != null && val.Brain.Data.ID == id) { return val; } } return null; } private static Structure GetCurrentUpgrade(PlacementRegion region) { object? obj = CurrentUpgradeField?.GetValue(region); return (Structure)((obj is Structure) ? obj : null); } private static int GetStructureId(Structure structure) { if (!((Object)(object)structure != (Object)null) || structure.Brain == null || structure.Brain.Data == null) { return -1; } return structure.Brain.Data.ID; } internal void ObserveNativeUpgrade(PlacementRegion region) { if (!_invokingCustomUpgrade && !((Object)(object)region == (Object)null) && IsPlaceHeld()) { int structureId = GetStructureId(GetCurrentUpgrade(region)); if (structureId >= 0) { _handledWhileHeld.Add(structureId); } } } internal bool ShouldSkipNativeUpgrade(PlacementRegion region) { if (_invokingCustomUpgrade || (Object)(object)region == (Object)null || _suppressNativeUpgradeUntilFrame < Time.frameCount) { return false; } _suppressNativeUpgradeUntilFrame = -1; return true; } private void UpdatePrompt() { if (!UpgradeBuildToolsConfig.ShowUpgradeAllPrompt.Value || !UpgradeBuildToolsConfig.Enabled.Value || (Object)(object)PlayerFarming.Instance == (Object)null || (Object)(object)PlayerFarming.Instance.indicator == (Object)null) { HidePrompt(); return; } if (!IsUpgradePlacement(PlacementRegion.Instance, out var _)) { HidePrompt(); return; } Indicator indicator = PlayerFarming.Instance.indicator; if (EnsurePrompt(indicator)) { bool flag = IsControllerInput(); _promptControl.playerFarming = PlayerFarming.Instance; _promptControl.PrioritizeMouse = false; _promptText.text = "Upgrade all"; _promptCellObject.SetActive(true); SizePromptRow(_promptRowObject); _promptRowObject.SetActive(true); if (_promptWasController != flag) { _promptWasController = flag; RefreshPromptGlyph(flag); } } } private bool EnsurePrompt(Indicator indicator) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_promptOwner == (Object)(object)indicator && (Object)(object)_promptCellObject != (Object)null && (Object)(object)_promptControl != (Object)null && (Object)(object)_promptText != (Object)null) { return true; } DestroyPromptUi(); if ((Object)(object)indicator == (Object)null || (Object)(object)indicator.FourthControlPrompt == (Object)null || (Object)(object)((Transform)indicator.FourthControlPrompt).parent == (Object)null || (Object)(object)indicator.Fourthtext == (Object)null) { return false; } EnsurePromptRow(indicator); if ((Object)(object)_promptRowObject == (Object)null) { return false; } GameObject val = new GameObject("UpgradeBuildTools_UpgradeAllCell"); ((Transform)val.AddComponent<RectTransform>()).SetParent(_promptRowObject.transform, false); LayoutElement obj = val.AddComponent<LayoutElement>(); obj.preferredWidth = 150f; obj.minWidth = 150f; HorizontalLayoutGroup obj2 = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f; ((LayoutGroup)obj2).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true; GameObject val2 = Object.Instantiate<GameObject>(((Component)indicator.FourthControlPrompt).gameObject, val.transform, false); ((Object)val2).name = "UpgradeBuildTools_UpgradeAllKey"; val2.SetActive(true); val2.transform.localScale = Vector3.one; MMControlPrompt val3 = val2.GetComponent<MMControlPrompt>() ?? val2.GetComponentInChildren<MMControlPrompt>(true); LayoutElement obj3 = val2.GetComponent<LayoutElement>() ?? val2.AddComponent<LayoutElement>(); obj3.preferredWidth = 50f; obj3.minWidth = 42f; obj3.preferredHeight = 40f; TMP_Text val4 = (TMP_Text)(object)Object.Instantiate<TextMeshProUGUI>(indicator.Fourthtext, val.transform, false); ((Object)val4).name = "UpgradeBuildTools_UpgradeAllLabel"; ((Component)val4).gameObject.SetActive(true); val4.transform.localScale = Vector3.one; val4.alignment = (TextAlignmentOptions)4097; val4.enableAutoSizing = true; val4.fontSizeMin = 12f; val4.fontSizeMax = 22f; LayoutElement obj4 = ((Component)val4).GetComponent<LayoutElement>() ?? ((Component)val4).gameObject.AddComponent<LayoutElement>(); obj4.preferredWidth = 92f; obj4.minWidth = 92f; Behaviour[] components = ((Component)val4).GetComponents<Behaviour>(); foreach (Behaviour val5 in components) { if ((Object)(object)val5 != (Object)null && ((object)val5).GetType().FullName == "I2.Loc.Localize") { val5.enabled = false; } } if ((Object)(object)val3 == (Object)null) { Object.Destroy((Object)(object)val); if (!_promptCreationWarningLogged) { _promptCreationWarningLogged = true; Log.LogWarning((object)"Could not create the standalone Upgrade All control prompt."); } return false; } _promptOwner = indicator; _promptCellObject = val; _promptObject = val2; _promptControl = val3; _promptText = val4; _promptWasController = null; _promptCreationWarningLogged = false; return true; } private void EnsurePromptRow(Indicator indicator) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown Transform promptParent = GetPromptParent(indicator); if (!((Object)(object)promptParent == (Object)null)) { Transform val = promptParent.Find("RemoteBuildCancel_BuilderToolsPromptRow"); if ((Object)(object)val != (Object)null) { ConfigurePromptRow(((Component)val).gameObject); AddVanillaPromptBackground(((Component)val).gameObject, indicator); _promptOwner = indicator; _promptRowObject = ((Component)val).gameObject; } else { GameObject val2 = new GameObject("RemoteBuildCancel_BuilderToolsPromptRow"); ((Transform)val2.AddComponent<RectTransform>()).SetParent(promptParent, false); ConfigurePromptRow(val2); AddVanillaPromptBackground(val2, indicator); val2.transform.SetAsLastSibling(); _promptOwner = indicator; _promptRowObject = val2; } } } private static void ConfigurePromptRow(GameObject row) { //IL_001b: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown RectTransform obj = row.GetComponent<RectTransform>() ?? row.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0.5f, 0f); obj.anchorMax = new Vector2(0.5f, 0f); obj.pivot = new Vector2(0f, 0f); obj.anchoredPosition = new Vector2(240f, 112f); obj.sizeDelta = new Vector2(0f, 52f); LayoutElement obj2 = row.GetComponent<LayoutElement>() ?? row.AddComponent<LayoutElement>(); obj2.minWidth = 0f; obj2.preferredWidth = 0f; obj2.flexibleWidth = 0f; obj2.minHeight = 52f; obj2.preferredHeight = 52f; obj2.flexibleHeight = 0f; ContentSizeFitter obj3 = row.GetComponent<ContentSizeFitter>() ?? row.AddComponent<ContentSizeFitter>(); obj3.horizontalFit = (FitMode)2; obj3.verticalFit = (FitMode)0; ((Behaviour)obj3).enabled = false; HorizontalLayoutGroup obj4 = row.GetComponent<HorizontalLayoutGroup>() ?? row.AddComponent<HorizontalLayoutGroup>(); ((LayoutGroup)obj4).padding = new RectOffset(18, 18, 5, 5); ((HorizontalOrVerticalLayoutGroup)obj4).spacing = 18f; ((LayoutGroup)obj4).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = true; } private static void SizePromptRow(GameObject row) { if ((Object)(object)row == (Object)null) { return; } RectTransform component = row.GetComponent<RectTransform>(); HorizontalLayoutGroup component2 = row.GetComponent<HorizontalLayoutGroup>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { return; } float num = ((LayoutGroup)component2).padding.left + ((LayoutGroup)component2).padding.right; int num2 = 0; for (int i = 0; i < row.transform.childCount; i++) { GameObject gameObject = ((Component)row.transform.GetChild(i)).gameObject; if (gameObject.activeSelf && ((Object)gameObject).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) < 0) { LayoutElement component3 = gameObject.GetComponent<LayoutElement>(); float num3 = (((Object)(object)component3 != (Object)null) ? Mathf.Max(component3.minWidth, component3.preferredWidth) : 0f); if (num3 <= 0f) { num3 = 40f; } if (num2 > 0) { num += ((HorizontalOrVerticalLayoutGroup)component2).spacing; } num += num3; num2++; } } num = Mathf.Max(num, 1f); component.SetSizeWithCurrentAnchors((Axis)0, num); component.SetSizeWithCurrentAnchors((Axis)1, 52f); LayoutElement component4 = row.GetComponent<LayoutElement>(); if ((Object)(object)component4 != (Object)null) { component4.minWidth = num; component4.preferredWidth = num; } } private static Transform GetPromptParent(Indicator indicator) { Transform val = (((Object)(object)indicator != (Object)null && (Object)(object)indicator.ControlPromptUI != (Object)null) ? indicator.ControlPromptUI.transform : (((Object)(object)indicator != (Object)null) ? ((Component)indicator).transform : null)); if ((Object)(object)val == (Object)null) { return null; } Canvas val2 = ((Component)val).GetComponent<Canvas>() ?? ((Component)val).GetComponentInParent<Canvas>(); if (!((Object)(object)val2 != (Object)null)) { if (!((Object)(object)val.parent != (Object)null)) { return val; } return val.parent; } return ((Component)val2).transform; } private static void AddVanillaPromptBackground(GameObject row, Indicator indicator) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Image val = (((Object)(object)indicator != (Object)null && (Object)(object)indicator.BG != (Object)null) ? (((Component)indicator.BG).GetComponent<Image>() ?? ((Component)indicator.BG).GetComponentInChildren<Image>(true)) : null); Image val2 = row.GetComponent<Image>() ?? row.AddComponent<Image>(); ((Behaviour)val2).enabled = true; ((Graphic)val2).raycastTarget = false; val2.sprite = (((Object)(object)val != (Object)null) ? val.sprite : null); val2.type = (Type)(((Object)(object)val != (Object)null) ? ((int)val.type) : 0); if ((Object)(object)val2.sprite == (Object)null) { val2.sprite = Sprite.Create(Texture2D.whiteTexture, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); val2.type = (Type)0; } ((Graphic)val2).color = new Color(0f, 0f, 0f, 0.88f); ((Graphic)val2).canvasRenderer.SetColor(((Graphic)val2).color); } private void RefreshPromptGlyph(bool controller) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_promptControl == (Object)null)) { SetCustomPromptKey(_promptControl, controller ? ControllerButtonLabel(_controllerUpgradeAllKey) : ((object)Unsafe.As<KeyCode, KeyCode>(ref _upgradeAllKey)/*cast due to .constrained prefix*/).ToString()); } } private static void SetCustomPromptKey(MMControlPrompt prompt, string label) { prompt.IgnoreControllerChange = true; object? obj = AccessTools.Field(typeof(MMControlPrompt), "_text")?.GetValue(prompt); TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); object? obj2 = AccessTools.Field(typeof(MMControlPrompt), "_iconText")?.GetValue(prompt); TMP_Text val2 = (TMP_Text)((obj2 is TMP_Text) ? obj2 : null); object? obj3 = AccessTools.Field(typeof(MMControlPrompt), "_icon")?.GetValue(prompt); Image val3 = (Image)((obj3 is Image) ? obj3 : null); if ((Object)(object)val != (Object)null) { val.text = label; val.fontSize = 20f; val.enableAutoSizing = true; val.fontSizeMin = 8f; val.fontSizeMax = 20f; ((Component)val).gameObject.SetActive(true); } if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(false); } if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(true); } } private static bool IsControllerInput() { try { return (Object)(object)PlayerFarming.Instance != (Object)null && InputManager.General.InputIsController(PlayerFarming.Instance); } catch { return false; } } private unsafe static string ControllerButtonLabel(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_0034: Expected I4, but got Unknown return (key - 330) switch { 0 => "A", 1 => "B", 2 => "X", 3 => "Y", 4 => "LB", 5 => "RB", 6 => "Back", 7 => "Start", 8 => "LS", 9 => "RS", _ => ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString().Replace("JoystickButton", "Pad "), }; } private void HidePrompt() { if ((Object)(object)_promptCellObject != (Object)null) { _promptCellObject.SetActive(false); } RefreshPromptRowVisibility(_promptRowObject); } private static void RefreshPromptRowVisibility(GameObject row) { if ((Object)(object)row == (Object)null) { return; } bool active = false; for (int i = 0; i < row.transform.childCount; i++) { GameObject gameObject = ((Component)row.transform.GetChild(i)).gameObject; if (gameObject.activeSelf && ((Object)gameObject).name.IndexOf("VanillaPromptBackground", StringComparison.Ordinal) < 0) { active = true; break; } } SizePromptRow(row); row.SetActive(active); } private void DestroyPromptUi() { if ((Object)(object)_promptCellObject != (Object)null) { Object.Destroy((Object)(object)_promptCellObject); } _promptOwner = null; _promptRowObject = null; _promptCellObject = null; _promptObject = null; _promptControl = null; _promptText = null; _promptWasController = null; } private static KeyCode ParseKey(string raw, KeyCode fallback) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references) try { return (KeyCode)Enum.Parse(typeof(KeyCode), raw, ignoreCase: true); } catch { return fallback; } } } internal static class UpgradeBuildToolsConfig { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> EnableHoldToUpgrade; internal static ConfigEntry<bool> EnableControllerUpgradeAll; internal static ConfigEntry<bool> ShowUpgradeAllPrompt; internal static ConfigEntry<string> UpgradeAllKey; internal static ConfigEntry<string> ControllerUpgradeAllKey; internal static ConfigEntry<float> UpgradeInterval; internal static void Bind(ConfigFile config) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Upgrade Build Tools."); ShowUpgradeAllPrompt = config.Bind<bool>("General", "ShowUpgradeAllPrompt", true, "Show the vanilla-style Upgrade all prompt while an upgrade is selected."); EnableHoldToUpgrade = config.Bind<bool>("Behavior", "EnableHoldToUpgrade", true, "Upgrade each new structure under the mouse while the normal place input is held."); UpgradeInterval = config.Bind<float>("Behavior", "UpgradeInterval", 0.16f, new ConfigDescription("Minimum seconds between held upgrades. Matches Path Brush Plus by default.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>())); UpgradeAllKey = config.Bind<string>("Controls", "UpgradeAllKey", "G", "Keyboard key that upgrades every eligible previous-tier structure to the selected upgrade."); EnableControllerUpgradeAll = config.Bind<bool>("Controls", "EnableControllerUpgradeAll", true, "Enable the controller shortcut for Upgrade all."); ControllerUpgradeAllKey = config.Bind<string>("Controls", "ControllerUpgradeAllKey", "JoystickButton3", "Controller button used for Upgrade all. JoystickButton3 is Y on the standard layout."); } } }