autopopulate flea offer price; update flea offer price when bulk; ammobox unload in place fixes

This commit is contained in:
Tyfon
2024-07-23 16:46:45 -07:00
parent 35d54c282e
commit 48faa97082
7 changed files with 207 additions and 11 deletions

View File

@@ -1,5 +1,7 @@
using EFT.InventoryLogic;
using EFT.UI.DragAndDrop;
using EFT.UI.Ragfair;
using System;
using System.Runtime.CompilerServices;
using UnityEngine;
@@ -87,3 +89,16 @@ public static class ExtraItemViewStatsProperties
public static void SetHideMods(this ItemViewStats itemViewStats, bool value) => properties.GetOrCreateValue(itemViewStats).HideMods = value;
}
public static class ExtraItemMarketPricesPanelProperties
{
private static readonly ConditionalWeakTable<ItemMarketPricesPanel, Properties> properties = new();
private class Properties
{
public Action OnMarketPricesCallback = null;
}
public static Action GetOnMarketPricesCallback(this ItemMarketPricesPanel panel) => properties.GetOrCreateValue(panel).OnMarketPricesCallback;
public static Action SetOnMarketPricesCallback(this ItemMarketPricesPanel panel, Action handler) => properties.GetOrCreateValue(panel).OnMarketPricesCallback = handler;
}

View File

