diff --git a/Patches/AddOfferContextMenuPatches.cs b/Patches/AddOfferContextMenuPatches.cs new file mode 100644 index 0000000..1dff872 --- /dev/null +++ b/Patches/AddOfferContextMenuPatches.cs @@ -0,0 +1,190 @@ +using Comfort.Common; +using EFT.InventoryLogic; +using EFT.UI; +using EFT.UI.Ragfair; +using HarmonyLib; +using SPT.Reflection.Patching; +using SPT.Reflection.Utils; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEngine; + +namespace UIFixes; + +public static class AddOfferContextMenuPatches +{ + private const EItemInfoButton AddOfferInfoButton = (EItemInfoButton)77; + + private static Item AddOfferItem = null; + + public static void Enable() + { + new AddOfferMenuPatch().Enable(); + new AddOfferIsActivePatch().Enable(); + new AddOfferIsInteractivePatch().Enable(); + new AddOfferNameIconPatch().Enable(); + + new AddOfferExecutePatch().Enable(); + new ShowAddOfferWindowPatch().Enable(); + new SelectItemPatch().Enable(); + } + + public class AddOfferMenuPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.DeclaredProperty(R.InventoryInteractions.CompleteType, "AvailableInteractions").GetMethod; + } + + [PatchPostfix] + public static void Postfix(ref IEnumerable __result) + { + if (Settings.AddOfferContextMenu.Value) + { + var list = __result.ToList(); + list.Insert(list.IndexOf(EItemInfoButton.Tag), AddOfferInfoButton); + __result = list; + } + } + } + + public class AddOfferNameIconPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(InteractionButtonsContainer), nameof(InteractionButtonsContainer.Show)).MakeGenericMethod(typeof(EItemInfoButton)); + } + + [PatchPrefix] + public static void Prefix(ref IReadOnlyDictionary names, ref IReadOnlyDictionary icons) + { + names ??= new Dictionary() + { + { AddOfferInfoButton, "ragfair/OFFER ADD" } + }; + + icons ??= new Dictionary() + { + { AddOfferInfoButton, EFTHardSettings.Instance.StaticIcons.GetSmallCurrencySign(ECurrencyType.RUB) } + }; + } + } + + public class AddOfferIsActivePatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(R.ContextMenuHelper.Type, "IsActive"); + } + + [PatchPrefix] + public static bool Prefix(EItemInfoButton button, ref bool __result) + { + if (button != AddOfferInfoButton) + { + return true; + } + + if (Plugin.InRaid()) + { + __result = false; + return false; + } + + __result = true; + return false; + } + } + + public class AddOfferIsInteractivePatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(R.ContextMenuHelper.Type, "IsInteractive"); + } + + [PatchPostfix] + public static void Postfix(EItemInfoButton button, ref IResult __result, Item ___item_0) + { + if (button != AddOfferInfoButton) + { + return; + } + + ISession session = PatchConstants.BackEndSession; + RagFairClass ragfair = session.RagFair; + if (ragfair.MyOffersCount >= ragfair.GetMaxOffersCount(ragfair.MyRating)) + { + __result = new FailedResult("ragfair/Reached maximum amount of offers"); + } + + RagfairOfferSellHelperClass ragfairHelper = new(session.Profile, session.Profile.Inventory.Stash.Grid); + if (!ragfairHelper.method_4(___item_0, out string error)) + { + __result = new FailedResult(error); + } + } + } + + public class AddOfferExecutePatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(R.InventoryInteractions.Type, "ExecuteInteractionInternal"); + } + + [PatchPrefix] + public static bool Prefix(ItemInfoInteractionsAbstractClass __instance, EItemInfoButton interaction, Item ___item_0) + { + if (interaction != AddOfferInfoButton) + { + return true; + } + + AddOfferItem = ___item_0; + + __instance.ExecuteInteractionInternal(EItemInfoButton.FilterSearch); + return false; + } + } + + public class ShowAddOfferWindowPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(RagfairScreen), nameof(RagfairScreen.Show)); + } + + [PatchPostfix] + public static void Postfix(RagfairScreen __instance) + { + if (AddOfferItem == null) + { + return; + } + + __instance.method_27(); // click the add offer button + } + } + + public class SelectItemPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(AddOfferWindow), nameof(AddOfferWindow.Show)); + } + + [PatchPostfix] + public static void Postfix(RagfairOfferSellHelperClass ___ragfairOfferSellHelperClass) + { + if (AddOfferItem == null) + { + return; + } + + ___ragfairOfferSellHelperClass.SelectItem(AddOfferItem); + AddOfferItem = null; + } + } +} \ No newline at end of file diff --git a/Plugin.cs b/Plugin.cs index 7c4a0bd..71abfb2 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -75,6 +75,7 @@ public class Plugin : BaseUnityPlugin WeaponModdingPatches.Enable(); TagPatches.Enable(); TacticalBindsPatches.Enable(); + AddOfferContextMenuPatches.Enable(); } public static bool InRaid() diff --git a/R.cs b/R.cs index ba934f1..1d2ad26 100644 --- a/R.cs +++ b/R.cs @@ -736,10 +736,12 @@ public static class R public class InventoryInteractions(object value) : Wrapper(value) { public static Type Type { get; private set; } + public static Type CompleteType { get; private set; } public static void InitTypes() { Type = PatchConstants.EftTypes.Single(t => t.GetField("HIDEOUT_WEAPON_MODIFICATION_REQUIRED") != null); // GClass3045 + CompleteType = PatchConstants.EftTypes.Single(t => t != Type && Type.IsAssignableFrom(t)); // GClass3046 } } diff --git a/Settings.cs b/Settings.cs index 2c26dea..71138d2 100644 --- a/Settings.cs +++ b/Settings.cs @@ -94,6 +94,8 @@ internal class Settings public static ConfigEntry UnpackKeyBind { get; set; } public static ConfigEntry FilterByKeyBind { get; set; } public static ConfigEntry LinkedSearchKeyBind { get; set; } + public static ConfigEntry AddOfferContextMenu { get; set; } // Advanced + public static ConfigEntry AddOfferKeyBind { get; set; } public static ConfigEntry SortingTableKeyBind { get; set; } public static ConfigEntry LimitNonstandardDrags { get; set; } // Advanced public static ConfigEntry ItemContextBlocksTextInputs { get; set; } // Advanced @@ -422,6 +424,24 @@ internal class Settings null, new ConfigurationManagerAttributes { }))); + configEntries.Add(AddOfferContextMenu = config.Bind( + InputSection, + "Add Offer Context Menu", + true, + new ConfigDescription( + "Add a context menu to list the item on the flea market", + null, + new ConfigurationManagerAttributes { IsAdvanced = true }))); + + configEntries.Add(AddOfferKeyBind = config.Bind( + InputSection, + "Linked Search Shortcut", + new KeyboardShortcut(KeyCode.None), + new ConfigDescription( + "Keybind to list item on the flea market", + null, + new ConfigurationManagerAttributes { }))); + configEntries.Add(SortingTableKeyBind = config.Bind( InputSection, "Transfer to/from Sorting Table",