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 MultiCraft v1.5.0
MultiCraft.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CraftFromContainers; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("MultiCraft")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MultiCraft")] [assembly: AssemblyTitle("MultiCraft")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MultiCraft { [HarmonyPatch(typeof(InventoryGui), "Show")] public static class CraftGUI_Patch { private static void Postfix(Container container) { MultiCraft_UI.instance?.Start(); MultiCraft_Logic.instance?.Start(); } public static void Update() { if (MultiCraft_Logic.Started && InventoryGui.IsVisible()) { MultiCraft_UI.instance.RefreshCustomButtonStates(); MultiCraft_Logic.instance.Update(); } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class CraftGUI_Hide_Patch { private static void Postfix() { if (MultiCraft_Logic.Started) { MultiCraft_Logic.instance.ResetMultiCrafting(); } } } public class RequirementInformation { public string name; public int RequiredAmount; public RequirementInformation(int reqAmount, string itemName) { RequiredAmount = reqAmount; name = itemName; } public int GetMaxByCurrentRequirement() { if (RequiredAmount <= 0) { return int.MaxValue; } return Helper.GetAvailableItems(name) / RequiredAmount; } } public class CurrentRecipeInformation { private static CurrentRecipeInformation _instance; public static UnityEvent OnRecipeChanged = new UnityEvent(); private Dictionary<string, RequirementInformation> requirements; private string _name = ""; public static CurrentRecipeInformation instance { get { if (_instance == null) { _instance = new CurrentRecipeInformation(); } return _instance; } } public static bool Started { get; private set; } public bool IsRecipeReady { get; private set; } public string name { get { return _name; } set { if (!IsRecipe(value)) { _name = value; UnityEvent onRecipeChanged = OnRecipeChanged; if (onRecipeChanged != null) { onRecipeChanged.Invoke(); } ClearRequirements(); } } } public bool HasRequirements => requirements.Count > 0; private CurrentRecipeInformation() { requirements = new Dictionary<string, RequirementInformation>(); IsRecipeReady = false; } public void Start() { Started = true; } public bool IsRecipe(string otherName) { return name == otherName; } public void ClearRequirements() { IsRecipeReady = false; requirements.Clear(); } public void AddRequirement(string name, int requiredAmount) { if (requirements.ContainsKey(name)) { IsRecipeReady = true; return; } RequirementInformation value = new RequirementInformation(requiredAmount, name); requirements[name] = value; } public int GetCurrentMaxCraftable() { int num = 99; foreach (KeyValuePair<string, RequirementInformation> requirement in requirements) { num = Math.Min(num, requirement.Value.GetMaxByCurrentRequirement()); } return num; } } internal class Helper { public static ManualLogSource Logger; public static bool CraftFromContainersRunning = false; private static string CraftFromContainersGUID = "aedenthorn.CraftFromContainers"; public static bool CraftFromContainersInstalledAndActive { get; private set; } public static void CheckAvailabilityForCraftFromContainersPlugin() { CraftFromContainersRunning = false; BaseUnityPlugin[] componentsInChildren = GameObject.Find("BepInEx_Manager").GetComponentsInChildren<BaseUnityPlugin>(); for (int i = 0; i < componentsInChildren.Length; i++) { if (componentsInChildren[i].Info.Metadata.GUID == CraftFromContainersGUID) { CraftFromContainersRunning = IsCraftFromContainersEnabled(); } } } public static bool IsCraftFromContainersEnabled() { GameObject val = GameObject.Find("BepInEx_Manager"); Debug.Log((object)("Found bepInExManager: " + (object)val)); BaseUnityPlugin[] componentsInChildren = val.GetComponentsInChildren<BaseUnityPlugin>(); for (int i = 0; i < componentsInChildren.Length; i++) { if (componentsInChildren[i].Info.Metadata.GUID == "aedenthorn.CraftFromContainers") { return BepInExPlugin.modEnabled.Value; } } return false; } public static int GetAvailableItems(string itemName) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return 0; } int num = 0; if (CraftFromContainersRunning) { num = GetItemsInCloseContainers(itemName); } return ((Humanoid)localPlayer).GetInventory().CountItems(itemName, -1, true) + num; } public static int GetItemsInCloseContainers(string itemName) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (CraftFromContainersRunning) { int num = 0; { foreach (Container nearbyContainer in BepInExPlugin.GetNearbyContainers(((Component)Player.m_localPlayer).transform.position)) { num += nearbyContainer.GetInventory().CountItems(itemName, -1, true); } return num; } } return ((Humanoid)Player.m_localPlayer).GetInventory().CountItems(itemName, -1, true); } } [HarmonyPatch(typeof(Menu), "Start", new Type[] { })] public static class MainMenuShow_Patch { private static void Postfix() { Helper.CheckAvailabilityForCraftFromContainersPlugin(); } } [BepInPlugin("maximods.valheim.multicraft", "MultiCraft", "1.5.0")] [BepInProcess("valheim.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class MultiCraftPlugin : BaseUnityPlugin { public const string pluginGuid = "maximods.valheim.multicraft"; public const string pluginName = "MultiCraft"; public const string pluginVersion = "1.5.0"; public static ConfigEntry<bool> CapMaximumCrafts; public static ConfigEntry<bool> DisableVanillaMultiCraft; public static ConfigEntry<bool> GreyOutPlusAtMax; public static ConfigEntry<bool> EnableGamepadInput; public static ConfigEntry<int> GamepadBulkStep; public static ConfigEntry<bool> ShowCraftAmountHints; private Harmony _harmony; public static bool CraftFromContainersInstalledAndActive; private static List<Container> cachedContainers; public void Awake() { CapMaximumCrafts = ((BaseUnityPlugin)this).Config.Bind<bool>("MultiCraft", "CapMaximumCrafts", false, "Caps the maximum amount to craft to the maximum possible to craft."); DisableVanillaMultiCraft = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "DisableVanillaMultiCraft", true, "Disables Valheim's built-in \"Craft x5\" shortcut (Left Shift on keyboard, Left Stick click on controller) while MultiCraft is active, including the \" x 5\" suffix on the craft button."); GreyOutPlusAtMax = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "GreyOutPlusAtMax", true, "Greys out the + button once the craft amount reaches the maximum craftable with the materials available."); EnableGamepadInput = ((BaseUnityPlugin)this).Config.Bind<bool>("Gamepad", "EnableGamepadInput", true, "Enables controller input for the craft amount. D-Pad Left/Right steps the amount; hold Left Trigger for bulk steps, hold Right Trigger to jump to the maximum (or back to 1)."); GamepadBulkStep = ((BaseUnityPlugin)this).Config.Bind<int>("Gamepad", "GamepadBulkStep", 10, "How much the amount changes when Left Trigger is held while pressing D-Pad Left/Right."); ShowCraftAmountHints = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowCraftAmountHints", true, "Adds entries to the inventory hint bar describing the bulk and maximum craft-amount shortcuts."); Helper.Logger = ((BaseUnityPlugin)this).Logger; _harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { CraftGUI_Patch.Update(); } private void LateUpdate() { if (CraftFromContainersInstalledAndActive && cachedContainers != null) { cachedContainers.Clear(); cachedContainers = null; } } } public static class MultiCraft_KeyHints { private const string BULK_ENTRY = "MultiCraft_Bulk"; private const string MAX_ENTRY = "MultiCraft_Max"; private const string KEYBOARD_GROUP = "Keyboard"; private const string KEYBOARD_TEMPLATE = "Split"; private const string GAMEPAD_TEMPLATE = "Text - Split"; private static readonly string[] HintRoots = new string[2] { "InventoryHints", "InventoryWithContainerHints" }; private static readonly string[] GamepadGroups = new string[2] { "Gamepad", "GamepadMouse" }; private static readonly string[] VanillaMultiCraftEntries = new string[3] { "Keyboard/Multicraft", "Gamepad/Text - Multicraft", "GamepadMouse/Text - Multicraft" }; public static void Refresh() { if ((Object)(object)KeyHints.instance == (Object)null) { return; } string[] hintRoots = HintRoots; foreach (string text in hintRoots) { Transform val = ((Component)KeyHints.instance).transform.Find(text); if (!((Object)(object)val == (Object)null)) { HideVanillaMultiCraftHint(val); RefreshCraftAmountHints(val); } } } private static void HideVanillaMultiCraftHint(Transform root) { bool active = !MultiCraftPlugin.DisableVanillaMultiCraft.Value; string[] vanillaMultiCraftEntries = VanillaMultiCraftEntries; foreach (string text in vanillaMultiCraftEntries) { Transform val = root.Find(text); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(active); } } } private static void RefreshCraftAmountHints(Transform root) { bool value = MultiCraftPlugin.ShowCraftAmountHints.Value; int num = Mathf.Max(1, MultiCraftPlugin.GamepadBulkStep.Value); Transform val = root.Find("Keyboard"); if ((Object)(object)val != (Object)null) { Transform orCreateEntry = GetOrCreateEntry(val, "Split", "MultiCraft_Bulk"); SetKeyboardEntry(orCreateEntry, "Craft +" + num, "L-Shift"); Transform orCreateEntry2 = GetOrCreateEntry(val, "Split", "MultiCraft_Max"); SetKeyboardEntry(orCreateEntry2, "Craft max", "L-Ctrl"); SetVisible(orCreateEntry, value); SetVisible(orCreateEntry2, value); } string[] gamepadGroups = GamepadGroups; foreach (string text in gamepadGroups) { Transform val2 = root.Find(text); if (!((Object)(object)val2 == (Object)null)) { Transform orCreateEntry3 = GetOrCreateEntry(val2, "Text - Split", "MultiCraft_Bulk"); SetGamepadEntry(orCreateEntry3, "Craft +" + num, "JoyLTrigger"); Transform orCreateEntry4 = GetOrCreateEntry(val2, "Text - Split", "MultiCraft_Max"); SetGamepadEntry(orCreateEntry4, "Craft max", "JoyRTrigger"); bool visible = value && MultiCraftPlugin.EnableGamepadInput.Value; SetVisible(orCreateEntry3, visible); SetVisible(orCreateEntry4, visible); } } } private static Transform GetOrCreateEntry(Transform group, string templateName, string entryName) { Transform val = group.Find(entryName); if ((Object)(object)val != (Object)null) { return val; } Transform val2 = group.Find(templateName); if ((Object)(object)val2 == (Object)null) { return null; } Transform obj = Object.Instantiate<Transform>(val2, group); ((Object)obj).name = entryName; obj.SetAsLastSibling(); return obj; } private static void SetKeyboardEntry(Transform entry, string label, string modifierKey) { if (!((Object)(object)entry == (Object)null)) { SetText(entry.Find("Text"), label); SetText(entry.Find("key_bkg/Key"), modifierKey); SetText(entry.Find("key_bkg (2)/Key"), "Mouse-1"); } } private static void SetGamepadEntry(Transform entry, string label, string modifierZinputKey) { if (!((Object)(object)entry == (Object)null) && ZInput.instance != null) { string boundKeyString = ZInput.instance.GetBoundKeyString(modifierZinputKey, true); string boundKeyString2 = ZInput.instance.GetBoundKeyString("JoyDPadRight", true); if (!string.IsNullOrEmpty(boundKeyString) && !string.IsNullOrEmpty(boundKeyString2)) { SetText(entry, label + " <mspace=0.6em> " + boundKeyString + " + " + boundKeyString2 + "</mspace>"); } } } private static void SetText(Transform target, string value) { if (!((Object)(object)target == (Object)null)) { TMP_Text component = ((Component)target).GetComponent<TMP_Text>(); if ((Object)(object)component != (Object)null) { component.text = value; } } } private static void SetVisible(Transform entry, bool visible) { if ((Object)(object)entry != (Object)null) { ((Component)entry).gameObject.SetActive(visible); } } } public class MultiCraft_Logic { private static MultiCraft_Logic _instance; public static bool Started; private int _CurrentCraftAmount = 1; public int value = 5; private bool WasCrafting; private int WaitUpdates; public static MultiCraft_Logic instance { get { if (_instance == null) { _instance = new MultiCraft_Logic(); } return _instance; } } public int CurrentCraftAmount { get { return _CurrentCraftAmount; } set { _CurrentCraftAmount = value; MultiCraft_UI.instance.UpdateAmountLabel(_CurrentCraftAmount); } } public void Start() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown Started = true; CurrentCraftAmount = 1; CurrentRecipeInformation.OnRecipeChanged.AddListener(new UnityAction(OnRecipeChanged)); } public void OnRecipeChanged() { ResetMultiCrafting(); } public void ResetMultiCrafting() { CurrentCraftAmount = 1; CancelMultiCrafting(); } public void CancelMultiCrafting() { WasCrafting = false; if (Object.op_Implicit((Object)(object)InventoryGui.instance) && InventoryGui.instance.InCraftTab()) { MultiCraft_UI.instance.UnblockCustomButtons(); } } public void StartCraftingLogic() { WasCrafting = true; WaitUpdates = 5; } public void SetCraftAmount(int value) { CurrentCraftAmount = ClampCraftAmount(value); } public void AddToCraftAmount(int delta) { CurrentCraftAmount = ClampCraftAmount(CurrentCraftAmount + delta); } private int ClampCraftAmount(int value) { if (MultiCraftPlugin.CapMaximumCrafts.Value) { value = Math.Min(value, CurrentRecipeInformation.instance.GetCurrentMaxCraftable()); } if (value < 1) { value = 1; } return value; } public bool IsCrafting() { return ((Component)InventoryGui.instance.m_craftProgressBar).gameObject.activeInHierarchy; } public void Update() { if (WaitUpdates-- <= 0 && WasCrafting && !IsCrafting()) { if (CurrentCraftAmount <= 1) { CancelMultiCrafting(); } else { TryNextCraft(); } } } public void TryNextCraft() { WasCrafting = false; if (CurrentCraftAmount > 1) { int currentCraftAmount = CurrentCraftAmount - 1; CurrentCraftAmount = currentCraftAmount; if (!instance.CanCraft()) { CancelMultiCrafting(); } else { ((UnityEvent)((Component)InventoryGui.instance.m_craftButton).GetComponent<Button>().onClick).Invoke(); } } } public bool CanCraft() { return MultiCraft_UI.instance.IsCraftButtonEnabled(); } } public class MultiCraft_UI { private class UI_Names { public static string PLUS_BUTTON = "plus"; public static string MINUS_BUTTON = "minus"; public static string AMOUNT_TEXT = "amountText"; } public const string PLUS_ZINPUT_KEY = "JoyDPadRight"; public const string MINUS_ZINPUT_KEY = "JoyDPadLeft"; private const string GAMEPAD_HINT = "gamepad_hint"; private const float HINT_GAP = 4f; private const int MAX_CRAFT_AMOUNT = 99; private static MultiCraft_UI _instance; public static bool Started; private bool customButtonsBlocked; private RectTransform plusButton; private RectTransform minusButton; private RectTransform amountText; public static MultiCraft_UI instance { get { if (_instance == null) { _instance = new MultiCraft_UI(); } return _instance; } } public void Start() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown InventoryGui val = InventoryGui.instance; CreateSpaceFromCraftButton(val); plusButton = FindUiComponent(UI_Names.PLUS_BUTTON); if (!Object.op_Implicit((Object)(object)plusButton)) { Helper.Logger.LogMessage((object)"Creating new plus button"); Started = false; plusButton = CreateMultiCraftButton(val, UI_Names.PLUS_BUTTON, "+", "JoyDPadRight"); AttachButtonsToRight((Transform)(object)plusButton, 0.8f); ((UnityEvent)((Component)plusButton).GetComponent<Button>().onClick).AddListener(new UnityAction(OnPlusButtonPressed)); } minusButton = FindUiComponent(UI_Names.MINUS_BUTTON); if (!Object.op_Implicit((Object)(object)minusButton)) { Helper.Logger.LogMessage((object)"Creating new minus button"); Started = false; minusButton = CreateMultiCraftButton(val, UI_Names.MINUS_BUTTON, "-", "JoyDPadLeft"); AttachButtonsToRight((Transform)(object)minusButton, 0.1f); ((UnityEvent)((Component)minusButton).GetComponent<Button>().onClick).AddListener(new UnityAction(OnMinusButtonPressed)); } amountText = FindUiComponent(UI_Names.AMOUNT_TEXT); if (!Object.op_Implicit((Object)(object)amountText)) { Helper.Logger.LogMessage((object)"CreatingNewAmountText"); Started = false; CreateAmountLabel(); } if (!Started) { ((UnityEvent)val.m_craftButton.onClick).AddListener(new UnityAction(OnCraftButtonPressed)); ((UnityEvent)val.m_craftCancelButton.onClick).AddListener(new UnityAction(OnCraftCancelledButtonPressed)); ((UnityEvent)val.m_tabCraft.onClick).AddListener(new UnityAction(TabCraftPressed)); ((UnityEvent)val.m_tabUpgrade.onClick).AddListener(new UnityAction(UpgradeTabPressed)); } MultiCraft_KeyHints.Refresh(); RefreshGamepadHintGlyph(plusButton, "JoyDPadRight"); RefreshGamepadHintGlyph(minusButton, "JoyDPadLeft"); Started = true; } public RectTransform FindUiComponent(string name) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown return (RectTransform)((Component)((Component)InventoryGui.instance.m_craftButton).transform.parent).transform.Find(name); } public void TabCraftPressed() { UnblockCustomButtons(); ChangedTab(); } public void UpgradeTabPressed() { BlockCustomButtons(); ChangedTab(); } public bool IsCraftButtonEnabled() { return ((Selectable)((Component)InventoryGui.instance.m_craftButton).GetComponent<Button>()).interactable; } public void ChangedTab() { MultiCraft_Logic.instance.ResetMultiCrafting(); } public void BlockCustomButtons() { customButtonsBlocked = true; SetButtonInteractable(plusButton, value: false); SetButtonInteractable(minusButton, value: false); } public void UnblockCustomButtons() { customButtonsBlocked = false; RefreshCustomButtonStates(); } public bool AreCustomButtonsUsable() { if (Started) { return !customButtonsBlocked; } return false; } public void RefreshCustomButtonStates() { if (!customButtonsBlocked) { SetButtonInteractable(plusButton, !IsAtMaximumCraftable()); SetButtonInteractable(minusButton, MultiCraft_Logic.instance.CurrentCraftAmount > 1); } } private bool IsAtMaximumCraftable() { if (!MultiCraftPlugin.GreyOutPlusAtMax.Value) { return false; } if (!CurrentRecipeInformation.instance.HasRequirements) { return false; } return MultiCraft_Logic.instance.CurrentCraftAmount >= CurrentRecipeInformation.instance.GetCurrentMaxCraftable(); } private static void SetButtonInteractable(RectTransform buttonTransform, bool value) { if (!((Object)(object)buttonTransform == (Object)null)) { Button component = ((Component)buttonTransform).GetComponent<Button>(); if (!((Object)(object)component == (Object)null)) { ((Selectable)component).interactable = value; } } } public void OnCraftCancelledButtonPressed() { MultiCraft_Logic.instance.CancelMultiCrafting(); } public void OnCraftButtonPressed() { MultiCraft_Logic.instance.StartCraftingLogic(); BlockCustomButtons(); } public void CreateAmountLabel() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)InventoryGui.instance.m_craftButton).transform.Find("Text"); amountText = (RectTransform)((Component)Object.Instantiate<Transform>(val, ((Component)InventoryGui.instance.m_craftButton).transform.parent)).transform; ((Object)amountText).name = UI_Names.AMOUNT_TEXT; ((TMP_Text)((Component)amountText).GetComponent<TextMeshProUGUI>()).text = $"{MultiCraft_Logic.instance.CurrentCraftAmount}"; amountText.SetSizeWithCurrentAnchors((Axis)0, 50f); amountText.SetSizeWithCurrentAnchors((Axis)1, 50f); amountText.pivot = new Vector2(1.15f, 0.3f); } public void OnRecipeSelected() { MultiCraft_Logic.instance.ResetMultiCrafting(); } public void UpdateAmountLabel(int value) { if (Object.op_Implicit((Object)(object)amountText)) { ((TMP_Text)((Component)amountText).GetComponent<TextMeshProUGUI>()).text = $"{value}"; } } private void OnPlusButtonPressed() { if (JumpToExtremeRequested()) { MultiCraft_Logic.instance.SetCraftAmount(CurrentRecipeInformation.instance.HasRequirements ? CurrentRecipeInformation.instance.GetCurrentMaxCraftable() : 99); return; } int delta = 1; if (Input.GetKey((KeyCode)306)) { delta = 99; } else if (BulkStepRequested()) { delta = BulkStep(); } MultiCraft_Logic.instance.AddToCraftAmount(delta); } private void OnMinusButtonPressed() { if (Input.GetKey((KeyCode)306) || JumpToExtremeRequested()) { MultiCraft_Logic.instance.SetCraftAmount(1); return; } int delta = -1; if (BulkStepRequested()) { delta = -BulkStep(); } MultiCraft_Logic.instance.AddToCraftAmount(delta); } private static bool JumpToExtremeRequested() { if (MultiCraftPlugin.EnableGamepadInput.Value) { return ZInput.GetButton("JoyRTrigger"); } return false; } private static bool BulkStepRequested() { if (!Input.GetKey((KeyCode)304)) { if (MultiCraftPlugin.EnableGamepadInput.Value) { return ZInput.GetButton("JoyLTrigger"); } return false; } return true; } private static int BulkStep() { return Math.Max(1, MultiCraftPlugin.GamepadBulkStep.Value); } private void RetargetGamepadBinding(RectTransform button, string zinputKey) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) UIGamePad component = ((Component)button).GetComponent<UIGamePad>(); if (!((Object)(object)component == (Object)null)) { component.m_zinputKey = zinputKey; component.m_keyCode = (KeyCode)0; RectTransform val = (RectTransform)((Transform)button).Find("gamepad_hint"); if (!((Object)(object)val == (Object)null)) { val.anchorMin = new Vector2(1f, 0.5f); val.anchorMax = new Vector2(1f, 0.5f); val.pivot = new Vector2(0f, 0.5f); val.anchoredPosition = new Vector2(4f, 0f); UpdateGamepadHintGlyph(val, zinputKey); } } } private void RefreshGamepadHintGlyph(RectTransform button, string zinputKey) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (!((Object)(object)button == (Object)null)) { RectTransform val = (RectTransform)((Transform)button).Find("gamepad_hint"); if ((Object)(object)val != (Object)null) { UpdateGamepadHintGlyph(val, zinputKey); } } } private void UpdateGamepadHintGlyph(RectTransform hint, string zinputKey) { if (ZInput.instance == null) { return; } string boundKeyString = ZInput.instance.GetBoundKeyString(zinputKey, true); if (!string.IsNullOrEmpty(boundKeyString)) { TextMeshProUGUI[] componentsInChildren = ((Component)hint).GetComponentsInChildren<TextMeshProUGUI>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((TMP_Text)componentsInChildren[i]).text = boundKeyString; } } } private void CreateSpaceFromCraftButton(InventoryGui instance) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown RectTransform transform = (RectTransform)((Component)instance.m_craftButton).transform.parent; AttachButtonsToLeft((Transform)(object)transform); } private void AttachButtonsToLeft(Transform transform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) transform.localScale = new Vector3(0.8f, 1f, 1f); RectTransform val = (RectTransform)transform; if (Object.op_Implicit((Object)(object)val)) { val.anchorMin = new Vector2(0f, 0f); val.pivot = new Vector2(0f, 0.5f); } } private void AttachButtonsToRight(Transform transform, float verticalAllignment) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)transform; if (Object.op_Implicit((Object)(object)val)) { val.pivot = new Vector2(1.3f, verticalAllignment); } } private RectTransform CreateMultiCraftButton(InventoryGui __instance, string name, string text, string zinputKey) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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) Debug.Log((object)("Start of CreateButton: " + name)); RectTransform val = (RectTransform)((Component)__instance).transform.parent.Find(name); if ((Object)(object)val == (Object)null) { Transform transform = ((Component)__instance.m_craftButton).transform; Transform obj = Object.Instantiate<Transform>(transform, ((Component)transform).transform.parent); ((Object)obj).name = name; ((Component)obj).transform.SetAsFirstSibling(); val = (RectTransform)((Component)obj).transform; val.SetSizeWithCurrentAnchors((Axis)0, 45f); val.SetSizeWithCurrentAnchors((Axis)1, 30f); RectTransform val2 = (RectTransform)((Component)val).transform.Find("Text"); val2.SetSizeWithCurrentAnchors((Axis)0, 45f); val2.SetSizeWithCurrentAnchors((Axis)1, 30f); ((TMP_Text)((Component)val2).gameObject.GetComponent<TextMeshProUGUI>()).text = text; RetargetGamepadBinding(val, zinputKey); } return val; } } [HarmonyPatch(typeof(InventoryGui), "SetupRequirement", new Type[] { typeof(Transform), typeof(Requirement), typeof(Player), typeof(bool), typeof(int), typeof(int) })] public static class SetupRequirement_Patch { private static void Postfix(Transform elementRoot, Requirement req, Player player, bool craft, int quality, int craftMultiplier = 1) { string name = req.m_resItem.m_itemData.m_shared.m_name; CurrentRecipeInformation.instance.name = InventoryGui.instance.m_recipeName.text; if (!CurrentRecipeInformation.instance.IsRecipeReady && req.m_amount != 0) { CurrentRecipeInformation.instance?.AddRequirement(name, req.GetAmount(quality)); } UpdateRequirementLabels(elementRoot, req, quality); } private static void UpdateRequirementLabels(Transform elementRoot, Requirement req, int quality) { TextMeshProUGUI component = ((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent<TextMeshProUGUI>(); int availableItems = Helper.GetAvailableItems(req.m_resItem.m_itemData.m_shared.m_name); int num = req.GetAmount(quality) * MultiCraft_Logic.instance.CurrentCraftAmount; ((TMP_Text)component).text = $"{num}/{availableItems}"; } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe", new Type[] { typeof(Player), typeof(float) })] public static class VanillaMultiCraft_Patch { private static int _originalMultiCraftAmount = -1; private static void Prefix(InventoryGui __instance) { if (_originalMultiCraftAmount < 0) { _originalMultiCraftAmount = __instance.m_multiCraftAmount; } __instance.m_multiCraftAmount = (MultiCraftPlugin.DisableVanillaMultiCraft.Value ? 1 : _originalMultiCraftAmount); } private static void Postfix(InventoryGui __instance) { if (MultiCraftPlugin.DisableVanillaMultiCraft.Value) { TMP_Text componentInChildren = ((Component)__instance.m_craftButton).GetComponentInChildren<TMP_Text>(); if (!((Object)(object)componentInChildren == (Object)null) && componentInChildren.text.EndsWith(" x 1", StringComparison.Ordinal)) { componentInChildren.text = componentInChildren.text.Substring(0, componentInChildren.text.Length - " x 1".Length); } } } } }