@@ -1,7 +1,9 @@
using EFT.UI.Ragfair;
using EFT.InventoryLogic;
using EFT.UI.Ragfair;
using HarmonyLib;
using JetBrains.Annotations;
using SPT.Reflection.Patching;
using System;
using System.Linq;
using System.Reflection;
using TMPro;
@@ -16,6 +18,9 @@ public static class AddOfferClickablePricesPatches
public static void Enable()
{
new AddButtonPatch().Enable();
new MarketPriceUpdatePatch().Enable();
new BulkTogglePatch().Enable();
new MultipleStacksPatch().Enable();
}
public class AddButtonPatch : ModulePatch
@@ -43,10 +48,99 @@ public static class AddOfferClickablePricesPatches
Button maximumButton = panel.MaximumLabel.GetOrAddComponent<HighlightButton>();
maximumButton.onClick.AddListener(() => SetRequirement(__instance, rublesRequirement, ____pricesPanel.Maximum));
____pricesPanel.AddDisposable(maximumButton.onClick.RemoveAllListeners);
____pricesPanel.SetOnMarketPricesCallback(() => PopulateOfferPrice(__instance, ____pricesPanel, rublesRequirement));
}
}
private static void SetRequirement(AddOfferWindow window, RequirementView requirement, float price)
public class MarketPriceUpdatePatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return AccessTools.Method(typeof(ItemMarketPricesPanel), nameof(ItemMarketPricesPanel.method_1));
}
[PatchPostfix]
public static void Postfix(ItemMarketPricesPanel __instance)
{
var action = __instance.GetOnMarketPricesCallback();
action?.Invoke();
}
}
public class BulkTogglePatch : ModulePatch
{
protected override MethodBase GetTargetMethod()
{
return AccessTools.Method(typeof(AddOfferWindow), nameof(AddOfferWindow.method_12));
}
[PatchPostfix]
public static void Postfix(AddOfferWindow __instance, bool arg, ItemMarketPricesPanel ____pricesPanel, RequirementView[] ____requirementViews)
{
if (!Settings.UpdatePriceOnBulk.Value)
{
return;
}
RequirementView rublesRequirement = ____requirementViews.First(rv => rv.name == "Requirement (RUB)");
double currentPrice = rublesRequirement.Requirement.PreciseCount;
if (currentPrice <= 0)
{
return;
}
// SetRequirement will multiply (or not), so just need the individual price
double individualPrice = arg ? currentPrice : Math.Ceiling(currentPrice / __instance.Int32_0);
SetRequirement(__instance, rublesRequirement, individualPrice);
}
}
// Called when item selection changes. Handles updating price if bulk is (or was) checked
public class MultipleStacksPatch : ModulePatch
{
private static bool WasBulk;
protected override MethodBase GetTargetMethod()
{
return AccessTools.Method(typeof(AddOfferWindow), nameof(AddOfferWindow.method_9));
}
[PatchPrefix]
public static void Prefix(AddOfferWindow __instance)
{
WasBulk = __instance.R().BulkOffer;
}
[PatchPostfix]
public static void Postfix(AddOfferWindow __instance, Item item, bool selected, ItemMarketPricesPanel ____pricesPanel, RequirementView[] ____requirementViews)
{
if (!Settings.UpdatePriceOnBulk.Value || __instance.Int32_0 < 1)
{
return;
}
// Bulk can autochange when selecting/deselecting, so only bail if it wasn't and still isn't bulk
if (!WasBulk && !__instance.R().BulkOffer)
{
return;
}
var rublesRequirement = ____requirementViews.First(rv => rv.name == "Requirement (RUB)");
double currentPrice = rublesRequirement.Requirement.PreciseCount;
// Need to figure out the price per item *before* this item was added/removed
int oldCount = __instance.Int32_0 + (selected ? -item.StackObjectsCount : item.StackObjectsCount);
if (oldCount <= 0)
{
return;
}
SetRequirement(__instance, rublesRequirement, currentPrice / oldCount);
}
}
private static void SetRequirement(AddOfferWindow window, RequirementView requirement, double price)
{
if (window.R().BulkOffer)
{
@@ -56,6 +150,26 @@ public static class AddOfferClickablePricesPatches
requirement.method_0(price.ToString("F0"));
}
private static void PopulateOfferPrice(AddOfferWindow window, ItemMarketPricesPanel pricesPanel, RequirementView rublesRequirement)
{
switch (Settings.AutoOfferPrice.Value)
{
case AutoFleaPrice.Minimum:
SetRequirement(window, rublesRequirement, pricesPanel.Minimum);
break;
case AutoFleaPrice.Average:
SetRequirement(window, rublesRequirement, pricesPanel.Average);
break;
case AutoFleaPrice.Maximum:
SetRequirement(window, rublesRequirement, pricesPanel.Maximum);
break;
case AutoFleaPrice.None:
default:
break;
}
}
public class HighlightButton : Button
{
private Color originalColor;

View File

@@ -1,4 +1,5 @@
using Comfort.Common;
using EFT;
using EFT.InventoryLogic;
using EFT.UI;
using HarmonyLib;
@@ -115,15 +116,21 @@ public static class UnloadAmmoPatches
[PatchPrefix]
public static void Prefix(Item item)
{
if (item is AmmoBox)
if (Settings.UnloadAmmoBoxInPlace.Value && item is AmmoBox)
{
UnloadState = new();
}
}
[PatchPostfix]
public static void Postfix()
public static async void Postfix(Task __result)
{
if (!Settings.UnloadAmmoBoxInPlace.Value)
{
return;
}
await __result;
UnloadState = null;
}
}
@@ -143,8 +150,7 @@ public static class UnloadAmmoPatches
return;
}
AmmoBox box = item.Parent.Container.ParentItem as AmmoBox;
if (box == null)
if (item.Parent.Container.ParentItem is not AmmoBox box)
{
return;
}
@@ -191,10 +197,17 @@ public static class UnloadAmmoPatches
public UnloadAmmoBoxState()
{
fakeStash = (StashClass)Singleton<ItemFactory>.Instance.CreateItem("FakeStash", "566abbc34bdc2d92178b4576", null);
if (Plugin.InRaid())
{
fakeStash = Singleton<GameWorld>.Instance.R().Stash;
}
else
{
fakeStash = (StashClass)Singleton<ItemFactory>.Instance.CreateItem("FakeStash", "566abbc34bdc2d92178b4576", null);
var profile = PatchConstants.BackEndSession.Profile;
fakeController = new(fakeStash, profile.ProfileId, profile.Nickname);
var profile = PatchConstants.BackEndSession.Profile;
fakeController = new(fakeStash, profile.ProfileId, profile.Nickname);
}
}
}
}

16
R.cs
View File

