Please disclose if your mod was created primarily 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 EzBuild v2.1.1
EZBuild/EZBuild.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("EZ Build")] [assembly: AssemblyDescription("jwlei")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("EZ Build")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9f1a5358-2c6f-4772-9111-b4e7a8897242")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace EZBuild; [HarmonyPatch] public class PatchHotkey : BaseUnityPlugin { public static string[] pickaxeCompareTexts = new string[7] { "Rock", "Tin deposit", "Muddy scrap pile", "Copper deposit", "Obsidian deposit", "Silver vein", "Guck Sack" }; public static string[] axeCompareTexts = new string[9] { "Log", "Stump", "Beech", "Birch", "Oak", "Ancient tree", "Fir", "Pine", "Guck sack" }; private static MethodInfo InPlaceModeRef = AccessTools.Method(typeof(Character), "InPlaceMode", (Type[])null, (Type[])null); private static bool m_stopAutorun = false; private static void ClearSelectedPiece(Player player) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (((Character)player).InPlaceMode()) { player.SetSelectedPiece(new Vector2Int(0, 0)); } } private static void ScrollPieceSelection(Player player) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) Vector2Int selectedIndex = player.m_buildPieces.GetSelectedIndex(); int num = 0; if ((double)Input.mouseScrollDelta.y > 0.0) { num = ((Vector2Int)(ref selectedIndex)).x + 1; player.m_placeRotation--; } else { num = ((Vector2Int)(ref selectedIndex)).x - 1; player.m_placeRotation++; } int num2 = ((Vector2Int)(ref selectedIndex)).y; if (num < 0) { num = 14; num2 = ((Vector2Int)(ref selectedIndex)).y - 1; } else if (num > 14) { num = 0; num2 = ((Vector2Int)(ref selectedIndex)).y + 1; } int availablePiecesInSelectedCategory = player.m_buildPieces.GetAvailablePiecesInSelectedCategory(); if (num2 < 0) { player.m_buildPieces.PrevCategory(); availablePiecesInSelectedCategory = player.m_buildPieces.GetAvailablePiecesInSelectedCategory(); num2 = availablePiecesInSelectedCategory / 15; num = availablePiecesInSelectedCategory % 15 - 1; } else if (num2 > availablePiecesInSelectedCategory / 15 || (num2 == availablePiecesInSelectedCategory / 15 && num >= availablePiecesInSelectedCategory % 15)) { player.m_buildPieces.NextCategory(); num2 = 0; num = 0; } ((Vector2Int)(ref selectedIndex))..ctor(num, num2); player.SetSelectedPiece(selectedIndex); player.SetupPlacementGhost(); Hud.instance.m_hoveredPiece = null; } private static void ScrollSnapPointSelection(Player player) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)player.m_placementGhost)) { if ((double)Input.mouseScrollDelta.y > 0.0) { player.m_manualSnapPoint++; player.m_placeRotation--; } else { player.m_manualSnapPoint--; player.m_placeRotation++; } } player.SetupPlacementGhost(); } private static void Equip_Hammer(Player player) { ItemData rightItem = ((Humanoid)player).m_rightItem; if (rightItem != null && rightItem.m_shared.m_name == "$item_hammer" && !((Character)player).InAttack()) { player.QueueUnequipAction(rightItem); } else if (!Hud.IsPieceSelectionVisible()) { Predicate<ItemData> match = (ItemData item) => item.m_shared.m_name == "$item_hammer"; List<ItemData> list = ((Humanoid)player).m_inventory.m_inventory.FindAll(match); list.Sort(new CompareDurability()); if (list.Count > 0) { player.QueueEquipAction(list[0]); } } } private static void RepairHighlighted(Player player) { if (!Hud.IsPieceSelectionVisible() && ((Character)player).InPlaceMode()) { ItemData rightItem = ((Humanoid)player).GetRightItem(); if (rightItem != null && ((Character)player).HaveStamina(rightItem.m_shared.m_attack.m_attackStamina)) { player.Repair(rightItem, player.m_buildPieces.GetSelectedPiece()); } } } private static bool Pipette_Pickaxe(Player player) { GameObject hoverObject = ((Humanoid)player).GetHoverObject(); Hoverable val = (Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<Hoverable>() : null); if (val == null) { return true; } string hoverText = val.GetHoverText(); if (Array.Exists(pickaxeCompareTexts, (string element) => element == hoverText)) { if (((Humanoid)player).m_rightItem != null && ((Humanoid)player).m_rightItem.m_shared.m_name.Contains("$item_pickaxe")) { player.QueueUnequipAction(((Humanoid)player).m_rightItem); m_stopAutorun = true; return false; } Predicate<ItemData> match = (ItemData item) => item.m_shared.m_name.Contains("$item_pickaxe"); List<ItemData> source = ((Humanoid)player).m_inventory.m_inventory.FindAll(match); List<ItemData> list = source.Where((ItemData pick) => pick.m_durability != 0f).ToList(); if (list.Count > 0) { int maxTier = list.Max((ItemData pick) => pick.m_shared.m_toolTier); List<ItemData> list2 = list.Where((ItemData pick) => pick.m_shared.m_toolTier == maxTier).ToList(); list2.Sort(new CompareDurability()); if (list2.Count > 0) { player.QueueUnequipAction(((Humanoid)player).m_rightItem); player.QueueEquipAction(list2[0]); m_stopAutorun = true; return false; } } } return true; } private static bool Pipette_Axe(Player player) { GameObject hoverObject = ((Humanoid)player).GetHoverObject(); Hoverable val = (Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<Hoverable>() : null); if (val == null) { return true; } string hoverText = val.GetHoverText(); if (Array.Exists(axeCompareTexts, (string element) => element == hoverText)) { if (((Humanoid)player).m_rightItem != null && (((Humanoid)player).m_rightItem.m_shared.m_name.Contains("$item_axe") || ((Humanoid)player).m_rightItem.m_shared.m_name.Contains("$item_battleaxe"))) { player.QueueUnequipAction(((Humanoid)player).m_rightItem); return false; } Predicate<ItemData> match = (ItemData item) => item.m_shared.m_name.Contains("$item_axe"); Predicate<ItemData> match2 = (ItemData item) => item.m_shared.m_name.Contains("$item_battleaxe"); List<ItemData> source = ((Humanoid)player).m_inventory.m_inventory.FindAll(match); List<ItemData> list = source.Where((ItemData axe) => axe.m_durability != 0f).ToList(); List<ItemData> source2 = ((Humanoid)player).m_inventory.m_inventory.FindAll(match2); List<ItemData> list2 = source2.Where((ItemData battleaxe) => battleaxe.m_durability != 0f).ToList(); if (EZBuild.Prefer_2H_Axe.Value) { if (list2.Count > 0) { int maxTier4 = list2.Max((ItemData Battleaxe) => Battleaxe.m_shared.m_toolTier); List<ItemData> list3 = list2.Where((ItemData Battleaxe) => Battleaxe.m_shared.m_toolTier == maxTier4).ToList(); list3.Sort(new CompareDurability()); if (list3.Count > 0) { player.QueueUnequipAction(((Humanoid)player).m_rightItem); player.QueueEquipAction(list3[0]); return false; } } else if (list.Count > 0) { int maxTier3 = list.Max((ItemData axe) => axe.m_shared.m_toolTier); List<ItemData> list4 = list.Where((ItemData axe) => axe.m_shared.m_toolTier == maxTier3).ToList(); list4.Sort(new CompareDurability()); if (list4.Count > 0) { player.QueueUnequipAction(((Humanoid)player).m_rightItem); player.QueueEquipAction(list4[0]); return false; } } } if (!EZBuild.Prefer_2H_Axe.Value) { if (list.Count > 0) { int maxTier2 = list.Max((ItemData axe) => axe.m_shared.m_toolTier); List<ItemData> list5 = list.Where((ItemData axe) => axe.m_shared.m_toolTier == maxTier2).ToList(); list5.Sort(new CompareDurability()); if (list5.Count > 0) { player.QueueUnequipAction(((Humanoid)player).m_rightItem); player.QueueEquipAction(list5[0]); return false; } } else if (list2.Count > 0) { int maxTier = list2.Max((ItemData Battleaxe) => Battleaxe.m_shared.m_toolTier); List<ItemData> list6 = list2.Where((ItemData Battleaxe) => Battleaxe.m_shared.m_toolTier == maxTier).ToList(); list6.Sort(new CompareDurability()); if (list6.Count > 0) { player.QueueUnequipAction(((Humanoid)player).m_rightItem); player.QueueEquipAction(list6[0]); return false; } } } } return true; } private static void Pipette_Building(Player player) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected I4, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected I4, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) bool flag = false; if (!((Character)player).InPlaceMode() && Hud.IsPieceSelectionVisible()) { return; } Piece hoveringPiece = player.GetHoveringPiece(); if ((Object)(object)hoveringPiece == (Object)null) { return; } PieceTable buildPieces = player.m_buildPieces; PieceCategory category = hoveringPiece.m_category; int availablePiecesInCategory = buildPieces.GetAvailablePiecesInCategory(category); for (int i = 0; i < availablePiecesInCategory; i++) { if (flag) { break; } Piece piece = buildPieces.GetPiece((int)category, new Vector2Int(i % 15, i / 15)); if (((Object)piece.m_icon).name == ((Object)hoveringPiece.m_icon).name) { Debug.Log((object)piece.m_icon); buildPieces.SetCategory((int)piece.m_category); player.SetSelectedPiece(new Vector2Int(i % 15, i / 15)); Quaternion localRotation = ((Component)hoveringPiece).transform.localRotation; player.m_placeRotation = (int)Math.Round(((Quaternion)(ref localRotation)).eulerAngles.y / 22.5f); MethodInfo method = typeof(Player).GetMethod("SetupPlacementGhost", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(player, new object[0]); Hud.instance.m_hoveredPiece = null; flag = true; } } } [HarmonyPostfix] [HarmonyPatch(typeof(Hud), "Awake")] private static void MoveHealthRoot(Hud __instance) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Vector3 localPosition = ((Transform)__instance.m_pieceHealthRoot).localPosition; ((Transform)__instance.m_pieceHealthRoot).localPosition = new Vector3(localPosition.x, localPosition.y + 20f, localPosition.z); } [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "UpdateHover")] private static IEnumerable<CodeInstruction> Patch(IEnumerable<CodeInstruction> instructions) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown if (!EZBuild.InteractWithToolEquipped.Value) { return instructions; } List<CodeInstruction> list = instructions.ToList(); for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.Calls(list[i], InPlaceModeRef)) { list[i - 1].opcode = OpCodes.Nop; list[i] = new CodeInstruction(OpCodes.Ldc_I4_0, (object)null); } } return list.AsEnumerable(); } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "Update")] private static bool Prefix_Update(Player __instance) { //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) //IL_003b: 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_006d: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer != (Object)(object)__instance) { return true; } if (!((Character)__instance).TakeInput()) { return true; } KeyboardShortcut value = EZBuild.Pipette_Hotkey.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey) && (Object)(object)((Humanoid)__instance).GetHoverObject() != (Object)null) { Pipette_Axe(__instance); } value = EZBuild.Pipette_Hotkey.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey) && (Object)(object)((Humanoid)__instance).GetHoverObject() != (Object)null) { Pipette_Pickaxe(__instance); } value = EZBuild.ClearSelectedPiece_Hotkey.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey) && ((Character)__instance).InPlaceMode()) { ClearSelectedPiece(__instance); } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "Update")] private static void Postfix_Update(Player __instance) { //IL_0031: 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_0039: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer != (Object)(object)__instance || !((Character)__instance).TakeInput()) { return; } KeyboardShortcut value; if (((Character)__instance).InPlaceMode()) { value = EZBuild.ScrollPieceSelection_Hotkey.Value; if (Input.GetKey(((KeyboardShortcut)(ref value)).MainKey) && (double)Input.mouseScrollDelta.y != 0.0) { ScrollPieceSelection(__instance); return; } } value = EZBuild.Pipette_Hotkey.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { Pipette_Building(__instance); return; } value = EZBuild.Repair_Hotkey.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { RepairHighlighted(__instance); return; } value = EZBuild.Hammer_Hotkey.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { Equip_Hammer(__instance); } else if (((Character)__instance).InPlaceMode()) { value = EZBuild.ScrollingSnapPointSelectionModifier.Value; if (Input.GetKey(((KeyboardShortcut)(ref value)).MainKey) && (double)Input.mouseScrollDelta.y != 0.0) { ScrollSnapPointSelection(__instance); } } } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerController), "FixedUpdate")] private static void Postfix_FixedUpdate() { if (m_stopAutorun) { Player.m_localPlayer.m_autoRun = false; m_stopAutorun = false; } } } [BepInPlugin("jwlei.EZBuild", "EZ Build and pipette", "2.1.1")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class EZBuild : BaseUnityPlugin { private const string MID = "jwlei.EZBuild"; private const string modName = "EZ Build and pipette"; private const string pluginVersion = "2.1.1"; private static string GENERAL_SETTINGS = "Settings"; public static ConfigEntry<bool> EnableMod { get; set; } public static ConfigEntry<bool> InteractWithToolEquipped { get; set; } public static ConfigEntry<bool> ScrollingSnapPointSelection { get; set; } public static ConfigEntry<KeyboardShortcut> ScrollingSnapPointSelectionModifier { get; set; } public static ConfigEntry<KeyboardShortcut> ScrollingSnapPointSelectionModifier2 { get; set; } public static ConfigEntry<bool> Prefer_2H_Axe { get; set; } public static ConfigEntry<KeyboardShortcut> Pipette_Hotkey { get; set; } public static ConfigEntry<KeyboardShortcut> Repair_Hotkey { get; set; } public static ConfigEntry<KeyboardShortcut> Hammer_Hotkey { get; set; } public static ConfigEntry<KeyboardShortcut> ScrollPieceSelection_Hotkey { get; set; } public static ConfigEntry<KeyboardShortcut> ClearSelectedPiece_Hotkey { get; set; } private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown Harmony val = new Harmony("jwlei.EZBuild"); LoadConfig(); if (!EnableMod.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"EZ Build and pipette has been disabled in the mod config"); OnDestroy(); } val.PatchAll(); } private void OnDestroy() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown Harmony val = new Harmony("jwlei.EZBuild"); val.UnpatchSelf(); } private void LoadConfig() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>(GENERAL_SETTINGS, "1. Enable EZ Build", true, "Enables or disables the mod"); InteractWithToolEquipped = ((BaseUnityPlugin)this).Config.Bind<bool>(GENERAL_SETTINGS, "2. Enable interaction when a tool is equipped", true, "Enables interaction with e.g. chests, ..., workbenches while holding tools"); ScrollingSnapPointSelectionModifier = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>(GENERAL_SETTINGS, "3. Modifier for scrolling through snap-points", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Hold modifier+mouse scroll to iterate over items in placemode (while building and not in the menu)."); Prefer_2H_Axe = ((BaseUnityPlugin)this).Config.Bind<bool>(GENERAL_SETTINGS, "4. Prefer 2H Axe over 1H Axe", false, "Toggles which axe is preffered when pipetting on trees etc."); Pipette_Hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>(GENERAL_SETTINGS, "5. Hotkey for pipette", new KeyboardShortcut((KeyCode)113, Array.Empty<KeyCode>()), "Pipette tool to copy piece and orientation of the build piece you're pointing at, or equipping the correct tool for the item you're aimed at."); Repair_Hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>(GENERAL_SETTINGS, "6. Hotkey for repairing", new KeyboardShortcut((KeyCode)118, Array.Empty<KeyCode>()), "With the hammer equipped, press the hotkey to repair the item you are pointing at."); Hammer_Hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>(GENERAL_SETTINGS, "7. Hotkey for equipping hammer", new KeyboardShortcut((KeyCode)98, Array.Empty<KeyCode>()), "Hotkey for equipping Hammer"); ScrollPieceSelection_Hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>(GENERAL_SETTINGS, "8. Modifier for scrolling piece selection", new KeyboardShortcut((KeyCode)306, Array.Empty<KeyCode>()), "Hold modifier+mouse scroll to iterate over items in the hammer/hoe/cultivator menu"); ClearSelectedPiece_Hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>(GENERAL_SETTINGS, "10. Hotkey for clearing the piece", new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()), "With the hammer equipped, press the hotkey to clear the current piece"); } } public class CompareDurability : IComparer<ItemData> { int IComparer<ItemData>.Compare(ItemData x, ItemData y) { if (x.m_durability == 0f) { return 1; } if (y.m_durability == 0f) { return -1; } return (x.m_durability > y.m_durability) ? 1 : (-1); } }