ClientMods/ItemSellPrice/ItemSellPrice.cs

212 lines
8.1 KiB
C#
Raw Normal View History

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