Black market merchant shelves, bulk discount, bulk merchants, volume-driven taint, list-all

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-03 20:50:58 +08:00
1 parent d35425933c
commit d6b344f70b
11 files changed
+279 -60

No files matched your search

+70 -19
View File
@@ -343,20 +343,7 @@ namespace Decentralized
c.AddButton(L.T("black.buy"), () => BuyOffer(offer));
});
}
else
{
if (d.Black.Catalog.Count == 0) b.AddLabel(L.T("black.empty"));
Shelf(b, d.Black.Catalog.Cast<BmGood>().ToList(), (c, g) =>
{
var listing = (BmListing)g;
var seller = d.Black.Sellers[listing.Seller];
GoodHead(c, g, L.T("black.seller", seller.Name, seller.Trades, seller.Rating));
c.AddLabel(L.T("black.price", BlackMarket.Pay(listing.Price, _mode)));
c.AddFlexibleSpace();
bool ok = _mode == PayMode.Escrow || seller.Advance;
c.AddButton(ok ? L.T("black.order", Tuning.BmDoorDays) : L.T("black.noadvance"), () => { if (ok) PlaceOrder(listing); });
});
}
else MerchantShelf(b, d);
}
private static double _sellMult = 1.0;
@@ -375,6 +362,7 @@ namespace Decentralized
}
b.End();
b.AddLabel(L.T("mixer.balance", _payAsset, Fmt.Num(d.Hot.Avail(_payAsset))) + " " + L.T("black.sell.rating", d.Black.Rating));
b.AddButton(L.T("black.sell.all"), ListAll);
b.AddSeparator();
var items = BlackDelivery.Sellable();
if (items.Count == 0) { b.AddLabel(L.T("black.sell.none")); return; }
@@ -382,7 +370,7 @@ namespace Decentralized
{
string id = BlackDelivery.SellId(it);
var kind = BlackDelivery.KindOf(id);
var g = new BmGood { Item = id, Kind = kind, Level = kind == GoodKind.Contraband ? BlackMarket.Pool.First(x => x.Key == id).Value : 3 };
var g = new BmGood { Item = id, Kind = kind, Level = kind == GoodKind.Contraband ? BlackMarket.Pool.Concat(BlackMarket.PharmaPool).First(x => x.Key == id).Value : 3 };
if (kind == GoodKind.Gpu) g.Health = Items.ToUnit(it).Health;
g.Price = BlackMarket.ListPriceOf(BlackDelivery.RefValue(it), _sellMult);
return new { g, it };
@@ -398,6 +386,25 @@ namespace Decentralized
private static readonly System.Collections.Generic.Dictionary<BmGood, GameItem> SellCards = new System.Collections.Generic.Dictionary<BmGood, GameItem>();
private static void ListAll()
{
var d = Session.Data;
int n = 0;
foreach (var it in BlackDelivery.Sellable())
{
string id = BlackDelivery.SellId(it);
if (id == null) continue;
var u = Items.IsGpu(it) ? Items.ToUnit(it) : null;
var s = d.Black.List(id, u?.Model, u?.FakeOf, u?.Health ?? 0, BlackDelivery.RefValue(it), _sellMult, d.Hot, _payAsset, StoreStation.GetDayCounter(), Session.Price);
if (s == null) break;
it.Destroy();
n++;
}
_message = L.T("black.sell.listedall", n);
Session.Save();
Open();
}
private static void ListItem(GameItem it)
{
var d = Session.Data;
@@ -412,6 +419,50 @@ namespace Decentralized
Open();
}
private static int _merchant;
private static int _qty = 1;
private static readonly int[] Qtys = { 1, 5, 10 };
/// <summary>商家货架:选一家商家,看它这周的货,选件数下单。</summary>
private static void MerchantShelf(CustomUIBuilder b, SaveData d)
{
var sellers = d.Black.Sellers;
if (sellers.Count == 0) { b.AddLabel(L.T("black.empty")); return; }
if (_merchant >= sellers.Count) _merchant = 0;
b.BeginRow();
foreach (var m in Qtys)
{
int q = m;
b.AddButton(q == _qty ? $"[×{q}]" : "×" + q, () => { _qty = q; Open(); });
}
b.End();
for (int i = 0; i < sellers.Count; i += 3)
{
b.BeginRow();
for (int k = i; k < Math.Min(sellers.Count, i + 3); k++)
{
int idx = k;
string n = L.T("merchant." + sellers[k].Type) + " " + sellers[k].Name;
b.AddButton(idx == _merchant ? $"[{n}]" : n, () => { _merchant = idx; Open(); });
}
b.End();
}
var seller = sellers[_merchant];
b.AddLabel(L.T("black.seller", seller.Name, seller.Trades, seller.Rating) + " " + L.T("black.days", seller.Days));
var goods = d.Black.Catalog.Where(l => l.Seller == _merchant).Cast<BmGood>().ToList();
if (goods.Count == 0) { b.AddLabel(L.T("black.empty")); return; }
Shelf(b, goods, (c, g) =>
{
var listing = (BmListing)g;
int count = Math.Min(_qty, listing.Qty);
GoodHead(c, g, L.T("black.stock", listing.Qty));
c.AddLabel(L.T("black.price", BlackMarket.Pay(BlackMarket.OrderTotal(listing.Price, count), _mode)) + (count > 1 ? " ×" + count : ""));
c.AddFlexibleSpace();
bool ok = _mode == PayMode.Escrow || seller.Advance;
c.AddButton(ok ? L.T("black.order") : L.T("black.noadvance"), () => { if (ok) PlaceOrder(listing, count); });
});
}
private const int ShelfCols = 4;
private const float CardW = 172f, CardH = 268f;
@@ -455,12 +506,12 @@ namespace Decentralized
Open();
}
private static void PlaceOrder(BmListing l)
private static void PlaceOrder(BmListing l, int count)
{
var d = Session.Data;
var o = d.Black.Place(l, _mode, d.Hot, _payAsset, StoreStation.GetDayCounter(), Session.Price);
var o = d.Black.Place(l, count, _mode, d.Hot, _payAsset, StoreStation.GetDayCounter(), Session.Price);
if (o == null) { _message = L.T("msg.balance"); Open(); return; }
_message = L.T("black.ordered", ItemName(o.Item), o.DueDay);
_message = L.T("black.ordered", ItemName(o.Item) + (o.Count > 1 ? " ×" + o.Count : ""), o.DueDay);
Session.Save();
Open();
}
@@ -490,7 +541,7 @@ namespace Decentralized
if (sale.State == SaleState.Listed) l.AddButton(L.T("black.sell.delist"), () => Delist(sale));
}
foreach (var o in d.Black.Orders.OrderByDescending(x => x.PlacedDay))
l.AddLabel(L.T("black.mine.line", ItemName(o.Item), o.Seller, L.T("black.mode." + o.Mode), L.T("black.state." + o.State + (o.Why != null && o.State != OrderState.Done ? "." + o.Why : "")), o.DueDay));
l.AddLabel(L.T("black.mine.line", ItemName(o.Item) + (o.Count > 1 ? " ×" + o.Count : ""), o.Seller, L.T("black.mode." + o.Mode), L.T("black.state." + o.State + (o.Why != null && o.State != OrderState.Done ? "." + o.Why : "")), o.DueDay));
}, r =>
{
r.AddHeader(L.T("black.forum.h"));