diff --git a/art/__pycache__/big_cases.cpython-314.pyc b/art/__pycache__/big_cases.cpython-314.pyc
new file mode 100644
index 0000000..972e03c
Binary files /dev/null and b/art/__pycache__/big_cases.cpython-314.pyc differ
diff --git a/art/__pycache__/sprites.cpython-314.pyc b/art/__pycache__/sprites.cpython-314.pyc
index e88a153..7c4eabd 100644
Binary files a/art/__pycache__/sprites.cpython-314.pyc and b/art/__pycache__/sprites.cpython-314.pyc differ
diff --git a/art/big_cases.py b/art/big_cases.py
new file mode 100644
index 0000000..ee2d3d9
--- /dev/null
+++ b/art/big_cases.py
@@ -0,0 +1,1159 @@
+
+"""显卡检视大图叠加层:用于放大镜检视台的各种真假/成色鉴定 case 细节层。
+与底图同尺寸(192×128),仅绘制发生变化的像素。
+"""
+
+import math
+import random
+from big import (
+ BW,
+ BH,
+ FANS,
+ FR,
+ NOTCH_X,
+ SH0,
+ SH1,
+ FING_Y0,
+ FING_Y1,
+ Canvas,
+ text57,
+ F57,
+)
+
+
+def _new():
+ return Canvas(BW, BH)
+
+
+# ==============================================================================
+# 正面 Case
+# ==============================================================================
+
+
+def fan_dust1():
+ """1. 风扇轻度积灰:叶片边缘灰线、轴心轻微积垢、少量蛛丝细线。"""
+ c = _new()
+ rnd = random.Random(101)
+
+ for cx, cy in FANS:
+ # 轴心周围微灰圈
+ for a_deg in range(0, 360, 15):
+ rad = math.radians(a_deg)
+ r = 7.0 + (rnd.random() * 2.5)
+ x, y = int(cx + math.cos(rad) * r), int(cy + math.sin(rad) * r)
+ c.put(x, y, "m" if rnd.random() < 0.65 else "d")
+
+ # 九片叶片的前缘微量积灰与边角聚灰
+ for blade in range(9):
+ base_ang = blade * (2 * math.pi / 9)
+ for r in range(10, FR - 4, 2):
+ ang = base_ang - (r - 7) * 0.055
+ x = int(cx + math.cos(ang) * r)
+ y = int(cy + math.sin(ang) * r)
+ if rnd.random() < 0.40:
+ c.put(x, y, "b" if rnd.random() < 0.6 else "m")
+ # 叶尖处积微灰
+ if r > FR - 8 and rnd.random() < 0.55:
+ c.put(x + 1, y, "l" if rnd.random() < 0.3 else "m")
+
+ # 2~3 根搭在扇叶与风道外框之间的微细蛛丝
+ for p0, p1 in (
+ ((cx - 18, cy - 14), (cx - 25, cy - 10)),
+ ((cx + 10, cy + 18), (cx + 22, cy + 14)),
+ ):
+ x0, y0 = p0
+ x1, y1 = p1
+ steps = max(abs(x1 - x0), abs(y1 - y0))
+ for i in range(steps + 1):
+ t = i / steps
+ sx = int(x0 + (x1 - x0) * t)
+ sy = int(y0 + (y1 - y0) * t + math.sin(t * math.pi) * 1.5)
+ c.put(sx, sy, "l" if i % 2 == 0 else "b")
+
+ return c
+
+
+def fan_dust2():
+ """1. 风扇重度积灰:轴心厚灰结垢、叶面大团絮状灰斑、风道外圈堵灰、蜘蛛网细丝。"""
+ c = _new()
+ rnd = random.Random(102)
+
+ for cx, cy in FANS:
+ # 轴心及周边重垢厚积
+ for dy in range(-12, 13):
+ for dx in range(-12, 13):
+ r = math.hypot(dx, dy)
+ if 5.5 <= r <= 13.0:
+ val = rnd.random()
+ if val < 0.70:
+ c.put(
+ cx + dx,
+ cy + dy,
+ "b" if val < 0.25 else "m" if val < 0.55 else "d",
+ )
+
+ # 扇叶大面积覆灰与灰絮团
+ for blade in range(9):
+ base_ang = blade * (2 * math.pi / 9)
+ for r in range(8, FR - 3):
+ ang = base_ang - (r - 7) * 0.055
+ x = int(cx + math.cos(ang) * r)
+ y = int(cy + math.sin(ang) * r)
+ c.put(x, y, "b" if rnd.random() < 0.4 else "m")
+ if rnd.random() < 0.35:
+ c.put(x, y + 1, "d")
+
+ # 风道死角与外圈凹陷堵灰
+ for a_deg in range(0, 360, 4):
+ rad = math.radians(a_deg)
+ for dr in (FR - 6, FR - 5, FR - 4):
+ if rnd.random() < 0.65:
+ x = int(cx + math.cos(rad) * dr)
+ y = int(cy + math.sin(rad) * dr)
+ c.put(x, y, "d" if (x + y) % 2 else "m")
+
+ # 灰絮团(带厚度高光)
+ clumps = (
+ (cx - 14, cy - 8),
+ (cx + 12, cy - 14),
+ (cx - 8, cy + 15),
+ (cx + 15, cy + 12),
+ )
+ for kx, ky in clumps:
+ c.rect(kx - 1, ky - 1, kx + 2, ky + 1, "m")
+ c.rect(kx - 1, ky - 1, kx + 1, ky - 1, "l")
+ c.put(kx + 2, ky + 1, "d")
+ c.put(kx - 2, ky, "b")
+ c.put(kx + 3, ky, "d")
+
+ # 蛛网连线(从内到外蜘蛛网状蛛丝结构)
+ anchors = [
+ (cx - 24, cy - 12),
+ (cx - 16, cy - 20),
+ (cx, cy - 25),
+ (cx + 18, cy - 18),
+ (cx - 12, cy - 5),
+ (cx + 8, cy - 8),
+ ]
+ edges = [(0, 4), (1, 4), (1, 5), (2, 5), (3, 5), (4, 5)]
+ for i0, i1 in edges:
+ x0, y0 = anchors[i0]
+ x1, y1 = anchors[i1]
+ steps = max(abs(x1 - x0), abs(y1 - y0))
+ for s in range(steps + 1):
+ t = s / steps
+ sx = int(x0 + (x1 - x0) * t)
+ sy = int(y0 + (y1 - y0) * t)
+ c.put(sx, sy, "w" if s % 3 == 0 else "l")
+
+ return c
+
+
+def fan_chip():
+ """2. 风扇叶片缺角:扇叶断裂缺损,断面 jagged 崩缺、露出黑风道底,带裂纹延伸至根部。"""
+ c = _new()
+
+ # 左风扇断叶:位于右上方叶片(约 15°~45°)
+ cx, cy = FANS[0]
+ # 崩缺露出底部风道黑腔
+ for r in range(16, FR - 2):
+ for deg in range(12, 44):
+ rad = math.radians(deg)
+ # 形成犬牙交错的不规则裂口形状
+ r_edge = 18 + int(3 * math.sin(deg * 0.7) + 2 * math.cos(deg * 1.3))
+ if r >= r_edge:
+ px = int(cx + math.cos(rad) * r)
+ py = int(cy + math.sin(rad) * r)
+ c.put(px, py, "n" if (px + py) % 3 else "k")
+
+ # 断裂口侧缘受光白色高光毛刺与背光阴影
+ break_edge = [
+ (cx + 17, cy + 6),
+ (cx + 18, cy + 8),
+ (cx + 19, cy + 11),
+ (cx + 20, cy + 12),
+ (cx + 22, cy + 14),
+ (cx + 24, cy + 16),
+ (cx + 25, cy + 20),
+ ]
+ for i, (bx, by) in enumerate(break_edge):
+ c.put(bx, by, "h" if i % 2 == 0 else "w")
+ c.put(bx + 1, by + 1, "k")
+
+ # 裂纹延伸(Stress crack)自断面一路裂向轴心根部
+ crack = [
+ (cx + 16, cy + 6),
+ (cx + 15, cy + 5),
+ (cx + 13, cy + 5),
+ (cx + 12, cy + 4),
+ (cx + 10, cy + 4),
+ (cx + 9, cy + 3),
+ (cx + 7, cy + 2),
+ ]
+ for kx, ky in crack:
+ c.put(kx, ky, "n")
+ c.put(kx, ky - 1, "l") # 裂缝边缘受光面
+
+ # 右风扇:叶尖崩掉一个小角
+ rx, ry = FANS[1]
+ for r in range(FR - 8, FR - 2):
+ for deg in range(215, 235):
+ rad = math.radians(deg)
+ if r > FR - 6 + (deg % 3):
+ c.put(
+ int(rx + math.cos(rad) * r),
+ int(ry + math.sin(rad) * r),
+ "n",
+ )
+ c.put(rx - 21, ry - 14, "h")
+ c.put(rx - 22, ry - 13, "w")
+ c.put(rx - 20, ry - 13, "k")
+
+ return c
+
+
+def fan_oil():
+ """3. 风扇轴心漏油/褪色:轴承油渍沿离心方向与重力向下渗出浸润、轴心贴纸褪色混浊。"""
+ c = _new()
+
+ for cx, cy in FANS:
+ # 轴心贴纸油污褪色(盖掉原来的鲜艳色,变暗浊褐灰)
+ for dy in range(-4, 5):
+ for dx in range(-4, 5):
+ r = math.hypot(dx, dy)
+ if r <= 4.2:
+ c.put(cx + dx, cy + dy, "e" if r < 2.5 else "d")
+
+ # 轴心缝隙溢出的深色环状油垢
+ for deg in range(0, 360, 10):
+ rad = math.radians(deg)
+ for r in (5.0, 6.0, 7.0):
+ ox = int(cx + math.cos(rad) * r)
+ oy = int(cy + math.sin(rad) * r)
+ c.put(ox, oy, "c" if deg % 20 == 0 else "e")
+
+ # 向下及顺着离心叶片流淌的渗油泪痕(重力向下,沿扇叶根部流淌)
+ # 1) 主滴漏条(竖直向下)
+ drips = [
+ (cx, cy + 7, "c"),
+ (cx + 1, cy + 7, "e"),
+ (cx, cy + 8, "c"),
+ (cx - 1, cy + 8, "q"),
+ (cx, cy + 9, "e"),
+ (cx, cy + 10, "c"),
+ (cx + 1, cy + 10, "h"), # 油液反光
+ (cx, cy + 11, "e"),
+ (cx, cy + 12, "q"),
+ (cx, cy + 13, "e"),
+ (cx, cy + 14, "c"),
+ (cx, cy + 15, "h"),
+ (cx, cy + 16, "e"),
+ (cx + 1, cy + 17, "q"),
+ ]
+ for dx, dy, col in drips:
+ c.put(dx, dy, col)
+
+ # 2) 右下斜向叶片根部浸润油晕
+ side_drips = [
+ (cx + 6, cy + 5, "e"),
+ (cx + 7, cy + 6, "c"),
+ (cx + 8, cy + 7, "q"),
+ (cx + 9, cy + 7, "h"),
+ (cx + 10, cy + 8, "e"),
+ (cx + 11, cy + 9, "c"),
+ (cx + 12, cy + 10, "e"),
+ (cx + 13, cy + 10, "q"),
+ ]
+ for dx, dy, col in side_drips:
+ c.put(dx, dy, col)
+
+ # 3) 左上回渗微斑
+ c.put(cx - 6, cy - 4, "e")
+ c.put(cx - 7, cy - 5, "q")
+ c.put(cx - 8, cy - 5, "c")
+
+ return c
+
+
+def fin_dim():
+ """4. 金手指发暗:镀金磨损发褐,失去高光亮黄,露出发黑氧化的暗铜色和划轨。"""
+ c = _new()
+ x0, x1 = SH0[0], SH1[0]
+
+ for x in range(x0 + 2, x1 - 2):
+ if NOTCH_X - 2 <= x <= NOTCH_X + 3 or (x - x0) % 4 == 3:
+ continue
+ pin_offset = (x - x0) % 4
+
+ # 顶部斜切高光被暗黄铜/暗灰取代
+ c.put(x, FING_Y0, "q" if x % 2 == 0 else "m")
+
+ # 针脚本体:失去 'Y',变为接触氧化的暗褐 'e'、暗铜 'q' 与焦褐
+ for y in range(FING_Y0 + 1, FING_Y1):
+ # 模拟 PCIe 插拔划道痕迹(中间有极细竖向磨损深槽)
+ if pin_offset == 1 and y in (112, 113, 116, 117, 118, 120):
+ c.put(x, y, "c") # 磨损黑槽
+ elif (x + y * 2) % 5 == 0:
+ c.put(x, y, "c")
+ elif (x + y) % 2 == 0:
+ c.put(x, y, "e")
+ else:
+ c.put(x, y, "q")
+
+ # 底部插拔磨耗端
+ c.put(x, FING_Y1, "c" if pin_offset == 0 else "e")
+
+ return c
+
+
+def fin_oxide():
+ """5. 金手指氧化:铜绿由根部与底部向上爬蔓延,斑驳的蓝绿/深绿锈斑('G'/'g2'/'S')。"""
+ c = _new()
+ rnd = random.Random(205)
+ x0, x1 = SH0[0], SH1[0]
+
+ # 定义几个主要锈蚀蔓延爆发区(树枝状爬生)
+ oxide_zones = [
+ (35, 62, 11), # (x_start, x_end, max_h)
+ (78, 105, 8),
+ (125, 168, 13),
+ ]
+
+ for x in range(x0 + 2, x1 - 2):
+ if NOTCH_X - 2 <= x <= NOTCH_X + 3 or (x - x0) % 4 == 3:
+ continue
+
+ # 计算当前 x 的铜锈高度
+ h_grow = 0
+ for z0, z1, max_h in oxide_zones:
+ if z0 <= x <= z1:
+ mid = (z0 + z1) / 2
+ span = (z1 - z0) / 2
+ wave = math.cos((x - mid) / span * (math.pi / 2))
+ h_grow = max(
+ h_grow,
+ int(
+ wave * max_h
+ + rnd.randint(-1, 2)
+ + (1 if x % 3 == 0 else 0)
+ ),
+ )
+
+ if h_grow > 0:
+ # 铜锈从底部根部 FING_Y1 往上爬
+ for dy in range(h_grow + 1):
+ y = FING_Y1 - dy
+ if y < FING_Y0:
+ continue
+ # 锈壳中心粉绿 'S',主体 'G',深根 'g2'
+ if dy == h_grow:
+ col = "S" if rnd.random() < 0.4 else "G"
+ elif dy > h_grow // 2:
+ col = (
+ "G"
+ if rnd.random() < 0.7
+ else "S"
+ if rnd.random() < 0.5
+ else "g2"
+ )
+ else:
+ col = "g2" if rnd.random() < 0.8 else "c"
+ c.put(x, y, col)
+
+ # 少量铜锈蔓延到相邻缝隙
+ if (x - x0) % 4 == 2 and rnd.random() < 0.65:
+ c.put(x + 1, FING_Y1 - (h_grow // 2), "g2")
+
+ return c
+
+
+def brk_scratch():
+ """6. 挡板划痕与凹坑:斜向金属切划痕(亮边+暗槽)与冲压碰伤凹坑。"""
+ c = _new()
+
+ # 细划痕 1:贯穿上部金属区(斜向上提)
+ scratch1 = [
+ (5, 18, "h"),
+ (6, 17, "w"),
+ (7, 16, "h"),
+ (8, 15, "w"),
+ (9, 14, "h"),
+ (10, 13, "l"),
+ (11, 12, "h"),
+ (12, 11, "k"),
+ ]
+ for x, y, col in scratch1:
+ c.put(x, y, col)
+ c.put(x, y + 1, "k") # 划痕背光刻沟
+
+ # 细划痕 2:接口 1 与 2 之间的斜割痕
+ scratch2 = [
+ (7, 31, "w"),
+ (8, 32, "h"),
+ (9, 32, "k"),
+ (10, 33, "h"),
+ (11, 33, "w"),
+ (12, 34, "h"),
+ (13, 35, "k"),
+ (14, 35, "h"),
+ (15, 36, "w"),
+ ]
+ for x, y, col in scratch2:
+ c.put(x, y, col)
+ c.put(x, y - 1, "d")
+
+ # 细划痕 3:接口 2 与 3 之间十字交叉滑刀
+ cross1 = [
+ (6, 51, "h"),
+ (7, 52, "w"),
+ (8, 52, "h"),
+ (9, 53, "h"),
+ (10, 54, "w"),
+ (11, 54, "k"),
+ ]
+ cross2 = [
+ (6, 54, "w"),
+ (7, 53, "h"),
+ (8, 53, "k"),
+ (9, 52, "h"),
+ (10, 51, "w"),
+ (11, 51, "h"),
+ ]
+ for x, y, col in cross1:
+ c.put(x, y, col)
+ for x, y, col in cross2:
+ c.put(x, y, col)
+
+ # 细划痕 4:底部螺丝附近的起子滑刀伤
+ slip = [
+ (8, 103, "k"),
+ (9, 104, "w"),
+ (10, 104, "h"),
+ (11, 105, "w"),
+ (12, 105, "h"),
+ (13, 105, "k"),
+ (14, 106, "w"),
+ (15, 106, "h"),
+ ]
+ for x, y, col in slip:
+ c.put(x, y, col)
+ c.put(x, y + 1, "k")
+
+ # 冲压小凹坑(小落伤,凹陷光影:左上暗槽、右下挤压高光圈)
+ pits = ((14, 22), (8, 72), (16, 75))
+ for px, py in pits:
+ c.put(px, py, "k")
+ c.put(px + 1, py, "d")
+ c.put(px, py + 1, "d")
+ c.put(px + 1, py + 1, "w")
+ c.put(px + 2, py + 1, "h")
+
+ return c
+
+
+def brk_port():
+ """7. 挡板接口数量不对:第三个接口被粗糙铁皮焊死/堵死,带焊渣点与开孔被封死。"""
+ c = _new()
+ y0, y1 = 56, 69
+
+ # 盖上一整块粗糙铁皮盲板封死
+ c.rect(5, y0 - 1, 18, y1 + 1, "d")
+ c.rect(6, y0, 17, y1, "m")
+
+ # 盲板拉丝与表面凹凸
+ for x in range(6, 18):
+ for y in range(y0, y1 + 1):
+ if (x * 3 + y * 7) % 5 == 0:
+ c.put(x, y, "b")
+ elif (x + y) % 4 == 0:
+ c.put(x, y, "d")
+
+ # 边缘粗糙焊缝与接合处阴影黑线
+ for y in range(y0 - 1, y1 + 2):
+ c.put(5, y, "n")
+ c.put(18, y, "k")
+ for x in range(5, 19):
+ c.put(x, y0 - 1, "n")
+ c.put(x, y1 + 1, "k")
+
+ # 两处粗糙固定冲压铆钉/点焊斑点
+ for ry in (y0 + 2, y1 - 3):
+ c.rect(10, ry, 13, ry + 2, "k")
+ c.put(11, ry + 1, "b")
+ c.put(12, ry + 1, "h")
+ c.put(10, ry, "d")
+
+ # 焊渣与高温变色痕(铜黄/焦色斑点)
+ weld_slag = [
+ (5, y0 + 1, "e"),
+ (6, y0 + 1, "q"),
+ (17, y0 + 4, "e"),
+ (18, y0 + 5, "c"),
+ (6, y1 - 1, "q"),
+ (5, y1, "e"),
+ (18, y1 - 2, "c"),
+ ]
+ for sx, sy, scol in weld_slag:
+ c.put(sx, sy, scol)
+
+ return c
+
+
+def shroud_chip():
+ """8. 散热罩磕碰/掉漆:外罩棱角撞击凹瘪、掉漆露出底铝银光与发散暗裂纹。"""
+ c = _new()
+
+ # 1) 顶部主磕碰坑(x=80~90 处受剧烈撞击)
+ # 撞入深凹坑
+ c.rect(81, 14, 88, 16, "k")
+ c.rect(82, 14, 87, 15, "n")
+ # 露出的底漆生铝金属高光反光
+ c.rect(83, 16, 86, 17, "w")
+ c.put(82, 16, "h")
+ c.put(87, 16, "l")
+ # 漆皮外卷毛边
+ for kx in range(80, 90):
+ c.put(kx, 13, "h" if kx % 2 == 0 else "l")
+ c.put(kx, 17, "k" if kx % 2 == 0 else "d")
+ # 撞击点向下延伸出的塑料/金属外壳发丝状应力裂纹
+ crack1 = [
+ (84, 18, "n"),
+ (84, 19, "k"),
+ (83, 20, "n"),
+ (83, 21, "k"),
+ (82, 22, "n"),
+ (81, 23, "k"),
+ (81, 24, "n"),
+ ]
+ for cx, cy, col in crack1:
+ c.put(cx, cy, col)
+ c.put(cx + 1, cy, "h") # 裂缝一侧高光
+
+ # 2) 中筋(两风扇之间)被工具磕掉漆皮
+ c.rect(104, 46, 107, 51, "k")
+ c.rect(105, 47, 106, 49, "w") # 露底生铝
+ c.put(106, 50, "h")
+ c.put(104, 45, "h")
+ c.put(107, 52, "d")
+
+ # 3) 右上角倒角处擦碰
+ c.rect(179, 17, 183, 20, "k")
+ c.put(180, 18, "w")
+ c.put(181, 19, "h")
+ c.put(182, 20, "l")
+ c.put(178, 16, "h")
+
+ # 4) 下部边缘刮蹭掉漆痕
+ c.rect(34, 93, 44, 94, "k")
+ for gx in range(35, 44, 2):
+ c.put(gx, 93, "w")
+ c.put(gx + 1, 94, "l")
+
+ return c
+
+
+# ==============================================================================
+# 背面 Case
+# ==============================================================================
+
+
+def print_overlay(model_text, style="normal"):
+ """9. 型号丝印:
+ - normal: 激光蚀刻(深色凹槽衬底+规整高光金属字)
+ - skew: 字歪重印(各字上下抖动、墨色不均、重影移位、边缘溢墨)
+ - stamp: 盖章式补印(原字发暗底层+倾斜补印红框印章层覆盖)
+ """
+ c = _new()
+ scale = 2
+ # 丝印凹槽居中计算
+ total_w = len(model_text) * (5 + 1) * scale
+ x_start = max(42, 38 + (136 - total_w) // 2)
+ y_start = 31
+
+ if style == "normal":
+ # 先打一层蚀刻内凹深色边缘刻痕
+ text57(
+ c,
+ x_start + 1,
+ y_start + 1,
+ model_text,
+ "k",
+ scale=scale,
+ skew=False,
+ gap=1,
+ )
+ # 精致激光银白字
+ text57(
+ c,
+ x_start,
+ y_start,
+ model_text,
+ "h",
+ scale=scale,
+ skew=False,
+ gap=1,
+ )
+
+ elif style == "skew":
+ cur_x = x_start
+ rnd = random.Random(309)
+ jitters = [0, 2, -1, 1, -2, 2, 0, 1]
+
+ # 1) 先打一层失准的底墨重影(偏移)
+ for i, ch in enumerate(model_text):
+ dy = jitters[i % len(jitters)]
+ # 偏色与残墨
+ text57(
+ c,
+ cur_x + 1,
+ y_start + dy + 1,
+ ch,
+ "d",
+ scale=scale,
+ skew=False,
+ gap=1,
+ )
+ cur_x += (5 + 1) * scale + (1 if i % 3 == 0 else 0)
+
+ # 2) 正式墨迹(每字高度不齐、颜色深浅不同)
+ cur_x = x_start
+ ink_colors = ["h", "l", "b", "h", "m", "l"]
+ for i, ch in enumerate(model_text):
+ dy = jitters[i % len(jitters)]
+ col = ink_colors[i % len(ink_colors)]
+ text57(
+ c,
+ cur_x,
+ y_start + dy,
+ ch,
+ col,
+ scale=scale,
+ skew=False,
+ gap=1,
+ )
+
+ # 边缘溢墨斑点 (Ink bleed)
+ if ch != " ":
+ for _ in range(4):
+ bx = cur_x + rnd.randint(-1, 10)
+ by = y_start + dy + rnd.randint(-1, 14)
+ if 36 <= bx <= 178 and 26 <= by <= 50:
+ c.put(bx, by, "x" if rnd.random() < 0.5 else "d")
+
+ cur_x += (5 + 1) * scale + (1 if i % 3 == 0 else 0)
+
+ elif style == "stamp":
+ # 1) 底层被磨掉/发暗的原型号痕迹(原先低配型号残影)
+ orig_text = "RZX 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)
+
+ # 2) 盖章边框(红章边框,微倾斜)
+ box_x0 = x_start - 4
+ box_y0 = y_start - 3
+ box_x1 = min(176, x_start + total_w + 4)
+ box_y1 = y_start + 17
+ c.rect(box_x0, box_y0, box_x1, box_y0 + 1, "R")
+ c.rect(box_x0, box_y1 - 1, box_x1, box_y1, "R")
+ c.rect(box_x0, box_y0, box_x0 + 1, box_y1, "R")
+ c.rect(box_x1 - 1, box_y0, box_x1, box_y1, "R")
+
+ # 章角溢印与盖印残红
+ c.put(box_x0 - 1, box_y0, "r2")
+ c.put(box_x1 + 1, box_y1, "r2")
+ c.put(box_x0 + 1, box_y1 + 1, "r2")
+
+ # 3) 盖印文字(红色印油,因印泥压力不均带斑驳漏白)
+ text57(
+ c,
+ x_start,
+ y_start,
+ model_text,
+ "R",
+ scale=scale,
+ skew=False,
+ gap=1,
+ )
+ rnd = random.Random(409)
+ for y in range(box_y0, box_y1 + 1):
+ for x in range(box_x0, box_x1 + 1):
+ if c.px[y][x] == "R" and rnd.random() < 0.22:
+ c.put(x, y, "r2" if rnd.random() < 0.6 else "w")
+
+ return c
+
+
+def print_skew(model_text="RZX 80Ti"):
+ return print_overlay(model_text, "skew")
+
+
+def print_stamp(model_text="RZX 80Ti"):
+ return print_overlay(model_text, "stamp")
+
+
+def print_normal(model_text="RZX 80Ti"):
+ return print_overlay(model_text, "normal")
+
+
+def sticker_hand():
+ """10. 序列号贴纸:白胶条盖住原条码,上面粗劣手写伪造序列号。"""
+ c = _new()
+
+ # 白胶带打底覆盖条码区域 (x=116..168, y=68..86)
+ c.rect(116, 68, 168, 86, "w")
+ # 胶带边缘立体层感与受光边
+ c.rect(116, 68, 168, 68, "h")
+ c.rect(116, 86, 168, 86, "l")
+ c.rect(116, 68, 116, 86, "h")
+ c.rect(168, 68, 168, 86, "l")
+
+ # 手写体字符 "SN:8942-X"(手写黑色笔画,带运笔粗细与倾斜波动)
+ strokes = [
+ # S
+ (120, 72),
+ (121, 72),
+ (122, 72),
+ (119, 73),
+ (120, 74),
+ (121, 75),
+ (122, 76),
+ (119, 77),
+ (120, 78),
+ (121, 78),
+ # N
+ (125, 78),
+ (125, 77),
+ (125, 76),
+ (125, 75),
+ (125, 74),
+ (125, 73),
+ (125, 72),
+ (126, 74),
+ (127, 75),
+ (128, 76),
+ (129, 77),
+ (129, 72),
+ (129, 73),
+ (129, 74),
+ (129, 75),
+ (129, 76),
+ (129, 78),
+ # :
+ (132, 74),
+ (132, 77),
+ # 8
+ (136, 72),
+ (137, 72),
+ (135, 73),
+ (138, 73),
+ (136, 75),
+ (137, 75),
+ (135, 76),
+ (138, 76),
+ (135, 77),
+ (138, 77),
+ (136, 78),
+ (137, 78),
+ # 9
+ (142, 72),
+ (143, 72),
+ (141, 73),
+ (144, 73),
+ (141, 74),
+ (144, 74),
+ (142, 75),
+ (143, 75),
+ (144, 75),
+ (144, 76),
+ (144, 77),
+ (143, 78),
+ (142, 78),
+ # 4
+ (147, 72),
+ (147, 73),
+ (147, 74),
+ (147, 75),
+ (148, 75),
+ (149, 75),
+ (150, 75),
+ (150, 72),
+ (150, 73),
+ (150, 74),
+ (150, 76),
+ (150, 77),
+ (150, 78),
+ # 2
+ (153, 72),
+ (154, 72),
+ (155, 73),
+ (154, 74),
+ (153, 75),
+ (153, 76),
+ (153, 77),
+ (153, 78),
+ (154, 78),
+ (155, 78),
+ (156, 78),
+ # -
+ (158, 75),
+ (159, 75),
+ (160, 75),
+ # X
+ (162, 72),
+ (163, 73),
+ (164, 74),
+ (165, 76),
+ (166, 77),
+ (166, 78),
+ (166, 72),
+ (165, 73),
+ (164, 75),
+ (163, 77),
+ (162, 78),
+ ]
+ for x, y in strokes:
+ c.put(x, y, "O")
+ c.put(x + 1, y, "O") # 笔尖圆珠粗细
+ c.put(x, y + 1, "k") # 圆珠笔纸面压痕阴影
+
+ return c
+
+
+def sticker_scratch():
+ """10. 序列号贴纸:条码被硬物反复恶意刮花破坏,白纸撕破、划痕露底。"""
+ c = _new()
+
+ # 横向主刮痕(钥匙/一字起深划过,条码截断)
+ for x in range(116, 168):
+ c.put(x, 75, "w")
+ c.put(x, 76, "w")
+ c.put(x, 77, "h" if x % 3 == 0 else "l")
+ c.put(x, 78, "d" if x % 2 == 0 else "m")
+
+ # 两道斜向猛烈刮叉痕
+ slash1 = [
+ (120, 70),
+ (123, 72),
+ (126, 74),
+ (130, 77),
+ (134, 80),
+ (138, 82),
+ (142, 84),
+ (145, 86),
+ ]
+ for x, y in slash1:
+ c.rect(x - 1, y - 1, x + 1, y, "w")
+ c.put(x + 2, y, "d")
+ c.put(x - 1, y + 1, "k")
+
+ slash2 = [
+ (160, 71),
+ (157, 73),
+ (153, 76),
+ (149, 79),
+ (145, 82),
+ (142, 84),
+ (138, 86),
+ ]
+ for x, y in slash2:
+ c.rect(x - 1, y - 1, x + 1, y, "w")
+ c.put(x + 1, y + 1, "k")
+ c.put(x - 2, y, "l")
+
+ # 纸屑翻边卷毛 (Torn paper fibers)
+ for fx, fy in (
+ (128, 74),
+ (132, 78),
+ (146, 83),
+ (152, 75),
+ (162, 74),
+ (121, 77),
+ ):
+ c.rect(fx, fy, fx + 1, fy + 1, "h")
+ c.put(fx, fy - 1, "w")
+
+ return c
+
+
+def sticker_torn():
+ """10. 序列号贴纸:贴纸被撕掉一大半,留撕破犬牙撕口与发黄恶心残胶。"""
+ c = _new()
+ rnd = random.Random(510)
+
+ # 撕裂区域:x=120..172, y=64..100(右侧大半被撕走,露出背板石墨底)
+ for y in range(64, 101):
+ # 锯齿状撕裂边界 x_tear
+ x_tear = 120 + int(3 * math.sin(y * 0.45) + (y % 4))
+ # 撕除暴露出的背板底色(重现 backplate 拉丝暗底)
+ for x in range(x_tear, 173):
+ c.put(x, y, "d" if y % 2 else "m" if (x // 3) % 4 else "d")
+
+ # 犬牙差互的白纸撕口边缘 (White torn paper fringe)
+ c.put(x_tear - 2, y, "w")
+ c.put(x_tear - 1, y, "h")
+ c.put(x_tear, y, "l")
+ c.put(x_tear + 1, y, "d")
+
+ # 背板上残留的大片发干、粘着灰尘的胶痕(残胶:'e', 'q', 'm', 'd', 'k')
+ glue_patches = [
+ (126, 68, 142, 82),
+ (148, 72, 168, 92),
+ (132, 84, 150, 96),
+ ]
+ for gx0, gy0, gx1, gy1 in glue_patches:
+ for gy in range(gy0, gy1 + 1):
+ for gx in range(gx0, gx1 + 1):
+ val = rnd.random()
+ if val < 0.55:
+ c.put(
+ gx,
+ gy,
+ (
+ "e"
+ if val < 0.20
+ else "q"
+ if val < 0.35
+ else "m"
+ if val < 0.48
+ else "k"
+ ),
+ )
+
+ # 没撕干净的局部纸片孤岛
+ c.rect(156, 82, 165, 87, "w")
+ c.rect(157, 83, 164, 86, "h")
+ c.put(166, 88, "d")
+
+ return c
+
+
+def seal_missing():
+ """11. 封条缺失:防拆封条被撕除,留边缘红碎纸片、底层 honeycomb/VOID 残胶与刮痕。"""
+ c = _new()
+ # 封条原本位置: x=174..182, y=60..104
+
+ # 露出底板金属
+ for y in range(60, 105):
+ for x in range(174, 183):
+ c.put(x, y, "d" if y % 2 else "m" if (x // 3) % 4 else "d")
+
+ # 顶部和底部断裂未撕净的红色封条碎片 (Torn seal scraps)
+ c.rect(174, 60, 182, 63, "R")
+ c.put(174, 64, "R")
+ c.put(175, 64, "r2")
+ c.put(178, 64, "R")
+ c.put(181, 64, "r2")
+
+ c.rect(174, 102, 182, 104, "R")
+ c.put(176, 101, "R")
+ c.put(177, 101, "r2")
+ c.put(180, 101, "R")
+
+ # 撕裂防伪胶转移层遗留的网格残胶斑(VOID 格状残留胶质)
+ for y in range(65, 101):
+ for x in range(174, 183):
+ # 规则点阵中带撕损
+ if (x + y) % 3 == 0:
+ c.put(x, y, "r2" if (x * y) % 2 == 0 else "e")
+ elif (x * 2 + y) % 5 == 0:
+ c.put(x, y, "m")
+
+ # 指甲抠挖清理残胶的竖划痕
+ for y in range(70, 95):
+ c.put(177, y, "h" if y % 3 == 0 else "k")
+ c.put(180, y, "k" if y % 2 == 0 else "d")
+
+ return c
+
+
+def seal_reglued():
+ """11. 封条被重新粘过:封条贴歪、角落起翘卷边(带投影)、内含明显鼓起气泡与折痕。"""
+ c = _new()
+
+ # 封条重贴发生偏斜(整体往左歪 1px,并露出右边缘的旧胶印)
+ # 旧胶缝留痕
+ for y in range(60, 105):
+ c.put(182, y, "e" if y % 2 else "d")
+
+ # 重新贴上的红封条(略微偏斜移位)
+ c.rect(173, 62, 181, 103, "R")
+ c.rect(173, 62, 174, 103, "r2")
+ c.rect(180, 62, 181, 103, "r2")
+
+ # 上端角落起翘卷边 (Curled Dog-ear corner)
+ # 起翘角露出白色背胶与内卷高光
+ c.put(179, 61, "w")
+ c.put(180, 60, "w")
+ c.put(181, 60, "h")
+ c.put(179, 62, "h")
+ c.put(180, 61, "l")
+ # 翘起卷角下方投下的深暗阴影
+ c.put(177, 62, "n")
+ c.put(178, 62, "k")
+ c.put(178, 63, "n")
+
+ # 起泡 1:中间圆形隆起气泡 (Air bubble 1)
+ bubble1 = [
+ (176, 73, "l"),
+ (177, 73, "w"),
+ (178, 73, "h"),
+ (175, 74, "l"),
+ (176, 74, "R"),
+ (177, 74, "w"),
+ (178, 74, "R"),
+ (179, 74, "r2"),
+ (175, 75, "h"),
+ (176, 75, "R"),
+ (177, 75, "R"),
+ (178, 75, "r2"),
+ (179, 75, "k"),
+ (176, 76, "r2"),
+ (177, 76, "k"),
+ (178, 76, "r2"),
+ ]
+ for x, y, col in bubble1:
+ c.put(x, y, col)
+
+ # 起泡 2:下部条状长气泡 (Air bubble 2)
+ bubble2 = [
+ (175, 87, "w"),
+ (176, 87, "l"),
+ (175, 88, "h"),
+ (176, 88, "R"),
+ (177, 88, "r2"),
+ (175, 89, "h"),
+ (176, 89, "R"),
+ (177, 89, "k"),
+ (176, 90, "r2"),
+ ]
+ for x, y, col in bubble2:
+ c.put(x, y, col)
+
+ # 被撕下时产生的死褶横折白印 (Crease stress marks)
+ for x in range(173, 182):
+ c.put(x, 81, "w" if x % 2 == 0 else "h")
+ c.put(x, 82, "r2")
+ c.put(x, 95, "h" if x % 3 == 0 else "w")
+ c.put(x, 96, "r2")
+
+ return c
+
+
+def screw_opened():
+ """12. 背板螺丝被拆过:
+ - (174, 94) 右下螺丝十字孔严重拧花/滑丝,溢出金属毛刺,起子滑出刮花背板;
+ - (36, 24) 左上螺丝十字槽口豁开变形磨损;
+ - (36, 94) 左下螺丝换成了一颗不同款的一字平头生锈旧螺丝。
+ """
+ c = _new()
+
+ # --------------------------------------------------------------------------
+ # 1. 右下螺丝 (174, 94):十字彻底滑丝拧烂 (Stripped screw) + 滑刀大划痕
+ # --------------------------------------------------------------------------
+ sx, sy = 174, 94
+ # 彻底磨平滑丝的中心烂圆坑
+ c.rect(sx - 2, sy - 2, sx + 2, sy + 2, "k")
+ c.rect(sx - 1, sy - 1, sx + 1, sy + 1, "n")
+ # 被起子强行旋转挤压出来的银白色金属毛刺边缘
+ c.put(sx - 2, sy - 1, "w")
+ c.put(sx - 1, sy - 2, "w")
+ c.put(sx + 2, sy, "h")
+ c.put(sx, sy + 2, "h")
+ c.put(sx + 1, sy + 1, "w")
+ c.put(sx - 2, sy + 2, "l")
+ # 螺丝刀猛烈滑出拧花槽、在背板上划出的一道深深弧形刀痕
+ driver_slip = [
+ (sx - 2, sy - 2, "w"),
+ (sx - 3, sy - 3, "h"),
+ (sx - 4, sy - 4, "w"),
+ (sx - 5, sy - 4, "k"),
+ (sx - 6, sy - 5, "w"),
+ (sx - 7, sy - 5, "h"),
+ (sx - 8, sy - 5, "k"),
+ (sx - 9, sy - 6, "h"),
+ (sx - 10, sy - 6, "w"),
+ (sx - 11, sy - 6, "k"),
+ ]
+ for px, py, pcol in driver_slip:
+ c.put(px, py, pcol)
+ c.put(px, py + 1, "k") # 划痕阴影
+
+ # --------------------------------------------------------------------------
+ # 2. 左上螺丝 (36, 24):起子咬合磨损划口,槽角崩损
+ # --------------------------------------------------------------------------
+ tx, ty = 36, 24
+ c.rect(tx - 1, ty - 1, tx + 1, ty + 1, "k")
+ c.put(tx, ty, "n")
+ c.put(tx - 2, ty, "w") # 槽口外翻高光
+ c.put(tx + 2, ty, "h")
+ c.put(tx, ty - 2, "w")
+ c.put(tx, ty + 2, "k")
+ c.put(tx - 1, ty - 1, "l")
+ c.put(tx + 1, ty + 1, "d")
+
+ # --------------------------------------------------------------------------
+ # 3. 左下螺丝 (36, 94):被换成了一颗规格不一致的一字平头暗铜色旧螺丝
+ # --------------------------------------------------------------------------
+ lx, ly = 36, 94
+ # 重新画一个完全不同的圆头一字锈螺丝(基调为暗铜色 'q'/'e')
+ c.rect(lx - 3, ly - 3, lx + 3, ly + 3, "e")
+ c.rect(lx - 3, ly - 3, lx - 1, ly - 3, "q")
+ c.rect(lx - 2, ly - 2, lx + 2, ly + 2, "q")
+ c.rect(lx + 2, ly + 2, lx + 3, ly + 3, "c")
+ # 一字槽(水平横槽,而不是十字孔)
+ c.rect(lx - 2, ly, lx + 2, ly, "n")
+ c.rect(lx - 2, ly - 1, lx + 2, ly - 1, "h") # 一字边缘受光
+ c.rect(lx - 2, ly + 1, lx + 2, ly + 1, "c") # 一字边缘阴影
+
+ return c
+
+
+# ==============================================================================
+# 导出字典
+# ==============================================================================
+
+CASES = {
+ # 正面
+ "gpu_big_ov_fan_dust1": fan_dust1,
+ "gpu_big_ov_fan_dust2": fan_dust2,
+ "gpu_big_ov_fan_chip": fan_chip,
+ "gpu_big_ov_fan_oil": fan_oil,
+ "gpu_big_ov_fin_dim": fin_dim,
+ "gpu_big_ov_fin_oxide": fin_oxide,
+ "gpu_big_ov_brk_scratch": brk_scratch,
+ "gpu_big_ov_brk_port": brk_port,
+ "gpu_big_ov_shroud_chip": shroud_chip,
+ # 背面
+ "gpu_big_ov_print_skew": print_skew,
+ "gpu_big_ov_print_stamp": print_stamp,
+ "gpu_big_ov_print_normal": print_normal,
+ "gpu_big_ov_sticker_hand": sticker_hand,
+ "gpu_big_ov_sticker_scratch": sticker_scratch,
+ "gpu_big_ov_sticker_torn": sticker_torn,
+ "gpu_big_ov_seal_missing": seal_missing,
+ "gpu_big_ov_seal_reglued": seal_reglued,
+ "gpu_big_ov_screw_opened": screw_opened,
+}
+
+__all__ = [
+ "CASES",
+ "print_overlay",
+ "fan_dust1",
+ "fan_dust2",
+ "fan_chip",
+ "fan_oil",
+ "fin_dim",
+ "fin_oxide",
+ "brk_scratch",
+ "brk_port",
+ "shroud_chip",
+ "print_skew",
+ "print_stamp",
+ "print_normal",
+ "sticker_hand",
+ "sticker_scratch",
+ "sticker_torn",
+ "seal_missing",
+ "seal_reglued",
+ "screw_opened",
+]
diff --git a/art/sprites.py b/art/sprites.py
index 01c3f99..f866b90 100644
--- a/art/sprites.py
+++ b/art/sprites.py
@@ -568,7 +568,13 @@ if __name__ == '__main__':
canvas.png(os.path.join(out, name + '.png'))
for name, make in OVERLAYS.items():
make().png(os.path.join(out, name + '.png'))
- import big
- for name, make in {**big.BIG, **big.BIG_OV}.items():
+ import big, big_cases
+ for name, make in big.BIG.items():
make().png(os.path.join(out, name + '.png'))
+ for name, make in big_cases.CASES.items():
+ if not name.startswith('gpu_big_ov_print_'):
+ make().png(os.path.join(out, name + '.png'))
+ for m in MODELS:
+ for style in ('normal', 'skew', 'stamp'):
+ big_cases.print_overlay(m, style).png(os.path.join(out, 'gpu_big_ov_print_%s_%s.png' % (style, key(m))))
print(out)
diff --git a/src/Decentralized.Domain/CardLook.cs b/src/Decentralized.Domain/CardLook.cs
index d05f80d..e4efa64 100644
--- a/src/Decentralized.Domain/CardLook.cs
+++ b/src/Decentralized.Domain/CardLook.cs
@@ -32,6 +32,19 @@ namespace Decentralized.Domain
return new CardLook { Fan = D(0), Fingers = D(1), Bracket = D(2), Print = D(3), Sticker = D(4) };
}
+ // 外观维度对应卡的真实状态:价格、损耗、暴毙概率都随之变化,所以看外观就是在估价
+ private static readonly double[] FanValue = { 1.00, 0.96, 0.88 }, FanWear = { 1.00, 1.10, 1.30 }, FanDeath = { 1.00, 1.00, 1.20 };
+ private static readonly double[] FingerValue = { 1.00, 0.96, 0.88 }, FingerDeath = { 1.00, 1.10, 1.30 };
+
+ /// 外观对价值的折扣:风扇积灰 −4%、缺角 −12%;金手指发暗 −4%、氧化 −12%;挡板划痕 −2%;封条缺失(开过封)−6%。
+ public double ValueFactor => FanValue[Fan] * FingerValue[Fingers] * (Bracket == 1 ? 0.98 : 1.0) * (Sticker == 2 ? 0.94 : 1.0);
+
+ /// 每晚损耗倍数:风扇积灰散热差 ×1.1,缺角 ×1.3。
+ public double WearFactor => FanWear[Fan];
+
+ /// 暴毙概率倍数:风扇缺角 ×1.2;金手指发暗 ×1.1、氧化 ×1.3(接触不良)。
+ public double DeathFactor => FanDeath[Fan] * FingerDeath[Fingers];
+
/// 只在假卡上出现的取值:玩家一旦看到,就能肯定是假的。
public bool HasFakeSign => Bracket == 2 || Print != 0 || Sticker == 1;
@@ -87,8 +100,8 @@ namespace Decentralized.Domain
return Math.Max(1, (long)Math.Round(spec.Price * f));
}
- /// 真实价值(芯片型号 + 健康度)。
- public static long True(Unit u) => Of(u.FakeOf ?? u.Model, u.Health);
+ /// 真实价值(芯片型号 + 健康度 + 外观折扣)。
+ public static long True(Unit u) => Math.Max(1, (long)Math.Round(Of(u.FakeOf ?? u.Model, u.Health) * u.Look.ValueFactor));
/// 标称价:贩子报的价,按标称型号算;二手卡也折旧,但只按贩子"自称"的健康度。
public static long Quoted(Unit u, double claimedHealth) => Of(u.Model, claimedHealth);
diff --git a/src/Decentralized.Domain/Mining.cs b/src/Decentralized.Domain/Mining.cs
index 50b3a82..0c2c8d2 100644
--- a/src/Decentralized.Domain/Mining.cs
+++ b/src/Decentralized.Domain/Mining.cs
@@ -103,14 +103,14 @@ namespace Decentralized.Domain
public double DeathChance(ModuleBonus b)
{
double p = Tuning.DeathBase + Tuning.DeathWorn * Math.Pow(1 - Health / 100, 2);
- return p * Label.DeathFactor * (FakeOf != null ? Tuning.FakeDeathFactor : 1) * b.Death;
+ return p * Label.DeathFactor * (FakeOf != null ? Tuning.FakeDeathFactor : 1) * b.Death * Look.DeathFactor;
}
/// 一夜的损耗与暴毙判定;返回是否在今晚暴毙。
public bool Night(ModuleBonus b, Rng rng)
{
if (Dead) return false;
- Health = Math.Max(0, Health - Label.WearFactor * b.Wear);
+ Health = Math.Max(0, Health - Label.WearFactor * b.Wear * Look.WearFactor);
if (rng.Chance(DeathChance(b)))
{
Dead = true;
diff --git a/src/Decentralized/GpuInspectView.cs b/src/Decentralized/GpuInspectView.cs
index 14df97e..f4499cd 100644
--- a/src/Decentralized/GpuInspectView.cs
+++ b/src/Decentralized/GpuInspectView.cs
@@ -58,6 +58,34 @@ namespace Decentralized
});
}
+ /// 检视大图的叠加层。五个维度各自对应一种或几种细节,组合时再加几处同源的小细节(磕碰、开过壳的螺丝、重新粘过的封条)。
+ public static List BigOverlays(GameItem item)
+ {
+ var o = new List();
+ var u = Items.ToUnit(item);
+ if (u.Dead) return o;
+ var l = u.Look;
+ string P = "gpu_big_ov_";
+ if (!Items.IsBack(item))
+ {
+ if (l.Fan == 1) o.Add(P + (l.Fingers > 0 ? "fan_dust2" : "fan_dust1"));
+ if (l.Fan == 2) { o.Add(P + "fan_chip"); if (l.Fingers == 2) o.Add(P + "fan_oil"); }
+ if (l.Fingers == 1) o.Add(P + "fin_dim");
+ if (l.Fingers == 2) o.Add(P + "fin_oxide");
+ if (l.Bracket == 1) { o.Add(P + "brk_scratch"); if (l.Fan > 0) o.Add(P + "shroud_chip"); }
+ if (l.Bracket == 2) o.Add(P + "brk_port");
+ }
+ else
+ {
+ string model = (l.Print == 1 && u.FakeOf != null ? u.FakeOf : u.Model).ToLowerInvariant();
+ o.Add(P + "print_" + (l.Print == 2 ? "skew_" : l.Print == 1 ? "stamp_" : "normal_") + model);
+ if (l.Print == 2) o.Add(P + "screw_opened"); // 重印过,说明拆开过
+ if (l.Sticker == 1) o.Add(P + "sticker_hand");
+ if (l.Sticker == 2) o.Add(P + (l.Print != 0 ? "seal_reglued" : "seal_missing"));
+ }
+ return o;
+ }
+
private void Build(InspectionUIManager m)
{
root = new GameObject("_PdGpuInspection", typeof(RectTransform)).GetComponent();
@@ -92,12 +120,11 @@ namespace Decentralized
{
foreach (Transform c in cardRoot) Destroy(c.gameObject);
var keys = new List();
- string baseKey = Items.LookKeys(item, keys);
- keys.Insert(0, baseKey);
- foreach (var small in keys)
+ string baseKey = Items.LookKeys(item, keys); // 小图键名只用来取底图(品牌与正反面)
+ var layers = new List { "gpu_big_" + baseKey.Substring("gpu_".Length) };
+ layers.AddRange(BigOverlays(item));
+ foreach (var k in layers)
{
- // 检视用大图:键名对应小图(gpu_probidia_f → gpu_big_probidia_f,gpu_ov_fan1 → gpu_big_ov_fan1)
- string k = small.StartsWith("gpu_ov_") ? "gpu_big_ov_" + small.Substring("gpu_ov_".Length) : "gpu_big_" + small.Substring("gpu_".Length);
var sprite = Items.ModSprite(k);
if (sprite == null) continue;
var go = new GameObject(k, typeof(RectTransform), typeof(Image));
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk1.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk1.png
deleted file mode 100644
index 21e08d2..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk1.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk2.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk2.png
deleted file mode 100644
index e804332..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk2.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk_port.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk_port.png
new file mode 100644
index 0000000..697655e
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk_port.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk_scratch.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk_scratch.png
new file mode 100644
index 0000000..cce203e
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_brk_scratch.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan1.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan1.png
deleted file mode 100644
index dbf02f7..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan1.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan2.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan2.png
deleted file mode 100644
index 9933c6a..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan2.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_chip.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_chip.png
new file mode 100644
index 0000000..f61d657
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_chip.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_dust1.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_dust1.png
new file mode 100644
index 0000000..d6cefee
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_dust1.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_dust2.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_dust2.png
new file mode 100644
index 0000000..32d2733
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_dust2.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_oil.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_oil.png
new file mode 100644
index 0000000..4e37fdb
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fan_oil.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin1.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin1.png
deleted file mode 100644
index 5f3eb74..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin1.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin2.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin2.png
deleted file mode 100644
index 04de9f5..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin2.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin_dim.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin_dim.png
new file mode 100644
index 0000000..cd9a6c9
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin_dim.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin_oxide.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin_oxide.png
new file mode 100644
index 0000000..abe8e80
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_fin_oxide.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz470.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz470.png
new file mode 100644
index 0000000..23d18e1
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz470.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz580.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz580.png
new file mode 100644
index 0000000..2a440ba
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz580.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz6800.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz6800.png
new file mode 100644
index 0000000..cf272a8
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz6800.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz7900.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz7900.png
new file mode 100644
index 0000000..4e6dfaa
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rz7900.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx50.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx50.png
new file mode 100644
index 0000000..afd9621
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx50.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx60.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx60.png
new file mode 100644
index 0000000..dd7b405
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx60.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx70.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx70.png
new file mode 100644
index 0000000..932e7e3
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx70.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx80ti.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx80ti.png
new file mode 100644
index 0000000..a65824e
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx80ti.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx90.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx90.png
new file mode 100644
index 0000000..d9ad64a
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_normal_rzx90.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz470.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz470.png
new file mode 100644
index 0000000..60d30b6
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz470.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz580.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz580.png
new file mode 100644
index 0000000..4c959d5
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz580.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz6800.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz6800.png
new file mode 100644
index 0000000..1d81cef
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz6800.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz7900.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz7900.png
new file mode 100644
index 0000000..0a05090
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rz7900.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx50.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx50.png
new file mode 100644
index 0000000..e281b2d
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx50.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx60.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx60.png
new file mode 100644
index 0000000..1eab1c2
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx60.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx70.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx70.png
new file mode 100644
index 0000000..7a30318
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx70.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx80ti.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx80ti.png
new file mode 100644
index 0000000..dd69532
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx80ti.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx90.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx90.png
new file mode 100644
index 0000000..51ae82e
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_skew_rzx90.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz470.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz470.png
new file mode 100644
index 0000000..845c47f
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz470.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz580.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz580.png
new file mode 100644
index 0000000..81f1a55
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz580.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz6800.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz6800.png
new file mode 100644
index 0000000..24b0a15
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz6800.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz7900.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz7900.png
new file mode 100644
index 0000000..f489c99
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rz7900.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx50.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx50.png
new file mode 100644
index 0000000..a44d7af
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx50.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx60.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx60.png
new file mode 100644
index 0000000..e4c5877
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx60.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx70.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx70.png
new file mode 100644
index 0000000..b301cb9
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx70.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx80ti.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx80ti.png
new file mode 100644
index 0000000..e967b3c
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx80ti.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx90.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx90.png
new file mode 100644
index 0000000..4240368
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_print_stamp_rzx90.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_screw_opened.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_screw_opened.png
new file mode 100644
index 0000000..3fb7a89
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_screw_opened.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_seal_missing.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_seal_missing.png
new file mode 100644
index 0000000..a5a45d3
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_seal_missing.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_seal_reglued.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_seal_reglued.png
new file mode 100644
index 0000000..ab260be
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_seal_reglued.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_shroud_chip.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_shroud_chip.png
new file mode 100644
index 0000000..92699a9
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_shroud_chip.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_sticker_hand.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_sticker_hand.png
new file mode 100644
index 0000000..642447a
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_sticker_hand.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_sticker_scratch.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_sticker_scratch.png
new file mode 100644
index 0000000..e313992
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_sticker_scratch.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_sticker_torn.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_sticker_torn.png
new file mode 100644
index 0000000..f563a40
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_sticker_torn.png differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_stk1.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_stk1.png
deleted file mode 100644
index 14051a7..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_stk1.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_stk2.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_stk2.png
deleted file mode 100644
index d934e9e..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_stk2.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz470.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz470.png
deleted file mode 100644
index 55b73ba..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz470.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz580.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz580.png
deleted file mode 100644
index f42f89e..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz580.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz6800.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz6800.png
deleted file mode 100644
index 939e124..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz6800.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz7900.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz7900.png
deleted file mode 100644
index 6dc73a5..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rz7900.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx50.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx50.png
deleted file mode 100644
index 65f66cc..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx50.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx60.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx60.png
deleted file mode 100644
index d91bf65..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx60.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx70.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx70.png
deleted file mode 100644
index 0cd95fb..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx70.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx80ti.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx80ti.png
deleted file mode 100644
index e6d8c83..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx80ti.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx90.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx90.png
deleted file mode 100644
index 77e5d14..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txs_rzx90.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz470.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz470.png
deleted file mode 100644
index 47acb85..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz470.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz580.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz580.png
deleted file mode 100644
index 5777ff6..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz580.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz6800.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz6800.png
deleted file mode 100644
index c17088c..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz6800.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz7900.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz7900.png
deleted file mode 100644
index eac4089..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rz7900.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx50.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx50.png
deleted file mode 100644
index c1d5cce..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx50.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx60.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx60.png
deleted file mode 100644
index 383ebc5..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx60.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx70.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx70.png
deleted file mode 100644
index 0aed346..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx70.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx80ti.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx80ti.png
deleted file mode 100644
index 6d16b64..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx80ti.png and /dev/null differ
diff --git a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx90.png b/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx90.png
deleted file mode 100644
index 6639936..0000000
Binary files a/src/Decentralized/ModFiles/Textures/Items/gpu_big_ov_txt_rzx90.png and /dev/null differ
diff --git a/tests/Decentralized.Domain.Tests/Program.cs b/tests/Decentralized.Domain.Tests/Program.cs
index becffce..36b8d8b 100644
--- a/tests/Decentralized.Domain.Tests/Program.cs
+++ b/tests/Decentralized.Domain.Tests/Program.cs
@@ -156,6 +156,11 @@ internal static class Program
var u = new Unit { Model = "RZX90", FakeOf = "RZX60", Health = 80 };
Check(CardValue.True(u) == CardValue.Of("RZX60", 80) && CardValue.Quoted(u, 80) == CardValue.Of("RZX90", 80), "真实价值按芯片型号,标称价按标称型号");
Check(CardValue.Quoted(u, 80) > CardValue.True(u) * 8, $"假 RZX 90 的标称价 {CardValue.Quoted(u, 80)} 远高于真值 {CardValue.True(u)}");
+ var worn = new Unit { Model = "RZX70", Health = 100, Look = new CardLook { Fan = 2, Fingers = 2, Bracket = 1, Sticker = 2 } };
+ Check(Near(CardLook.Decode("22102").ValueFactor, 0.88 * 0.88 * 0.98 * 0.94, 1e-9) && CardValue.True(worn) == (long)Math.Round(800 * 0.88 * 0.88 * 0.98 * 0.94), "外观折扣乘进真实价值:风扇缺角 + 金手指氧化 + 划痕 + 封条缺失");
+ var clean = new Unit { Model = "RZX70", Health = 80 };
+ var dusty = new Unit { Model = "RZX70", 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%");
});