autopopulate flea offer price; update flea offer price when bulk; ammobox unload in place fixes
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
using EFT.InventoryLogic;
|
using EFT.InventoryLogic;
|
||||||
using EFT.UI.DragAndDrop;
|
using EFT.UI.DragAndDrop;
|
||||||
|
using EFT.UI.Ragfair;
|
||||||
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using UnityEngine;
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using EFT.UI.Ragfair;
|
using EFT.InventoryLogic;
|
||||||
|
using EFT.UI.Ragfair;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using SPT.Reflection.Patching;
|
using SPT.Reflection.Patching;
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
@@ -16,6 +18,9 @@ public static class AddOfferClickablePricesPatches
|
|||||||
public static void Enable()
|
public static void Enable()
|
||||||
{
|
{
|
||||||
new AddButtonPatch().Enable();
|
new AddButtonPatch().Enable();
|
||||||
|
new MarketPriceUpdatePatch().Enable();
|
||||||
|
new BulkTogglePatch().Enable();
|
||||||
|
new MultipleStacksPatch().Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AddButtonPatch : ModulePatch
|
public class AddButtonPatch : ModulePatch
|
||||||
@@ -43,10 +48,99 @@ public static class AddOfferClickablePricesPatches
|
|||||||
Button maximumButton = panel.MaximumLabel.GetOrAddComponent<HighlightButton>();
|
Button maximumButton = panel.MaximumLabel.GetOrAddComponent<HighlightButton>();
|
||||||
maximumButton.onClick.AddListener(() => SetRequirement(__instance, rublesRequirement, ____pricesPanel.Maximum));
|
maximumButton.onClick.AddListener(() => SetRequirement(__instance, rublesRequirement, ____pricesPanel.Maximum));
|
||||||
____pricesPanel.AddDisposable(maximumButton.onClick.RemoveAllListeners);
|
____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)
|
if (window.R().BulkOffer)
|
||||||
{
|
{
|
||||||
@@ -56,6 +150,26 @@ public static class AddOfferClickablePricesPatches
|
|||||||
requirement.method_0(price.ToString("F0"));
|
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
|
public class HighlightButton : Button
|
||||||
{
|
{
|
||||||
private Color originalColor;
|
private Color originalColor;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Comfort.Common;
|
using Comfort.Common;
|
||||||
|
using EFT;
|
||||||
using EFT.InventoryLogic;
|
using EFT.InventoryLogic;
|
||||||
using EFT.UI;
|
using EFT.UI;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
@@ -115,15 +116,21 @@ public static class UnloadAmmoPatches
|
|||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static void Prefix(Item item)
|
public static void Prefix(Item item)
|
||||||
{
|
{
|
||||||
if (item is AmmoBox)
|
if (Settings.UnloadAmmoBoxInPlace.Value && item is AmmoBox)
|
||||||
{
|
{
|
||||||
UnloadState = new();
|
UnloadState = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[PatchPostfix]
|
[PatchPostfix]
|
||||||
public static void Postfix()
|
public static async void Postfix(Task __result)
|
||||||
{
|
{
|
||||||
|
if (!Settings.UnloadAmmoBoxInPlace.Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await __result;
|
||||||
UnloadState = null;
|
UnloadState = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,8 +150,7 @@ public static class UnloadAmmoPatches
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AmmoBox box = item.Parent.Container.ParentItem as AmmoBox;
|
if (item.Parent.Container.ParentItem is not AmmoBox box)
|
||||||
if (box == null)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -191,10 +197,17 @@ public static class UnloadAmmoPatches
|
|||||||
|
|
||||||
public UnloadAmmoBoxState()
|
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;
|
var profile = PatchConstants.BackEndSession.Profile;
|
||||||
fakeController = new(fakeStash, profile.ProfileId, profile.Nickname);
|
fakeController = new(fakeStash, profile.ProfileId, profile.Nickname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
R.cs
16
R.cs
@@ -67,6 +67,7 @@ public static class R
|
|||||||
InventoryScreen.InitTypes();
|
InventoryScreen.InitTypes();
|
||||||
ScavengerInventoryScreen.InitTypes();
|
ScavengerInventoryScreen.InitTypes();
|
||||||
LocalizedText.InitTypes();
|
LocalizedText.InitTypes();
|
||||||
|
GameWorld.InitTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class Wrapper(object value)
|
public abstract class Wrapper(object value)
|
||||||
@@ -867,6 +868,20 @@ public static class R
|
|||||||
set { StringCaseField.SetValue(Value, value); }
|
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
|
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.InventoryScreen R(this InventoryScreen value) => new(value);
|
||||||
public static R.ScavengerInventoryScreen R(this ScavengerInventoryScreen 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.LocalizedText R(this LocalizedText value) => new(value);
|
||||||
|
public static R.GameWorld R(this GameWorld value) => new(value);
|
||||||
}
|
}
|
||||||
|
|||||||
38
Settings.cs
38
Settings.cs
@@ -37,6 +37,14 @@ internal enum SortingTableDisplay
|
|||||||
Both
|
Both
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal enum AutoFleaPrice
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Minimum,
|
||||||
|
Average,
|
||||||
|
Maximum
|
||||||
|
}
|
||||||
|
|
||||||
internal class Settings
|
internal class Settings
|
||||||
{
|
{
|
||||||
// Categories
|
// Categories
|
||||||
@@ -87,6 +95,7 @@ internal class Settings
|
|||||||
public static ConfigEntry<bool> SwapItems { get; set; }
|
public static ConfigEntry<bool> SwapItems { get; set; }
|
||||||
public static ConfigEntry<bool> SwapMags { get; set; }
|
public static ConfigEntry<bool> SwapMags { get; set; }
|
||||||
public static ConfigEntry<bool> AlwaysSwapMags { 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> SwapImpossibleContainers { get; set; }
|
||||||
public static ConfigEntry<bool> ReorderGrids { get; set; }
|
public static ConfigEntry<bool> ReorderGrids { get; set; }
|
||||||
public static ConfigEntry<bool> SynchronizeStashScrolling { 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> ShowRequiredQuest { get; set; }
|
||||||
public static ConfigEntry<bool> AutoExpandCategories { get; set; }
|
public static ConfigEntry<bool> AutoExpandCategories { get; set; }
|
||||||
public static ConfigEntry<bool> ClearFiltersOnSearch { 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<bool> KeepAddOfferOpen { get; set; }
|
||||||
public static ConfigEntry<KeyboardShortcut> PurchaseAllKeybind { get; set; }
|
public static ConfigEntry<KeyboardShortcut> PurchaseAllKeybind { get; set; }
|
||||||
public static ConfigEntry<bool> KeepAddOfferOpenIgnoreMaxOffers { get; set; } // Advanced
|
public static ConfigEntry<bool> KeepAddOfferOpenIgnoreMaxOffers { get; set; } // Advanced
|
||||||
@@ -452,6 +463,15 @@ internal class Settings
|
|||||||
null,
|
null,
|
||||||
new ConfigurationManagerAttributes { })));
|
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(
|
configEntries.Add(SwapImpossibleContainers = config.Bind(
|
||||||
InventorySection,
|
InventorySection,
|
||||||
"Swap with Incompatible Containers",
|
"Swap with Incompatible Containers",
|
||||||
@@ -734,6 +754,24 @@ internal class Settings
|
|||||||
null,
|
null,
|
||||||
new ConfigurationManagerAttributes { })));
|
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(
|
configEntries.Add(ShowRequiredQuest = config.Bind(
|
||||||
FleaMarketSection,
|
FleaMarketSection,
|
||||||
"Show Required Quest for Locked Offers",
|
"Show Required Quest for Locked Offers",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<TargetFramework>net471</TargetFramework>
|
<TargetFramework>net471</TargetFramework>
|
||||||
<AssemblyName>Tyfon.UIFixes</AssemblyName>
|
<AssemblyName>Tyfon.UIFixes</AssemblyName>
|
||||||
<Description>SPT UI Fixes</Description>
|
<Description>SPT UI Fixes</Description>
|
||||||
<Version>2.3.1</Version>
|
<Version>2.3.2</Version>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "uifixes",
|
"name": "uifixes",
|
||||||
"version": "2.3.1",
|
"version": "2.3.2",
|
||||||
"main": "src/mod.js",
|
"main": "src/mod.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Tyfon",
|
"author": "Tyfon",
|
||||||
|
|||||||
Reference in New Issue
Block a user