Price entry for listings with tiers as helpers; exclude storage containers from selling

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-03 21:58:19 +08:00
1 parent ce02773738
commit 776f66fd2c
5 files changed
+83 -24

No files matched your search

+4 -1
View File
@@ -65,8 +65,11 @@ namespace Decentralized
return Merchants.IsGood(id) ? id : null;
}
/// <summary>自己的储藏区、背包不能上架:卖掉会带走里面的东西,也会丢掉容量。</summary>
private static readonly System.Collections.Generic.HashSet<string> StorageIds = new System.Collections.Generic.HashSet<string>(Merchants.Table[MerchantType.Storage].Select(e => e.Id));
public static System.Collections.Generic.List<GameItem> Sellable() =>
GraphUtils.FindAllChildrenType<GameItem>(EmporiumEntry.Instance.invElement, i => GeneralHelper.IsItemOwned(i) && SellId(i) != null, i => i.identifier != Items.Rig);
GraphUtils.FindAllChildrenType<GameItem>(EmporiumEntry.Instance.invElement, i => GeneralHelper.IsItemOwned(i) && SellId(i) != null && !StorageIds.Contains(i.identifier) && i.FindAllChildItems().Count == 0, i => i.identifier != Items.Rig);
/// <summary>参考价:显卡按标称型号与成色,其余按游戏基础价。</summary>
public static long RefValue(GameItem it)
@@ -300,7 +300,7 @@ black.sell.listed,"Listed: {0} at {1}."
black.sell.delist,Take down
black.sell.rating,"Rating {0}%"
black.mine.sales,My listings
black.mine.sale,"{0} x{1}: {2}"
black.mine.sale,"{0} ref {1} price {2} (x{3}): {4}"
black.sale.Listed,listed
black.sale.Sold,"sold, payout day {0}"
black.sale.Paid,paid
@@ -343,6 +343,13 @@ black.pay.cancel,Cancel
black.pay.bad,Address does not match; nothing paid.
pay.mix,"Mixer {0} {1}"
pay.swap,"Ponero desk {0} {1}"
pay.listfee, (listing fee)
pay.listfee," (listing fee x{0})"
pay.repricefee," (repricing fee x{0})"
black.sell.repriced,"Repriced: {0}, now {1}."
black.edit.ref,"Reference price {0}"
black.edit.input,Enter a price
black.edit.price,"Price {0} (x{1})"
black.edit.ok,OK
black.edit.cancel,Cancel
black.edit.range,"The price must be 0.6 to 1.8 times the reference ({0} to {1})."
black.sell.reprice,Reprice
1 # Probably Decentralized localization table: English (en)
300 black.sell.delist
301 black.sell.rating
302 black.mine.sales
303 black.mine.sale
304 black.sale.Listed
305 black.sale.Sold
306 black.sale.Paid
343 black.pay.bad
344 pay.mix
345 pay.swap
346 pay.listfee
347 pay.repricefee
348 black.sell.repriced
349 black.edit.ref
350 black.edit.input
351 black.edit.price
352 black.edit.ok
353 black.edit.cancel
354 black.edit.range
355 black.sell.reprice
@@ -299,7 +299,7 @@ black.sell.listed,"已上架:{0},标价 {1}。"
black.sell.delist,撤下
black.sell.rating,"好评 {0}%"
black.mine.sales,我的上架
black.mine.sale,"{0} ×{1}:{2}"
black.mine.sale,"{0} 参考 {1} 标价 {2}(×{3}):{4}"
black.sale.Listed,上架中
black.sale.Sold,"已成交,第 {0} 天放款"
black.sale.Paid,已到账
@@ -342,6 +342,13 @@ black.pay.cancel,取消
black.pay.bad,地址不符,没有付款。
pay.mix,"混币器 {0} {1}"
pay.swap,"Ponero 兑换处 {0} {1}"
pay.listfee,(上架费)
pay.listfee,"(上架费 ×{0})"
pay.repricefee,"(改价费 ×{0})"
black.sell.repriced,"已改价:{0},标价 {1}。"
black.edit.ref,"参考价 {0}"
black.edit.input,输入标价
black.edit.price,"标价 {0}(×{1})"
black.edit.ok,确定
black.edit.cancel,取消
black.edit.range,"标价要在参考价的 0.6 到 1.8 倍之间({0} 到 {1})。"
black.sell.reprice,改价
1 # Probably Decentralized 本地化表:简体中文(zh)
299 black.sell.delist
300 black.sell.rating
301 black.mine.sales
302 black.mine.sale
303 black.sale.Listed
304 black.sale.Sold
305 black.sale.Paid
342 black.pay.bad
343 pay.mix
344 pay.swap
345 pay.listfee
346 pay.repricefee
347 black.sell.repriced
348 black.edit.ref
349 black.edit.input
350 black.edit.price
351 black.edit.ok
352 black.edit.cancel
353 black.edit.range
354 black.sell.reprice
+59 -19
View File
@@ -18,6 +18,9 @@ namespace Decentralized
private static Page _page = Page.Home;
private sealed class PendingPay { public string Address, Summary; public int Total; public Action Execute; }
private static PendingPay _pay;
private sealed class EditPrice { public GameItem Item; public BmSale Sale; public string Id; public long Ref; }
private static EditPrice _edit;
private static string _editPrice = "";
private static string _addr = "";
private static string _amount = "";
private static string _message;
@@ -33,7 +36,7 @@ namespace Decentralized
{
var page = p;
string name = L.T("tab." + p.ToString().ToLowerInvariant());
b.AddButton(page == _page ? $"[{name}]" : name, () => { _page = page; _message = null; _pay = null; Open(); });
b.AddButton(page == _page ? $"[{name}]" : name, () => { _page = page; _message = null; _pay = null; _edit = null; Open(); });
}
b.End();
b.AddSeparator();
@@ -51,7 +54,7 @@ namespace Decentralized
b.Show();
}
private static void Go(Page p) { _page = p; _message = null; _pay = null; Open(); }
private static void Go(Page p) { _page = p; _message = null; _pay = null; _edit = null; Open(); }
private static void Entry(CustomUIBuilder b, string icon, string name, string line1, string line2, Page target)
{
@@ -248,7 +251,7 @@ namespace Decentralized
if ((t == Web3Tab.Mixer && !Unlock.MixerUnlocked) || (t == Web3Tab.Black && !Unlock.BlackUnlocked)) continue;
var tab = t;
string name = L.T("web3.sub." + t.ToString().ToLowerInvariant());
b.AddButton(tab == _web3Tab ? $"[{name}]" : name, () => { _web3Tab = tab; _message = null; _pay = null; Open(); });
b.AddButton(tab == _web3Tab ? $"[{name}]" : name, () => { _web3Tab = tab; _message = null; _pay = null; _edit = null; Open(); });
}
b.End();
if (_web3Tab == Web3Tab.Mining) { ReportPage(b); return; }
@@ -310,10 +313,11 @@ namespace Decentralized
if (t == BlackTab.Desk && !desk) continue;
var tab = t;
string name = L.T("black.sub." + t.ToString().ToLowerInvariant());
b.AddButton(tab == _blackTab ? $"[{name}]" : name, () => { _blackTab = tab; _message = null; _pay = null; Open(); });
b.AddButton(tab == _blackTab ? $"[{name}]" : name, () => { _blackTab = tab; _message = null; _pay = null; _edit = null; Open(); });
}
b.End();
if (d.Black.Closed(day)) { b.AddLabel(L.T("black.rugged", d.Black.ClosedUntil - day + 1)); return; }
if (_edit != null) { EditPage(b); return; }
if (_blackTab == BlackTab.Desk && desk) { DeskPage(b, rep, day); return; }
if (_blackTab == BlackTab.Mine) { MinePage(b, day); return; }
if (_blackTab == BlackTab.Sell) { SellPage(b, day); return; }
@@ -366,7 +370,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) + " " + L.T("black.sell.slots", d.Black.ActiveListings, Tuning.BmMaxListings));
b.AddButton(L.T("black.sell.all"), () => BeginPay(d.Address("platform"), L.T("black.sell.all") + L.T("pay.listfee"), BlackDelivery.Sellable().Sum(it => BlackMarket.ListFee(BlackMarket.ListPriceOf(BlackDelivery.RefValue(it), _sellMult))), ListAll));
b.AddButton(L.T("black.sell.all"), () => BeginPay(d.Address("platform"), L.T("black.sell.all") + L.T("pay.listfee", _sellMult.ToString("0.0", CultureInfo.InvariantCulture)), BlackDelivery.Sellable().Sum(it => BlackMarket.ListFee(BlackMarket.ListPriceOf(BlackDelivery.RefValue(it), _sellMult))), ListAll));
b.AddSeparator();
var items = BlackDelivery.Sellable();
if (items.Count == 0) { b.AddLabel(L.T("black.sell.none")); return; }
@@ -384,7 +388,7 @@ namespace Decentralized
GoodHead(c, g, "");
c.AddLabel(L.T("black.price", g.Price));
c.AddFlexibleSpace();
c.AddButton(L.T("black.sell.list"), () => BeginPay(d.Address("platform"), ItemName(g.Item) + L.T("pay.listfee"), BlackMarket.ListFee(g.Price), () => ListItem(it)));
c.AddButton(L.T("black.sell.list"), () => BeginEdit(new EditPrice { Item = it, Id = g.Item, Ref = BlackDelivery.RefValue(it) }, g.Price));
});
}
@@ -409,13 +413,13 @@ namespace Decentralized
Open();
}
private static void ListItem(GameItem it)
private static void ListItem(GameItem it, double mult)
{
var d = Session.Data;
string id = BlackDelivery.SellId(it);
if (id == null) { Open(); return; }
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);
var s = d.Black.List(id, u?.Model, u?.FakeOf, u?.Health ?? 0, BlackDelivery.RefValue(it), mult, d.Hot, _payAsset, StoreStation.GetDayCounter(), Session.Price);
if (s == null) { _message = d.Black.ActiveListings >= Tuning.BmMaxListings ? L.T("black.sell.full", Tuning.BmMaxListings) : L.T("msg.balance"); Open(); return; }
it.Destroy();
_message = L.T("black.sell.listed", ItemName(id), s.ListPrice);
@@ -551,6 +555,51 @@ namespace Decentralized
Open();
}
private static void BeginEdit(EditPrice e, int initial)
{
_edit = e;
_editPrice = initial.ToString(CultureInfo.InvariantCulture);
_message = null;
Open();
}
private static int MinPrice(long refValue) => (int)Math.Ceiling(Tuning.BmSellMin * refValue - 1e-9);
private static int MaxPrice(long refValue) => (int)Math.Floor(Tuning.BmSellMax * refValue + 1e-9);
/// <summary>设定标价:显示参考价,档位按钮只是帮忙填价格,价格也可以手输;按 标价 / 参考价 的比例算成交和污点。</summary>
private static void EditPage(CustomUIBuilder b)
{
var e = _edit;
b.AddHeader(ItemName(e.Id));
b.AddLabel(L.T("black.edit.ref", e.Ref));
b.BeginPanel(RightW, -1f, TextAnchor.MiddleCenter, 0f, 0f);
b.AddInput(L.T("black.edit.input"), _editPrice, s => _editPrice = s, "price", s => _editPrice = s);
b.End();
b.BeginRow();
foreach (var m in SellMults)
{
double mult = m;
b.AddButton("×" + m.ToString("0.0", CultureInfo.InvariantCulture), () => { _editPrice = BlackMarket.ListPriceOf(e.Ref, mult).ToString(CultureInfo.InvariantCulture); Open(); });
}
b.End();
if (int.TryParse((_editPrice ?? "").Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out int p) && p > 0)
b.AddLabel(L.T("black.edit.price", p, (p / (double)e.Ref).ToString("0.00", CultureInfo.InvariantCulture)));
b.BeginRow();
b.AddButton(L.T("black.edit.ok"), () =>
{
if (!int.TryParse((_editPrice ?? "").Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out int price) || price < MinPrice(e.Ref) || price > MaxPrice(e.Ref))
{ _message = L.T("black.edit.range", MinPrice(e.Ref), MaxPrice(e.Ref)); Open(); return; }
double mult = price / (double)e.Ref;
var d = Session.Data;
int fee = e.Sale != null ? BlackMarket.RepriceFee(price) : BlackMarket.ListFee(price);
_edit = null;
BeginPay(d.Address("platform"), ItemName(e.Id) + L.T(e.Sale != null ? "pay.repricefee" : "pay.listfee", mult.ToString("0.00", CultureInfo.InvariantCulture)), fee,
() => { if (e.Sale != null) RepriceSale(e.Sale, mult); else ListItem(e.Item, mult); });
});
b.AddButton(L.T("black.edit.cancel"), () => { _edit = null; _message = null; Open(); });
b.End();
}
private static void RepriceSale(BmSale s, double mult)
{
var d = Session.Data;
@@ -581,20 +630,11 @@ namespace Decentralized
{
var sale = sl;
string st = sale.State == SaleState.Sold ? L.T("black.sale.Sold", sale.PayDay) : L.T("black.sale." + sale.State + (sale.State == SaleState.Delisted && sale.Why != null ? "." + sale.Why : ""));
l.AddLabel(L.T("black.mine.sale", ItemName(sale.Item), sale.Mult.ToString("0.0", CultureInfo.InvariantCulture), st));
l.AddLabel(L.T("black.mine.sale", ItemName(sale.Item), sale.Ref, sale.ListPrice, sale.Mult.ToString("0.00", CultureInfo.InvariantCulture), st));
if (sale.State == SaleState.Listed)
{
l.BeginRow();
foreach (var m in SellMults)
{
double mult = m;
string n = m.ToString("0.0", CultureInfo.InvariantCulture);
l.AddButton(Math.Abs(mult - sale.Mult) < 1e-9 ? $"[{n}]" : n, () =>
{
if (Math.Abs(mult - sale.Mult) < 1e-9) return;
BeginPay(d.Address("platform"), ItemName(sale.Item) + L.T("pay.repricefee", n), BlackMarket.RepriceFee(BlackMarket.ListPriceOf(sale.Ref, mult)), () => RepriceSale(sale, mult));
});
}
l.AddButton(L.T("black.sell.reprice"), () => BeginEdit(new EditPrice { Sale = sale, Id = sale.Item, Ref = sale.Ref }, sale.ListPrice));
l.AddButton(L.T("black.sell.delist"), () => Delist(sale));
l.End();
}