125 lines
3.2 KiB
Python
125 lines
3.2 KiB
Python
import fxconv
|
|
import yaml
|
|
|
|
def convert(input, output, params, target):
|
|
recognized = True
|
|
if params["custom-type"] == "blockinfo":
|
|
o = convert_blockinfo(input, params)
|
|
elif params["custom-type"] == "iteminfo":
|
|
o = convert_iteminfo(input, params)
|
|
else:
|
|
recognized = False
|
|
|
|
if recognized:
|
|
fxconv.elf(o, output, "_" + params["name"], **target)
|
|
return 0
|
|
|
|
return 1
|
|
|
|
def mkBreakability(br):
|
|
return fxconv.u8({
|
|
None: 0,
|
|
"Fluid": 0,
|
|
"ByAnything": 1,
|
|
"ByTool": 2,
|
|
"Unbreakable": 3,
|
|
}[br])
|
|
|
|
def mkToolKind(tk):
|
|
return fxconv.u8({
|
|
None: 0xff,
|
|
"Pickaxe": 0,
|
|
"Axe": 1,
|
|
"Shovel": 2,
|
|
"Hoe": 3,
|
|
}[tk])
|
|
|
|
def mkBool(b):
|
|
if isinstance(b, str):
|
|
b = b.lower()
|
|
return fxconv.u8(b in [True, "yes", "true"])
|
|
|
|
def mkGlyph(s):
|
|
assert len(s) == 1
|
|
special = {
|
|
0x2058: 1,
|
|
0x00B7: 2,
|
|
0x2225: 3,
|
|
0x00A4: 4,
|
|
0x2197: 5,
|
|
0x00BB: 6,
|
|
0x2193: 7,
|
|
0x00EE: 8,
|
|
0x222B: 9,
|
|
0x25AA: 10,
|
|
0x2605: 11,
|
|
0x25CF: 12,
|
|
0x21A5: 13,
|
|
0x039B: 14,
|
|
# 15 is combined with a diacritic (from CASIO's custom charset)
|
|
0x2295: 16,
|
|
0x25A1: 0x7f,
|
|
}
|
|
if ord(s) >= 0x20 and ord(s) <= 0x7f:
|
|
return fxconv.u8(ord(s))
|
|
elif ord(s) in special:
|
|
return fxconv.u8(special[ord(s)])
|
|
else:
|
|
raise ValueError(f"unknown glyph {s}")
|
|
|
|
def mkGlyphCluster(str):
|
|
assert len(str) == 4
|
|
return b"".join(mkGlyph(s) for s in str)
|
|
|
|
def convert_blockinfo(input, params):
|
|
with open(input, "r") as fp:
|
|
data = yaml.safe_load(fp.read())
|
|
|
|
o = fxconv.ObjectData()
|
|
|
|
for b in data:
|
|
# Make sure there are no typos in the fields
|
|
assert (f in ["name", "breakability", "toolKind",
|
|
"baseBreakDurationTicks", "walkable", "replaceable"] for f in b)
|
|
|
|
# If a tool is specified, default to Breakability::ByTool
|
|
tk = b.get("toolKind", None)
|
|
br = b.get("breakability", "ByTool" if tk is not None else "ByAnything")
|
|
|
|
o += fxconv.string(b["name"])
|
|
o += mkGlyphCluster(b["cluster"])
|
|
o += mkBreakability(br)
|
|
o += mkToolKind(tk)
|
|
o += fxconv.u16(int(b.get("breakingTime", 20)))
|
|
o += mkBool(b.get("walkable", False))
|
|
o += mkBool(b.get("replaceable", False))
|
|
o += bytes(2)
|
|
|
|
o += fxconv.sym("Nooncraft_blockInfoCount")
|
|
o += fxconv.u32(len(data))
|
|
return o
|
|
|
|
def convert_iteminfo(input, params):
|
|
with open(input, "r") as fp:
|
|
data = yaml.safe_load(fp.read())
|
|
|
|
o = fxconv.ObjectData()
|
|
|
|
for i in data:
|
|
# Make sure there are no typos in the fields
|
|
assert (f in ["name", "cluster", "toolKind", "toolLevel", "stackSize"]
|
|
for f in i)
|
|
|
|
tk = i.get("toolKind", None)
|
|
|
|
o += fxconv.string(i["name"])
|
|
o += mkGlyphCluster(i["cluster"])
|
|
o += fxconv.u8(tk is not None)
|
|
o += mkToolKind(tk)
|
|
o += fxconv.u8(0 if tk is None else i["toolLevel"])
|
|
o += fxconv.u8(int(i.get("stackSize", 1 if tk is not None else 64)))
|
|
|
|
o += fxconv.sym("Nooncraft_itemInfoCount")
|
|
o += fxconv.u32(len(data))
|
|
return o
|