@@ -67,6 +67,7 @@ public static class R
InventoryScreen.InitTypes();
ScavengerInventoryScreen.InitTypes();
LocalizedText.InitTypes();
GameWorld.InitTypes();
}
public abstract class Wrapper(object value)
@@ -867,6 +868,20 @@ public static class R
set { StringCaseField.SetValue(Value, value); }
}
}
public class GameWorld(object value) : Wrapper(value)
{
public static Type Type { get; private set; }
private static FieldInfo StashField;
public static void InitTypes()
{
Type = typeof(EFT.GameWorld);
StashField = AccessTools.Field(Type, "stashClass");
}
public StashClass Stash { get { return (StashClass)StashField.GetValue(Value); } }
}
}
public static class RExtentensions
@@ -898,4 +913,5 @@ public static class RExtentensions
public static R.InventoryScreen R(this InventoryScreen value) => new(value);
public static R.ScavengerInventoryScreen R(this ScavengerInventoryScreen value) => new(value);
public static R.LocalizedText R(this LocalizedText value) => new(value);
public static R.GameWorld R(this GameWorld value) => new(value);
}

View File

@@ -37,6 +37,14 @@ internal enum SortingTableDisplay
Both
}
internal enum AutoFleaPrice
{
None,
Minimum,
Average,
Maximum
}
internal class Settings
{
// Categories
@@ -87,6 +95,7 @@ internal class Settings
public static ConfigEntry<bool> SwapItems { get; set; }
public static ConfigEntry<bool> SwapMags { get; set; }
public static ConfigEntry<bool> AlwaysSwapMags { get; set; }
public static ConfigEntry<bool> UnloadAmmoBoxInPlace { get; set; } // Advanced
public static ConfigEntry<bool> SwapImpossibleContainers { get; set; }
public static ConfigEntry<bool> ReorderGrids { get; set; }
public static ConfigEntry<bool> SynchronizeStashScrolling { get; set; }
@@ -125,6 +134,8 @@ internal class Settings
public static ConfigEntry<bool> ShowRequiredQuest { get; set; }
public static ConfigEntry<bool> AutoExpandCategories { get; set; }
public static ConfigEntry<bool> ClearFiltersOnSearch { get; set; }
public static ConfigEntry<AutoFleaPrice> AutoOfferPrice { get; set; }
public static ConfigEntry<bool> UpdatePriceOnBulk { get; set; }
public static ConfigEntry<bool> KeepAddOfferOpen { get; set; }
public static ConfigEntry<KeyboardShortcut> PurchaseAllKeybind { get; set; }
public static ConfigEntry<bool> KeepAddOfferOpenIgnoreMaxOffers { get; set; } // Advanced
@@ -452,6 +463,15 @@ internal class Settings
null,
new ConfigurationManagerAttributes { })));
configEntries.Add(UnloadAmmoBoxInPlace = config.Bind(
InventorySection,
"Unload Ammo Boxes In-Place",
true,
new ConfigDescription(
"Whether to unload ammo boxes in-place, otherwise there needs to be free space somewhere",
null,
new ConfigurationManagerAttributes { IsAdvanced = true })));
configEntries.Add(SwapImpossibleContainers = config.Bind(
InventorySection,
"Swap with Incompatible Containers",
@@ -734,6 +754,24 @@ internal class Settings
null,
new ConfigurationManagerAttributes { })));
configEntries.Add(AutoOfferPrice = config.Bind(
FleaMarketSection,
"Autopopulate Offer Price",
AutoFleaPrice.None,
new ConfigDescription(
"Autopopulte new offers with min/avg/max market price, or leave blank",
null,
new ConfigurationManagerAttributes { })));
configEntries.Add(UpdatePriceOnBulk = config.Bind(
FleaMarketSection,
"Update Offer Price on Bulk",
true,
new ConfigDescription(
"Automatically multiply or divide the price when you check/uncheck bulk, or or when you change the number of selected items while bulk is checked.",
null,
new ConfigurationManagerAttributes { })));
configEntries.Add(ShowRequiredQuest = config.Bind(
FleaMarketSection,
"Show Required Quest for Locked Offers",

View File

@@ -4,7 +4,7 @@
<TargetFramework>net471</TargetFramework>
<AssemblyName>Tyfon.UIFixes</AssemblyName>
<Description>SPT UI Fixes</Description>
<Version>2.3.1</Version>
<Version>2.3.2</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<Configurations>Debug;Release</Configurations>

View File

@@ -1,6 +1,6 @@
{
"name": "uifixes",
"version": "2.3.1",
"version": "2.3.2",
"main": "src/mod.js",
"license": "MIT",
"author": "Tyfon",