Rename GPU models: RZX→RTX, RZ→RX

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-03 18:34:57 +08:00
1 parent 7255befa01
commit 81b42ac2d3
94 files changed
+65 -64

No files matched your search

+8 -7
View File
@@ -5,10 +5,11 @@
### 第三阶段:数值调优(进行中)
- 混币器每轮手续费 6% → 4%;用币付款的顾客概率提到上层 30%、黑市 50%、革命派 50%、下层 25%,并多付 12%(溢价只加在币数上,污点仍按货值算)。
- 区块奖励 90 → 100;RZ800 耗电 12 → 14 kJ。
- 区块奖励 90 → 100;RX800 耗电 12 → 14 kJ。
- 减半对币价的传导改成每次在 0.15–0.85 的指数里随机(锚 +11% 到 +80%),历次累计存档。
- 低档次的卡也会被冒充:新增废片芯片 RZ10(不上架,只作假卡背后的真实芯片)。
- 低档次的卡也会被冒充:新增废片芯片 RX10(不上架,只作假卡背后的真实芯片)。
- 型号档次与实物不符(供电口、风扇数)的卡,摆给顾客时必被看穿并扣信誉(原来 50%),堵住用标签机把低档卡改成高档型号转卖的漏洞。
- 显卡型号改名:Probidia RZX → RTX,PMD RZ → RX(RTX 60/70/80/90,RX 70/80/800/900);贴图重新生成。旧存档里的旧型号物品不再识别。
- 买家看穿率、信誉扣减封顶收进 `Tuning.cs`。
- 单元测试 8909 项通过;游戏内只验证了模组正常载入,没有跑到新的假卡、减半随机和币付款溢价的实际画面。
@@ -27,18 +28,18 @@
以下条目取代下面较早条目里已过时的部分(型号、入口价、终端页面):
- 显卡改成每个牌子四档(低端、中端、高端、旗舰):Probidia RZX 60 / 70 / 80 / 90,PMD RZ 70 / 80 / 800 / 900;型号只是显示名,性能由牌子和档次定;档次对应供电口(6 / 8 / 8 / 8+8 针)和风扇数(1 / 2 / 3 / 3)。显卡 3×2 格,正反面各一张图;价格约为最初的 1.8 倍,出块奖励 90。
- 显卡改成每个牌子四档(低端、中端、高端、旗舰):Probidia RTX 60 / 70 / 80 / 90,PMD RX 70 / 80 / 800 / 900;型号只是显示名,性能由牌子和档次定;档次对应供电口(6 / 8 / 8 / 8+8 针)和风扇数(1 / 2 / 3 / 3)。显卡 3×2 格,正反面各一张图;价格约为最初的 1.8 倍,出块奖励 90。
- 显卡外观:叶片、金手指、挡板、封条,随每晚损耗变差,影响价值、算力、损耗、暴毙。
- 二手卡贩子(老实人、中间商、骗子)、假卡(低档芯片套高档壳)、序列号(牌子前缀、档次码、工厂码、流水)、背面丝印、鉴定公会收显卡、显卡鉴定手册。
- 放大镜检视显卡:专门的大图和标签栏(型号真伪加叶片、金手指、挡板、封条四项成色),卖家说法与逐项指出、标签机改说法、买家验货与按价差扣信誉。
- 减半抬高价格锚(传导 0.6,减半前一周有预期行情,减半前 3 天上报纸)。
- 交易终端重做:首页三个入口(银行、Poinbase、Web3)加报告;左右分栏表格;买入均价;Web3 页的稳定币价格与状态;银行提取前的审查提示;金额输入框加宽。
- 入口升级价 400,开局送交易终端、矿架、RZX 60 和鉴定手册。
- 经济模拟 v7(运维库 research/sim/out_v7.md):电网电价下 RZX 70 挖矿第 30 天占总收入 18%、第 60 天 20%。
- 入口升级价 400,开局送交易终端、矿架、RTX 60 和鉴定手册。
- 经济模拟 v7(运维库 research/sim/out_v7.md):电网电价下 RTX 70 挖矿第 30 天占总收入 18%、第 60 天 20%。
- 纯逻辑层:带种子的随机数、资产登记、地址账本(污点与成本随币走)、恒定乘积交易对、挖矿(显卡、矿机、全网算力、减半、损耗与暴毙)。
- 纯逻辑层:市场(价格锚、情绪、游戏事件冲击、NPC 大户、多交易对套利回归、当日均价),三种稳定币(CRC 脱锚与减记、CRT 脱锚与冻结概率、CRA 补贴池与死亡螺旋),合规出金与 AML(大额与累计阈值、污点比例、轻度与重度命中、只对收益计税)。
- mod 本体(第一阶段的第一部分):人脉网络"Web3 治理社区"(300,整个 mod 的入口)交付交易终端和一张 RZX 50;矿架向杰克逊博士购买;矿架是带电池槽和 4 个显卡槽的机器,每晚从电池扣电挖 PSC;显卡按型号显示算力、耗电与健康度,每晚损耗并可能烧毁;交易终端有钱包、交易(四个交易对、存入信用点、提取 CRC 过合规审查)、报告三页;夜间结算写晨间日志;PSC 交易所开业与减半上报纸;状态存进游戏的 mod 存档数据。中英双语。
- mod 本体(第一阶段的第一部分):人脉网络"Web3 治理社区"(300,整个 mod 的入口)交付交易终端和一张 RTX 50;矿架向杰克逊博士购买;矿架是带电池槽和 4 个显卡槽的机器,每晚从电池扣电挖 PSC;显卡按型号显示算力、耗电与健康度,每晚损耗并可能烧毁;交易终端有钱包、交易(四个交易对、存入信用点、提取 CRC 过合规审查)、报告三页;夜间结算写晨间日志;PSC 交易所开业与减半上报纸;状态存进游戏的 mod 存档数据。中英双语。
- 物品图:art/sprites.py 生成显卡(Probidia、PMD、烧毁)、矿架、交易终端。
- 矿架加入游戏原有的通用模块槽:性能、效率、品质三项百分比折算 1/4 后作用于算力、耗电和显卡损耗,算力最多 +20%、省电最多 25%、损耗最多 −30%;性能加成同时提高损耗与暴毙率。取代原计划的 mod 自带超频模块。
- 杰克逊博士上货(游戏给 mod 的进货钩子,夜间去他店里或他每周来本店摆摊时):没有矿架时必有一个,有了之后 30% 再上;基础显卡每次两张;进阶显卡第 10 天起 60%(再 30% 多一张);旗舰第 30 天起 25%,特供货事件时第 20 天起必有。全新真货,价格为物品价值加他的加价。加入 Web3 治理社区后才上货。开发者模式 F9 有测试入口。
@@ -50,4 +51,4 @@
- 矿架默认 2 个显卡槽,投入电子元件升级,最多 5 个:第 3 槽 4 个普通电子元件,第 4 槽 1 个稀有,第 5 槽 2 个稀有。窗口里新增"升级槽位",只收下一级需要的元件,放进去立即消耗并累计进度;显卡格子的形状随槽数变化,槽数与进度存在矿架标签上。
- 矿架的"基础耗电"标签随显卡变化(机身 + 各卡耗电,不含模块),游戏装卸模块时据此重算,不会把耗电改回只有机身的 2 kJ。
- Web3 治理社区改为同时送一个矿架:交易终端、矿架、一张 RZX 50,送的货值 520;解锁价定为 400(见运维库定价说明)。
- Web3 治理社区改为同时送一个矿架:交易终端、矿架、一张 RTX 50,送的货值 520;解锁价定为 400(见运维库定价说明)。
Binary file not shown.
Binary file not shown.
+4 -4
View File
@@ -644,7 +644,7 @@ def print_overlay(model_text, style="normal"):
elif style == "stamp":
# 1) 底层被磨掉/发暗的原型号痕迹(原先低配型号残影)
orig_text = "RZX 50" if "80" in model_text else "PMD 60"
orig_text = "RTX 50" if "80" in model_text else "PMD 60"
text57(c, x_start + 4, y_start + 1, orig_text, "z", scale=scale, gap=1)
text57(c, x_start + 5, y_start + 2, orig_text, "k", scale=scale, gap=1)
@@ -683,15 +683,15 @@ def print_overlay(model_text, style="normal"):
return c
def print_skew(model_text="RZX 80Ti"):
def print_skew(model_text="RTX 80Ti"):
return print_overlay(model_text, "skew")
def print_stamp(model_text="RZX 80Ti"):
def print_stamp(model_text="RTX 80Ti"):
return print_overlay(model_text, "stamp")
def print_normal(model_text="RZX 80Ti"):
def print_normal(model_text="RTX 80Ti"):
return print_overlay(model_text, "normal")
+1 -1
View File
@@ -379,7 +379,7 @@ def ov_sticker(kind):
return c
MODELS = ['RZX 60', 'RZX 70', 'RZX 80', 'RZX 90', 'RZ 70', 'RZ 80', 'RZ 800', 'RZ 900']
MODELS = ['RTX 60', 'RTX 70', 'RTX 80', 'RTX 90', 'RX 70', 'RX 80', 'RX 800', 'RX 900']
def rig():
+3 -3
View File
@@ -9,9 +9,9 @@ namespace Decentralized.Domain
{
public const string Rig = "RIG";
public static readonly string[] Basic = { "RZX60", "RZ70" };
public static readonly string[] Advanced = { "RZX70", "RZ80", "RZX80", "RZ800" };
public static readonly string[] Flagship = { "RZX90", "RZ900" };
public static readonly string[] Basic = { "RTX60", "RX70" };
public static readonly string[] Advanced = { "RTX70", "RX80", "RTX80", "RX800" };
public static readonly string[] Flagship = { "RTX90", "RX900" };
public const int AdvancedFromDay = 10, FlagshipFromDay = 30, SpecialFlagshipFromDay = 20;
public const double RigRestockChance = 0.30, AdvancedChance = 0.60, AdvancedSecondChance = 0.30, FlagshipChance = 0.25;
+5 -5
View File
@@ -38,11 +38,11 @@ namespace Decentralized.Domain
public static readonly IReadOnlyDictionary<string, HardwareSpec> Specs = new[]
{
// 四个档次(低端、中端、高端、旗舰),两个牌子通用:型号只是显示名,性能和价格由「牌子 + 档次」决定
Gpu("RZX60", Probidia, 0, 1.0, 4, 220), Gpu("RZX70", Probidia, 1, 5.0, 12, 800),
Gpu("RZX80", Probidia, 2, 8.0, 18, 1300), Gpu("RZX90", Probidia, 3, 20.0, 30, 5000),
Gpu("RZ70", Pmd, 0, 0.8, 2.5, 170), Gpu("RZ80", Pmd, 1, 4.0, 8, 680),
Gpu("RZ800", Pmd, 2, 8.0, 14, 1500), Gpu("RZ900", Pmd, 3, 15.0, 20, 4000),
Scrap("RZ10", Pmd, 0, 0.3, 2, 60),
Gpu("RTX60", Probidia, 0, 1.0, 4, 220), Gpu("RTX70", Probidia, 1, 5.0, 12, 800),
Gpu("RTX80", Probidia, 2, 8.0, 18, 1300), Gpu("RTX90", Probidia, 3, 20.0, 30, 5000),
Gpu("RX70", Pmd, 0, 0.8, 2.5, 170), Gpu("RX80", Pmd, 1, 4.0, 8, 680),
Gpu("RX800", Pmd, 2, 8.0, 14, 1500), Gpu("RX900", Pmd, 3, 15.0, 20, 4000),
Scrap("RX10", Pmd, 0, 0.3, 2, 60),
Asic("M1", 50, 60, 11000), Asic("M2", 120, 110, 27000), Asic("M3", 300, 220, 72000),
}.ToDictionary(s => s.Model);
+7 -7
View File
@@ -19,10 +19,10 @@ namespace Decentralized
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Used cards x4 (test)", () =>
{
var rng = Session.Data.Rng;
Items.Give(Items.NewCard("RZX80", 40, null, rng));
Items.Give(Items.NewCard("RZX80", 70, "RZX60", rng));
Items.Give(Items.NewCard("RZ800", 30, "RZ70", rng));
Items.Give(Items.NewCard("RZ900", 90, "RZ70", rng));
Items.Give(Items.NewCard("RTX80", 40, null, rng));
Items.Give(Items.NewCard("RTX80", 70, "RTX60", rng));
Items.Give(Items.NewCard("RX800", 30, "RX70", rng));
Items.Give(Items.NewCard("RX900", 90, "RX70", rng));
});
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Dump inspection UI (test)", () => Log.Guard("检视界面结构", () =>
{
@@ -45,10 +45,10 @@ namespace Decentralized
{
var rng = Session.Data.Rng;
// 自己的一张真卡:标签机改成旗舰型号并把成色说成没问题,再摆给一位买家
var item = Items.NewCard("RZX70", 55, null, rng);
var item = Items.NewCard("RTX70", 55, null, rng);
Items.Give(item);
var u = Items.ToUnit(item);
var c = Claim.Truth(u); c.Model = "RZX90"; c.Fan = 0; c.Fingers = 0; c.Bracket = 0; c.Sticker = 0;
var c = Claim.Truth(u); c.Model = "RTX90"; c.Fan = 0; c.Fingers = 0; c.Bracket = 0; c.Sticker = 0;
item.EnableTag(Items.EditedTag);
Items.SetClaim(item, c, 0);
var client = new StoreClient { identifier = "pd_test_buyer", displayName = "买家", spriteName = SpriteDict.GetRandomScavSpriteName(), clientIntent = StoreClient.ClientIntent.BUY };
@@ -61,7 +61,7 @@ namespace Decentralized
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Buy scam card (test)", () => Log.Guard("买入侧测试", () =>
{
var rng = Session.Data.Rng;
var item = Items.NewCard("RZX90", 60, "RZX60", rng, DealerKind.Scammer, 0);
var item = Items.NewCard("RTX90", 60, "RTX60", rng, DealerKind.Scammer, 0);
long before = item.unitValue;
GeneralHelper.SetItemOwned(item, true);
Items.Refresh(item);
+2 -2
View File
@@ -79,7 +79,7 @@ namespace Decentralized
// ---------- 显卡 ----------
/// <summary>RZX70 → "RZX 70",RZ800 → "RZ 800"。</summary>
/// <summary>RTX70 → "RTX 70",RX800 → "RX 800"。</summary>
public static string DisplayModel(string model) => Regex.Replace(Regex.Replace(model, @"(?<=[A-Za-z])(?=\d)", " "), @"(?<=\d)(?=[A-Z])", " ");
private static GameItem CreateGpu(HardwareSpec spec)
@@ -257,7 +257,7 @@ namespace Decentralized
public static Unit ToUnit(GameItem item)
{
string model = item.identifier.Substring(GpuPrefix.Length);
model = Hardware.Specs.Keys.FirstOrDefault(k => k.ToLowerInvariant() == model) ?? "RZX60";
model = Hardware.Specs.Keys.FirstOrDefault(k => k.ToLowerInvariant() == model) ?? "RTX60";
var u = new Unit { Model = model, Health = 100 };
if (item.IsTag(HealthTag)) u.Health = item.GetTagReadonly(HealthTag).GetDouble();
if (item.IsTag(FakeTag)) u.FakeOf = item.GetTagReadonly(FakeTag).GetString();
@@ -2,7 +2,7 @@
# Source language and fallback. Format: key,text (text may be quoted; \n is a line break).
upgrade.tab,Web3
upgrade.title,Web3 Governance Community
upgrade.desc,"Members receive a trading terminal, a mining rig, an RZX 60 graphics card and a graphics card appraisal guide. The terminal holds the bank, the Poinbase exchange and the Web3 wallet. More cards and rigs are sold by Dr. Jackson."
upgrade.desc,"Members receive a trading terminal, a mining rig, an RTX 60 graphics card and a graphics card appraisal guide. The terminal holds the bank, the Poinbase exchange and the Web3 wallet. More cards and rigs are sold by Dr. Jackson."
item.terminal.name,Trading Terminal
item.terminal.desc,Wallet, the Poinbase exchange and the nightly mining report.
item.rig.name,Mining Rig
@@ -117,7 +117,7 @@ lbl.tier.1,"Mid"
lbl.tier.2,"High"
lbl.tier.3,"Flagship"
item.guide.name,"Graphics card appraisal guide"
item.guide.desc,"Tiers: entry has a 6-pin connector and one fan; mid 8-pin and two fans; high 8-pin and three fans; flagship dual 8-pin and three fans. Model names are display only: Probidia RZX 60 / 70 / 80 / 90, PMD RZ 70 / 80 / 800 / 900, lowest to highest tier. Serial: prefix PB (Probidia) or MD (PMD), tier code 1 to 4, a dash, a two-digit factory code, a dash, four digits. Valid factory codes: PB 11, 12, 21, 34, 47; MD 13, 22, 35, 41, 58. A tier code that does not match the model, or a bad factory code or length, means a fake. Appearance discounts: dusty blades -4%, chipped -12%; dull contacts -4%, oxidised -12%; scratched bracket -2%; missing seal -6%."
item.guide.desc,"Tiers: entry has a 6-pin connector and one fan; mid 8-pin and two fans; high 8-pin and three fans; flagship dual 8-pin and three fans. Model names are display only: Probidia RTX 60 / 70 / 80 / 90, PMD RX 70 / 80 / 800 / 900, lowest to highest tier. Serial: prefix PB (Probidia) or MD (PMD), tier code 1 to 4, a dash, a two-digit factory code, a dash, four digits. Valid factory codes: PB 11, 12, 21, 34, 47; MD 13, 22, 35, 41, 58. A tier code that does not match the model, or a bad factory code or length, means a fake. Appearance discounts: dusty blades -4%, chipped -12%; dull contacts -4%, oxidised -12%; scratched bracket -2%; missing seal -6%."
lbl.row.spec,"Model authenticity"
lbl.hint,"Check: power connector and fan count, serial, back print"
lbl.ev.prefix,"Evidence: "
1 # Probably Decentralized localization table: English (en)
2 # Source language and fallback. Format: key
3 upgrade.tab
4 upgrade.title
5 upgrade.desc
6 item.terminal.name
7 item.terminal.desc
8 item.rig.name
117 lbl.tier.2
118 lbl.tier.3
119 item.guide.name
120 item.guide.desc
121 lbl.row.spec
122 lbl.hint
123 lbl.ev.prefix
@@ -1,7 +1,7 @@
# Probably Decentralized 本地化表:简体中文(zh)
upgrade.tab,Web3
upgrade.title,Web3 治理社区
upgrade.desc,"成员可获得一台交易终端、一个矿架、一张 RZX 60 显卡和一本显卡鉴定手册。终端里有银行、Poinbase 交易所和 Web3 钱包。更多显卡和矿架由杰克逊博士出售。"
upgrade.desc,"成员可获得一台交易终端、一个矿架、一张 RTX 60 显卡和一本显卡鉴定手册。终端里有银行、Poinbase 交易所和 Web3 钱包。更多显卡和矿架由杰克逊博士出售。"
item.terminal.name,交易终端
item.terminal.desc,钱包、Poinbase 交易所与夜间挖矿报告。
item.rig.name,矿架
@@ -116,7 +116,7 @@ lbl.tier.1,"中端"
lbl.tier.2,"高端"
lbl.tier.3,"旗舰"
item.guide.name,"显卡鉴定手册"
item.guide.desc,"档次:低端 6 针供电、单风扇;中端 8 针、双风扇;高端 8 针、三风扇;旗舰双 8 针、三风扇。型号只是显示名:Probidia 为 RZX 60 / 70 / 80 / 90,PMD 为 RZ 70 / 80 / 800 / 900,按档次从低到高。序列号:前缀 PB(Probidia)或 MD(PMD),接档次码 1 至 4,一道横杠,两位工厂码,一道横杠,四位流水。合法工厂码:PB 为 11、12、21、34、47;MD 为 13、22、35、41、58。档次码与型号不符,或工厂码、位数不对,都是假的。外观折扣:叶片积灰 -4%,缺角 -12%;金手指发暗 -4%,氧化 -12%;挡板划痕 -2%;封条缺失 -6%。"
item.guide.desc,"档次:低端 6 针供电、单风扇;中端 8 针、双风扇;高端 8 针、三风扇;旗舰双 8 针、三风扇。型号只是显示名:Probidia 为 RTX 60 / 70 / 80 / 90,PMD 为 RX 70 / 80 / 800 / 900,按档次从低到高。序列号:前缀 PB(Probidia)或 MD(PMD),接档次码 1 至 4,一道横杠,两位工厂码,一道横杠,四位流水。合法工厂码:PB 为 11、12、21、34、47;MD 为 13、22、35、41、58。档次码与型号不符,或工厂码、位数不对,都是假的。外观折扣:叶片积灰 -4%,缺角 -12%;金手指发暗 -4%,氧化 -12%;挡板划痕 -2%;封条缺失 -6%。"
lbl.row.spec,"型号真伪"
lbl.hint,"依据:供电口与风扇数、序列号、背面丝印"
lbl.ev.prefix,"依据:"
1 # Probably Decentralized 本地化表:简体中文(zh)
2 upgrade.tab
3 upgrade.title
4 upgrade.desc
5 item.terminal.name
6 item.terminal.desc
7 item.rig.name
116 lbl.tier.2
117 lbl.tier.3
118 item.guide.name
119 item.guide.desc
120 lbl.row.spec
121 lbl.hint
122 lbl.ev.prefix
Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

+2 -2
View File
@@ -2,7 +2,7 @@ using System;
namespace Decentralized
{
/// <summary>人脉网络里的"Web3 治理社区":整个 mod 的入口。买下后交付交易终端、一个矿架、一张 RZX 60 和一本显卡鉴定手册,并开始每天的行情与挖矿结算;更多显卡、矿架向杰克逊博士购买。</summary>
/// <summary>人脉网络里的"Web3 治理社区":整个 mod 的入口。买下后交付交易终端、一个矿架、一张 RTX 60 和一本显卡鉴定手册,并开始每天的行情与挖矿结算;更多显卡、矿架向杰克逊博士购买。</summary>
public static class Unlock
{
public const string Id = "PD_WEB3_COMMUNITY";
@@ -38,7 +38,7 @@ namespace Decentralized
{
Items.Give(ModHelper.SpawnItem(Items.Terminal));
Items.Give(ModHelper.SpawnItem(Items.Rig));
Items.Give(ModHelper.SpawnItem(Items.GpuId("RZX60")));
Items.Give(ModHelper.SpawnItem(Items.GpuId("RTX60")));
Items.Give(ModHelper.SpawnItem(Items.Guide));
Log.Info("已加入 Web3 治理社区");
}
+1 -1
View File
@@ -18,7 +18,7 @@ namespace Decentralized
public static void Subscribe()
{
ModHook.OnGenerateCustomerNormal += OnGenerate;
ModHelper.AddAppraisalItem(ModInfo.Id, Appraisal, Items.GpuId("RZX60"), 2, CreateForAppraisal, u => (int)CardValue.True(Items.ToUnit(u)),
ModHelper.AddAppraisalItem(ModInfo.Id, Appraisal, Items.GpuId("RTX60"), 2, CreateForAppraisal, u => (int)CardValue.True(Items.ToUnit(u)),
Items.IsGpu, Items.Guide, () => L.T("appraisal.gpu"));
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Appraisal client (test)", () => Log.Guard("鉴定客户(测试)", () =>
{
+28 -28
View File
@@ -112,19 +112,19 @@ internal static class Program
Test("显卡:型号、显示单位、健康度与算力衰减", () =>
{
Check(Hardware.Specs["RZX70"].DisplayHash == 50 && Hardware.Specs["RZ80"].DisplayHash == 40, "RZX70 50 MH/s,RZ80 40 MH/s");
Check(Hardware.Specs["RTX70"].DisplayHash == 50 && Hardware.Specs["RX80"].DisplayHash == 40, "RTX70 50 MH/s,RX80 40 MH/s");
Check(Near(Hardware.Specs["M3"].DisplayHash, 3, 1e-9), "RatDigg M3 3 GH/s");
var u = new Unit { Model = "RZX70" };
var u = new Unit { Model = "RTX70" };
Check(u.Hash(ModuleBonus.None) == 5, "满健康 5 H");
u.Health = 25;
Check(Near(u.Hash(ModuleBonus.None), 4.0, 1e-9), "健康 25:5 × (0.6 + 0.4 × 0.5) = 4 H");
u.Health = 0;
Check(Near(u.Hash(ModuleBonus.None), 3.0, 1e-9), "健康 0:60%");
Check(Near(new Unit { Model = "RZX70" }.Hash(ModuleBonus.From(36, -44, 0)), 5 * 1.09, 1e-9), "一个超频模块(+36 性能):算力 +9%");
var fake = new Unit { Model = "RZX90", FakeOf = "RZX60" };
Check(fake.Hash(ModuleBonus.None) == 1.0 && fake.Label.Model == "RZX90", "假卡标着 RZX90,算力按 RZX60");
Check(Near(fake.DeathChance(ModuleBonus.None), new Unit { Model = "RZX90" }.DeathChance(ModuleBonus.None) * 2, 1e-12), "假卡暴毙率 ×2");
var r = new Unit { Model = "RZX70", Health = 50 };
Check(Near(new Unit { Model = "RTX70" }.Hash(ModuleBonus.From(36, -44, 0)), 5 * 1.09, 1e-9), "一个超频模块(+36 性能):算力 +9%");
var fake = new Unit { Model = "RTX90", FakeOf = "RTX60" };
Check(fake.Hash(ModuleBonus.None) == 1.0 && fake.Label.Model == "RTX90", "假卡标着 RTX90,算力按 RTX60");
Check(Near(fake.DeathChance(ModuleBonus.None), new Unit { Model = "RTX90" }.DeathChance(ModuleBonus.None) * 2, 1e-12), "假卡暴毙率 ×2");
var r = new Unit { Model = "RTX70", Health = 50 };
Check(r.Refurbish() && r.Health == 80 && !r.Refurbish(), "翻新一次 +30,不能再翻新");
});
@@ -152,15 +152,15 @@ internal static class Program
Check(Near(fakeSigns / (double)n, 0.55 * 1 + 0.65 * 1, 0.1), $"假卡平均 1.2 处额外破绽(重印丝印、补贴序列号):{fakeSigns / (double)n:0.00}");
Check(oldWorn > newWorn * 1.8, $"低健康度的真卡明显更旧:{oldWorn / (double)n:P0} 对 {newWorn / (double)n:P0}");
Check(seen.Count >= 60, $"抽样见到 {seen.Count} 种不同组合(上限 243)");
Check(Hardware.Specs["RZX60"].Price == 220 && Hardware.Specs["RZX90"].Price == 5000 && Hardware.Specs["RZ900"].Price == 4000, "价格已抬高到约 1.8 倍");
var u = new Unit { Model = "RZX90", FakeOf = "RZX60", Health = 80 };
Check(CardValue.True(u) == CardValue.Of("RZX60", 80) && CardValue.Of("RZX90", 80) > CardValue.True(u) * 8, "真实价值按芯片型号,标称型号的价远高于真值");
var worn = new Unit { Model = "RZX70", Health = 100, Look = new CardLook { Fan = 2, Fingers = 2, Bracket = 1, Sticker = 2 } };
Check(Hardware.Specs["RTX60"].Price == 220 && Hardware.Specs["RTX90"].Price == 5000 && Hardware.Specs["RX900"].Price == 4000, "价格已抬高到约 1.8 倍");
var u = new Unit { Model = "RTX90", FakeOf = "RTX60", Health = 80 };
Check(CardValue.True(u) == CardValue.Of("RTX60", 80) && CardValue.Of("RTX90", 80) > CardValue.True(u) * 8, "真实价值按芯片型号,标称型号的价远高于真值");
var worn = new Unit { Model = "RTX70", Health = 100, Look = new CardLook { Fan = 2, Fingers = 2, Bracket = 1, Sticker = 2 } };
Check(CardValue.True(worn) == (long)Math.Round(800 * (1 - 0.12 - 0.12 - 0.02 - 0.06)), "各标签折扣相加进真实价值:风扇缺角 + 金手指氧化 + 划痕 + 封条缺失");
var clean = new Unit { Model = "RZX70", Health = 80 };
var dusty = new Unit { Model = "RZX70", Health = 80, Look = new CardLook { Fan = 2, Fingers = 2 } };
var clean = new Unit { Model = "RTX70", Health = 80 };
var dusty = new Unit { Model = "RTX70", Health = 80, Look = new CardLook { Fan = 2, Fingers = 2 } };
Check(dusty.DeathChance(ModuleBonus.None) > clean.DeathChance(ModuleBonus.None) * 1.5 && Near(CardLook.Decode("20000").WearFactor, 1.3, 1e-9), "风扇缺角、金手指氧化抬高暴毙概率与损耗");
Check(CardValue.Of("RZX70", 100) == 800 && CardValue.Of("RZX70", 0) == 200 && CardValue.Of("RZX70", 50) == 500, "健康 100 满价、0 剩 25%、50 为 62.5%");
Check(CardValue.Of("RTX70", 100) == 800 && CardValue.Of("RTX70", 0) == 200 && CardValue.Of("RTX70", 50) == 500, "健康 100 满价、0 剩 25%、50 为 62.5%");
});
Test("矿架槽位:默认 2 个,投入电子元件逐个升级到最多 5 个;只收下一级需要的;形状随槽数变化", () =>
@@ -214,10 +214,10 @@ internal static class Program
}
return deadBy.Select(x => (double)x / n).ToArray();
}
var p = Run("RZX70", ModuleBonus.None, 20000);
var p = Run("RTX70", ModuleBonus.None, 20000);
Check(Near(p[0], 0.11, 0.02) && Near(p[1], 0.53, 0.02) && Near(p[2], 0.84, 0.02),
$"Probidia 11% / 53% / 84%:{p[0]:P0} / {p[1]:P0} / {p[2]:P0}");
var q = Run("RZ80", ModuleBonus.None, 20000);
var q = Run("RX80", ModuleBonus.None, 20000);
Check(Near(q[0], 0.20, 0.02) && Near(q[1], 0.76, 0.02) && Near(q[2], 0.95, 0.02),
$"PMD 20% / 76% / 95%:{q[0]:P0} / {q[1]:P0} / {q[2]:P0}");
});
@@ -393,19 +393,19 @@ internal static class Program
Check(Hardware.Specs[c.FakeOf].Price * 2 <= Hardware.Specs[c.Model].Price, "假卡的芯片至少便宜一半");
}
Check(fakes > cards * 0.2 && fakes < cards * 0.5, $"骗子的假卡占两成多(入门卡便宜到没法冒充):{fakes}/{cards}");
Check(UsedDealers.Pool(5).All(m => Dealer.Basic.Contains(m)) && UsedDealers.Pool(30).Contains("RZX90"), "型号按天数放开");
// 标签:假 RZX 70(芯片 RZX 50)、健康 60、风扇缺角、金手指氧化、丝印印着真实型号
var u = new Unit { Model = "RZX70", FakeOf = "RZX60", Health = 60, Look = new CardLook { Fan = 2, Fingers = 2, Print = 1 } };
Check(UsedDealers.Pool(5).All(m => Dealer.Basic.Contains(m)) && UsedDealers.Pool(30).Contains("RTX90"), "型号按天数放开");
// 标签:假 RTX 70(芯片 RTX 50)、健康 60、风扇缺角、金手指氧化、丝印印着真实型号
var u = new Unit { Model = "RTX70", FakeOf = "RTX60", Health = 60, Look = new CardLook { Fan = 2, Fingers = 2, Print = 1 } };
var claim = CardLabels.DealerClaim(u, DealerKind.Scammer, new Rng(3));
Check(claim.Model == "RZX70" && claim.Fan == 0 && claim.Fingers == 0 && claim.Print == 0, "骗子的说法:标称型号,外观全是没问题");
Check(claim.Model == "RTX70" && claim.Fan == 0 && claim.Fingers == 0 && claim.Print == 0, "骗子的说法:标称型号,外观全是没问题");
long hidden = CardLabels.Value(u, claim, 0), real = CardValue.True(u);
Check(hidden == CardValue.Of("RZX70", 60) && real == (long)Math.Round(CardValue.Of("RZX60", 60) * 0.76), "没指出时按说法算(标称型号满价),真实价值按芯片和外观算");
Check(hidden == CardValue.Of("RTX70", 60) && real == (long)Math.Round(CardValue.Of("RTX60", 60) * 0.76), "没指出时按说法算(标称型号满价),真实价值按芯片和外观算");
int ex = 0;
Check(CardLabels.Point(u, claim, CardLabels.RowFan, ref ex) == 1 && CardLabels.Value(u, claim, ex) == (long)Math.Round(CardValue.Of("RZX70", 60) * 0.88), "指出风扇缺角:扣 12%");
Check(CardLabels.Point(u, claim, CardLabels.RowFan, ref ex) == 1 && CardLabels.Value(u, claim, ex) == (long)Math.Round(CardValue.Of("RTX70", 60) * 0.88), "指出风扇缺角:扣 12%");
Check(CardLabels.Point(u, claim, CardLabels.RowPrint, ref ex) == 2 && (ex & CardLabels.RowSpec) != 0, "指出丝印印着真实型号:拆穿假货,型号标签一并拆穿");
Check(CardLabels.Point(u, claim, CardLabels.RowFingers, ref ex) == 1 && CardLabels.Value(u, claim, ex) == real, "全部指出之后价格回到真实价值");
int ex2 = 0;
var honestUnit = new Unit { Model = "RZX70", Health = 60, Look = new CardLook { Fan = 1 } };
var honestUnit = new Unit { Model = "RTX70", Health = 60, Look = new CardLook { Fan = 1 } };
Check(CardLabels.Point(honestUnit, CardLabels.DealerClaim(honestUnit, DealerKind.Honest, new Rng(1)), CardLabels.RowFan, ref ex2) == 0, "老实人说的是实话,指出去没用");
Check(CardLabels.Lies(u, claim, 0) == (CardLabels.RowSpec | CardLabels.RowFan | CardLabels.RowFingers), "骗子隐瞒了型号、叶片、金手指");
Check(CardLabels.Lies(u, claim, ex) == 0, "指出之后不再算隐瞒");
@@ -427,13 +427,13 @@ internal static class Program
}
}
Check(lowFake && !midScrap, "低档次的卡也会被冒充(背后是废片),中高档的假卡不用废片");
var real = new Unit { Model = "RZ80", Health = 100, Look = new CardLook { Seed = 7 } };
var real = new Unit { Model = "RX80", Health = 100, Look = new CardLook { Seed = 7 } };
var t = CardLabels.SerialText(real);
Check(t.StartsWith("MD2-") && CardLabels.Factories("PMD").Contains(int.Parse(t.Substring(4, 2))) && t.Length == 11, $"真卡的序列号:牌子 + 档次码 + 合法工厂码 + 四位流水:{t}");
var forged = new Unit { Model = "RZX90", FakeOf = "RZX60", Health = 100, Look = new CardLook { Seed = 7, Serial = 1 } };
var forged = new Unit { Model = "RTX90", FakeOf = "RTX60", Health = 100, Look = new CardLook { Seed = 7, Serial = 1 } };
var f = CardLabels.SerialText(forged);
Check(f.StartsWith("PB4-") && (!CardLabels.Factories("Probidia").Contains(int.Parse(f.Substring(4, 2))) || f.Length == 10), $"补贴的序列号:档次码对,工厂码不合法或位数不对:{f}");
var original = new Unit { Model = "RZX90", FakeOf = "RZX60", Health = 100, Look = new CardLook { Seed = 7, Serial = 2 } };
var original = new Unit { Model = "RTX90", FakeOf = "RTX60", Health = 100, Look = new CardLook { Seed = 7, Serial = 2 } };
Check(CardLabels.SerialText(original).StartsWith("PB1-"), "贴的是原芯片的序列号:档次码是真实芯片的档次");
var claim = CardLabels.DealerClaim(original, DealerKind.Scammer, new Rng(1));
int ex = 0;
@@ -455,8 +455,8 @@ internal static class Program
Check(worse > total * 0.9, $"健康度从 100 掉到 20,九成以上的卡外观变差:{worse}/{total}");
var fake = CardLook.Generate(rng, 80, true);
Check(fake.HasFakeSign && fake.Appearance(10).HasFakeSign, "假卡的破绽不随健康度变化");
var clean = new Unit { Model = "RZX70", Health = 100 };
var bad = new Unit { Model = "RZX70", Health = 100, Look = new CardLook { Fan = 2, Fingers = 2 } };
var clean = new Unit { Model = "RTX70", Health = 100 };
var bad = new Unit { Model = "RTX70", Health = 100, Look = new CardLook { Fan = 2, Fingers = 2 } };
Check(Near(bad.Hash(ModuleBonus.None) / clean.Hash(ModuleBonus.None), 0.92 * 0.94, 1e-9), "风扇缺角 + 金手指氧化:算力 ×0.92 ×0.94");
});