diff --git a/CHANGELOG.md b/CHANGELOG.md index 44800ef..56ea46e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ### 第九阶段:剧情与收尾 - 多语言第二轮审校(Claude 子代理逐语言通读 UI 与 16 章手册,交叉复审 Gemini 的修订):采用 de 39、fr 56、es 34、pl 37、ru 45、ja 142 条(ja 里约一半是全角标点、×、〜 等机械统一)。要点:天数不再缩写、Tumbler 称谓与 Key-Drive 统一、手册页签名对齐界面、ASIC 时代统一、修正数处误译(俄语手册首章“卖出”写成用交易币付款、永续/挖矿章、日语质押章“向池子付款”等)。 +- 检视面板的型号行右侧显示“标签价”(当前报价,随指出和改标签实时变化),鉴定客户的估价框同步。 +- 显卡鉴定指南的鉴定示例由 1 个增至 5 个(成色很差、假冒、轻微使用、全新),共 13 页。 - 二手贩子的卡按卖家调整健康度:老实人 72–97、中间商 55–85、骗子 42–72,平均每张卡成色有问题的项(叶片、金手指、挡板、封条,共 4 项)约 0.5 / 1.5 / 2.5(原来三者都是 25–85,约 2.4)。范围进 `Tuning.UsedHealthMin/Max`。 - 显卡鉴定指南改为游戏原版的纸质指南样式(笔记本背景、委员会页眉、居中标题、插图加图注、“价格不变 / -n%”标注、末页鉴定示例,共 9 页,插图用检视台的大图),文案改成名词标题加陈述句,用词与原版鉴定指南一致(假冒、品相、价格不变)。 - (已被上一条取代)显卡鉴定手册曾做成阅读窗口(和 Web3 手册同一个窗口,共 8 页,8 种语言);外观折价六个数字进 `Tuning`(`CardFanDust` 等),手册用占位符取值。物品提示缩短为一句。 diff --git a/src/Decentralized/GpuGuide.cs b/src/Decentralized/GpuGuide.cs index fbfcf71..4dc204c 100644 --- a/src/Decentralized/GpuGuide.cs +++ b/src/Decentralized/GpuGuide.cs @@ -288,32 +288,62 @@ namespace Decentralized Text(b, y, T("gg.point.body"), "body"); } - // ---- 9 鉴定示例 ---- - private static void Page9(PaperUI b) + // ---- 9 起:鉴定示例 ---- + private sealed class Ex { public string Title, Label, Chip; public int Health, Fan, Fingers, Bracket, Seal; } + + private static readonly Ex[] Examples = + { + new Ex { Title = "gg.ex.h", Label = "RTX80", Health = 60, Fan = 2, Fingers = 1, Seal = 2 }, + new Ex { Title = "gg.ex.h3", Label = "RX800", Health = 35, Fan = 2, Fingers = 2, Bracket = 1, Seal = 2 }, + new Ex { Title = "gg.ex.h2", Label = "RTX90", Chip = "RTX60", Health = 90, Fan = 1 }, + new Ex { Title = "gg.ex.h4", Label = "RTX70", Health = 85, Fan = 1 }, + new Ex { Title = "gg.ex.h5", Label = "RX70", Health = 100 }, + }; + + private static void Page9(PaperUI b) { foreach (var e in Examples) ExamplePage(b, e); } + + private static string Brand(string model) => Hardware.Specs[model].Brand.ToString(); + + private static void ExamplePage(PaperUI b, Ex e) { float y = NewPage(b); - y = Section(b, y, L.T("gg.ex.h")); - const int health = 60; - var u = new Unit - { - Model = "RTX80", Health = health, - Look = new CardLook { Seed = 0, Fan = 2, Fingers = 1, Sticker = 2 }, - }; - long baseV = CardValue.Of("RTX80", health); - long fan = (long)Math.Round(baseV * Tuning.CardFanChipped), fin = (long)Math.Round(baseV * Tuning.CardFingersDark), seal = (long)Math.Round(baseV * Tuning.CardSealMissing); - long total = CardLabels.Value(u, null, 0); - var layers = new[] { Front("probidia", 2), "gpu_big_ov_fan_dust1_" + Fans(2), "gpu_big_ov_fan_chip_" + Fans(2), "gpu_big_ov_fin_dim" }; - float bottom = Art(b, X + (W - 150f) / 2, y, 0.78f, layers); + y = Section(b, y, L.T(e.Title)); + string real = e.Chip ?? e.Label; + var u = new Unit { Model = e.Label, FakeOf = e.Chip, Health = e.Health, Look = new CardLook { Seed = 0, Fan = e.Fan, Fingers = e.Fingers, Bracket = e.Bracket, Sticker = e.Seal } }; + long baseV = CardValue.Of(real, e.Health); + var layers = new List { Front(Hardware.Specs[real].Brand == "PMD" ? "pmd" : "probidia", Hardware.Specs[real].Tier) }; + int fans = Fans(Hardware.Specs[real].Tier); + if (e.Fan == 1) layers.Add("gpu_big_ov_fan_dust2_" + fans); + if (e.Fan == 2) { layers.Add("gpu_big_ov_fan_dust1_" + fans); layers.Add("gpu_big_ov_fan_chip_" + fans); } + if (e.Fingers == 1) layers.Add("gpu_big_ov_fin_dim"); + if (e.Fingers == 2) layers.Add("gpu_big_ov_fin_oxide"); + if (e.Bracket == 1) layers.Add("gpu_big_ov_brk_scratch"); + float bottom = Art(b, X + (W - 140f) / 2, y, 0.73f, layers.ToArray()); y = bottom + 6f; - y = Text(b, y, L.T("gg.ex.card", "Probidia RTX 80", health), "body", align: "center", gap: 10f); - const float lx = X + 38f, lw = W - 76f; - y = Text(b, y, L.T("gg.ex.base", baseV), "caption", align: "right", gap: 3f, x: lx, w: lw); - y = Text(b, y, L.T("gg.ex.fan", fan), "caption", Bad, "right", 3f, lx, lw); - y = Text(b, y, L.T("gg.ex.fin", fin), "caption", Bad, "right", 3f, lx, lw); - y = Text(b, y, L.T("gg.ex.seal", seal), "caption", Bad, "right", 6f, lx, lw); + string name = Hardware.Specs[e.Label].Brand + " " + Items.DisplayModel(e.Label); + y = Text(b, y, L.T("gg.ex.card", name, e.Health), "body", align: "center", gap: 8f); + const float lx = X + 20f, lw = W - 40f; + if (e.Chip != null) + { + y = Text(b, y, L.T("gg.ex.fake", name, Hardware.Specs[e.Chip].Brand + " " + Items.DisplayModel(e.Chip)), "caption", Bad, "center", 6f); + y = Text(b, y, L.T("gg.ex.claimed", CardValue.Of(e.Label, e.Health)), "caption", Ink, "right", 3f, lx, lw); + } + y = Text(b, y, L.T("gg.ex.base", baseV), "caption", Ink, "right", 3f, lx, lw); + int n = 0; + long Disc(double p) { n++; return (long)Math.Round(baseV * p); } + if (e.Fan == 1) y = Text(b, y, L.T("gg.ex.fan1", Disc(Tuning.CardFanDust)), "caption", Bad, "right", 3f, lx, lw); + if (e.Fan == 2) y = Text(b, y, L.T("gg.ex.fan", Disc(Tuning.CardFanChipped)), "caption", Bad, "right", 3f, lx, lw); + if (e.Fingers == 1) y = Text(b, y, L.T("gg.ex.fin", Disc(Tuning.CardFingersDark)), "caption", Bad, "right", 3f, lx, lw); + if (e.Fingers == 2) y = Text(b, y, L.T("gg.ex.fin2", Disc(Tuning.CardFingersOxidized)), "caption", Bad, "right", 3f, lx, lw); + if (e.Bracket == 1) y = Text(b, y, L.T("gg.ex.brk", Disc(Tuning.CardBracketScratch)), "caption", Bad, "right", 3f, lx, lw); + if (e.Seal == 2) y = Text(b, y, L.T("gg.ex.seal", Disc(Tuning.CardSealMissing)), "caption", Bad, "right", 3f, lx, lw); + if (n == 0) y = Text(b, y, L.T("gg.ex.nodisc"), "caption", Good, "right", 3f, lx, lw); + y += 3f; b.AddLine(lx, y, lx + lw, y, 1f, "#6A6458"); y += 6f; - y = Text(b, y, L.T("gg.ex.total", total), "label", Ink, "right", 10f, lx, lw); + long total = CardLabels.Value(u, null, 0); + y = Text(b, y, L.T("gg.ex.total", total), "label", Ink, "right", 8f, lx, lw); + if (e.Chip != null) y = Text(b, y, L.T("gg.ex.gap", CardValue.Of(e.Label, e.Health) - total), "caption", Bad, "right", 8f, lx, lw); Text(b, y, L.T("gg.ex.note"), "caption", Ink, "center"); } } diff --git a/src/Decentralized/GpuInspectView.cs b/src/Decentralized/GpuInspectView.cs index dd0bd80..88c073b 100644 --- a/src/Decentralized/GpuInspectView.cs +++ b/src/Decentralized/GpuInspectView.cs @@ -18,7 +18,7 @@ namespace Decentralized { private const float RowH = 30f, CardScale = 3f, PanelTop = -112f, DetailH = 26f, GroupGap = 8f; private const int RowCount = 5; - private TextMeshProUGUI detailText; + private TextMeshProUGUI detailText, priceText; private static GpuInspectView instance; private RectTransform root, cardRoot; private Button flip; @@ -178,7 +178,10 @@ namespace Decentralized MakeRect(root, "LabelFrame", new Vector2(0, panelY), new Vector2(648, panelH + 8), new Color(0.78f, 0.68f, 0.45f, 1f)); MakeRect(root, "LabelBack", new Vector2(0, panelY), new Vector2(640, panelH), new Color(0.10f, 0.11f, 0.14f, 0.96f)); MakeRect(root, "LabelDivider", new Vector2(0, PanelTop - 5 - RowH * CardLabels.AuthRows - DetailH - GroupGap / 2), new Vector2(620, 2), new Color(0.78f, 0.68f, 0.45f, 0.8f)); - detailText = MakeText(root, "Detail", new Vector2(-15, PanelTop - 5 - RowH * CardLabels.AuthRows - DetailH / 2), new Vector2(600, DetailH), TextAlignmentOptions.Left, 17); + detailText = MakeText(root, "Detail", new Vector2(-90, PanelTop - 5 - RowH * CardLabels.AuthRows - DetailH / 2), new Vector2(450, DetailH), TextAlignmentOptions.Left, 17); + priceText = MakeText(root, "LabelPrice", new Vector2(230, PanelTop - 5 - RowH * CardLabels.AuthRows - DetailH / 2), new Vector2(170, DetailH), TextAlignmentOptions.Right, 19); + priceText.color = new Color(1f, 0.85f, 0.45f); + PledgerSkin.Fit(priceText); PledgerSkin.Fit(detailText); flip = MakeButton(root, "Flip", new Vector2(0, PanelTop - panelH - 24), new Vector2(200, 30), out flipText); flip.onClick.AddListener(() => { if (shown != null) Items.Flip(shown); }); for (int i = 0; i < RowCount; i++) @@ -249,6 +252,7 @@ namespace Decentralized detailText.text = detail; detailText.color = spec ? new Color(1f, 0.7f, 0.6f) : new Color(0.75f, 0.78f, 0.85f); } + if (priceText != null) priceText.text = L.T("lbl.price", item.unitValue); if (flipText != null) flipText.text = L.T(Items.IsBack(item) ? "inspect.flip.front" : "inspect.flip.back"); // 贴纸上的序列号:只在背面显示 if (serialText != null) diff --git a/src/Decentralized/ModFiles/Localization/de.csv b/src/Decentralized/ModFiles/Localization/de.csv index 8fae97e..d098c27 100644 --- a/src/Decentralized/ModFiles/Localization/de.csv +++ b/src/Decentralized/ModFiles/Localization/de.csv @@ -869,3 +869,15 @@ gg.ex.fin,Matte Kontakte: -{0} gg.ex.seal,Siegel fehlt: -{0} gg.ex.total,Endwert: {0} gg.ex.note,Jeder Abzug ist ein Anteil des Grundwerts; die Abzüge werden addiert und abgezogen. +gg.ex.fan1,Lüfterblätter verstaubt: -{0} +gg.ex.fin2,Oxidierte Kontakte: -{0} +gg.ex.brk,Slotblende zerkratzt: -{0} +gg.ex.nodisc,Kein Abzug: -0 +gg.ex.fake,"Angegeben {0}, echter Chip {1}: Bewertung nach echtem Chip" +gg.ex.claimed,Preis als angegebenes Modell: {0} +gg.ex.gap,Abweichung vom Angebot: {0} +gg.ex.h2,Prüfbeispiel: Fälschung +gg.ex.h3,Prüfbeispiel: Stark abgenutzt +gg.ex.h4,Prüfbeispiel: Leicht gebraucht +gg.ex.h5,Prüfbeispiel: Neu +lbl.price,Etikettenpreis: {0} diff --git a/src/Decentralized/ModFiles/Localization/en.csv b/src/Decentralized/ModFiles/Localization/en.csv index 5620f03..a089d41 100644 --- a/src/Decentralized/ModFiles/Localization/en.csv +++ b/src/Decentralized/ModFiles/Localization/en.csv @@ -869,3 +869,15 @@ gg.ex.fin,Dull contacts: -{0} gg.ex.seal,Missing seal: -{0} gg.ex.total,Final value: {0} gg.ex.note,Every discount is a share of the base value; they are added up and deducted. +gg.ex.fan1,Dusty fan: -{0} +gg.ex.fin2,Oxidized contacts: -{0} +gg.ex.brk,Scratched bracket: -{0} +gg.ex.nodisc,No discounts: -0 +gg.ex.fake,"Stated {0}, real chip {1}: valued as the real chip" +gg.ex.claimed,Price as the stated model: {0} +gg.ex.gap,Difference from the quote: {0} +gg.ex.h2,Appraisal Example: Counterfeit +gg.ex.h3,Appraisal Example: Badly Worn +gg.ex.h4,Appraisal Example: Lightly Used +gg.ex.h5,Appraisal Example: Brand New +lbl.price,Label price: {0} diff --git a/src/Decentralized/ModFiles/Localization/es.csv b/src/Decentralized/ModFiles/Localization/es.csv index 1bf844a..8abd50c 100644 --- a/src/Decentralized/ModFiles/Localization/es.csv +++ b/src/Decentralized/ModFiles/Localization/es.csv @@ -869,3 +869,15 @@ gg.ex.fin,Contactos opacos: -{0} gg.ex.seal,Sello ausente: -{0} gg.ex.total,Valor final: {0} gg.ex.note,Cada descuento es una parte del valor base; se suman y se deducen. +gg.ex.fan1,Aspas con polvo: -{0} +gg.ex.fin2,Contactos oxidados: -{0} +gg.ex.brk,Soporte rayado: -{0} +gg.ex.nodisc,Sin descuentos: -0 +gg.ex.fake,"Indicado {0}, chip real {1}: se valora el chip real" +gg.ex.claimed,Precio del modelo indicado: {0} +gg.ex.gap,Diferencia con la oferta: {0} +gg.ex.h2,Ejemplo práctico: falsificación +gg.ex.h3,Ejemplo práctico: muy desgastada +gg.ex.h4,Ejemplo práctico: poco uso +gg.ex.h5,Ejemplo práctico: nueva +lbl.price,Precio de etiqueta: {0} diff --git a/src/Decentralized/ModFiles/Localization/fr.csv b/src/Decentralized/ModFiles/Localization/fr.csv index c899ddf..2a680c2 100644 --- a/src/Decentralized/ModFiles/Localization/fr.csv +++ b/src/Decentralized/ModFiles/Localization/fr.csv @@ -869,3 +869,15 @@ gg.ex.fin,Contacts ternes : -{0} gg.ex.seal,Scellé manquant : -{0} gg.ex.total,Valeur finale : {0} gg.ex.note,Chaque décote est une part de la valeur de base ; elles sont additionnées puis déduites. +gg.ex.fan1,Pales poussiéreuses : -{0} +gg.ex.fin2,Contacts oxydés : -{0} +gg.ex.brk,Équerre rayée : -{0} +gg.ex.nodisc,Aucune décote : -0 +gg.ex.fake,"Annoncé {0}, puce réelle {1} : valeur de la puce réelle" +gg.ex.claimed,Prix du modèle annoncé : {0} +gg.ex.gap,Écart avec l'offre : {0} +gg.ex.h2,Exemple : contrefaçon +gg.ex.h3,Exemple : très usée +gg.ex.h4,Exemple : peu utilisée +gg.ex.h5,Exemple : neuve +lbl.price,Prix affiché : {0} diff --git a/src/Decentralized/ModFiles/Localization/ja.csv b/src/Decentralized/ModFiles/Localization/ja.csv index 75aeec7..634e97e 100644 --- a/src/Decentralized/ModFiles/Localization/ja.csv +++ b/src/Decentralized/ModFiles/Localization/ja.csv @@ -869,3 +869,15 @@ gg.ex.fin,端子のくすみ:-{0} gg.ex.seal,封印シール欠損:-{0} gg.ex.total,最終価値:{0} gg.ex.note,各減額は基礎価値に対する割合で計算し、合計して差し引く。 +gg.ex.fan1,ブレードに埃:-{0} +gg.ex.fin2,端子の酸化:-{0} +gg.ex.brk,ブラケットのキズ:-{0} +gg.ex.nodisc,減額なし:-0 +gg.ex.fake,申告{0}、実チップ{1}:実チップで評価 +gg.ex.claimed,申告型番での価格:{0} +gg.ex.gap,提示額との差:{0} +gg.ex.h2,鑑定例:偽物 +gg.ex.h3,鑑定例:状態不良 +gg.ex.h4,鑑定例:軽使用 +gg.ex.h5,鑑定例:新品 +lbl.price,表示価格:{0} diff --git a/src/Decentralized/ModFiles/Localization/pl.csv b/src/Decentralized/ModFiles/Localization/pl.csv index 11e83e9..2b43638 100644 --- a/src/Decentralized/ModFiles/Localization/pl.csv +++ b/src/Decentralized/ModFiles/Localization/pl.csv @@ -869,3 +869,15 @@ gg.ex.fin,Zmatowiałe styki: -{0} gg.ex.seal,Brak plomby: -{0} gg.ex.total,Wartość końcowa: {0} gg.ex.note,Każda obniżka to część wartości bazowej; obniżki sumuje się i odejmuje. +gg.ex.fan1,Zakurzone łopatki: -{0} +gg.ex.fin2,Utlenione styki: -{0} +gg.ex.brk,Porysowany śledź: -{0} +gg.ex.nodisc,Brak obniżek: -0 +gg.ex.fake,"Deklarowano {0}, faktycznie {1}: wycena wg faktycznego chipa" +gg.ex.claimed,Cena dla podanego modelu: {0} +gg.ex.gap,Różnica względem oferty: {0} +gg.ex.h2,Przykład oceny: podróbka +gg.ex.h3,Przykład oceny: mocno zużyta +gg.ex.h4,Przykład oceny: lekko używana +gg.ex.h5,Przykład oceny: nowa +lbl.price,Cena z etykiety: {0} diff --git a/src/Decentralized/ModFiles/Localization/ru.csv b/src/Decentralized/ModFiles/Localization/ru.csv index a7fbdf5..d6bfb57 100644 --- a/src/Decentralized/ModFiles/Localization/ru.csv +++ b/src/Decentralized/ModFiles/Localization/ru.csv @@ -869,3 +869,15 @@ gg.ex.fin,Потускневшие контакты: -{0} gg.ex.seal,Нет пломбы: -{0} gg.ex.total,Итоговая стоимость: {0} gg.ex.note,Каждая скидка — доля базовой стоимости; скидки складываются и вычитаются. +gg.ex.fan1,Лопасти в пыли: -{0} +gg.ex.fin2,Окисленные контакты: -{0} +gg.ex.brk,Царапины на планке: -{0} +gg.ex.nodisc,Скидок нет: -0 +gg.ex.fake,"Указано {0}, реальный чип {1}: оценка по реальному чипу" +gg.ex.claimed,Цена указанной модели: {0} +gg.ex.gap,Разница с предложением: {0} +gg.ex.h2,Пример оценки: подделка +gg.ex.h3,Пример оценки: сильный износ +gg.ex.h4,Пример оценки: лёгкий износ +gg.ex.h5,Пример оценки: новая +lbl.price,Цена по ярлыку: {0} diff --git a/src/Decentralized/ModFiles/Localization/zh.csv b/src/Decentralized/ModFiles/Localization/zh.csv index a24bba3..53cb950 100644 --- a/src/Decentralized/ModFiles/Localization/zh.csv +++ b/src/Decentralized/ModFiles/Localization/zh.csv @@ -868,3 +868,15 @@ gg.ex.fin,金手指发暗:-{0} gg.ex.seal,封条缺失:-{0} gg.ex.total,最终价值:{0} gg.ex.note,各项折价都按基础价值计算,相加后扣除。 +gg.ex.fan1,叶片积灰:-{0} +gg.ex.fin2,金手指氧化:-{0} +gg.ex.brk,挡板划痕:-{0} +gg.ex.nodisc,没有折价:-0 +gg.ex.fake,标称 {0},实际芯片 {1}:按实际芯片计价 +gg.ex.claimed,按标称型号的报价:{0} +gg.ex.gap,与报价相差:{0} +gg.ex.h2,鉴定示例:假冒显卡 +gg.ex.h3,鉴定示例:成色很差的显卡 +gg.ex.h4,鉴定示例:轻微使用 +gg.ex.h5,鉴定示例:全新显卡 +lbl.price,标签价:{0} diff --git a/src/Decentralized/ShowcaseCases.cs b/src/Decentralized/ShowcaseCases.cs index 6a3fec2..93b477c 100644 --- a/src/Decentralized/ShowcaseCases.cs +++ b/src/Decentralized/ShowcaseCases.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Decentralized.Domain; @@ -35,6 +36,8 @@ namespace Decentralized }; private static int _next; + /// 设了之后,贩子和鉴定客户上货时只拿这一件。 + public static Func Override; private static GameItem _last; private static void Place(GameItem item) @@ -59,6 +62,23 @@ namespace Decentralized public static void Register() { + ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Showcase: queue dealer case (test)", () => Log.Guard("展示样例(贩子,排队)", () => + { + var c = All[_next++ % All.Count]; + Override = () => Make(c, DealerKind.Middleman); + PlayerStore.Instance.storeClientManager.AddNextClient(UsedDealerClient.Create(DealerKind.Middleman, 40)); + PlayerStore.Instance.TryCallNextClient(); + Log.Info($"展示样例(贩子,排队){_next}/{All.Count}:{c.Name}"); + })); + ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Showcase: queue appraisal case (test)", () => Log.Guard("展示样例(鉴定,排队)", () => + { + var c = All[_next++ % All.Count]; + while (AppraisalRankHelper.GetRank() < 2) AppraisalRankHelper.Promote(); + Override = () => { var it = Make(c, DealerKind.Honest); AppraisalHelper.InitAppraisalItem(it, (int)it.unitValue); return it; }; + PlayerStore.Instance.storeClientManager.AddNextClient(StoreClientListAppraisal.CreateAppraisalRandom()); + PlayerStore.Instance.TryCallNextClient(); + Log.Info($"展示样例(鉴定,排队){_next}/{All.Count}:{c.Name}"); + })); ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Showcase: next dealer case (test)", () => Log.Guard("展示样例(贩子)", () => { var c = All[_next++ % All.Count]; diff --git a/src/Decentralized/UsedDealerClient.cs b/src/Decentralized/UsedDealerClient.cs index 10fa58e..02e3cfa 100644 --- a/src/Decentralized/UsedDealerClient.cs +++ b/src/Decentralized/UsedDealerClient.cs @@ -64,6 +64,7 @@ namespace Decentralized /// 鉴定公会送来的卡:一成是假卡;默认估价是按标称型号算的价。 private static GameItem CreateForAppraisal() { + if (ShowcaseCases.Override != null) { var o = ShowcaseCases.Override(); ShowcaseCases.Override = null; return o; } var rng = Session.Data?.Rng ?? new Rng(1); int day = StoreStation.GetDayCounter(); var cards = UsedDealers.Cards(DealerKind.Middleman, day, rng); @@ -96,6 +97,12 @@ namespace Decentralized private static void Place(DealerKind kind, List cards, Rng rng) => Log.Guard("二手贩子上货", () => { NegociationUIManager.Instance.OpenUI(); + if (ShowcaseCases.Override != null) + { + var one = ShowcaseCases.Override(); ShowcaseCases.Override = null; + PlayerStore.Instance.AddDirectSellingItemToTable(one); + return; + } var placed = new List(); foreach (var c in cards) {