ClientMods/ItemSellPrice/ItemSellPrice.cs

148 lines
5.9 KiB
C#
Raw Normal View History

using Comfort.Common;
using EFT;
using EFT.InventoryLogic;
using SPT.Reflection.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using CurrencyUtil = GClass2531;
2024-03-05 22:48:21 +02:00
namespace IcyClawz.ItemSellPrice;
internal static class TraderClassExtensions
{
2024-03-05 22:48:21 +02:00
private static ISession _Session;
private static ISession Session => _Session ??= ClientAppUtils.GetMainApp().GetClientBackEndSession();
2023-07-09 22:38:08 +03:00
2024-03-05 22:48:21 +02:00
private static readonly FieldInfo SupplyDataField =
typeof(TraderClass).GetField("supplyData_0", BindingFlags.NonPublic | BindingFlags.Instance);
2023-07-09 22:38:08 +03:00
2024-03-05 22:48:21 +02:00
public static SupplyData GetSupplyData(this TraderClass trader) =>
SupplyDataField.GetValue(trader) as SupplyData;
2023-07-09 22:38:08 +03:00
2024-03-05 22:48:21 +02:00
public static void SetSupplyData(this TraderClass trader, SupplyData supplyData) =>
SupplyDataField.SetValue(trader, supplyData);
2023-07-09 22:38:08 +03:00
2024-03-05 22:48:21 +02:00
public static async void UpdateSupplyData(this TraderClass trader)
{
Result<SupplyData> result = await Session.GetSupplyData(trader.Id);
if (result.Succeed)
2023-07-09 22:38:08 +03:00
trader.SetSupplyData(result.Value);
2024-03-05 22:48:21 +02:00
else
Debug.LogError("Failed to download supply data");
2023-07-09 22:38:08 +03:00
}
2024-03-05 22:48:21 +02:00
}
2023-07-09 22:38:08 +03:00
2024-03-05 22:48:21 +02:00
internal static class ItemExtensions
{
private static readonly Dictionary<string, string[]> DisplayNames = new()
{
2024-03-05 22:48:21 +02:00
["ch"] = ["售价({0}", "无法出售给商人"],
["cz"] = ["Prodejní cena ({0})", "Nemůže být prodán obchodníkům"],
["en"] = ["Selling price ({0})", "Cannot be sold to traders"],
["es"] = ["Precio de venta ({0})", "No puede ser vendido a los vendedores"],
["es-mx"] = ["Precio de venta ({0})", "No puede ser vendido a comerciantes"],
["fr"] = ["Prix de vente ({0})", "Ne peut pas être vendu aux marchands"],
["ge"] = ["Verkaufspreis ({0})", "Kann nicht an Händler verkauft werden"],
["hu"] = ["Eladási ár ({0})", "Kereskedőknek nem adható el"],
["it"] = ["Prezzo di vendita ({0})", "Non vendibile ai mercanti"],
["jp"] = ["販売価格({0}", "トレーダーには販売できません"],
["kr"] = ["판매 가격 ({0})", "상인에게 판매 불가"],
["pl"] = ["Cena sprzedaży ({0})", "Nie można sprzedawać handlarzom"],
["po"] = ["Preço de venda ({0})", "Não pode ser vendido a comerciantes"],
["ru"] = ["Цена продажи ({0})", "Невозможно продать торговцам"],
["sk"] = ["Predajná cena ({0})", "Nedá sa predať obchodníkom"],
["tu"] = ["Satış fiyatı ({0})", "Tüccarlara satılamaz"]
};
2024-03-05 22:48:21 +02:00
private static ISession _Session;
private static ISession Session => _Session ??= ClientAppUtils.GetMainApp().GetClientBackEndSession();
2024-03-05 22:48:21 +02:00
public static void AddTraderOfferAttribute(this Item item)
{
ItemAttributeClass attribute = new(EItemAttributeId.MoneySum)
{
2024-03-05 22:48:21 +02:00
Name = EItemAttributeId.MoneySum.GetName(),
DisplayNameFunc = () =>
{
2024-03-05 22:48:21 +02:00
string language = Singleton<SharedGameSettingsClass>.Instance?.Game?.Settings?.Language?.GetValue();
if (language is null || !DisplayNames.ContainsKey(language))
language = "en";
TraderOffer offer = GetBestTraderOffer(item);
return offer is not null
? string.Format(DisplayNames[language][0], offer.Name)
: DisplayNames[language][1];
},
Base = () =>
{
2024-03-05 22:48:21 +02:00
TraderOffer offer = GetBestTraderOffer(item);
return offer is not null ? offer.Price : 0.01f;
},
StringValue = () =>
{
2024-03-05 22:48:21 +02:00
TraderOffer offer = GetBestTraderOffer(item);
return offer is not null
? $"{offer.Currency} {offer.Price}" + (offer.Count > 1 ? $" ({offer.Count})" : "")
: "";
},
FullStringValue = () =>
{
IEnumerable<TraderOffer> offers = GetAllTraderOffers(item);
return offers is not null
? string.Join(Environment.NewLine, offers.Select(offer => $"{offer.Name}: {offer.Currency} {offer.Price}"))
: "";
},
DisplayType = () => EItemAttributeDisplayType.Compact
};
item.Attributes = [attribute, .. item.Attributes];
}
private sealed class TraderOffer(string name, int price, string currency, double course, int count)
{
public string Name = name;
public int Price = price;
public string Currency = currency;
public double Course = course;
public int Count = count;
}
private static TraderOffer GetTraderOffer(Item item, TraderClass trader)
{
var result = trader.GetUserItemPrice(item);
return result is null ? null : new(
trader.LocalizedName,
result.Value.Amount,
CurrencyUtil.GetCurrencyCharById(result.Value.CurrencyId),
trader.GetSupplyData().CurrencyCourses[result.Value.CurrencyId],
item.StackObjectsCount
);
}
2024-03-05 22:48:21 +02:00
private static IEnumerable<TraderOffer> GetAllTraderOffers(Item item)
{
if (!Session.Profile.Examined(item))
return null;
switch (item.Owner?.OwnerType)
{
2024-03-05 22:48:21 +02:00
case EOwnerType.RagFair:
case EOwnerType.Trader:
if (item.StackObjectsCount > 1 || item.UnlimitedCount)
{
2024-03-05 22:48:21 +02:00
item = item.CloneItem();
item.StackObjectsCount = 1;
item.UnlimitedCount = false;
}
2024-03-05 22:48:21 +02:00
break;
}
2024-03-05 22:48:21 +02:00
return Session.Traders
.Select(trader => GetTraderOffer(item, trader))
.Where(offer => offer is not null)
.OrderByDescending(offer => offer.Price * offer.Course);
}
2024-03-05 22:48:21 +02:00
private static TraderOffer GetBestTraderOffer(Item item) =>
GetAllTraderOffers(item)?.FirstOrDefault() ?? null;
}