Files

66 lines
4.4 KiB
Python

#!/usr/bin/env python3
"""Stage the exact AVA2 biology items/icons for the current 156-byte proto format.
No whole AVA2 locale/protocol is imported. Outputs are a reproducible, small client patch pack.
"""
import argparse,json,shutil,subprocess
from pathlib import Path
HERE=Path(__file__).resolve().parent
NAMES={70028:'研究奖励重选券',300004:'榉木树枝',300005:'图吉木板',300006:'红鬼树枝',300007:'首领笔记',300008:'嫉妒宝石',300009:'智慧宝石',300010:'凤凰羽毛',300011:'红色单片镜',300012:'古老配方',30229:'智慧灵魂石',30230:'凤凰灵魂石',30231:'红镜灵魂石',30232:'古方灵魂石',30250:'研究冷却药剂',71035:'研究员精华'}
def prepare(proto,ava,locale,output,tool,packer):
catalog=json.loads((HERE/'catalog.json').read_text());wanted={v for r in catalog for v in (r['material'],r['stone'],r['enhancer'],r['skip']) if v}|{70028}
rows={}
for line in proto.read_bytes().splitlines():
cols=line.split(b'\t')
if cols[0].isdigit() and int(cols[0]) in wanted: rows[int(cols[0])]=cols
assert rows.keys()==wanted
output.mkdir(parents=True,exist_ok=True)
server=[];numeric=[]
listrows={}
for line in (ava/'locale/locale/es/item_list.txt').read_bytes().splitlines():
c=line.split();
if c and c[0].isdigit() and int(c[0]) in wanted:listrows[int(c[0])]=c
assert listrows.keys()==wanted
assets=output/'assets';(assets/'icon/item').mkdir(parents=True,exist_ok=True)
# Chinese names for existing IDs come from the already reviewed current locale.
names={}
for filename in ('item_names_zh.txt','item_names_zh_overlay.txt'):
path=HERE.parents[2]/'data/zh_40250'/filename
for line in path.read_text().splitlines():
c=line.split('\t',1)
if len(c)==2 and c[0].isdigit():names[int(c[0])]=c[1]
for v,c in sorted(rows.items()):
original_name=c[1].decode('cp949','replace')
name=NAMES.get(v,names.get(v,original_name))
c[1]=name.encode('gbk');server.append(b'\t'.join(c))
types={b'ITEM_NONE':0,b'ITEM_MATERIAL':5,b'ITEM_QUEST':18}
flags={b'NONE':0,b'ITEM_STACKABLE':4,b'LOG':8192}
antis={b'NONE':0,b'ANTI_DROP':128,b'ANTI_SELL':256,b'ANTI_GIVE':8192,b'ANTI_MYSHOP':65536}
parse=lambda s,m:sum(m[x.strip()] for x in s.split(b'|'))
assert all(c[i] in (b'0',b'',b'LIMIT_NONE',b'APPLY_NONE',b'NONE') for i in (12,14,15,16,17,18,19,20,21,22,23))
numeric.append('%d\t%d\t0\t%d\t%d\t%d\t%d\t%d\t%s\t%s' % (v,types[c[2]],int(c[4]),parse(c[5],antis),parse(c[6],flags),int(c[9]),int(c[10]),'\t'.join(str(int(c[i] or b'0')) for i in range(24,30)),name))
icon=listrows[v][2].decode('ascii');shutil.copy2(ava/'icon'/icon,assets/icon)
(output/'items-server.tsv').write_bytes(b'\n'.join(server)+b'\n')
(output/'items-client.tsv').write_bytes(('\n'.join(numeric)+'\n').encode('gbk'))
target=assets/'locale/zh';target.mkdir(parents=True,exist_ok=True)
subprocess.run([str(tool),str(locale/'item_proto'),str(output/'items-client.tsv'),str(target/'item_proto')],check=True)
# Replace only the matching item_list/description rows; all other current entries stay byte-identical.
for filename in ('item_list.txt','itemdesc.txt'):
lines=(locale/filename).read_bytes().splitlines();result=[]
for line in lines:
key=line.split(b'\t',1)[0]
if not key.isdigit() or int(key) not in wanted:result.append(line)
for v in sorted(wanted):
if filename=='item_list.txt':result.append(b'\t'.join(listrows[v]))
else:
name=NAMES.get(v,names.get(v,'研究材料')).encode('gbk')
description=('重新选择一次已经领取的生物学家奖励。' if v==70028 else '提高本次研究成功率 50 个百分点。' if v==71035 else '跳过本次提交的等待时间;仅在冷却期间消耗。' if v==30250 else '用于生物学家研究。').encode('gbk')
result.append(str(v).encode()+b'\t'+name+b'\t'+description)
(target/filename).write_bytes(b'\n'.join(result)+b'\n')
subprocess.run([str(packer),str(output/'biolog'),str(assets), ''],check=True)
(output/'items.json').write_text(json.dumps({v:NAMES.get(v,names.get(v,'研究材料')) for v in sorted(wanted)},ensure_ascii=False,indent=2)+'\n')
if __name__=='__main__':
p=argparse.ArgumentParser();p.add_argument('proto',type=Path);p.add_argument('ava',type=Path);p.add_argument('locale',type=Path);p.add_argument('output',type=Path);p.add_argument('tool',type=Path);p.add_argument('packer',type=Path)
a=p.parse_args();prepare(a.proto,a.ava,a.locale,a.output,a.tool.resolve(),a.packer.resolve())