Tiers drive physical traits and serial checks; guide item

Fans (1/2/3/3) and power connectors (6/8/8/8+8) follow the real chip's tier,
so a fake shows its real tier physically. Serial numbers (brand prefix, tier
code, factory code, four digits) are drawn on the sticker from card state;
the label bar gets power-and-fans and serial rows, eight in total, with a
framed panel. A graphics card appraisal guide item holds the rules.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-03 14:18:01 +08:00
1 parent 9d19df407a
commit 7f458b0139
113 files changed
+227 -133

No files matched your search

Binary file not shown.
Binary file not shown.
+27 -29
View File
@@ -7,8 +7,9 @@ import random
from sprites import Canvas, C, key, MODELS
BW, BH = 192, 128
FANS = ((68, 51), (142, 51))
FR = 30 # 风扇半径
# 风扇布局(按风扇数):中心与半径;FANS / FR 保留为双风扇的值,给叠加图模块当默认
FAN_LAYOUT = {1: ([(105, 55)], 34), 2: ([(68, 51), (142, 51)], 30), 3: ([(52, 51), (96, 51), (140, 51)], 21)}
FANS, FR = FAN_LAYOUT[2][0], FAN_LAYOUT[2][1]
SH0, SH1 = (24, 14), (186, 96) # 散热罩 左上 / 右下
FING_Y0, FING_Y1 = 109, 122
NOTCH_X = 112
@@ -94,9 +95,9 @@ def bracket(c):
c.rect(9, 10, 14, 12, 'k')
def fan(c, cx, cy, accent, accent_dark):
def fan(c, cx, cy, accent, accent_dark, R=None):
"""风扇:九片弯曲扇叶(前缘高光、叶面渐变、叶尖暗边),外圈带四个固定螺丝,轴心带品牌圆标。"""
R = FR
R = R or FR
for y in range(cy - R - 1, cy + R + 2):
for x in range(cx - R - 1, cx + R + 2):
dx, dy = x - cx, y - cy
@@ -135,7 +136,10 @@ def fan(c, cx, cy, accent, accent_dark):
c.put(sx, sy, 'g')
def gpu_front(accent, accent_dark, brand_text, burnt=False):
def gpu_front(accent, accent_dark, brand_text, tier=1, burnt=False):
"""tier 决定实物特征:风扇数(1/2/3/3)与供电口(6 针 / 8 针 / 8 针 / 双 8 针)。"""
count = (1, 2, 3, 3)[tier]
fans, R = FAN_LAYOUT[count]
c = Canvas(BW, BH)
bracket(c)
x0, y0 = SH0
@@ -161,21 +165,26 @@ def gpu_front(accent, accent_dark, brand_text, burnt=False):
c.put(x, y, 'x' if (x - (x1 - 18)) % 3 == 0 else 'g' if (x - (x1 - 18)) % 3 == 1 else 'n')
c.rect(x1 - 20, y0 + 10, x1 - 19, y1 - 4, 'x')
# 风扇之间的中筋
c.rect(105, y0 + 8, 106, y1 - 5, 'k'); c.rect(107, y0 + 8, 107, y1 - 5, 'x')
for cx, cy in FANS:
fan(c, cx, cy, accent, accent_dark)
for a, b in zip(fans, fans[1:]):
mx = (a[0] + b[0]) // 2 + 1
c.rect(mx - 1, y0 + 8, mx, y1 - 5, 'k'); c.rect(mx + 1, y0 + 8, mx + 1, y1 - 5, 'x')
for cx, cy in fans:
fan(c, cx, cy, accent, accent_dark, R)
# 前沿斜切装饰条:品牌色 + 品牌字
for x in range(x0 + 4, x1 - 20):
c.rect(x, y1 - 5, x, y1 - 3, accent if x % 11 else accent_dark)
text57(c, 112, 84, brand_text, 'h')
text57(c, 136 if count == 1 else 112, 84, brand_text, 'h')
# 顶沿:四根铜热管端头与 8 针供电口
for i in range(4):
x = 38 + i * 9
c.rect(x, 7, x + 6, y0 - 1, 'p'); c.rect(x, 7, x + 1, y0 - 1, 'h' if i == 0 else 'p')
c.rect(x + 5, 7, x + 6, y0 - 1, 'q'); c.rect(x, 7, x + 6, 7, 'q')
c.rect(112, 5, 154, y0 - 1, 'n'); c.rect(112, 5, 154, 6, 'z')
for i in range(8):
c.rect(114 + i * 5, 7, 116 + i * 5, 9, 'k'); c.put(115 + i * 5, 8, 'Y')
# 供电口:低端 6 针;中端、高端 8 针;旗舰两个 8 针
for left, pins in ((((118, 6),) if tier == 0 else ((112, 8),) if tier < 3 else ((78, 8), (126, 8)))):
right = left + pins * 5 + 2
c.rect(left, 5, right, y0 - 1, 'n'); c.rect(left, 5, right, 6, 'z')
for i in range(pins):
c.rect(left + 2 + i * 5, 7, left + 4 + i * 5, 9, 'k'); c.put(left + 3 + i * 5, 8, 'Y')
# PCB:阻焊绿、边缘高光、元件与走线
for y in range(y1 + 1, FING_Y0):
for x in range(x0, x1 + 1):
@@ -248,8 +257,6 @@ def sticker(c, seed):
w = 1 + ((x * 7 + seed) % 3)
if (x * 5 + seed) % 4 != 0:
c.rect(x, 70, x, 84, 'n')
text57(c, 118, 88, "0X5A70", 'n')
c.rect(150, 88, 166, 94, 'm')
def seal(c):
@@ -407,19 +414,12 @@ def ov_sticker(kind):
BIG = {}
for _b, (_a, _ad, _t) in {'probidia': ('G', 'g2', 'PROBIDIA'), 'pmd': ('R', 'r2', 'PMD')}.items():
BIG['gpu_big_%s_f' % _b] = (lambda a=_a, ad=_ad, t=_t: gpu_front(a, ad, t))
for _tier in range(4):
BIG['gpu_big_%s_f_t%d' % (_b, _tier)] = (lambda a=_a, ad=_ad, t=_t, k=_tier: gpu_front(a, ad, t, k))
BIG['gpu_big_%s_b' % _b] = (lambda a=_a, ad=_ad: gpu_back(a, ad))
BIG['gpu_big_burnt_f'] = lambda: gpu_front('e', 'c', 'PROBIDIA', burnt=True)
BIG['gpu_big_burnt_f'] = lambda: gpu_front('e', 'c', 'PROBIDIA', 1, burnt=True)
BIG['gpu_big_burnt_b'] = lambda: gpu_back('e', 'c', burnt=True)
BIG_OV = {
'gpu_big_ov_fan1': lambda: ov_fan(1), 'gpu_big_ov_fan2': lambda: ov_fan(2),
'gpu_big_ov_fin1': lambda: ov_fingers(1), 'gpu_big_ov_fin2': lambda: ov_fingers(2),
'gpu_big_ov_brk1': lambda: ov_bracket(1), 'gpu_big_ov_brk2': lambda: ov_bracket(2),
'gpu_big_ov_stk1': lambda: ov_sticker(1), 'gpu_big_ov_stk2': lambda: ov_sticker(2),
}
for _m in MODELS:
BIG_OV['gpu_big_ov_txt_' + key(_m)] = (lambda m=_m: ov_text(m, False))
BIG_OV['gpu_big_ov_txs_' + key(_m)] = (lambda m=_m: ov_text(m, True))
BIG_OV = {}
if __name__ == '__main__':
import sys, os
@@ -435,7 +435,5 @@ if __name__ == '__main__':
b.px[y][x] = oc.px[y][x]
return b
bg = (0x6A, 0x72, 0x70)
stack('gpu_big_probidia_f').png(os.path.join(d, 'big_f.png'), scale=5, bg=bg)
stack('gpu_big_pmd_f', 'gpu_big_ov_fan1', 'gpu_big_ov_fin2', 'gpu_big_ov_brk2').png(os.path.join(d, 'big_f_fake.png'), scale=5, bg=bg)
stack('gpu_big_pmd_b', 'gpu_big_ov_txs_rz6800', 'gpu_big_ov_stk1').png(os.path.join(d, 'big_b_fake.png'), scale=5, bg=bg)
stack('gpu_big_probidia_b', 'gpu_big_ov_txt_rzx80ti').png(os.path.join(d, 'big_b.png'), scale=5, bg=bg)
for t in range(4):
stack('gpu_big_probidia_f_t%d' % t).png(os.path.join(d, 'big_f_t%d.png' % t), scale=3, bg=bg)
+72 -34
View File
@@ -137,13 +137,14 @@ def bracket(c):
c.put(2, 27, 'h'); c.put(4, 27, 'd')
def fan(c, cx, cy, accent, burnt=False):
def fan(c, cx, cy, accent, burnt=False, R=7):
"""风扇:深色风道里六片弯曲扇叶(前缘高光、叶面按受光渐变),外圈细边,轴心带品牌色点;光从左上来。"""
import math
for y in range(cy - 7, cy + 8):
for x in range(cx - 7, cx + 8):
k = 7.0 / R # 按半径折算到 R=7 的画法
for y in range(cy - R, cy + R + 1):
for x in range(cx - R, cx + R + 1):
dx, dy = x - cx, y - cy
r = math.hypot(dx, dy)
r = math.hypot(dx, dy) * k
if r > 7.4:
continue
ang = (math.atan2(dy, dx) / (2 * math.pi)) % 1.0
@@ -164,7 +165,10 @@ def fan(c, cx, cy, accent, burnt=False):
c.put(cx - 1, cy - 1, 'w')
def gpu_front(accent, accent_dark, burnt=False):
FAN_LAYOUT_SMALL = {1: ([(26, 13)], 9), 2: ([(17, 13), (34, 13)], 7), 3: ([(14, 13), (26, 13), (38, 13)], 5)}
def gpu_front(accent, accent_dark, burnt=False, tier=1):
"""显卡正面(48×32,3×2 格),略微俯视:石墨色散热罩带斜切角与品牌色斜条,两个七叶风扇,
右端露出鳍片,顶沿露出铜热管和 8 针供电口,前沿是带元件的 PCB 和逐根画出的金手指。每格中心都不透明。"""
c = Canvas(W, H)
@@ -182,26 +186,33 @@ def gpu_front(accent, accent_dark, burnt=False):
for y in range(TOP0 + 2, TOP1):
c.put(x, y, 'g' if (x - (R - 4)) % 2 == 0 else 'k')
c.rect(R - 5, TOP0 + 2, R - 5, TOP1 - 1, 'x')
# 中间的筋条(两个风扇之间)与上下沿的槽
for y in range(TOP0 + 3, TOP1 - 2):
c.put(25, y, 'k'); c.put(26, y, 'x')
count = (1, 2, 3, 3)[tier]
fans, fr = FAN_LAYOUT_SMALL[count]
# 风扇之间的筋条
for a, b in zip(fans, fans[1:]):
mx = (a[0] + b[0]) // 2
for y in range(TOP0 + 3, TOP1 - 2):
c.put(mx, y, 'k'); c.put(mx + 1, y, 'x')
# 品牌色斜条(从前沿向左上延伸)与前沿色条
for x in range(L + 1, R - 5):
c.put(x, TOP1 - 1, accent if x % 9 else accent_dark)
c.put(x, TOP1, accent_dark)
for cx, cy in FANS:
fan(c, cx, cy, accent)
for dx, dy in ((-7, -7), (7, -7), (-7, 7), (7, 7)): # 风扇四角的固定孔
c.put(cx + dx, cy + dy, 'n' if dx + dy else 'k')
for cx, cy in fans:
fan(c, cx, cy, accent, R=fr)
if count < 3:
for dx, dy in ((-7, -7), (7, -7), (-7, 7), (7, 7)): # 风扇四角的固定孔
c.put(cx + dx, cy + dy, 'n' if dx + dy else 'k')
# 顶沿:铜热管端头 + 8 针供电口(带针脚)
for x0 in (L + 6, L + 8, L + 10, L + 12):
c.put(x0, TOP0 - 1, 'p'); c.put(x0 + 1, TOP0 - 1, 'q')
for x in range(L + 18, L + 28):
c.put(x, TOP0 - 1, 'n')
for x in range(L + 18, L + 28, 2):
c.put(x, TOP0 - 2, 'k')
for x in range(L + 19, L + 28, 2):
c.put(x, TOP0 - 2, 'Y')
# 供电口:低端 6 针;中端、高端 8 针;旗舰两个 8 针(每针占两像素)
for left, pins in (((L + 22, 6),) if tier == 0 else ((L + 18, 8),) if tier < 3 else ((L + 8, 8), (L + 25, 8))):
for x in range(left, left + pins * 2):
c.put(x, TOP0 - 1, 'n')
for x in range(left, left + pins * 2, 2):
c.put(x, TOP0 - 2, 'k')
for x in range(left + 1, left + pins * 2, 2):
c.put(x, TOP0 - 2, 'Y')
# 前沿:PCB(绿)带元件,之后金手指
for x in range(L, R + 1):
c.put(x, TOP1 + 1, 'G' if x % 7 else 'g2'); c.put(x, TOP1 + 2, 'g2')
@@ -221,7 +232,7 @@ def gpu_front(accent, accent_dark, burnt=False):
c.put(x, y, 'c')
for x in range(L + 1, R - 5):
c.put(x, TOP1 - 1, 'e')
for cx, cy in FANS:
for cx, cy in fans:
for dx, dy in ((0, 0), (1, 1), (-1, 1), (2, -2), (-2, -2)):
c.put(cx + dx, cy + dy, 'c')
outline(c)
@@ -298,10 +309,10 @@ def overlay():
return Canvas(W, H)
def ov_fan(kind):
def ov_fan(kind, count=2):
"""风扇叠加:1 积灰(叶片上一层灰),2 叶片缺角(边缘缺一块并露出黑底)。"""
c = overlay()
for cx, cy in FANS:
for cx, cy in FAN_LAYOUT_SMALL[count][0]:
if kind == 1:
for dx, dy in ((-4, -2), (-2, -4), (3, -3), (4, 1), (-3, 3), (2, 4), (-5, 0), (0, 5), (1, -5), (-1, 2), (5, -1), (3, 2)):
c.put(cx + dx, cy + dy, 'l')
@@ -363,7 +374,7 @@ def ov_sticker(kind):
return c
MODELS = ['RZX 50', 'RZX 60', 'RZX 70', 'RZX 80 Ti', 'RZX 90', 'RZ 470', 'RZ 580', 'RZ 6800', 'RZ 7900']
MODELS = ['RZX 60', 'RZX 70', 'RZX 80', 'RZX 90', 'RZ 70', 'RZ 80', 'RZ 800', 'RZ 900']
def rig():
@@ -503,24 +514,43 @@ def key(model):
return model.replace(' ', '').lower()
def guide():
"""鉴定手册(16×16,一格):竖放的小册子,封面带品牌色条,书脊在左。"""
c = Canvas(16, 16)
c.box(2, 1, 13, 14, 'b')
c.rect(3, 2, 4, 13, 'd') # 书脊
c.rect(5, 2, 12, 2, 'h')
c.rect(6, 4, 11, 5, 'G') # 封面色块
c.rect(6, 4, 11, 4, 'g2')
for y in (7, 9, 11): # 文字行
c.rect(6, y, 11 if y != 11 else 9, y, 'm')
c.put(12, 13, 'd')
outline(c)
return c
SPRITES = {
'gpu_probidia_f': lambda: gpu_front('G', 'g2'),
'gpu_probidia_b': lambda: gpu_back('G', 'g2'),
'gpu_pmd_f': lambda: gpu_front('R', 'r2'),
'gpu_pmd_b': lambda: gpu_back('R', 'r2'),
'gpu_guide': guide,
'gpu_burnt_f': lambda: gpu_front('e', 'c', burnt=True),
'gpu_burnt_b': lambda: gpu_back('e', 'c', burnt=True),
'gpu_probidia_b': lambda: gpu_back('G', 'g2'),
'gpu_pmd_b': lambda: gpu_back('R', 'r2'),
'rig': rig,
'terminal': terminal,
}
for _tier in range(4):
SPRITES['gpu_probidia_f_t%d' % _tier] = (lambda t=_tier: gpu_front('G', 'g2', tier=t))
SPRITES['gpu_pmd_f_t%d' % _tier] = (lambda t=_tier: gpu_front('R', 'r2', tier=t))
# 叠加图:和底图同尺寸,位置 (0,0) 对齐,只画变化的像素,不参与判格
OVERLAYS = {
'gpu_ov_fan1': lambda: ov_fan(1), 'gpu_ov_fan2': lambda: ov_fan(2),
'gpu_ov_fin1': lambda: ov_fingers(1), 'gpu_ov_fin2': lambda: ov_fingers(2),
'gpu_ov_brk1': lambda: ov_bracket(1), 'gpu_ov_brk2': lambda: ov_bracket(2),
'gpu_ov_stk1': lambda: ov_sticker(1), 'gpu_ov_stk2': lambda: ov_sticker(2),
'gpu_ov_brk1': lambda: ov_bracket(1),
'gpu_ov_stk2': lambda: ov_sticker(2),
}
for _n in (1, 2, 3):
OVERLAYS['gpu_ov_fan1_%d' % _n] = (lambda n=_n: ov_fan(1, n))
OVERLAYS['gpu_ov_fan2_%d' % _n] = (lambda n=_n: ov_fan(2, n))
for _m in MODELS:
OVERLAYS['gpu_ov_txt_' + key(_m)] = (lambda m=_m: ov_text(m, False))
OVERLAYS['gpu_ov_txs_' + key(_m)] = (lambda m=_m: ov_text(m, True))
@@ -551,13 +581,13 @@ if __name__ == '__main__':
if oc.px[y][x] is not None:
b.px[y][x] = oc.px[y][x]
return b
stack('gpu_probidia_f', 'gpu_ov_fan1', 'gpu_ov_fin1', 'gpu_ov_brk1').png(os.path.join(sys.argv[2], 'prev_front_worn.png'), scale=6, bg=(0xA0, 0xA8, 0x9C))
stack('gpu_pmd_f', 'gpu_ov_fan2', 'gpu_ov_fin2', 'gpu_ov_brk2').png(os.path.join(sys.argv[2], 'prev_front_fake.png'), scale=6, bg=(0xA0, 0xA8, 0x9C))
stack('gpu_probidia_b', 'gpu_ov_txt_rzx80ti').png(os.path.join(sys.argv[2], 'prev_back_ok.png'), scale=6, bg=(0xA0, 0xA8, 0x9C))
stack('gpu_pmd_b', 'gpu_ov_txs_rz6800', 'gpu_ov_stk1', 'gpu_ov_stk2').png(os.path.join(sys.argv[2], 'prev_back_fake.png'), scale=6, bg=(0xA0, 0xA8, 0x9C))
stack('gpu_probidia_f_t1', 'gpu_ov_fan2_2', 'gpu_ov_fin1', 'gpu_ov_brk1').png(os.path.join(sys.argv[2], 'prev_front_worn.png'), scale=6, bg=(0xA0, 0xA8, 0x9C))
print(sys.argv[2])
else:
out = os.path.normpath(os.path.join(here, '..', 'src', 'Decentralized', 'ModFiles', 'Textures', 'Items'))
for f in os.listdir(out): # 清掉旧的显卡图,避免留下不再使用的文件
if f.startswith('gpu_'):
os.remove(os.path.join(out, f))
for name, make in SPRITES.items():
canvas = make()
check_cells(canvas, name)
@@ -568,8 +598,16 @@ if __name__ == '__main__':
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_'):
if name.startswith('gpu_big_ov_fan_'):
continue
if not name.startswith('gpu_big_ov_print_') and name in ('gpu_big_ov_fin_dim', 'gpu_big_ov_fin_oxide', 'gpu_big_ov_brk_scratch', 'gpu_big_ov_seal_missing'):
make().png(os.path.join(out, name + '.png'))
# 风扇叠加按风扇数各出一套:叠加模块里的风扇位置是模块级变量,换成对应布局后再画
for count, (centres, radius) in big.FAN_LAYOUT.items():
big_cases.FANS = list(centres) if len(centres) > 1 else [centres[0], centres[0]]
big_cases.FR = radius
for fname, short in (('fan_dust1', 'fan_dust1'), ('fan_dust2', 'fan_dust2'), ('fan_chip', 'fan_chip')):
getattr(big_cases, fname)().png(os.path.join(out, 'gpu_big_ov_%s_%d.png' % (short, count)))
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))))
+50 -38
View File
@@ -16,7 +16,8 @@ namespace Decentralized
/// </summary>
public sealed class GpuInspectView : MonoBehaviour
{
private const float RowH = 30f, CardScale = 3f;
private const float RowH = 27f, CardScale = 2.7f, PanelTop = -86f;
private const int RowCount = 8;
private static GpuInspectView instance;
private RectTransform root, cardRoot;
private Button flip;
@@ -26,9 +27,10 @@ namespace Decentralized
private bool hidGlass;
private Transform buttonTemplate;
private TMP_FontAsset font;
private readonly TextMeshProUGUI[] rowName = new TextMeshProUGUI[6], rowText = new TextMeshProUGUI[6];
private readonly Button[] rowButton = new Button[6];
private readonly TextMeshProUGUI[] rowButtonText = new TextMeshProUGUI[6];
private readonly TextMeshProUGUI[] rowName = new TextMeshProUGUI[RowCount], rowText = new TextMeshProUGUI[RowCount];
private readonly Button[] rowButton = new Button[RowCount];
private readonly TextMeshProUGUI[] rowButtonText = new TextMeshProUGUI[RowCount];
private TextMeshProUGUI serialText;
public static void Ensure()
{
@@ -83,18 +85,17 @@ namespace Decentralized
string P = "gpu_big_ov_";
if (!Items.IsBack(item))
{
if (l.Fan == 1) o.Add(P + "fan_dust2");
if (l.Fan == 2) { o.Add(P + "fan_dust1"); o.Add(P + "fan_chip"); }
int n = Items.FansOf(u);
if (l.Fan == 1) o.Add(P + "fan_dust2_" + n);
if (l.Fan == 2) { o.Add(P + "fan_dust1_" + n); o.Add(P + "fan_chip_" + n); }
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.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.Sticker == 1) o.Add(P + "sticker_hand");
if (l.Sticker == 2) o.Add(P + "seal_missing");
}
return o;
@@ -160,30 +161,40 @@ namespace Decentralized
root.localPosition = Vector3.zero;
cardRoot = new GameObject("Card", typeof(RectTransform)).GetComponent<RectTransform>();
cardRoot.SetParent(root, false);
cardRoot.localPosition = new Vector3(0, 85, 0);
cardRoot.localPosition = new Vector3(0, 95, 0);
buttonTemplate = m.appraisalPanel.transform.Find("buttonSend");
// 贴纸上的序列号:随卡变化,运行时用文字写在贴纸的空白处
serialText = MakeText(root, "Serial", Vector2.zero, new Vector2(48 * CardScale, 8 * CardScale), TextAlignmentOptions.Center, 20);
serialText.color = new Color(0.1f, 0.1f, 0.13f);
serialText.fontStyle = FontStyles.Bold;
serialText.overflowMode = TextOverflowModes.Overflow;
serialText.rectTransform.sizeDelta = new Vector2(48 * CardScale, 14 * CardScale);
if (buttonTemplate == null) return;
font = buttonTemplate.GetComponentInChildren<TextMeshProUGUI>()?.font;
if (font != null) serialText.font = font;
// 标签区:深色底加浅色边框,和上面的大图分开
MakeRect(root, "LabelFrame", new Vector2(0, -201), new Vector2(648, 194), new Color(0.78f, 0.68f, 0.45f, 1f));
MakeRect(root, "LabelBack", new Vector2(0, -201), new Vector2(640, 186), new Color(0.10f, 0.11f, 0.14f, 0.96f));
flip = MakeButton(root, "Flip", new Vector2(0, -326), new Vector2(200, 34), out flipText);
float panelH = RowCount * RowH + 10f, panelY = PanelTop - panelH / 2;
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));
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 < 6; i++)
for (int i = 0; i < RowCount; i++)
{
int row = CardLabels.Rows[i];
float y = -126 - i * RowH;
rowName[i] = MakeText(root, "RowName" + i, new Vector2(-255, y), new Vector2(110, RowH), TextAlignmentOptions.Left, 24);
rowText[i] = MakeText(root, "RowText" + i, new Vector2(-30, y), new Vector2(330, RowH), TextAlignmentOptions.Left, 24);
rowButton[i] = MakeButton(root, "RowButton" + i, new Vector2(245, y), new Vector2(110, RowH - 4), out rowButtonText[i]);
float y = PanelTop - 5 - RowH * (i + 0.5f);
rowName[i] = MakeText(root, "RowName" + i, new Vector2(-255, y), new Vector2(110, RowH), TextAlignmentOptions.Left, 22);
rowText[i] = MakeText(root, "RowText" + i, new Vector2(-30, y), new Vector2(330, RowH), TextAlignmentOptions.Left, 22);
rowButton[i] = MakeButton(root, "RowButton" + i, new Vector2(245, y), new Vector2(110, RowH - 3), out rowButtonText[i]);
rowButton[i].onClick.AddListener(() => Log.Guard("标签栏", () => OnRowButton(row)));
}
}
private static string ValueText(int row, int value) =>
row == CardLabels.RowSpec ? "" : L.T("lbl." + (row == CardLabels.RowFan ? "fan" : row == CardLabels.RowFingers ? "fingers" : row == CardLabels.RowBracket ? "bracket" : row == CardLabels.RowPrint ? "print" : "sticker") + "." + value);
private static string RowKey(int row) => row == CardLabels.RowSpec ? "spec" : row == CardLabels.RowBuild ? "build" : row == CardLabels.RowFan ? "fan" : row == CardLabels.RowFingers ? "fingers"
: row == CardLabels.RowBracket ? "bracket" : row == CardLabels.RowPrint ? "print" : row == CardLabels.RowSerial ? "serial" : "seal";
private static string RowName(int row) => L.T("lbl.row." + (row == CardLabels.RowSpec ? "spec" : row == CardLabels.RowFan ? "fan" : row == CardLabels.RowFingers ? "fingers" : row == CardLabels.RowBracket ? "bracket" : row == CardLabels.RowPrint ? "print" : "sticker"));
private static string ValueText(int row, int value) => row == CardLabels.RowSpec ? "" : L.T("lbl." + RowKey(row) + "." + (row == CardLabels.RowSeal && value == 1 ? 0 : value));
private static string RowName(int row) => L.T("lbl.row." + RowKey(row));
/// <summary>现场有没有卖家 / 鉴定客户在:决定"指出"按钮是否出现。</summary>
private static bool CanPoint(GameItem item)
@@ -203,37 +214,38 @@ namespace Decentralized
int exposed = Items.Exposed(item);
bool owned = GeneralHelper.IsItemOwned(item);
bool canPoint = CanPoint(item), canEdit = owned && HasLabeler();
for (int i = 0; i < 6; i++)
for (int i = 0; i < RowCount; i++)
{
int row = CardLabels.Rows[i];
rowName[i].text = RowName(row);
rowName[i].color = new Color(1f, 0.85f, 0.45f);
string text;
Color color = new Color(0.96f, 0.98f, 1f);
if (claim == null)
{
text = row == CardLabels.RowSpec ? DisplayModel(real.Model) : ValueText(row, real.Get(row));
}
string Show(Claim c) => row == CardLabels.RowSpec ? DisplayModel(c.Model) : ValueText(row, c.Get(row));
if (claim == null) text = Show(real);
else if ((exposed & row) != 0)
{
int r = row == CardLabels.RowSpec ? 0 : real.Get(row);
text = row == CardLabels.RowSpec ? DisplayModel(real.Model) : ValueText(row, r);
bool lied = row == CardLabels.RowSpec ? claim.Value.Model != real.Model : claim.Value.Get(row) != r;
if (lied) { color = new Color(1f, 0.45f, 0.4f); text += L.T("lbl.said", row == CardLabels.RowSpec ? DisplayModel(claim.Value.Model) : ValueText(row, claim.Value.Get(row))); }
text = Show(real);
bool lied = row == CardLabels.RowSpec ? claim.Value.Model != real.Model : claim.Value.Get(row) != real.Get(row);
if (lied) { color = new Color(1f, 0.45f, 0.4f); text += L.T("lbl.said", row == CardLabels.RowBuild ? L.T("lbl.tier." + claim.Value.Tier) : Show(claim.Value)); }
else color = new Color(0.5f, 1f, 0.55f);
}
else
{
text = row == CardLabels.RowSpec ? DisplayModel(claim.Value.Model) : ValueText(row, claim.Value.Get(row));
}
else text = Show(claim.Value);
rowText[i].text = text;
rowText[i].color = color;
bool show = row != CardLabels.RowSpec && ((canPoint && claim != null && (exposed & row) == 0) || canEdit || (canPoint && claim == null));
bool point = canPoint && !canEdit;
rowButton[i].gameObject.SetActive(row != CardLabels.RowSpec ? ((canPoint && (exposed & row) == 0) || canEdit) : canEdit);
bool editable = row != CardLabels.RowBuild;
rowButton[i].gameObject.SetActive(canEdit ? editable : canPoint && (exposed & row) == 0);
rowButtonText[i].text = L.T(canEdit ? "lbl.edit" : "lbl.point");
}
if (flipText != null) flipText.text = L.T(Items.IsBack(item) ? "inspect.flip.front" : "inspect.flip.back");
// 贴纸上的序列号:只在背面显示
if (serialText != null)
{
serialText.gameObject.SetActive(Items.IsBack(item) && !u.Dead);
serialText.text = CardLabels.SerialText(u);
// 贴纸空白处中心在大图 (142, 91):卡片坐标以图中心为原点,y 向上
serialText.rectTransform.localPosition = new Vector3((142 - 96) * CardScale, 95 + (64 - 91) * CardScale, 0);
}
}
private static string DisplayModel(string model) => Items.DisplayModel(model);
@@ -244,7 +256,7 @@ namespace Decentralized
var item = shown;
if (GeneralHelper.IsItemOwned(item))
{
// 标签机:改说法,每按一次换下一个取值(型号是在九个型号里轮换)
// 标签机:改说法,每按一次换下一个取值(型号是在八个型号里轮换)
var u = Items.ToUnit(item);
var cur = Items.GetClaim(item) ?? Claim.Truth(u);
if (row == CardLabels.RowSpec)
@@ -252,7 +264,7 @@ namespace Decentralized
var models = Hardware.Specs.Values.Where(s => !s.Asic).Select(s => s.Model).ToList();
Items.EditClaim(item, row, 0, models[(models.IndexOf(cur.Model) + 1) % models.Count]);
}
else Items.EditClaim(item, row, (cur.Get(row) + 1) % 3);
else Items.EditClaim(item, row, row == CardLabels.RowSeal ? (cur.Get(row) == 0 ? 2 : 0) : row == CardLabels.RowBracket ? (cur.Get(row) + 1) % 2 : (cur.Get(row) + 1) % 3);
EmporiumAudioPlayer.Instance?.audioLabeler?.Play();
return;
}
+26 -7
View File
@@ -15,6 +15,7 @@ namespace Decentralized
{
public const string Terminal = "pd_terminal";
public const string Rig = "pd_rig";
public const string Guide = "pd_gpu_guide";
public const string GpuPrefix = "pd_gpu_";
public const string HealthTag = "PD_HEALTH";
@@ -36,6 +37,7 @@ namespace Decentralized
{
dir.Add(Terminal, CreateTerminal);
dir.Add(Rig, CreateRig);
dir.Add(Guide, CreateGuide);
foreach (var spec in Hardware.Specs.Values.Where(s => !s.Asic))
{
var s = spec;
@@ -61,6 +63,20 @@ namespace Decentralized
return item;
}
/// <summary>显卡鉴定手册:档次对照、序列号规则、外观折扣。和游戏里的鉴定手册一样,是一件物品,说明里就是内容。</summary>
private static GameItem CreateGuide()
{
var item = ItemDirectory.CreateEmptyItem(Guide);
item.SetSpriteAndShapeFromMod(ModInfo.Id, "gpu_guide");
item.name = L.T("item.guide.name");
item.shortDescription = L.T("item.guide.desc");
item.unitValue = 0;
item.EnableTag(GeneralHelper.IMPORTANT_TAG);
item.EnableTag(TypeHelper.NOT_FOR_RESALE);
ModHelper.SetSource(item, ModInfo.Id, ModInfo.Name);
return item;
}
// ---------- 显卡 ----------
/// <summary>RZX70 → "RZX 70",RZ800 → "RZ 800"。</summary>
@@ -129,7 +145,7 @@ namespace Decentralized
if ((lies & r) != 0 && rng.Chance(CustomerSpotChance))
{
found |= r;
if (r != CardLabels.RowSpec && CardLabels.IsFakeSign(r, Claim.Truth(u).Get(r))) found |= CardLabels.RowSpec;
if (r != CardLabels.RowSpec && CardLabels.IsEvidence(r, claim.Value, Claim.Truth(u))) found |= CardLabels.RowSpec | CardLabels.RowBuild;
}
if (found == 0) return;
item.ModifyTag(ExposedTag, t => t.Enable().SetInt(exposed | found));
@@ -217,7 +233,7 @@ namespace Decentralized
public static Unit ToUnit(GameItem item)
{
string model = item.identifier.Substring(GpuPrefix.Length);
model = Hardware.Specs.Keys.First(k => k.ToLowerInvariant() == model);
model = Hardware.Specs.Keys.FirstOrDefault(k => k.ToLowerInvariant() == model) ?? "RZX60"; // 旧版本存档里的型号已改名,当作低端卡
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();
@@ -253,7 +269,7 @@ namespace Decentralized
item.SetSpriteAndShapeFromMod(ModInfo.Id, item.IsTag(BackTag) ? "gpu_burnt_b" : "gpu_burnt_f");
return;
}
item.SetSpriteAndShapeFromMod(ModInfo.Id, (label.Brand == Hardware.Probidia ? "gpu_probidia" : "gpu_pmd") + (item.IsTag(BackTag) ? "_b" : "_f"));
item.SetSpriteAndShapeFromMod(ModInfo.Id, LookKeys(item, new List<string>()));
SyncValue(item);
}
@@ -266,6 +282,9 @@ namespace Decentralized
}
/// <summary>当前面的底图名与叠加图名:正面三个维度,背面丝印与贴纸;烧毁的卡不叠。</summary>
/// <summary>实物上的风扇数:由真实芯片的档次决定(低档次的板子套高档次的壳,风扇数露馅)。</summary>
public static int FansOf(Unit u) => Hardware.FanCount[Hardware.Specs[u.FakeOf ?? u.Model].Tier];
public static string LookKeys(GameItem item, List<string> overlays)
{
var u = ToUnit(item);
@@ -275,18 +294,18 @@ namespace Decentralized
if (u.Dead) return back ? "gpu_burnt_b" : "gpu_burnt_f";
if (!back)
{
if (l.Fan > 0) overlays.Add("gpu_ov_fan" + l.Fan);
if (l.Fan > 0) overlays.Add($"gpu_ov_fan{l.Fan}_{FansOf(u)}");
if (l.Fingers > 0) overlays.Add("gpu_ov_fin" + l.Fingers);
if (l.Bracket > 0) overlays.Add("gpu_ov_brk" + l.Bracket);
if (l.Bracket > 0) overlays.Add("gpu_ov_brk1");
}
else
{
// 丝印:0 标称型号;1 印的是真实芯片型号;2 标称型号但字歪(重印过)
string model = l.Print == 1 && u.FakeOf != null ? u.FakeOf : u.Model;
overlays.Add((l.Print == 2 ? "gpu_ov_txs_" : "gpu_ov_txt_") + model.ToLowerInvariant());
if (l.Sticker > 0) overlays.Add("gpu_ov_stk" + l.Sticker);
if (l.Sticker == 2) overlays.Add("gpu_ov_stk2");
}
return brand + (back ? "_b" : "_f");
return brand + (back ? "_b" : "_f_t" + Hardware.Specs[u.FakeOf ?? u.Model].Tier);
}
public static Sprite ModSprite(string key)
+25 -12
View File
@@ -78,27 +78,15 @@ point.worn.1,"...Fine, it has that. I'll knock something off."
point.worn.2,"Sharp eyes. All right, this price."
point.fake.1,"...You caught it. It's a reflashed one. I'll price it for what it is."
point.fake.2,"Tch, not the original chip. Fine, the real chip's price."
lbl.row.spec,"Model"
lbl.row.fan,"Fans"
lbl.row.fingers,"Contacts"
lbl.row.bracket,"Bracket"
lbl.row.print,"Back print"
lbl.row.sticker,"Sticker"
lbl.fan.0,"Blades clean"
lbl.fan.1,"Blades dusty"
lbl.fan.2,"Blade chipped"
lbl.fingers.0,"Bright"
lbl.fingers.1,"Dull"
lbl.fingers.2,"Oxidised"
lbl.bracket.0,"Intact, three ports"
lbl.bracket.1,"Scratched"
lbl.bracket.2,"Wrong port count"
lbl.print.0,"Matches the model"
lbl.print.1,"Another model printed"
lbl.print.2,"Reprinted, crooked"
lbl.sticker.0,"Printed serial, seal intact"
lbl.sticker.1,"Handwritten serial"
lbl.sticker.2,"Seal missing"
lbl.said," (seller said: {0})"
lbl.point,"Point out"
lbl.edit,"Edit"
@@ -106,3 +94,28 @@ cust.fake.1,"That's not what the label says. You trying to pass off a fake?"
cust.fake.2,"The model doesn't match. That isn't the chip it claims."
cust.worn.1,"That's not what you wrote. You left out the flaws."
cust.worn.2,"The condition on the label is false. Not at this price."
lbl.row.spec,"Model"
lbl.row.build,"Power & fans"
lbl.row.fan,"Blades"
lbl.row.fingers,"Contacts"
lbl.row.bracket,"Bracket"
lbl.row.print,"Back print"
lbl.row.serial,"Serial"
lbl.row.seal,"Seal"
lbl.build.0,"Entry: 6-pin, single fan"
lbl.build.1,"Mid: 8-pin, two fans"
lbl.build.2,"High: 8-pin, three fans"
lbl.build.3,"Flagship: dual 8-pin, three fans"
lbl.bracket.0,"Intact"
lbl.bracket.1,"Scratched"
lbl.serial.0,"Valid"
lbl.serial.1,"Bad factory code or length"
lbl.serial.2,"Tier code does not match"
lbl.seal.0,"Intact"
lbl.seal.2,"Missing"
lbl.tier.0,"Entry"
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%."
1 # Probably Decentralized localization table: English (en)
78 point.worn.2
79 point.fake.1
80 point.fake.2
lbl.row.spec
lbl.row.fan
lbl.row.fingers
lbl.row.bracket
lbl.row.print
lbl.row.sticker
81 lbl.fan.0
82 lbl.fan.1
83 lbl.fan.2
84 lbl.fingers.0
85 lbl.fingers.1
86 lbl.fingers.2
lbl.bracket.0
lbl.bracket.1
lbl.bracket.2
87 lbl.print.0
88 lbl.print.1
89 lbl.print.2
lbl.sticker.0
lbl.sticker.1
lbl.sticker.2
90 lbl.said
91 lbl.point
92 lbl.edit
94 cust.fake.2
95 cust.worn.1
96 cust.worn.2
97 lbl.row.spec
98 lbl.row.build
99 lbl.row.fan
100 lbl.row.fingers
101 lbl.row.bracket
102 lbl.row.print
103 lbl.row.serial
104 lbl.row.seal
105 lbl.build.0
106 lbl.build.1
107 lbl.build.2
108 lbl.build.3
109 lbl.bracket.0
110 lbl.bracket.1
111 lbl.serial.0
112 lbl.serial.1
113 lbl.serial.2
114 lbl.seal.0
115 lbl.seal.2
116 lbl.tier.0
117 lbl.tier.1
118 lbl.tier.2
119 lbl.tier.3
120 item.guide.name
121 item.guide.desc
+25 -12
View File
@@ -77,27 +77,15 @@ point.worn.1,"……行,这点毛病是有,算你便宜点。"
point.worn.2,"眼睛挺毒。好吧,这个价。"
point.fake.1,"……被你看出来了。是翻新的货,按真的价给你。"
point.fake.2,"啧,不是原装的。那就按芯片本来的价吧。"
lbl.row.spec,"型号"
lbl.row.fan,"风扇"
lbl.row.fingers,"金手指"
lbl.row.bracket,"挡板"
lbl.row.print,"背面丝印"
lbl.row.sticker,"贴纸封条"
lbl.fan.0,"叶片干净"
lbl.fan.1,"叶片积灰"
lbl.fan.2,"叶片缺角"
lbl.fingers.0,"光亮"
lbl.fingers.1,"发暗"
lbl.fingers.2,"氧化发绿"
lbl.bracket.0,"完好,接口三个"
lbl.bracket.1,"有划痕"
lbl.bracket.2,"接口数不对"
lbl.print.0,"与型号一致"
lbl.print.1,"印着另一个型号"
lbl.print.2,"重印过,字歪"
lbl.sticker.0,"印刷序列号,封条完好"
lbl.sticker.1,"手写序列号"
lbl.sticker.2,"封条已缺失"
lbl.said,"(卖家说:{0})"
lbl.point,"指出"
lbl.edit,"改"
@@ -105,3 +93,28 @@ cust.fake.1,"这不是它标的那块。你拿假货糊弄我?"
cust.fake.2,"型号对不上,里面的芯片根本不是这个。"
cust.worn.1,"跟你写的不一样,毛病你没说。"
cust.worn.2,"标签上的成色是假的吧,这个价我不要。"
lbl.row.spec,"型号"
lbl.row.build,"供电与风扇"
lbl.row.fan,"叶片"
lbl.row.fingers,"金手指"
lbl.row.bracket,"挡板"
lbl.row.print,"背面丝印"
lbl.row.serial,"序列号"
lbl.row.seal,"封条"
lbl.build.0,"低端:6针,单风扇"
lbl.build.1,"中端:8针,双风扇"
lbl.build.2,"高端:8针,三风扇"
lbl.build.3,"旗舰:双8针,三风扇"
lbl.bracket.0,"完好"
lbl.bracket.1,"有划痕"
lbl.serial.0,"合规"
lbl.serial.1,"工厂码或位数不合规"
lbl.serial.2,"档次码与型号不符"
lbl.seal.0,"完好"
lbl.seal.2,"已缺失"
lbl.tier.0,"低端"
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%。"
1 # Probably Decentralized 本地化表:简体中文(zh)
77 point.worn.2
78 point.fake.1
79 point.fake.2
lbl.row.spec
lbl.row.fan
lbl.row.fingers
lbl.row.bracket
lbl.row.print
lbl.row.sticker
80 lbl.fan.0
81 lbl.fan.1
82 lbl.fan.2
83 lbl.fingers.0
84 lbl.fingers.1
85 lbl.fingers.2
lbl.bracket.0
lbl.bracket.1
lbl.bracket.2
86 lbl.print.0
87 lbl.print.1
88 lbl.print.2
lbl.sticker.0
lbl.sticker.1
lbl.sticker.2
89 lbl.said
90 lbl.point
91 lbl.edit
93 cust.fake.2
94 cust.worn.1
95 cust.worn.2
96 lbl.row.spec
97 lbl.row.build
98 lbl.row.fan
99 lbl.row.fingers
100 lbl.row.bracket
101 lbl.row.print
102 lbl.row.serial
103 lbl.row.seal
104 lbl.build.0
105 lbl.build.1
106 lbl.build.2
107 lbl.build.3
108 lbl.bracket.0
109 lbl.bracket.1
110 lbl.serial.0
111 lbl.serial.1
112 lbl.serial.2
113 lbl.seal.0
114 lbl.seal.2
115 lbl.tier.0
116 lbl.tier.1
117 lbl.tier.2
118 lbl.tier.3
119 item.guide.name
120 item.guide.desc
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 966 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 607 B

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff. Show more