Version 3.1.0: voice lines linked across all languages from the game data
This commit is contained in:
@@ -5,7 +5,8 @@ A package is a zip:
|
||||
items/NNN.wem the exact WEM that was applied (used as-is when the target matches)
|
||||
items/NNN.flac the same audio, decoded (used to re-encode when the target differs, e.g. another
|
||||
language whose original has a different size)
|
||||
Each item records archive, target, name, group and the SHA-1 of the original it replaced.
|
||||
Each item records archive, target, name, group, the SHA-1 of the original it replaced and, for a voice line,
|
||||
its line identity (the same in every language, ackit/lines.py): that is how another language finds it.
|
||||
"texts": [{"key", "text", "original"}] edited subtitles / menu texts (keys: ackit/texts.py); optional,
|
||||
so packages without texts stay valid
|
||||
"""
|
||||
@@ -49,6 +50,7 @@ def export_mod(ws, path, keys, name="", author="", description="", texts=()):
|
||||
z.writestr(base + ".wem", wem)
|
||||
z.writestr(base + ".flac", buf.getvalue())
|
||||
items.append({"archive": e["archive"], "target": e["target"], "name": s.name if s else "",
|
||||
"line": s.line if s else "",
|
||||
"group": s.group if s else "", "original_sha1": e["orig_sha1"],
|
||||
"wem": base + ".wem", "audio": base + ".flac", "meta": e.get("meta", {})})
|
||||
z.writestr("manifest.json", json.dumps({"format": FORMAT, "name": name, "author": author,
|
||||
@@ -63,7 +65,7 @@ def export_mod(ws, path, keys, name="", author="", description="", texts=()):
|
||||
class ImportItem:
|
||||
item: dict
|
||||
sound: object = None # matched Sound or None
|
||||
how: str = "" # 'exact' | 'by name' | 'missing'
|
||||
how: str = "" # 'exact' | 'same line' | 'by name' | 'missing'
|
||||
wem: bytes = None # ready-to-apply bytes (after `prepare_import`)
|
||||
note: str = ""
|
||||
|
||||
@@ -80,19 +82,34 @@ def match_mod(ws, path):
|
||||
"""Match package items to sounds of this workspace. -> (manifest, [ImportItem])"""
|
||||
z, man = read_mod(path)
|
||||
out = []
|
||||
by_line = {}
|
||||
for c in ws.catalog.sounds:
|
||||
if c.line:
|
||||
by_line.setdefault(c.line, []).append(c)
|
||||
for it in man["items"]:
|
||||
key = "%s:%s" % (it["archive"], it["target"])
|
||||
s = ws.catalog.by_key.get(key)
|
||||
if s and it.get("name") and s.name != it["name"]:
|
||||
s = None
|
||||
if s:
|
||||
# the very same recording: same position and the same name or the same original bytes
|
||||
if s and (s.name == it.get("name") or (s.sha1 and s.sha1 == it.get("original_sha1"))):
|
||||
out.append(ImportItem(it, s, "exact"))
|
||||
continue
|
||||
if it.get("line"): # a voice line: its recording in the language loaded here
|
||||
cands = sorted(by_line.get(it["line"], []), key=lambda c: (c.name != it.get("name"), c.key))
|
||||
if cands: # several only for one recording stored twice (written together)
|
||||
out.append(ImportItem(it, cands[0], "same line"))
|
||||
else:
|
||||
out.append(ImportItem(it, None, "missing", note="the line %r has no recording in the language "
|
||||
"loaded here" % it.get("name")))
|
||||
continue
|
||||
try:
|
||||
cands = [c for c in ws.catalog.search(it["name"]) if c.name == it["name"]] if it.get("name") else []
|
||||
except LookupError:
|
||||
cands = []
|
||||
if len(cands) == 1:
|
||||
if len(cands) == 1 and cands[0].line:
|
||||
# a voice line from a package without line identities (older version): names alone are not proof
|
||||
out.append(ImportItem(it, None, "missing", note="%r is a voice line from a package of an older "
|
||||
"version; export the mod again to move it to another language" % it["name"]))
|
||||
elif len(cands) == 1:
|
||||
out.append(ImportItem(it, cands[0], "by name"))
|
||||
else:
|
||||
out.append(ImportItem(it, None, "missing", note="no sound named %r in this game/language" % it.get("name")))
|
||||
|
||||
Reference in New Issue
Block a user