Black market: 18 merchant types from the game's items and player professions
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
378203d04d
commit
61ec91b34d
11 files changed
+132
-52
No files matched your search
@@ -5,8 +5,8 @@ using System.Linq;
|
||||
namespace Decentralized.Domain
|
||||
{
|
||||
public enum PayMode { Escrow, Advance }
|
||||
/// <summary>商家类型:全新矿卡经销商、二手矿卡贩子、模组高科技、军火、证件芯片、药物,大宗商家随机出现。</summary>
|
||||
public enum MerchantType { GpuNew, GpuUsed, Mods, Arms, Docs, Pharma, Bulk }
|
||||
/// <summary>商家类型:矿卡(全新 / 二手)、矿架能源、模组、军火、枪匠配件、证件芯片、药物、化学、酿酒、水培、养殖、矿工、水务、仓储、工具、奢侈品;大宗商家随机出现。</summary>
|
||||
public enum MerchantType { GpuNew, GpuUsed, Rigs, Modules, Arms, GunMods, Docs, Pharma, Chem, Brewer, Farm, Husbandry, Miner, Water, Storage, Tools, Luxury, Bulk }
|
||||
public enum OrderState { Pending, Ready, Done, Refunded, Lost }
|
||||
|
||||
/// <summary>黑市上的卖家:成交数与好评率公开;是不是骗子是隐藏的。</summary>
|
||||
@@ -104,33 +104,28 @@ namespace Decentralized.Domain
|
||||
|
||||
public double RugChance => Math.Min(Tuning.BmRugMax, Tuning.BmRugBase + Held / 10000.0 * Tuning.BmRugPerTenK);
|
||||
|
||||
private static readonly MerchantType[] Regular = { MerchantType.GpuNew, MerchantType.GpuUsed, MerchantType.Mods, MerchantType.Arms, MerchantType.Docs, MerchantType.Pharma };
|
||||
/// <summary>每周必有的"矿工路线"商家类型(从中抽 2 家),其余按全部类型抽。</summary>
|
||||
private static readonly MerchantType[] Core = { MerchantType.GpuNew, MerchantType.GpuUsed, MerchantType.Rigs, MerchantType.Modules };
|
||||
private static readonly MerchantType[] Others = { MerchantType.Arms, MerchantType.GunMods, MerchantType.Docs, MerchantType.Pharma, MerchantType.Chem, MerchantType.Brewer,
|
||||
MerchantType.Farm, MerchantType.Husbandry, MerchantType.Miner, MerchantType.Water, MerchantType.Storage, MerchantType.Tools, MerchantType.Luxury };
|
||||
|
||||
private static double F(Rng rng, double lo, double hi) => lo + rng.NextDouble() * (hi - lo);
|
||||
|
||||
/// <summary>商家类型对应的货(含货种、库存),按声望放开违禁等级。</summary>
|
||||
/// <summary>商家类型对应的货(含货种、库存),违禁品按声望放开等级。</summary>
|
||||
private List<BmListing> MerchantGoods(int idx, BmSeller s, int day, int rep, Rng rng, Func<string, long> value)
|
||||
{
|
||||
var list = new List<BmListing>();
|
||||
int n = s.Type == MerchantType.Bulk ? 2 : Tuning.BmMerchantListings;
|
||||
var contra = new List<KeyValuePair<string, int>>();
|
||||
switch (s.Type)
|
||||
{
|
||||
case MerchantType.Arms: contra = Pool.Where(x => ArmsIds.Contains(x.Key)).ToList(); break;
|
||||
case MerchantType.Docs: contra = Pool.Where(x => !ArmsIds.Contains(x.Key)).ToList(); break;
|
||||
case MerchantType.Pharma: contra = PharmaPool.ToList(); break;
|
||||
case MerchantType.Bulk: contra = Pool.Concat(PharmaPool).ToList(); break;
|
||||
}
|
||||
contra = contra.Where(x => x.Value <= MaxLevel(rep)).ToList();
|
||||
var tech = TechPool.ToList();
|
||||
bool gpuKind = s.Type == MerchantType.GpuNew || s.Type == MerchantType.GpuUsed;
|
||||
var entries = s.Type == MerchantType.Bulk ? Merchants.Table.Values.SelectMany(x => x).GroupBy(x => x.Id).Select(g => g.First()).ToList()
|
||||
: gpuKind ? new List<BmEntry>() : Merchants.Table[s.Type].ToList();
|
||||
entries = entries.Where(e => e.Kind != GoodKind.Contraband || e.Level <= MaxLevel(rep)).ToList();
|
||||
var gpus = UsedDealers.Pool(day);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
int qty = s.Type == MerchantType.Bulk ? rng.Range(Tuning.BmBulkQtyMin, Tuning.BmBulkQtyMax) : s.Type == MerchantType.GpuNew ? rng.Range(Math.Max(1, Tuning.BmQtyMin - 1), Tuning.BmQtyMax - 2) : rng.Range(Tuning.BmQtyMin, Tuning.BmQtyMax);
|
||||
double jitter = F(rng, 0.97, 1.03);
|
||||
BmListing l = null;
|
||||
bool gpuKind = s.Type == MerchantType.GpuNew || s.Type == MerchantType.GpuUsed;
|
||||
if (s.Type == MerchantType.Bulk) gpuKind = false;
|
||||
BmListing l;
|
||||
if (gpuKind)
|
||||
{
|
||||
bool fresh = s.Type == MerchantType.GpuNew;
|
||||
@@ -138,23 +133,14 @@ namespace Decentralized.Domain
|
||||
if (fresh) c.Health = 100;
|
||||
l = new BmListing { Item = "gpu:" + c.Model, Kind = GoodKind.Gpu, Level = 2, Model = c.Model, FakeOf = c.FakeOf, Health = c.Health, Price = (int)Math.Max(1, Math.Round(CardValue.Of(c.Model, c.Health) * s.Factor * jitter)) };
|
||||
}
|
||||
else if (s.Type == MerchantType.Mods || (s.Type == MerchantType.Bulk && tech.Count > 0 && (contra.Count == 0 || rng.Chance(0.4))))
|
||||
{
|
||||
if (tech.Count == 0) continue;
|
||||
int k = rng.Range(0, tech.Count - 1);
|
||||
string id = tech[k]; tech.RemoveAt(k);
|
||||
long v = value(id);
|
||||
if (v <= 0) continue;
|
||||
l = new BmListing { Item = id, Kind = GoodKind.Tech, Level = 3, Price = (int)Math.Max(1, Math.Round(v * s.Factor * jitter)) };
|
||||
}
|
||||
else
|
||||
{
|
||||
if (contra.Count == 0) continue;
|
||||
int k = rng.Range(0, contra.Count - 1);
|
||||
var pick = contra[k]; contra.RemoveAt(k);
|
||||
long v = value(pick.Key);
|
||||
if (v <= 0) continue;
|
||||
l = new BmListing { Item = pick.Key, Kind = GoodKind.Contraband, Level = pick.Value, Price = (int)Math.Max(1, Math.Round(v * s.Factor * jitter)) };
|
||||
if (entries.Count == 0) break;
|
||||
int k = rng.Range(0, entries.Count - 1);
|
||||
var e = entries[k]; entries.RemoveAt(k);
|
||||
long v = value(e.Id);
|
||||
if (v <= 0 || v > Tuning.BmMaxUnitValue) { i--; continue; }
|
||||
l = new BmListing { Item = e.Id, Kind = e.Kind, Level = e.Level, Price = (int)Math.Max(1, Math.Round(v * s.Factor * jitter)) };
|
||||
}
|
||||
l.Seller = idx; l.Qty = qty;
|
||||
list.Add(l);
|
||||
@@ -162,13 +148,12 @@ namespace Decentralized.Domain
|
||||
return list;
|
||||
}
|
||||
|
||||
private static readonly HashSet<string> ArmsIds = new HashSet<string> { "handmade_pistol", "printed_gun", "stun_baton", "revolver", "heavy_handmade_pistol", "flashbang_grenade", "smoke_grenade", "shotgun", "smg", "c4" };
|
||||
|
||||
/// <summary>每周重新生成商家、货架和论坛情报(与现货同一天刷新):从 6 种类型里抽 BmMerchantCount 家,另有概率出现一家大宗商家。</summary>
|
||||
public void RefreshOrders(int day, int rep, Rng rng, Func<string, long> value)
|
||||
{
|
||||
Sellers.Clear(); Catalog.Clear(); Forum.Clear();
|
||||
var types = Regular.OrderBy(_ => rng.NextDouble()).Take(Tuning.BmMerchantCount).ToList();
|
||||
var types = Core.OrderBy(_ => rng.NextDouble()).Take(Tuning.BmCoreMerchants).ToList();
|
||||
types.AddRange(Others.OrderBy(_ => rng.NextDouble()).Take(Tuning.BmMerchantCount - Tuning.BmCoreMerchants));
|
||||
if (rng.Chance(Tuning.BmBulkChance)) types.Add(MerchantType.Bulk);
|
||||
foreach (var t in types)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user