212 lines
8.1 KiB
C#
212 lines
8.1 KiB
C#
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 = GClass2334;
|
||
|
||
namespace IcyClawz.ItemSellPrice
|
||
{
|
||
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)
|
||
{
|
||
ItemAttributeClass attribute = new ItemAttributeClass(EItemAttributeId.MoneySum)
|
||
{
|
||
Name = EItemAttributeId.MoneySum.GetName(),
|
||
DisplayNameFunc = () =>
|
||
{
|
||
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
|
||
};
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
} |