0
0
mirror of https://github.com/sp-tarkov/modules.git synced 2025-02-13 09:50:43 -05:00
modules/project/Aki.SinglePlayer/Patches/ScavMode/ScavSellAllPriceStorePatch.cs
DrakiaXYZ 2e11148618 Fix the server sell all price not matching the client displayed value (!77)
- Add a patch that's triggered when the item list for the scav post-raid screen is populated that stores the calculated item value
- Add a second patch that's triggered when the player confirms a Sell All, that uses a custom request object that contains the previously calculated sell price

I made these patches not directly depend on any GClass/Class names to avoid having to update them with new client versions, this did make the code a bit harder to follow, but I think it's still readable.

Requires server PR: SPT-AKI/Server#216
Resolves: SPT-AKI/Issues#410

Co-authored-by: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com>
Reviewed-on: SPT-AKI/Modules#77
Co-authored-by: DrakiaXYZ <drakiaxyz@noreply.dev.sp-tarkov.com>
Co-committed-by: DrakiaXYZ <drakiaxyz@noreply.dev.sp-tarkov.com>
2024-02-08 09:11:22 +00:00

68 lines
2.2 KiB
C#

using Aki.Reflection.Patching;
using EFT.InventoryLogic;
using EFT.UI;
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Aki.SinglePlayer.Patches.ScavMode
{
/**
* After fetching the list of items for the post-raid scav inventory screen, calculate
* the total "Sell All" value, and store it for retrieval if the user hits "Sell All"
*/
public class ScavSellAllPriceStorePatch : ModulePatch
{
private static string FENCE_ID = "579dc571d53a0658a154fbec";
private static string ROUBLE_TID = "5449016a4bdc2d6f028b456f";
private static FieldInfo _sessionField;
public static int StoredPrice;
protected override MethodBase GetTargetMethod()
{
Type scavInventoryScreenType = typeof(ScavengerInventoryScreen);
_sessionField = AccessTools.GetDeclaredFields(scavInventoryScreenType).FirstOrDefault(f => f.FieldType == typeof(ISession));
return AccessTools.FirstMethod(scavInventoryScreenType, IsTargetMethod);
}
private bool IsTargetMethod(MethodBase method)
{
// Look for a method with one parameter named `items`
// method_3(out IEnumerable<Item> items)
if (method.GetParameters().Length == 1 && method.GetParameters()[0].Name == "items")
{
return true;
}
return false;
}
[PatchPostfix]
private static void PatchPostfix(ScavengerInventoryScreen __instance, IEnumerable<Item> items)
{
ISession session = _sessionField.GetValue(__instance) as ISession;
TraderClass traderClass = session.Traders.FirstOrDefault(x => x.Id == FENCE_ID);
int totalPrice = 0;
foreach (Item item in items)
{
if (item.TemplateId == ROUBLE_TID)
{
totalPrice += item.StackObjectsCount;
}
else
{
totalPrice += traderClass.GetItemPriceOnScavSell(item, true);
}
}
StoredPrice = totalPrice;
}
}
}