Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BetterHammer v1.0.1
BetterHammer.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BetterHammer.Core; using BetterHammer.Grid; using BetterHammer.Materials; using BetterHammer.Structures; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("BetterHammer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Open the build menu without a hammer, build with nearby materials, snap to a build grid, and copy and move structures.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+9ebcc11310090566bef46a7bd35a2e1c4f7e2898")] [assembly: AssemblyProduct("BetterHammer")] [assembly: AssemblyTitle("BetterHammer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BetterHammer { [BepInPlugin("javidahmed64592.betterhammer", "Better Hammer", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class BetterHammerPlugin : BaseUnityPlugin { public const string PluginGUID = "javidahmed64592.betterhammer"; public const string PluginName = "Better Hammer"; public const string PluginVersion = "1.0.1"; private const string HammerPrefabName = "Hammer"; private const string ButtonName = "BetterHammer_Toggle"; private const string ButtonQueryName = "BetterHammer_Toggle!javidahmed64592.betterhammer"; private static readonly float[] GridSizes = new float[5] { 0.25f, 0.5f, 1f, 2f, 4f }; internal static ItemData _phantomHammer; private static ConfigEntry<bool> _gridEnabled; internal static ConfigEntry<float> _gridSize; private static readonly GridOverlay Overlay = new GridOverlay(); internal static int _aimFrame = -10; internal static Vector3 _aimPoint; internal static GridPlane _aimPlane; internal static float _aimSign; private ConfigEntry<KeyCode> _keybind; private Harmony _harmony; private bool _knownRecipesRefreshed; private Piece _lastBuildPiece; internal static bool GridEnabled => _gridEnabled.Value; 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown _keybind = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keybinds", "Open Build Menu", (KeyCode)98, "Equips a virtual hammer and opens the build menu, without needing a real hammer in your inventory. Rebindable from the in-game controls menu."); InputManager.Instance.AddButton("javidahmed64592.betterhammer", new ButtonConfig { Name = "BetterHammer_Toggle", Config = _keybind }); _gridEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Grid", "Enabled", true, "Show a world grid while building and snap pieces to its vertices."); _gridSize = ((BaseUnityPlugin)this).Config.Bind<float>("Grid", "Snap Distance", GridSizes[1], new ConfigDescription("Distance in metres between grid vertices (0.25, 0.5, 1, 2 or 4). While building, hold Ctrl and scroll to double or halve it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(GridSizes[0], GridSizes[GridSizes.Length - 1]), Array.Empty<object>())); GridOverlay.BindConfig(((BaseUnityPlugin)this).Config); ChestMaterials.BindConfig(((BaseUnityPlugin)this).Config); CopyLibrary.BindConfig(((BaseUnityPlugin)this).Config); MultiCopy.BindConfig(((BaseUnityPlugin)this).Config); Translations.Load(); if (Array.IndexOf(GridSizes, _gridSize.Value) < 0) { _gridSize.Value = GridSizes[1]; } _harmony = new Harmony("javidahmed64592.betterhammer"); _harmony.PatchAll(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Overlay.Destroy(); } private void Update() { if (_phantomHammer != null) { _phantomHammer.m_durability = _phantomHammer.m_shared.m_maxDurability; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { _phantomHammer = null; _knownRecipesRefreshed = false; _lastBuildPiece = null; PieceMover.Reset(); MultiCopy.Reset(); Overlay.Hide(); return; } EnsurePhantomHammer(); CopyLibrary.EnsureLoaded(localPlayer, _phantomHammer?.m_shared.m_buildPieces); if (!_knownRecipesRefreshed && _phantomHammer != null) { _knownRecipesRefreshed = true; localPlayer.UpdateKnownRecipesList(); } if (Menu.IsVisible() || InventoryGui.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())) { Overlay.Hide(); return; } CopyLibrary.UpdateMenuInput(localPlayer); MultiCopy.UpdateSelectionKeys(localPlayer); if (ZInput.GetButtonDown("BetterHammer_Toggle!javidahmed64592.betterhammer")) { ToggleBuildMenu(localPlayer); } if (((Character)localPlayer).InPlaceMode() && Input.GetMouseButtonDown(1) && !PieceMover.RightClickConsumed && !MultiCopy.RightClickConsumed) { if (ShiftHeld()) { ToggleRepairMode(localPlayer); } else if (CtrlHeld()) { ToggleGrid(localPlayer); } } UpdateGrid(localPlayer); } private void LateUpdate() { MultiCopy.UpdateHighlight(); PieceMover.UpdateHighlight(); } private static void ToggleGrid(Player player) { _gridEnabled.Value = !_gridEnabled.Value; ((Character)player).Message((MessageType)1, _gridEnabled.Value ? "$betterhammer_grid_on" : "$betterhammer_grid_off", 0, (Sprite)null, false); } private static void UpdateGrid(Player player) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!GridActive(player) || Time.frameCount - _aimFrame > 2 || _aimPlane == GridPlane.None) { Overlay.Hide(); return; } HandleGridScroll(player); Overlay.Show(_aimPoint, _gridSize.Value, _aimPlane, _aimSign); } internal static bool GridActive(Player player) { if (_gridEnabled.Value && ((Character)player).InPlaceMode() && !player.InRepairMode() && (Object)(object)player.m_placementGhost != (Object)null) { return IsHammerEquipped(player); } return false; } internal static bool IsHammerEquipped(Player player) { ItemData rightItem = ((Humanoid)player).GetRightItem(); if (rightItem == null) { return false; } if (rightItem == _phantomHammer) { return true; } PieceTable val = rightItem.m_shared?.m_buildPieces; if ((Object)(object)val != (Object)null) { if (!ContainsHammer(rightItem.m_shared.m_name) && !ContainsHammer(((Object)(object)rightItem.m_dropPrefab != (Object)null) ? ((Object)rightItem.m_dropPrefab).name : null)) { return ContainsHammer(((Object)val).name); } return true; } return false; } private static bool ContainsHammer(string name) { if (name != null) { return name.IndexOf("hammer", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } internal static bool ShiftHeld() { if (!Input.GetKey((KeyCode)304)) { return Input.GetKey((KeyCode)303); } return true; } internal static bool CtrlHeld() { if (!Input.GetKey((KeyCode)306)) { return Input.GetKey((KeyCode)305); } return true; } internal static bool AltHeld() { if (!Input.GetKey((KeyCode)308)) { return Input.GetKey((KeyCode)307); } return true; } internal static bool AltZoomActive(Player player) { if ((Object)(object)player == (Object)(object)Player.m_localPlayer && AltHeld() && ((Character)player).InPlaceMode()) { return IsHammerEquipped(player); } return false; } private static void HandleGridScroll(Player player) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) float y = Input.mouseScrollDelta.y; if (y != 0f && CtrlHeld()) { float num = ((y > 0f) ? (_gridSize.Value * 2f) : (_gridSize.Value / 2f)); num = Mathf.Clamp(num, GridSizes[0], GridSizes[GridSizes.Length - 1]); if (!Mathf.Approximately(num, _gridSize.Value)) { _gridSize.Value = num; ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_grid_distance", new string[1] { num.ToString("0.###", CultureInfo.InvariantCulture) }), 0, (Sprite)null, false); } } } private void ToggleRepairMode(Player player) { if (player.InRepairMode()) { if ((Object)(object)_lastBuildPiece != (Object)null) { player.SetSelectedPiece(_lastBuildPiece); } return; } _lastBuildPiece = player.GetSelectedPiece(); Piece val = player.GetBuildPieces()?.FirstOrDefault((Func<Piece, bool>)((Piece p) => p.m_repairPiece)); if ((Object)(object)val != (Object)null) { player.SetSelectedPiece(val); } } private static void ToggleBuildMenu(Player player) { EnsurePhantomHammer(); if (_phantomHammer != null) { if (((Humanoid)player).GetRightItem() != _phantomHammer) { ((Humanoid)player).EquipItem(_phantomHammer, true); } else { ((Humanoid)player).UnequipItem(_phantomHammer, true); } } } private static void EnsurePhantomHammer() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown if (_phantomHammer == null && !((Object)(object)ObjectDB.instance == (Object)null)) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hammer"); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); _phantomHammer = new ItemData { m_shared = component.m_itemData.m_shared, m_dropPrefab = itemPrefab, m_stack = 1, m_quality = 1, m_variant = 0, m_durability = component.m_itemData.m_shared.m_maxDurability, m_customData = new Dictionary<string, string>() }; } } } } } namespace BetterHammer.UI { internal static class KeyHintUI { private enum HintVisibility { Always, GridOnly, BuildOnly, SelectionOnly, CopyOnly } private sealed class Hint { public string Label; public int Column; public string[] Keys; public HintVisibility Visibility; public GameObject Item; public CanvasGroup Group; } [HarmonyPatch(typeof(KeyHints), "UpdateHints")] private static class KeyHints_UpdateHints_Patch { [HarmonyPostfix] private static void Postfix(KeyHints __instance) { if (_container != null && (Object)(object)_container == (Object)null) { Reset(); } Update(__instance, Player.m_localPlayer); } } private const string ContainerName = "BetterHammer_KeyHints"; private const string ScrollIcon = "@scroll"; private const float LabelFontSize = 16f; private const float IconHeight = 32f; private const float IconScale = 1.8f; private const float ColumnSpacing = 12f; private const float RowSpacing = 16f; private const string Or = "/"; private const string DeleteKey = "@delete"; private const string ClearKey = "@clear"; private static readonly List<Hint> Hints = new List<Hint>(11) { new Hint { Label = "$betterhammer_hint_copy_selection", Column = 0, Keys = new string[2] { "Left Alt", "$button_mouse0" }, Visibility = HintVisibility.SelectionOnly }, new Hint { Label = "$betterhammer_hint_deselect", Column = 0, Keys = new string[2] { "Left Alt", "$button_mouse1" }, Visibility = HintVisibility.SelectionOnly }, new Hint { Label = "$betterhammer_hint_select", Column = 0, Keys = new string[2] { "Left Alt", "$button_mouse2" }, Visibility = HintVisibility.Always }, new Hint { Label = "$betterhammer_hint_move", Column = 0, Keys = new string[2] { "Left Ctrl", "$button_mouse2" }, Visibility = HintVisibility.Always }, new Hint { Label = "$betterhammer_hint_grid", Column = 0, Keys = new string[2] { "Left Ctrl", "$button_mouse1" }, Visibility = HintVisibility.BuildOnly }, new Hint { Label = "$betterhammer_hint_repair", Column = 0, Keys = new string[2] { "Left Shift", "$button_mouse1" }, Visibility = HintVisibility.Always }, new Hint { Label = "$betterhammer_hint_copy_piece", Column = 1, Keys = new string[4] { "Left Shift", "$KEY_TabLeft", "/", "$KEY_TabRight" }, Visibility = HintVisibility.CopyOnly }, new Hint { Label = "$betterhammer_hint_delete_selection", Column = 1, Keys = new string[1] { "@delete" }, Visibility = HintVisibility.SelectionOnly }, new Hint { Label = "$betterhammer_hint_clear_selection", Column = 1, Keys = new string[1] { "@clear" }, Visibility = HintVisibility.SelectionOnly }, new Hint { Label = "$betterhammer_hint_grid_distance", Column = 1, Keys = new string[2] { "Left Ctrl", "@scroll" }, Visibility = HintVisibility.GridOnly }, new Hint { Label = "$betterhammer_hint_zoom", Column = 1, Keys = new string[2] { "Left Alt", "@scroll" }, Visibility = HintVisibility.Always } }; private static GameObject _container; private static RectTransform _rotateAnchor; private static RectTransform _rotateIcon; private static Image _rotateIconImage; private static bool _createFailed; private static bool _layoutDirty; private static TextMeshProUGUI _buildMenuLabel; private static string _buildMenuText; public static void Update(KeyHints keyHints, Player player) { //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown UpdateAbortHint(keyHints); if (!((Object)(object)keyHints.m_buildHints != (Object)null) || !keyHints.m_buildHints.activeInHierarchy || !((Object)(object)player != (Object)null) || !((Character)player).InPlaceMode() || ZInput.IsGamepadActive() || !BetterHammerPlugin.IsHammerEquipped(player)) { if ((Object)(object)_container != (Object)null && _container.activeSelf) { _container.SetActive(false); } } else { if ((Object)(object)_container == (Object)null && (_createFailed || !Create(keyHints))) { return; } bool flag = player.InRepairMode(); bool gridEnabled = BetterHammerPlugin.GridEnabled; foreach (Hint hint in Hints) { bool flag2 = true; bool flag3 = false; switch (hint.Visibility) { case HintVisibility.BuildOnly: flag2 = !flag; break; case HintVisibility.GridOnly: flag2 = !flag; flag3 = !gridEnabled; break; case HintVisibility.SelectionOnly: flag3 = !MultiCopy.HasSelection; break; case HintVisibility.CopyOnly: flag2 = GhostGroup.Active; break; } if (hint.Item.activeSelf != flag2) { hint.Item.SetActive(flag2); _layoutDirty = true; } hint.Group.alpha = (flag3 ? 0f : 1f); } if (!_container.activeSelf) { _container.SetActive(true); _layoutDirty = true; } if (_layoutDirty) { LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)_container.transform); _layoutDirty = false; } AlignToRotateHint(); } } private static void UpdateAbortHint(KeyHints keyHints) { if ((Object)(object)_buildMenuLabel == (Object)null && (Object)(object)keyHints.m_buildHints != (Object)null) { Transform val = keyHints.m_buildHints.transform.Find("Keyboard/BuildMenu/Text"); _buildMenuLabel = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TextMeshProUGUI>() : null); _buildMenuText = null; } if ((Object)(object)_buildMenuLabel == (Object)null) { return; } if (PieceMover.Moving) { if (_buildMenuText == null) { _buildMenuText = ((TMP_Text)_buildMenuLabel).text; } ((TMP_Text)_buildMenuLabel).text = Localization.instance.Localize("$betterhammer_hint_abort"); } else if (_buildMenuText != null) { ((TMP_Text)_buildMenuLabel).text = _buildMenuText; _buildMenuText = null; } } private static void AlignToRotateHint() { //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_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_004d: 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_0093: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[4]; _rotateAnchor.GetWorldCorners(array); Rect rect = _rotateIcon.rect; float num = Mathf.Min(((Rect)(ref rect)).width, ((Rect)(ref rect)).height * SpriteAspect(_rotateIconImage)); float num2 = ((Transform)_rotateIcon).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center)).x + num / 2f * ((Transform)_rotateIcon).lossyScale.x; _container.transform.position = new Vector3(num2, array[2].y, array[2].z); } private static bool Create(KeyHints keyHints) { //IL_0118: 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_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Expected O, but got Unknown //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_0520: Expected O, but got Unknown //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Expected O, but got Unknown //IL_0462: Unknown result type (might be due to invalid IL or missing references) Transform val = keyHints.m_buildHints.transform.Find("Keyboard"); Transform val2 = (((Object)(object)val != (Object)null) ? val.Find("Copy") : null); Transform val3 = (((Object)(object)val != (Object)null) ? val.Find("rotate") : null); Transform val4 = (((Object)(object)val2 != (Object)null) ? val2.Find("Text") : null); Transform val5 = (((Object)(object)val2 != (Object)null) ? val2.Find("Text (1)") : null); Transform val6 = (((Object)(object)val2 != (Object)null) ? val2.Find("key_bkg") : null); Transform val7 = (((Object)(object)val3 != (Object)null) ? val3.Find("mousew_icon") : null); HorizontalLayoutGroup val8 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<HorizontalLayoutGroup>() : null); if ((Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null || (Object)(object)val7 == (Object)null || (Object)(object)val8 == (Object)null) { _createFailed = true; Debug.LogWarning((object)"BetterHammer: vanilla build key hints layout not as expected, not adding key hints."); return false; } RectTransform component = new GameObject("BetterHammer_KeyHints", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent(keyHints.m_buildHints.transform, false); component.pivot = new Vector2(1f, 0f); HorizontalLayoutGroup obj = ((Component)component).gameObject.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 12f; ((LayoutGroup)obj).childAlignment = (TextAnchor)8; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; ContentSizeFitter obj2 = ((Component)component).gameObject.AddComponent<ContentSizeFitter>(); obj2.horizontalFit = (FitMode)2; obj2.verticalFit = (FitMode)2; int num = 0; foreach (Hint hint in Hints) { num = Mathf.Max(num, hint.Column + 1); } Transform[] array = (Transform[])(object)new Transform[num]; for (int i = 0; i < num; i++) { GameObject val9 = new GameObject("BetterHammer_KeyHints_Column" + i, new Type[1] { typeof(RectTransform) }); val9.transform.SetParent((Transform)(object)component, false); VerticalLayoutGroup obj3 = val9.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 16f; ((LayoutGroup)obj3).childAlignment = (TextAnchor)((i == num - 1) ? 8 : 6); ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; array[i] = val9.transform; } foreach (Hint hint2 in Hints) { GameObject val10 = Object.Instantiate<GameObject>(((Component)val2).gameObject, array[hint2.Column], false); ((Object)val10).name = "BetterHammer_Hint_" + hint2.Label.TrimStart(new char[1] { '$' }); val10.SetActive(true); for (int num2 = val10.transform.childCount - 1; num2 >= 0; num2--) { Object.DestroyImmediate((Object)(object)((Component)val10.transform.GetChild(num2)).gameObject); } AddText(val4, val10.transform, Localization.instance.Localize(hint2.Label)); for (int j = 0; j < hint2.Keys.Length; j++) { if (hint2.Keys[j] == "/") { AddText(val5, val10.transform, "/"); continue; } if (j > 0 && hint2.Keys[j - 1] != "/") { AddText(val5, val10.transform, "+"); } if (hint2.Keys[j] == "@scroll") { GameObject val11 = Object.Instantiate<GameObject>(((Component)val7).gameObject, val10.transform, false); val11.SetActive(true); Image component2 = val11.GetComponent<Image>(); component2.preserveAspect = true; float num3 = SpriteAspect(component2); LayoutElement obj4 = val11.GetComponent<LayoutElement>() ?? val11.AddComponent<LayoutElement>(); float minWidth = (obj4.preferredWidth = 32f * num3 * 1.8f); obj4.minWidth = minWidth; minWidth = (obj4.preferredHeight = 32f); obj4.minHeight = minWidth; minWidth = (obj4.flexibleHeight = 0f); obj4.flexibleWidth = minWidth; val11.transform.localScale = new Vector3(1.8f, 1.8f, 1f); } else { GameObject obj5 = Object.Instantiate<GameObject>(((Component)val6).gameObject, val10.transform, false); obj5.SetActive(true); ((TMP_Text)obj5.GetComponentInChildren<TextMeshProUGUI>()).text = KeyText(hint2.Keys[j]); } } hint2.Item = val10; hint2.Group = val10.GetComponent<CanvasGroup>() ?? val10.AddComponent<CanvasGroup>(); } LayoutRebuilder.ForceRebuildLayoutImmediate(component); for (int k = 0; k < num; k++) { EqualiseColumnWidths(k); } _rotateAnchor = (RectTransform)val3; _rotateIcon = (RectTransform)val7; _rotateIconImage = ((Component)val7).GetComponent<Image>(); _container = ((Component)component).gameObject; _layoutDirty = true; return true; } private static void EqualiseColumnWidths(int column) { //IL_00bb: 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_00c5: Unknown result type (might be due to invalid IL or missing references) List<Transform> list = new List<Transform>(); foreach (Hint hint in Hints) { if (hint.Column == column) { list.Add(hint.Item.transform); } } int num = int.MaxValue; foreach (Transform item in list) { num = Mathf.Min(num, item.childCount); } for (int i = 0; i < num; i++) { float num2 = 0f; foreach (Transform item2 in list) { float num3 = num2; Rect rect = ((RectTransform)item2.GetChild(i)).rect; num2 = Mathf.Max(num3, ((Rect)(ref rect)).width); } foreach (Transform item3 in list) { GameObject gameObject = ((Component)item3.GetChild(i)).gameObject; (gameObject.GetComponent<LayoutElement>() ?? gameObject.AddComponent<LayoutElement>()).minWidth = num2; } } } private static string KeyText(string key) { //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!(key == "@delete")) { if (key == "@clear") { return ((object)MultiCopy.ClearKey/*cast due to .constrained prefix*/).ToString(); } return Localization.instance.Localize(key); } return ((object)CopyLibrary.DeleteKey/*cast due to .constrained prefix*/).ToString(); } private static float SpriteAspect(Image image) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!((Object)(object)image.sprite != (Object)null)) { return 0.6f; } Rect rect = image.sprite.rect; float width = ((Rect)(ref rect)).width; rect = image.sprite.rect; return width / ((Rect)(ref rect)).height; } private static void AddText(Transform template, Transform parent, string text) { GameObject obj = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); obj.SetActive(true); LayoutElement component = obj.GetComponent<LayoutElement>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } TextMeshProUGUI component2 = obj.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component2).enableAutoSizing = false; ((TMP_Text)component2).fontSize = 16f; ((TMP_Text)component2).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)component2).text = text; } public static void Reset() { _container = null; _rotateAnchor = null; _rotateIcon = null; _rotateIconImage = null; _createFailed = false; _buildMenuLabel = null; _buildMenuText = null; foreach (Hint hint in Hints) { hint.Item = null; hint.Group = null; } } } } namespace BetterHammer.Structures { internal static class CopyLibrary { private sealed class LibraryFile { public int NextNumber = 1; public List<SavedCopy> Copies = new List<SavedCopy>(); } internal sealed class SavedCopy { public int Number; public string Name; public List<SavedPiece> Pieces = new List<SavedPiece>(); } internal sealed class SavedPiece { public string Prefab; public float[] Position; public float[] Rotation; } internal sealed class Part { public Piece Prefab; public Vector3 Position; public Quaternion Rotation; public int SnapCount; } internal sealed class Copy { public string Name; public Piece Piece; public readonly List<Part> Parts = new List<Part>(); public readonly List<Piece> Prefabs = new List<Piece>(); public List<Piece> StationPieces = new List<Piece>(); public string Description; public SavedCopy Saved; } private sealed class NameReceiver(string initial, Action<string> onEntered) : TextReceiver { public string GetText() { return initial; } public void SetText(string text) { onEntered(text); } } [CompilerGenerated] private static class <>O { public static PopupButtonCallback <0>__Pop; } private const string CategoryName = "Copies"; private static readonly List<Copy> Copies = new List<Copy>(); private static readonly HashSet<string> Names = new HashSet<string>(); private static readonly List<Transform> SnapPoints = new List<Transform>(); private static LibraryFile _file; private static PieceTable _table; private static GameObject _container; private static PieceCategory _category; private const int NameCharacterLimit = 40; private static ConfigEntry<KeyCode> _deleteKey; private static ConfigEntry<KeyCode> _renameKey; private static string FilePath => Path.Combine(Paths.ConfigPath, "BetterHammer", "copies.json"); internal static KeyCode DeleteKey { get { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (_deleteKey == null) { return (KeyCode)127; } return _deleteKey.Value; } } internal static IEnumerable<string> AllNames => Names; public static void BindConfig(ConfigFile config) { _deleteKey = config.Bind<KeyCode>("Keybinds", "Delete", (KeyCode)127, "With the build menu open, hover a saved copy in the Copies tab and press this to delete it. With the build menu closed, press it to remove every piece selected for copying."); _renameKey = config.Bind<KeyCode>("Keybinds", "Rename Copy", (KeyCode)277, "With the build menu open, hover a saved copy in the Copies tab and press this to rename it."); } internal static void AskForName(string topic, string current, Action<string> onEntered) { if ((Object)(object)TextInput.instance == (Object)null) { onEntered(current); } else { TextInput.instance.RequestText((TextReceiver)(object)new NameReceiver(current, onEntered), topic, 40); } } internal static string NextDefaultName() { return DefaultName((_file == null) ? 1 : _file.NextNumber); } private static string DefaultName(int number) { return Localization.instance.Localize("$betterhammer_copy_name", new string[1] { number.ToString(CultureInfo.InvariantCulture) }); } private static string CleanName(string name, int number) { name = name?.Trim(); if (!string.IsNullOrEmpty(name) && !(name == DefaultName(number))) { return name; } return null; } private static void RefreshNames() { Names.Clear(); foreach (Copy copy in Copies) { Names.Add(copy.Name); } } internal static void EnsureLoaded(Player player, PieceTable table) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown if (_file != null || (Object)(object)table == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return; } _table = table; _category = PieceManager.Instance.AddPieceCategory("Copies"); _container = new GameObject("BetterHammer_Copies"); _container.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_container); _file = Read(); foreach (SavedCopy copy in _file.Copies) { Register(copy); } player.UpdateAvailablePiecesList(); } internal static Copy Find(Piece piece) { if ((Object)(object)piece == (Object)null) { return null; } foreach (Copy copy in Copies) { if ((Object)(object)copy.Piece == (Object)(object)piece) { return copy; } } return null; } internal static bool IsCopyName(string name) { return Names.Contains(name); } internal static Copy Add(Player player, IList<(Piece Prefab, Vector3 Position, Quaternion Rotation)> pieces, string name) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_007a: 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_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_00a9: 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_00bd: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (_file == null || pieces.Count == 0) { return null; } Vector3 item = pieces[0].Position; SavedCopy savedCopy = new SavedCopy { Number = _file.NextNumber++ }; savedCopy.Name = CleanName(name, savedCopy.Number); foreach (var piece in pieces) { Piece item2 = piece.Prefab; Vector3 item3 = piece.Position; Quaternion item4 = piece.Rotation; Vector3 val = item3 - item; savedCopy.Pieces.Add(new SavedPiece { Prefab = ((Object)item2).name, Position = new float[3] { val.x, val.y, val.z }, Rotation = new float[4] { item4.x, item4.y, item4.z, item4.w } }); } _file.Copies.Add(savedCopy); Save(); Copy result = Register(savedCopy); player.UpdateAvailablePiecesList(); return result; } internal static void UpdateMenuInput(Player player) { //IL_002f: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //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) //IL_00ea: Expected O, but got Unknown if (_deleteKey == null || !Hud.IsPieceSelectionVisible() || UnifiedPopup.IsVisible() || TypingInTextField()) { return; } bool keyDown = Input.GetKeyDown(_deleteKey.Value); bool flag = !keyDown && Input.GetKeyDown(_renameKey.Value); Copy copy = ((keyDown || flag) ? Find(Hud.instance.m_hoveredPiece) : null); if (copy == null) { return; } if (flag) { AskForName("$betterhammer_copy_rename_title", copy.Name, delegate(string name) { Rename(player, copy, name); }); return; } string text = Localization.instance.Localize("$betterhammer_copy_delete_text", new string[1] { copy.Name }); PopupButtonCallback val = delegate { UnifiedPopup.Pop(); Delete(player, copy); }; object obj = <>O.<0>__Pop; if (obj == null) { PopupButtonCallback val2 = UnifiedPopup.Pop; <>O.<0>__Pop = val2; obj = (object)val2; } UnifiedPopup.Push((PopupBase)new YesNoPopup("$betterhammer_copy_delete_title", text, val, (PopupButtonCallback)obj, true, false)); } internal static bool TypingInTextField() { if (Console.IsVisible() || TextInput.IsVisible()) { return true; } GameObject val = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null); TMP_InputField val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<TMP_InputField>() : null); if ((Object)(object)val2 != (Object)null) { return val2.isFocused; } return false; } internal static string MenuHint() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (_deleteKey == null) { return ""; } return Localization.instance.Localize("$betterhammer_copy_menu_hint", new string[2] { ((object)_renameKey.Value/*cast due to .constrained prefix*/).ToString(), ((object)_deleteKey.Value/*cast due to .constrained prefix*/).ToString() }); } private static void Rename(Player player, Copy copy, string name) { if (!Copies.Contains(copy)) { return; } string name2 = copy.Name; copy.Saved.Name = CleanName(name, copy.Saved.Number); copy.Name = copy.Saved.Name ?? DefaultName(copy.Saved.Number); copy.Piece.m_name = copy.Name; Save(); RefreshNames(); if ((Object)(object)player != (Object)null) { player.UpdateAvailablePiecesList(); if (Hud.IsPieceSelectionVisible()) { Hud.instance.m_buildUi.OpenBuildMenu(); } ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_copy_renamed", new string[2] { name2, copy.Name }), 0, (Sprite)null, false); } } private static void Delete(Player player, Copy copy) { _table.m_pieces.Remove(((Component)copy.Piece).gameObject); Copies.Remove(copy); RefreshNames(); _file.Copies.Remove(copy.Saved); Save(); if ((Object)(object)player != (Object)null) { player.UpdateAvailablePiecesList(); if (Hud.IsPieceSelectionVisible()) { Hud.instance.m_buildUi.OpenBuildMenu(); } ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_copy_deleted", new string[1] { copy.Name }), 0, (Sprite)null, false); } } internal static Part MakePart(Piece prefab, Vector3 position, Quaternion rotation) { //IL_0037: 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_003e: 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) SnapPoints.Clear(); prefab.GetSnapPoints(SnapPoints); int count = SnapPoints.Count; SnapPoints.Clear(); return new Part { Prefab = prefab, Position = position, Rotation = rotation, SnapCount = count }; } private static Copy Register(SavedCopy saved) { //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Expected O, but got Unknown //IL_01f0: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) Copy copy = new Copy { Name = (CleanName(saved.Name, saved.Number) ?? DefaultName(saved.Number)), Saved = saved }; foreach (SavedPiece piece in saved.Pieces) { GameObject prefab = ZNetScene.instance.GetPrefab(piece.Prefab); Piece val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Piece>() : null); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("BetterHammer: copy " + saved.Number + " uses missing piece " + piece.Prefab + ", not adding it.")); return null; } SnapPoints.Clear(); val.GetSnapPoints(SnapPoints); List<Part> parts = copy.Parts; Part obj = new Part { Prefab = val, Position = new Vector3(piece.Position[0], piece.Position[1], piece.Position[2]) }; Quaternion val2 = new Quaternion(piece.Rotation[0], piece.Rotation[1], piece.Rotation[2], piece.Rotation[3]); obj.Rotation = ((Quaternion)(ref val2)).normalized; obj.SnapCount = SnapPoints.Count; parts.Add(obj); copy.Prefabs.Add(val); } SnapPoints.Clear(); if (copy.Parts.Count == 0) { return null; } GameObject val3 = new GameObject("BetterHammer_Copy_" + saved.Number.ToString(CultureInfo.InvariantCulture)); val3.transform.SetParent(_container.transform, false); Piece val4 = val3.AddComponent<Piece>(); val4.m_name = copy.Name; val4.m_category = _category; val4.m_resources = CombineRequirements(copy.Prefabs, out copy.StationPieces).ToArray(); val4.m_craftingStation = ((copy.StationPieces.Count > 0) ? copy.StationPieces[0].m_craftingStation : null); copy.Description = DescribePieces(copy.Prefabs); val4.m_description = copy.Description; val4.m_icon = RenderIcon(copy) ?? copy.Prefabs[0].m_icon; copy.Piece = val4; _table.m_pieces.Add(val3); Copies.Add(copy); RefreshNames(); return copy; } internal static List<Requirement> CombineRequirements(IEnumerable<Piece> pieces, out List<Piece> stationPieces) { //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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown List<Requirement> list = new List<Requirement>(); Dictionary<string, Requirement> dictionary = new Dictionary<string, Requirement>(); HashSet<string> hashSet = new HashSet<string>(); stationPieces = new List<Piece>(); foreach (Piece piece in pieces) { Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!((Object)(object)val.m_resItem == (Object)null) && val.m_amount > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; if (dictionary.TryGetValue(name, out var value)) { Requirement obj = value; obj.m_amount += val.m_amount; continue; } value = (dictionary[name] = new Requirement { m_resItem = val.m_resItem, m_amount = val.m_amount, m_recover = val.m_recover }); list.Add(value); } } if ((Object)(object)piece.m_craftingStation != (Object)null && hashSet.Add(piece.m_craftingStation.m_name)) { stationPieces.Add(piece); } } return list; } internal static string DescribePieces(IEnumerable<Piece> pieces) { return string.Join(", ", from piece in pieces group piece by piece.m_name into same select same.Count().ToString(CultureInfo.InvariantCulture) + "× " + Localization.instance.Localize(same.Key)); } private static Sprite RenderIcon(Copy copy) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_00b2: 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) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown GameObject val = new GameObject("BetterHammer_CopyPreview"); val.transform.position = new Vector3(0f, -5000f, 0f); ZNetView.m_forceDisableInit = true; TerrainOp.m_forceDisableTerrainOps = true; try { foreach (Part part in copy.Parts) { Object.Instantiate<GameObject>(((Component)part.Prefab).gameObject, val.transform.position + part.Position, part.Rotation, val.transform); } } finally { ZNetView.m_forceDisableInit = false; TerrainOp.m_forceDisableTerrainOps = false; } try { return RenderManager.Instance.Render(new RenderRequest(val) { Rotation = RenderManager.IsometricRotation, Width = 128, Height = 128 }); } catch (Exception ex) { Debug.LogWarning((object)("BetterHammer: couldn't render an icon for " + copy.Name + ": " + ex.Message)); return null; } finally { Object.DestroyImmediate((Object)(object)val); } } private static LibraryFile Read() { LibraryFile libraryFile = null; string filePath = FilePath; if (File.Exists(filePath)) { try { libraryFile = JsonConvert.DeserializeObject<LibraryFile>(File.ReadAllText(filePath)); } catch (Exception ex) { string text = filePath + ".unreadable-" + DateTime.Now.ToString("yyyyMMdd-HHmmss", CultureInfo.InvariantCulture); Debug.LogError((object)("BetterHammer: couldn't read " + filePath + " (" + ex.Message + "), moved it to " + text)); try { File.Move(filePath, text); } catch (Exception ex2) { Debug.LogError((object)("BetterHammer: couldn't move it either: " + ex2.Message)); } } } if (libraryFile == null) { libraryFile = new LibraryFile(); } LibraryFile libraryFile2 = libraryFile; if (libraryFile2.Copies == null) { libraryFile2.Copies = new List<SavedCopy>(); } foreach (SavedCopy copy in libraryFile.Copies) { copy?.Pieces?.RemoveAll(delegate(SavedPiece piece) { if (piece != null && piece.Prefab != null) { float[] position = piece.Position; if (position != null && position.Length == 3) { position = piece.Rotation; return position == null || position.Length != 4; } } return true; }); } libraryFile.Copies.RemoveAll((SavedCopy copy) => copy?.Pieces == null || copy.Pieces.Count == 0); int num = ((libraryFile.Copies.Count > 0) ? libraryFile.Copies.Max((SavedCopy copy) => copy.Number) : 0); libraryFile.NextNumber = Mathf.Max(libraryFile.NextNumber, num + 1); return libraryFile; } private static void Save() { try { string filePath = FilePath; Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, JsonConvert.SerializeObject((object)_file, (Formatting)1)); } catch (Exception ex) { Debug.LogError((object)("BetterHammer: couldn't save copies to " + FilePath + ": " + ex.Message)); } } } internal static class GhostGroup { internal enum Owner { None, Copy, Move } private sealed class Member { public CopyLibrary.Part Part; public GameObject Ghost; } private static readonly List<Member> Members = new List<Member>(); private static int _snapFrame = -10; internal static Owner ActiveOwner { get; private set; } internal static bool Active => Members.Count > 0; internal static int Count => Members.Count; internal static bool CreatingGhosts { get; private set; } internal static GameObject PrefabOverride { get; private set; } internal static int Reference { get; private set; } internal static void Begin(Player player, IList<CopyLibrary.Part> parts, Owner owner, int reference = 0, int snapPoint = -1) { End(); if ((Object)(object)player.m_placementGhost != (Object)null) { Object.Destroy((Object)(object)player.m_placementGhost); player.m_placementGhost = null; } int placeRotation = player.m_placeRotation; CreatingGhosts = true; try { foreach (CopyLibrary.Part part in parts) { Members.Add(new Member { Part = part, Ghost = CreateGhost(player, part.Prefab) }); } } finally { CreatingGhosts = false; PrefabOverride = null; } player.m_placeRotation = placeRotation; ActiveOwner = owner; if (reference < 0 || reference >= Members.Count) { reference = 0; snapPoint = -1; } UseAsReference(player, reference); player.m_manualSnapPoint = snapPoint; } internal static void End() { foreach (Member member in Members) { if ((Object)(object)member.Ghost != (Object)null) { Object.Destroy((Object)(object)member.Ghost); } } Members.Clear(); ActiveOwner = Owner.None; } internal static List<(Vector3 Position, Quaternion Rotation)> Poses(Player player) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) List<(Vector3, Quaternion)> list = new List<(Vector3, Quaternion)>(); foreach (Member member in Members) { Transform val = (((Object)(object)member.Ghost != (Object)null) ? member.Ghost.transform : player.m_placementGhost.transform); list.Add((val.position, val.rotation)); } return list; } internal static int RotationSteps(Player player, Quaternion rotation) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Mathf.RoundToInt(((Quaternion)(ref rotation)).eulerAngles.y / player.m_placeRotationDegrees); } private static GameObject CreateGhost(Player player, Piece prefab) { PrefabOverride = ((Component)prefab).gameObject; player.SetupPlacementGhost(); PrefabOverride = null; GameObject placementGhost = player.m_placementGhost; player.m_placementGhost = null; if ((Object)(object)placementGhost != (Object)null) { placementGhost.SetActive(false); } return placementGhost; } private static void UseAsReference(Player player, int index) { Member member = Members[index]; player.m_placementGhost = member.Ghost; if ((Object)(object)player.m_placementGhost != (Object)null) { player.m_placementGhost.SetActive(true); } member.Ghost = null; Reference = index; } private static void SwitchReference(Player player, int index) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0010: 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_007b: 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) GameObject placementGhost = player.m_placementGhost; Quaternion val = (((Object)(object)placementGhost != (Object)null) ? (placementGhost.transform.rotation * Quaternion.Inverse(Members[Reference].Part.Rotation)) : Quaternion.identity); Members[Reference].Ghost = placementGhost; if ((Object)(object)placementGhost != (Object)null) { placementGhost.SetActive(false); } player.m_placementGhost = null; UseAsReference(player, index); player.m_placeRotation = RotationSteps(player, val * Members[index].Part.Rotation); } internal static void BeforeUpdatePlacementGhost(Player player) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 if (!Active || (Object)(object)player.m_placementGhost == (Object)null || _snapFrame == Time.frameCount || ZInput.GetButton("JoyAltKeys") || Hud.IsPieceSelectionVisible() || ((Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 2) || Console.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())) { return; } int num = 0; if (ZInput.GetButtonDown("TabRight")) { num = 1; } else if (ZInput.GetButtonDown("TabLeft")) { num = -1; } if (num != 0) { _snapFrame = Time.frameCount; int piece = Reference; int point = player.m_manualSnapPoint; if (BetterHammerPlugin.ShiftHeld()) { piece = (piece + num + Members.Count) % Members.Count; point = ((Members[piece].Part.SnapCount <= 0) ? (-1) : 0); } else { NextSnapPoint(ref piece, ref point, num); } if (piece != Reference) { SwitchReference(player, piece); } player.m_manualSnapPoint = point - num; ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_copyReference", new string[3] { Localization.instance.Localize(Members[piece].Part.Prefab.m_name), (piece + 1).ToString(CultureInfo.InvariantCulture), Members.Count.ToString(CultureInfo.InvariantCulture) }), 0, (Sprite)null, false); } } private static void NextSnapPoint(ref int piece, ref int point, int step) { List<(int, int)> list = new List<(int, int)>(1) { (-1, -1) }; for (int i = 0; i < Members.Count; i++) { for (int j = 0; j < Members[i].Part.SnapCount; j++) { list.Add((i, j)); } } int num = ((point >= 0) ? list.IndexOf((piece, point)) : 0); if (num < 0) { num = 0; } var (num2, num3) = list[(num + step + list.Count) % list.Count]; if (num2 >= 0) { piece = num2; } point = num3; } internal static void AfterUpdatePlacementGhost(Player player, bool flashGuardStone) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_005d: 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_0032: 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_007c: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00d9: 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) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0151: 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_0112: 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_016a: Invalid comparison between Unknown and I4 //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } GameObject placementGhost = player.m_placementGhost; bool flag = (Object)(object)placementGhost != (Object)null && placementGhost.activeSelf; PlacementStatus val = player.m_placementStatus; Quaternion val2 = (((Object)(object)placementGhost != (Object)null) ? (placementGhost.transform.rotation * Quaternion.Inverse(Members[Reference].Part.Rotation)) : Quaternion.identity); Vector3 position = Members[Reference].Part.Position; foreach (Member member in Members) { if ((Object)(object)member.Ghost == (Object)null) { continue; } member.Ghost.SetActive(flag); if (!flag) { continue; } Vector3 val3 = placementGhost.transform.position + val2 * (member.Part.Position - position); member.Ghost.transform.SetPositionAndRotation(val3, val2 * member.Part.Rotation); if ((int)val == 0) { if (Location.IsInsideNoBuildLocation(val3)) { val = (PlacementStatus)3; } else if (!PrivateArea.CheckAccess(val3, 0f, flashGuardStone, false)) { val = (PlacementStatus)4; } } } if (!flag) { return; } if (val != player.m_placementStatus) { player.m_placementStatus = val; player.SetPlacementGhostValid(false); } bool flag2 = (int)val == 0; foreach (Member member2 in Members) { Piece val4 = (((Object)(object)member2.Ghost != (Object)null) ? member2.Ghost.GetComponent<Piece>() : null); if ((Object)(object)val4 != (Object)null) { val4.SetInvalidPlacementHeightlight(!flag2); } } } } internal static class MultiCopy { [CompilerGenerated] private static class <>O { public static PopupButtonCallback <0>__Pop; } private const string RemoveButton = "Remove"; private const string PlaceButton = "Attack"; private const float MaterialPageSeconds = 2.5f; private static readonly Color HighlightColor = new Color(0.25f, 0.9f, 0.75f); private static readonly int EmissionColor = Shader.PropertyToID("_EmissionColor"); private static readonly List<Piece> Selected = new List<Piece>(); private static CopyLibrary.Copy _active; private static (CopyLibrary.Copy Copy, int Reference, int SnapPoint) _kept; private static int _rightClickFrame = -10; private static bool _lit; private static Piece _summary; private static bool _selectionDirty = true; private static List<Requirement> _selectionRequirements = new List<Requirement>(); private static List<Piece> _selectionStations = new List<Piece>(); private static string _selectionDescription = ""; private static ConfigEntry<KeyCode> _clearKey; internal static KeyCode ClearKey { get { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (_clearKey == null) { return (KeyCode)8; } return _clearKey.Value; } } internal static bool Placing { get { if (_active != null) { return GhostGroup.ActiveOwner == GhostGroup.Owner.Copy; } return false; } } internal static bool HasSelection => Selected.Count > 0; internal static bool RightClickConsumed => _rightClickFrame == Time.frameCount; internal static bool BeforeUpdatePlacement(Player player, bool takeInput) { Prune(); if (Placing && (!((Character)player).InPlaceMode() || (Object)(object)player.m_placementGhost == (Object)null || CopyLibrary.Find(player.GetSelectedPiece()) != _active)) { Keep(player); Deactivate(); } bool placing = Placing; if (!takeInput || !((Character)player).InPlaceMode() || ((Character)player).IsDead() || Hud.IsPieceSelectionVisible() || Hud.InRadial() || ZInput.IsGamepadActive() || !BetterHammerPlugin.IsHammerEquipped(player)) { return placing; } bool flag = BetterHammerPlugin.AltHeld(); bool buttonDown = ZInput.GetButtonDown("Attack"); bool flag2 = placing; if (flag && ZInput.GetButtonDown("Remove")) { PieceMover.BlockRemoveUntilReleased(player); Select(player); } else if (flag && Input.GetMouseButtonDown(1)) { _rightClickFrame = Time.frameCount; Deselect(player); } else if (flag && buttonDown) { player.m_lastToolUseTime = Time.time; flag2 = true; Confirm(player); } else if (Placing && buttonDown && Time.time - player.m_lastToolUseTime > player.m_placeDelay) { Place(player); } if (!flag2) { return Placing; } return true; } public static void BindConfig(ConfigFile config) { _clearKey = config.Bind<KeyCode>("Keybinds", "Clear Selection", (KeyCode)8, "Deselects every piece selected for copying, without changing anything else."); } internal static void ReplaceSelected(Piece original, Piece replacement) { int num = Selected.IndexOf(original); if (num >= 0 && !((Object)(object)replacement == (Object)null)) { ResetHighlight(original); Selected[num] = replacement; _selectionDirty = true; } } internal static void UpdateSelectionKeys(Player player) { //IL_0049: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown if (Selected.Count == 0 || Hud.IsPieceSelectionVisible() || UnifiedPopup.IsVisible() || !((Character)player).InPlaceMode() || !BetterHammerPlugin.IsHammerEquipped(player) || CopyLibrary.TypingInTextField()) { return; } if (Input.GetKeyDown(ClearKey)) { int count = Selected.Count; ClearHighlights(); Selected.Clear(); _selectionDirty = true; ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_selection_cleared", new string[1] { Count(count) }), 0, (Sprite)null, false); } else if (Input.GetKeyDown(CopyLibrary.DeleteKey)) { Prune(); string text = Localization.instance.Localize("$betterhammer_selection_delete_text", new string[1] { Count(Selected.Count) }); PopupButtonCallback val = delegate { UnifiedPopup.Pop(); RemoveSelected(player); }; object obj = <>O.<0>__Pop; if (obj == null) { PopupButtonCallback val2 = UnifiedPopup.Pop; <>O.<0>__Pop = val2; obj = (object)val2; } UnifiedPopup.Push((PopupBase)new YesNoPopup("$betterhammer_selection_delete_title", text, val, (PopupButtonCallback)obj, true, false)); } } private static void RemoveSelected(Player player) { Prune(); int count = Selected.Count; int num = 0; foreach (Piece item in Selected.ToList()) { if (CanRemove(player, item)) { ResetHighlight(item); Remove(player, item); Selected.Remove(item); num++; } } _selectionDirty = true; ((Character)player).Message((MessageType)1, (num == count) ? Localization.instance.Localize("$betterhammer_selection_removed", new string[1] { Count(num) }) : Localization.instance.Localize("$betterhammer_selection_removed_some", new string[2] { Count(num), Count(count) }), 0, (Sprite)null, false); } private static bool CanRemove(Player player, Piece piece) { //IL_000d: 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_0048: 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_0082: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)piece).GetComponent<ZNetView>(); Vector3 position = ((Component)piece).transform.position; bool flag = player.m_noPlacementCost || (Object)(object)piece.m_craftingStation == (Object)null || ZoneSystem.instance.GetGlobalKey((GlobalKeys)27) || (Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)player).transform.position) != (Object)null; if ((Object)(object)component != (Object)null && component.IsValid() && piece.m_canBeRemoved && flag && !Location.IsInsideNoBuildLocation(position) && PrivateArea.CheckAccess(position, 0f, false, false)) { return piece.CanBeRemoved(); } return false; } private static void Remove(Player player, Piece piece) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_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_00ae: 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_0049: Expected O, but got Unknown IRemoved component = ((Component)piece).GetComponent<IRemoved>(); if (component != null) { component.OnRemoved(); } WearNTear component2 = ((Component)piece).GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null) { component2.Remove(false); return; } Character component3 = ((Component)piece).GetComponent<Character>(); if ((Object)(object)component3 != (Object)null) { component3.Damage(new HitData(1E+10f)); return; } ((Component)piece).GetComponent<ZNetView>().ClaimOwnership(); piece.DropResources((HitData)null); piece.m_placeEffect.Create(((Component)piece).transform.position, ((Component)piece).transform.rotation, ((Component)piece).transform, 1f, -1, ((Character)player).GetZDOID()); player.m_removeEffects.Create(((Component)piece).transform.position, Quaternion.identity, (Transform)null, 1f, -1, ((Character)player).GetZDOID()); ZNetScene.instance.Destroy(((Component)piece).gameObject); } internal static void Reset() { ClearHighlights(); Selected.Clear(); Deactivate(); _kept = default((CopyLibrary.Copy, int, int)); _selectionDirty = true; } private static void Select(Player player) { Piece hoveringPiece = player.GetHoveringPiece(); if ((Object)(object)hoveringPiece == (Object)null) { return; } string text = Localization.instance.Localize(hoveringPiece.m_name); if (Selected.Contains(hoveringPiece)) { ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_copy_already", new string[1] { text }), 0, (Sprite)null, false); return; } ZNetView component = ((Component)hoveringPiece).GetComponent<ZNetView>(); Vector2Int val = default(Vector2Int); PieceCategory val2 = default(PieceCategory); if ((Object)(object)component == (Object)null || !component.IsValid() || !player.m_buildPieces.GetPieceIndex(hoveringPiece, ref val, ref val2)) { ((Character)player).Message((MessageType)2, "$msg_missingrequirement", 0, (Sprite)null, false); return; } Selected.Add(hoveringPiece); _selectionDirty = true; ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_copy_selected", new string[2] { text, Count(Selected.Count) }), 0, (Sprite)null, false); } private static void Deselect(Player player) { Piece hoveringPiece = player.GetHoveringPiece(); int num = (((Object)(object)hoveringPiece != (Object)null) ? Selected.IndexOf(hoveringPiece) : (-1)); if (num >= 0) { ResetHighlight(hoveringPiece); Selected.RemoveAt(num); _selectionDirty = true; ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_copy_deselected", new string[2] { Localization.instance.Localize(hoveringPiece.m_name), Count(Selected.Count) }), 0, (Sprite)null, false); } } private static void Confirm(Player player) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) Prune(); if (Selected.Count == 0) { ((Character)player).Message((MessageType)2, "$betterhammer_copy_nothing", 0, (Sprite)null, false); return; } List<(Piece Prefab, Vector3 Position, Quaternion Rotation)> pieces = new List<(Piece, Vector3, Quaternion)>(); Vector2Int val2 = default(Vector2Int); PieceCategory val3 = default(PieceCategory); foreach (Piece item in Selected) { GameObject prefab = ZNetScene.instance.GetPrefab(Utils.GetPrefabName(((Component)item).gameObject)); Piece val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Piece>() : null); if ((Object)(object)val == (Object)null || !player.m_buildPieces.GetPieceIndex(val, ref val2, ref val3)) { ((Character)player).Message((MessageType)2, Localization.instance.Localize("$betterhammer_copy_unavailable", new string[1] { Localization.instance.Localize(item.m_name) }), 0, (Sprite)null, false); return; } pieces.Add((val, ((Component)item).transform.position, ((Component)item).transform.rotation)); } CopyLibrary.AskForName("$betterhammer_copy_name_title", CopyLibrary.NextDefaultName(), delegate(string name) { Save(player, pieces, name); }); } private static void Save(Player player, List<(Piece Prefab, Vector3 Position, Quaternion Rotation)> pieces, string name) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) PieceMover.Abort(player); CopyLibrary.Copy copy = CopyLibrary.Add(player, pieces, name); if (copy == null) { ((Character)player).Message((MessageType)2, "$betterhammer_copy_failed", 0, (Sprite)null, false); return; } ClearHighlights(); Selected.Clear(); _selectionDirty = true; if (player.SetSelectedPiece(copy.Piece)) { player.m_placeRotation = GhostGroup.RotationSteps(player, copy.Parts[0].Rotation); } ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_copy_saved", new string[1] { copy.Name }), 0, (Sprite)null, false); } internal static void BeforeSetupPlacementGhost(Player player) { if (!GhostGroup.CreatingGhosts) { Keep(player); } } private static void Keep(Player player) { if (Placing) { _kept = (Copy: _active, Reference: GhostGroup.Reference, SnapPoint: player.m_manualSnapPoint); } } internal static void AfterSetupPlacementGhost(Player player) { if (GhostGroup.CreatingGhosts) { return; } GhostGroup.End(); _active = null; if (!((Character)player).InPlaceMode() || ((Character)player).IsDead()) { return; } (CopyLibrary.Copy Copy, int Reference, int SnapPoint) kept = _kept; CopyLibrary.Copy item = kept.Copy; int item2 = kept.Reference; int item3 = kept.SnapPoint; _kept = default((CopyLibrary.Copy, int, int)); CopyLibrary.Copy copy = CopyLibrary.Find(player.GetSelectedPiece()); if (copy != null) { if (copy == item) { GhostGroup.Begin(player, copy.Parts, GhostGroup.Owner.Copy, item2, item3); } else { GhostGroup.Begin(player, copy.Parts, GhostGroup.Owner.Copy); } _active = copy; } } private static void Deactivate() { if (GhostGroup.ActiveOwner == GhostGroup.Owner.Copy) { GhostGroup.End(); } _active = null; } internal static List<Piece> SelectionStartingWith(Piece piece) { Prune(); if ((Object)(object)piece == (Object)null || Selected.Count < 2 || !Selected.Contains(piece)) { return null; } List<Piece> list = new List<Piece>(1); list.Add(piece); list.AddRange(Selected.Where((Piece other) => (Object)(object)other != (Object)(object)piece)); return list; } internal static bool IsSelected(Piece piece) { if ((Object)(object)piece != (Object)null) { return Selected.Contains(piece); } return false; } private static void Place(Player player) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) player.m_lastToolUseTime = Time.time; ItemData rightItem = ((Humanoid)player).GetRightItem(); if (!((Character)player).HaveStamina(rightItem.m_shared.m_attack.m_attackStamina)) { Hud.instance.StaminaBarEmptyFlash(); return; } player.UpdatePlacementGhost(true); GameObject placementGhost = player.m_placementGhost; if ((int)player.m_placementStatus != 0 || (Object)(object)placementGhost == (Object)null) { ((Character)player).Message((MessageType)2, PieceMover.StatusMessages.TryGetValue(player.m_placementStatus, out var value) ? value : "$msg_invalidplacement", 0, (Sprite)null, false); return; } if (!HaveStations(player, _active.Prefabs)) { ((Character)player).Message((MessageType)2, "$msg_missingstation", 0, (Sprite)null, false); return; } if (!player.m_noPlacementCost && !player.HaveRequirements(_active.Piece, (RequirementMode)0)) { ((Character)player).Message((MessageType)2, "$msg_missingrequirement", 0, (Sprite)null, false); return; } int placeRotation = player.m_placeRotation; List<(Vector3, Quaternion)> list = GhostGroup.Poses(player); for (int i = 0; i < list.Count; i++) { player.PlacePiece(_active.Parts[i].Prefab, list[i].Item1, list[i].Item2, i == 0, false); } player.m_placeRotation = placeRotation; if (!player.m_noPlacementCost && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)24)) { player.ConsumeResources(_active.Piece.m_resources, 0, -1, 1); } ((Character)player).UseStamina(player.GetBuildStamina()); if (rightItem.m_shared.m_useDurability) { rightItem.m_durability -= player.GetPlaceDurability(rightItem) * Game.m_durabilityRate; } if ((int)player.m_buildPieces.m_skill != 0) { ((Character)player).RaiseSkill(player.m_buildPieces.m_skill, 1f); } rightItem.m_shared.m_buildEffect.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, ((Character)player).GetZDOID()); ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_copy_placed", new string[1] { Count(list.Count) }), 0, (Sprite)null, false); } private static bool HaveStations(Player player, List<Piece> pieces) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (player.m_noPlacementCost || ZoneSystem.instance.GetGlobalKey((GlobalKeys)27)) { return true; } foreach (Piece piece in pieces) { if ((Object)(object)piece.m_craftingStation != (Object)null && (Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)player).transform.position) == (Object)null) { return false; } } return true; } internal static bool TryGetSummary(Piece piece, out Piece summary) { summary = null; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return false; } bool flag = Hud.IsPieceSelectionVisible(); Prune(); if (!flag && Selected.Count > 0 && BetterHammerPlugin.AltHeld() && BetterHammerPlugin.IsHammerEquipped(localPlayer)) { if (_selectionDirty) { _selectionDirty = false; _selectionRequirements = CopyLibrary.CombineRequirements(Selected, out _selectionStations); _selectionDescription = CopyLibrary.DescribePieces(Selected); } summary = Fill(localPlayer, Localization.instance.Localize("$betterhammer_copy_summary_selected", new string[1] { Count(Selected.Count) }), _selectionDescription, Selected[0].m_icon, _selectionRequirements, _selectionStations); return true; } CopyLibrary.Copy copy = CopyLibrary.Find(piece); if (copy == null) { return false; } string description = (flag ? (copy.Description + "\n" + CopyLibrary.MenuHint()) : copy.Description); summary = Fill(localPlayer, copy.Name, description, copy.Piece.m_icon, copy.Piece.m_resources, copy.StationPieces); return true; } private static Piece Fill(Player player, string name, string description, Sprite icon, IList<Requirement> requirements, List<Piece> stationPieces) { //IL_0012: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if ((Object)(object)_summary == (Object)null) { GameObject val = new GameObject("BetterHammer_CopySummary"); val.SetActive(false); Object.DontDestroyOnLoad((Object)val); _summary = val.AddComponent<Piece>(); } int num = (((Object)(object)Hud.instance != (Object)null) ? Mathf.Max(1, Hud.instance.m_requirementItems.Length - 1) : Mathf.Max(1, requirements.Count)); int num2 = Mathf.Max(1, Mathf.CeilToInt((float)requirements.Count / (float)num)); int num3 = (int)(Time.time / 2.5f) % num2; if (num2 > 1) { description = description + "\n" + Localization.instance.Localize("$betterhammer_copy_materials_page", new string[2] { Count(num3 + 1), Count(num2) }); } _summary.m_name = name; _summary.m_description = description; _summary.m_icon = icon; _summary.m_resources = requirements.Skip(num3 * num).Take(num).ToArray(); _summary.m_craftingStation = StationToShow(player, stationPieces); return _summary; } private static CraftingStation StationToShow(Player player, List<Piece> stationPieces) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) CraftingStation val = null; foreach (Piece stationPiece in stationPieces) { CraftingStation craftingStation = stationPiece.m_craftingStation; if (val == null) { val = craftingStation; } if ((Object)(object)CraftingStation.HaveBuildStationInRange(craftingStation.m_name, ((Component)player).transform.position) == (Object)null) { return craftingStation; } } return val; } internal static void UpdateHighlight() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (Selected.Count <= 0 || !((Object)(object)MaterialMan.instance != (Object)null) || !((Object)(object)localPlayer != (Object)null) || !((Character)localPlayer).InPlaceMode() || !BetterHammerPlugin.IsHammerEquipped(localPlayer)) { if (_lit) { ClearHighlights(); } return; } Prune(); float num = Mathf.Lerp(0.3f, 0.7f, (Mathf.Sin(Time.time * 5f) + 1f) * 0.5f); foreach (Piece item in Selected) { MaterialMan.instance.SetValue<Color>(((Component)item).gameObject, EmissionColor, HighlightColor * num, false); } _lit = true; } private static void ClearHighlights() { foreach (Piece item in Selected) { ResetHighlight(item); } _lit = false; } private static void ResetHighlight(Piece piece) { if ((Object)(object)piece != (Object)null && (Object)(object)MaterialMan.instance != (Object)null) { MaterialMan.instance.ResetValue(((Component)piece).gameObject, EmissionColor); } } private static void Prune() { if (Selected.RemoveAll(delegate(Piece piece) { if (!((Object)(object)piece == (Object)null)) { ZNetView component = ((Component)piece).GetComponent<ZNetView>(); if (component != null) { return !component.IsValid(); } } return true; }) > 0) { _selectionDirty = true; } } private static string Count(int value) { return value.ToString(CultureInfo.InvariantCulture); } } internal static class PieceMover { private const string RemoveButton = "Remove"; private const string PlaceButton = "Attack"; private static readonly List<ZNetView> Sources = new List<ZNetView>(); private static string _prefabName; private static Piece _previousPiece; private static int _previousRotation; private static bool _blockRemoveUntilReleased; private static int _rightClickFrame = -10; private static readonly Color HighlightColor = new Color(0.941f, 0.69f, 0.29f); private static readonly int EmissionColor = Shader.PropertyToID("_EmissionColor"); private static readonly List<Collider> SourceColliders = new List<Collider>(); private static readonly List<Collider> HiddenColliders = new List<Collider>(); private static readonly List<StationExtension> HiddenExtensions = new List<StationExtension>(); internal static readonly Dictionary<PlacementStatus, string> StatusMessages = new Dictionary<PlacementStatus, string> { [(PlacementStatus)3] = "$msg_nobuildzone", [(PlacementStatus)2] = "$msg_blocked", [(PlacementStatus)4] = "$msg_privatezone", [(PlacementStatus)5] = "$msg_needspace", [(PlacementStatus)6] = "$msg_noteleportarea", [(PlacementStatus)7] = "$msg_extensionmissingstation", [(PlacementStatus)8] = "$msg_wrongbiome", [(PlacementStatus)9] = "$msg_needcultivated", [(PlacementStatus)10] = "$msg_needdirt", [(PlacementStatus)11] = "$msg_notindungeon", [(PlacementStatus)13] = "$msg_snowtoodeep", [(PlacementStatus)14] = "$msg_nosnow" }; internal static bool Moving => Sources.Count > 0; private static bool MovingGroup => Sources.Count > 1; internal static bool RightClickConsumed { get { if (!Moving) { return _rightClickFrame == Time.frameCount; } return true; } } internal static bool BeforeUpdatePlacement(Player player, bool takeInput) { if (_blockRemoveUntilReleased) { if (ZInput.GetButton("Remove") || ZInput.GetButtonUp("Remove")) { player.m_blockRemove = true; } else { _blockRemoveUntilReleased = false; } } string text = (Moving ? AbortReason(player) : null); if (text != null) { Stop(player); ((Character)player).Message((MessageType)1, text, 0, (Sprite)null, false); } bool moving = Moving; if (!takeInput || !((Character)player).InPlaceMode() || ((Character)player).IsDead() || Hud.IsPieceSelectionVisible() || Hud.InRadial() || ZInput.IsGamepadActive() || !BetterHammerPlugin.IsHammerEquipped(player)) { return moving; } if (BetterHammerPlugin.CtrlHeld() && ZInput.GetButtonDown("Remove")) { BlockRemoveUntilReleased(player); PickUp(player); } else if (Moving && ZInput.GetButtonDown("Remove") && IsSource(player.GetHoveringPiece())) { BlockRemoveUntilReleased(player); ((Character)player).Message((MessageType)2, "$betterhammer_move_cant_remove", 0, (Sprite)null, false); } else if (Moving && Input.GetMouseButtonDown(1)) { _rightClickFrame = Time.frameCount; Stop(player); ((Character)player).Message((MessageType)1, "$betterhammer_move_aborted", 0, (Sprite)null, false); } else if (Moving && !BetterHammerPlugin.AltHeld() && ZInput.GetButtonDown("Attack") && Time.time - player.m_lastToolUseTime > player.m_placeDelay) { PutDown(player); } if (!moving) { return Moving; } return true; } internal static void BlockVanillaPlacing(Player player) { player.m_placePressedTime = -9999f; } internal static void BlockRemoveUntilReleased(Player player) { _blockRemoveUntilReleased = true; player.m_blockRemove = true; } internal static void Abort(Player player) { if (Moving) { Stop(player); ((Character)player).Message((MessageType)1, "$betterhammer_move_aborted", 0, (Sprite)null, false); } } internal static void Reset() { ClearHighlight(); Sources.Clear(); _prefabName = null; _previousPiece = null; _blockRemoveUntilReleased = false; } private static void PickUp(Player player) { //IL_00c2: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) Piece hoveringPiece = player.GetHoveringPiece(); if ((Object)(object)hoveringPiece == (Object)null) { return; } List<Piece> list = MultiCopy.SelectionStartingWith(hoveringPiece) ?? new List<Piece>(1) { hoveringPiece }; List<ZNetView> list2 = new List<ZNetView>(); foreach (Piece item in list) { if (!CanMove(player, item, out var nview)) { return; } list2.Add(nview); } if (!Moving) { _previousPiece = player.GetSelectedPiece(); _previousRotation = player.m_placeRotation; } bool flag = GhostGroup.ActiveOwner == GhostGroup.Owner.Move; if (flag) { GhostGroup.End(); } if (!player.SetSelectedPiece(hoveringPiece)) { ((Character)player).Message((MessageType)2, "$msg_missingrequirement", 0, (Sprite)null, false); return; } Quaternion rotation = ((Component)hoveringPiece).transform.rotation; player.m_placeRotation = (int)Math.Round(((Quaternion)(ref rotation)).eulerAngles.y / player.m_placeRotationDegrees); ClearHighlight(); Sources.Clear(); Sources.AddRange(list2); _prefabName = Utils.GetPrefabName(((Component)hoveringPiece).gameObject); if (!MovingGroup) { if (flag) { player.SetupPlacementGhost(); } ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_move_started", new string[1] { Localization.instance.Localize(hoveringPiece.m_name) }), 0, (Sprite)null, false); return; } List<CopyLibrary.Part> list3 = new List<CopyLibrary.Part>(); foreach (Piece item2 in list) { list3.Add(CopyLibrary.MakePart(PrefabOf(item2), ((Component)item2).transform.position, ((Component)item2).transform.rotation)); } GhostGroup.Begin(player, list3, GhostGroup.Owner.Move); ((Character)player).Message((MessageType)1, Localization.instance.Localize("$betterhammer_move_started_group", new string[1] { Sources.Count.ToString(CultureInfo.InvariantCulture) }), 0, (Sprite)null, false); } private static Piece PrefabOf(Piece piece) { GameObject prefab = ZNetScene.instance.GetPrefab(Utils.GetPrefabName(((Component)piece).gameObject)); if (!((Object)(object)prefab != (Object)null)) { return piece; } return prefab.GetComponent<Piece>(); } private static bool IsSource(Piece piece) { if ((Object)(object)piece == (Object)null) { return false; } foreach (ZNetView source in Sources) { if ((Object)(object)source != (Object)null && (Object)(object)((Component)source).GetComponent<Piece>() == (Object)(object)piece) { return true; } } return false; } private static void PutDown(Player player) { //IL_00a2: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) player.m_lastToolUseTime = Time.time; List<Piece> list = new List<Piece>(); foreach (ZNetView source in Sources) { Piece component = ((Component)source).GetComponent<Piece>(); if ((Object)(object)component == (Object)null || !CanMove(player, component, out var _)) { return; } list.Add(component); } ItemData rightItem = ((Humanoid)player).GetRightItem(); if (!((Character)player).HaveStamina(rightItem.m_shared.m_attack.m_attackStamina)) { Hud.instance.StaminaBarEmptyFlash(); return; } player.UpdatePlacementGhost(true); GameObject placementGhost = player.m_placementGhost; if ((int)player.m_placementStatus != 0 || (Object)(object)placementGhost == (Object)null) { ((Character)player).Message((MessageType)2, StatusMessages.TryGetValue(player.m_placementStatus, out var value) ? value : "$msg_invalidplacement", 0, (Sprite)null, false); return; } List<(Vector3, Quaternion)> list2 = (List<(Vector3, Quaternion)>)(MovingGroup ? ((IList)GhostGroup.Poses(player)) : ((IList)new List<(Vector3, Quaternion)>(1) { (placementGhost.transform.position, placementGhost.transform.rotation) })); List<GameObject> list3 = new List<GameObject>(); for (int i = 0; i < Sources.Count; i++) { GameObject val = Recreate(Sources[i], list2[i].Item1, list2[i].Item2); if ((Object)(object)val == (Object)null) { foreach (GameObject item in list3) { ZNetScene.instance.Destroy(item); } ((Character)player).Message((MessageType)2, "$betterhammer_move_failed", 0, (Sprite)null, false); return; } list3.Add(val); } Vector3 position = ((Component)list[0]).transform.position; ClearHighlight(); for (int j = 0; j < Sources.Count; j++) { MultiCopy.ReplaceSelected(list[j], list3[j].GetComponent<Piece>()); Sources[j].ClaimOwnership(); ZNetScene.instance.Destroy(((Component)Sources[j]).gameObject); list[j].m_placeEffect.Create(list2[j].Item1, list2[j].Item2, list3[j].transform, 1f, -1, ((Character)player).GetZDOID()); } player.m_removeEffects.Create(position, Quaternion.identity, (Transform)null, 1f, -1, ((Character)player).GetZDOID()); player.FaceLookDirection(); ((Character)player).m_zanim.SetTrigger(rightItem.m_shared.m_attack.m_attackAnimation); ((Character)player).UseStamina(player.GetBuildStamina()); if (rightItem.m_shared.m_useDurability) { rightItem.m_durability -= player.GetPlaceDurability(rightItem) * Game.m_durabilityRate; } int count = Sources.Count; Sources.Clear(); Stop(player); ((Character)player).Message((MessageType)1, (count > 1) ? Localization.instance.Localize("$betterhammer_moved_group", new string[1] { count.ToString(CultureInfo.InvariantCulture) }) : Localization.instance.Localize("$betterhammer_moved", new string[1] { Localization.instance.Localize(list[0].m_name) }), 0, (Sprite)null, false); } internal static void UpdateHighlight() { //IL_006f: 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) if (!Moving || (Object)(object)MaterialMan.instance == (Object)null) { return; } float num = Mathf.Lerp(0.3f, 0.7f, (Mathf.Sin(Time.time * 5f) + 1f) * 0.5f); foreach (ZNetView source in Sources) { if ((Object)(object)source != (Object)null) { MaterialMan.instance.SetValue<Color>(((Component)source).gameObject, EmissionColor, HighlightColor * num, false); } } } private static void ClearHighlight() { if ((Object)(object)MaterialMan.instance == (Object)null) { return; } foreach (ZNetView source in Sources) { if ((Object)(object)source != (Object)null) { MaterialMan.instance.ResetValue(((Component)source).gameObject, EmissionColor); } } } internal static void HideFromPlacementChecks() { if (!Moving) { return; } foreach (ZNetView source in Sources) { if ((Object)(object)source == (Object)null) { continue; } ((Component)source).GetComponentsInChildren<Collider>(SourceColliders); foreach (Collider sourceCollider in SourceColliders) { if (sourceCollider.enabled) { sourceCollider.enabled = false; HiddenColliders.Add(sourceCollider); } } SourceColliders.Clear(); StationExtension componentInChildren = ((Component)source).GetComponentInChildren<StationExtension>(); if ((Object)(object)componentInChildren != (Object)null && StationExtension.m_allExtensions.Remove(componentInChildren)) { HiddenExtensions.Add(componentInChildren); } } } internal static void RestoreAfterPlacementChecks() { foreach (Collider hiddenCollider in HiddenColliders) { if ((Object)(object)hiddenCollider != (Object)null) { hiddenCollider.enabled = true; } } HiddenColliders.Clear(); StationExtension.m_allExtensions.AddRange(HiddenExtensions); HiddenExtensions.Clear(); } private static GameObject Recreate(ZNetView source, Vector3 position, Quaternion rotation) { //IL_002a: 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_005e: 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_0080: 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) ZDO zDO = source.GetZDO(); int prefab = zDO.GetPrefab(); GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); if ((Object)(object)prefab2 == (Object)null) { return null; } ZDO val = ZDOMan.instance.CreateNewZDO(position, prefab); val.Persistent = zDO.Persistent; val.Type = zDO.Type; val.Distant = zDO.Distant; val.SetPrefab(prefab); val.SetRotation(rotation); CopyData(zDO.m_uid, val); GameObject val2 = null; ZNetView.m_useInitZDO = true; ZNetView.m_initZDO = val; try { val2 = Object.Instantiate<GameObject>(prefab2, position, rotation); } catch (Exception ex) { Debug.LogError((object)("BetterHammer: failed to move " + ((Object)prefab2).name + ": " + ex)); } finally { bool flag = ZNetView.m_initZDO != null; ZNetView.m_initZDO = null; ZNetView.m_useInitZDO = false; if ((Object)(object)val2 == (Object)null || flag) { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } ZDOMan.instance.DestroyZDO(val); val2 = null; } } return val2; } private static void CopyData(ZDOID from, ZDO to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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) List<KeyValuePair<int, float>> list = default(List<KeyValuePair<int, float>>); List<KeyValuePair<int, Vector3>> list2 = default(List<KeyValuePair<int, Vector3>>); List<KeyValuePair<int, Quaternion>> list3 = default(List<KeyValuePair<int, Quaternion>>); List<KeyValuePair<int, int>> list4 = default(List<KeyValuePair<int, int>>); List<KeyValuePair<int, long>> list5 = default(List<KeyValuePair<int, long>>); List<KeyValuePair<int, string>> list6 = default(List<KeyValuePair<int, string>>); List<KeyValuePair<int, byte[]>> list7 = default(List<KeyValuePair<int, byte[]>>); ZDOConnection val = default(ZDOConnection); ZDOExtraData.GetData(from, ref list, ref list2, ref list3, ref list4, ref list5, ref list6, ref list7, ref val); foreach (KeyValuePair<int, float> item in list) { to.Set(item.Key, item.Value); } foreach (KeyValuePair<int, Vector3> item2 in list2) { to.Set(item2.Key, item2.Value); } foreach (KeyValuePair<int, Quaternion> item3 in list3) { to.Set(item3.Key, item3.Value); } foreach (KeyValuePair<int, int> item4 in list4) { to.Set(item4.Key, item4.Value, false); } foreach (KeyValuePair<int, long> item5 in list5) { to.Set(item5.Key, item5.Value); } foreach (KeyValuePair<int, string> item6 in list6) { to.Set(item6.Key, item6.Value); } foreach (KeyValuePair<int, byte[]> item7 in list7) { to.Set(item7.Key, (byte[])item7.Value.Clone()); } } private static bool CanMove(Player player, Piece piece, out ZNetView nview) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) nview = ((Component)piece).GetComponent<ZNetView>(); if ((Object)(object)nview == (Object)null || !nview.IsValid() || !piece.m_canBeRemoved || !IsMovableKind(piece)) { ((Character)player).Message((MessageType)2, "$betterhammer_move_cant", 0, (Sprite)null, false); return false; } Vector3 position = ((Component)piece).transform.position; if (Location.IsInsideNoBuildLocation(position)) { ((Character)player).Message((MessageType)2, "$msg_nobuildzone", 0, (Sprite)null, false); retu