diff --git a/InsuranceInteractions.cs b/InsuranceInteractions.cs index 4684fac..dccde90 100644 --- a/InsuranceInteractions.cs +++ b/InsuranceInteractions.cs @@ -4,32 +4,33 @@ using EFT.UI; using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static RootMotion.FinalIK.InteractionTrigger.Range; namespace UIFixes { - public class InsuranceInteractions(Item item, ItemUiContext uiContext, int playerRubles) : ItemInfoInteractionsAbstractClass(uiContext) + public class InsuranceInteractions(IEnumerable items, ItemUiContext uiContext, int playerRubles) : ItemInfoInteractionsAbstractClass(uiContext) { private readonly InsuranceCompanyClass insurance = uiContext.Session.InsuranceCompany; - private readonly Item item = item; + private readonly List items = items.ToList(); private readonly int playerRubles = playerRubles; - private List items; + private List insurableItems; private readonly Dictionary prices = []; + public InsuranceInteractions(Item item, ItemUiContext uiContext, int playerRubles) : this([item], uiContext, playerRubles) { } + public void LoadAsync(Action callback) { - ItemClass itemClass = ItemClass.FindOrCreate(item); - items = insurance.GetItemChildren(itemClass).Flatten(insurance.GetItemChildren).Concat([itemClass]) + IEnumerable itemClasses = items.Select(ItemClass.FindOrCreate); + insurableItems = itemClasses.SelectMany(insurance.GetItemChildren) + .Flatten(insurance.GetItemChildren) + .Concat(itemClasses) .Where(i => insurance.ItemTypeAvailableForInsurance(i) && !insurance.InsuredItems.Contains(i)) .ToList(); - insurance.GetInsurePriceAsync(items, _ => + insurance.GetInsurePriceAsync(insurableItems, _ => { foreach (var insurer in insurance.Insurers) { - int price = this.items.Select(i => insurance.InsureSummary[insurer.Id][i]).Where(s => s.Loaded).Sum(s => s.Amount); + int price = this.insurableItems.Select(i => insurance.InsureSummary[insurer.Id][i]).Where(s => s.Loaded).Sum(s => s.Amount); prices[insurer.Id] = price; string priceColor = price > playerRubles ? "#FF0000" : "#ADB8BC"; @@ -46,7 +47,7 @@ namespace UIFixes private void Insure(string insurerId) { insurance.SelectedInsurerId = insurerId; - insurance.InsureItems(this.items, result => { }); + insurance.InsureItems(this.insurableItems, result => { }); } public IResult GetButtonInteraction(string interactionId) diff --git a/Patches/ContextMenuPatches.cs b/Patches/ContextMenuPatches.cs index 927ed16..246eaa3 100644 --- a/Patches/ContextMenuPatches.cs +++ b/Patches/ContextMenuPatches.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using TMPro; namespace UIFixes { @@ -63,6 +64,8 @@ namespace UIFixes }); TradingRootInteractionsItemField = AccessTools.Field(TradingRootInteractionsType, "item_0"); + new ContextMenuNamesPatch().Enable(); + new DeclareSubInteractionsInventoryPatch().Enable(); new CreateSubInteractionsInventoryPatch().Enable(); @@ -75,6 +78,28 @@ namespace UIFixes new EnableInsureInnerItemsPatch().Enable(); } + public class ContextMenuNamesPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(ContextMenuButton), nameof(ContextMenuButton.Show)); + } + + [PatchPostfix] + public static void Postfix(string caption, TextMeshProUGUI ____text) + { + if (caption == EItemInfoButton.Insure.ToString() && MultiSelect.Count > 1) + { + InsuranceCompanyClass insurance = ItemUiContext.Instance.Session.InsuranceCompany; + int count = MultiSelect.ItemContexts.Select(ic => ItemClass.FindOrCreate(ic.Item)) + .Where(i => insurance.ItemTypeAvailableForInsurance(i) && !insurance.InsuredItems.Contains(i)) + .Count(); + + ____text.text += " (x" + count + ")"; + } + } + } + public class DeclareSubInteractionsInventoryPatch : ModulePatch { protected override MethodBase GetTargetMethod() @@ -108,7 +133,9 @@ namespace UIFixes { int playerRubles = GetPlayerRubles(___itemUiContext_1); - CurrentInsuranceInteractions = new(___item_0, ___itemUiContext_1, playerRubles); + CurrentInsuranceInteractions = MultiSelect.Active ? + new(MultiSelect.ItemContexts.Select(ic => ic.Item), ___itemUiContext_1, playerRubles) : + new(___item_0, ___itemUiContext_1, playerRubles); // Because this is async, need to protect against a different subInteractions activating before loading is done // This isn't thread-safe at all but now the race condition is a microsecond instead of hundreds of milliseconds. @@ -176,6 +203,9 @@ namespace UIFixes Item item = (Item)TradingRootInteractionsItemField.GetValue(__instance); CurrentInsuranceInteractions = new(item, ___itemUiContext_0, playerRubles); + CurrentInsuranceInteractions = MultiSelect.Active ? + new(MultiSelect.ItemContexts.Select(ic => ic.Item), ___itemUiContext_0, playerRubles) : + new(item, ___itemUiContext_0, playerRubles); // Because this is async, need to protect against a different subInteractions activating before loading is done // This isn't thread-safe at all but now the race condition is a microsecond instead of hundreds of milliseconds. @@ -288,8 +318,12 @@ namespace UIFixes } InsuranceCompanyClass insurance = new R.ContextMenuHelper(__instance).InsuranceCompany; - ItemClass itemClass = ItemClass.FindOrCreate(___item_0); - IEnumerable insurableItems = insurance.GetItemChildren(itemClass).Flatten(insurance.GetItemChildren).Concat([itemClass]) + + IEnumerable items = MultiSelect.Active ? MultiSelect.ItemContexts.Select(ic => ic.Item) : [___item_0]; + IEnumerable itemClasses = items.Select(ItemClass.FindOrCreate); + IEnumerable insurableItems = itemClasses.SelectMany(insurance.GetItemChildren) + .Flatten(insurance.GetItemChildren) + .Concat(itemClasses) .Where(i => insurance.ItemTypeAvailableForInsurance(i) && !insurance.InsuredItems.Contains(i)); if (insurableItems.Any())