Adding more support for stuf

This commit is contained in:
dazedanon 2026-02-16 09:57:02 -06:00
parent 696ee730a6
commit e014e1c3f9
4 changed files with 196 additions and 2 deletions

View file

@ -54,6 +54,8 @@ class RPGMakerTab(QWidget):
"BRFLAG": False,
"FIXTEXTWRAP": True,
"IGNORETLTEXT": False,
"TLSYSTEMVARIABLES": False,
"TLSYSTEMSWITCHES": False,
# Main Codes (enabled by default)
"CODE401": True, # Show Text
@ -274,6 +276,16 @@ class RPGMakerTab(QWidget):
)
col1.addLayout(layout)
self.tlsystemvariables_cb, layout = self._create_checkbox_with_description(
"System Variables", "Translate variable names in System.json", "Translates the variables array in System.json. Can break stuff."
)
col1.addLayout(layout)
self.tlsystemswitches_cb, layout = self._create_checkbox_with_description(
"System Switches", "Translate switch names in System.json", "Translates the switches array in System.json."
)
col1.addLayout(layout)
self.join408_cb, layout = self._create_checkbox_with_description(
"Merge 408 Lines", "Join multi-line comments together", "Joins CODE408 lines into one string."
)
@ -494,6 +506,8 @@ class RPGMakerTab(QWidget):
self.brflag_cb.stateChanged.disconnect()
self.fixtextwrap_cb.stateChanged.disconnect()
self.ignoretltext_cb.stateChanged.disconnect()
self.tlsystemvariables_cb.stateChanged.disconnect()
self.tlsystemswitches_cb.stateChanged.disconnect()
self.join408_cb.stateChanged.disconnect()
if self.engine == "ACE":
self.speakers408_cb.stateChanged.disconnect()
@ -534,6 +548,8 @@ class RPGMakerTab(QWidget):
self.brflag_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.fixtextwrap_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.ignoretltext_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.tlsystemvariables_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.tlsystemswitches_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.join408_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
if self.engine == "ACE":
self.speakers408_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
@ -572,6 +588,8 @@ class RPGMakerTab(QWidget):
"BRFLAG": self.brflag_cb.isChecked(),
"FIXTEXTWRAP": self.fixtextwrap_cb.isChecked(),
"IGNORETLTEXT": self.ignoretltext_cb.isChecked(),
"TLSYSTEMVARIABLES": self.tlsystemvariables_cb.isChecked(),
"TLSYSTEMSWITCHES": self.tlsystemswitches_cb.isChecked(),
"JOIN408": self.join408_cb.isChecked(),
# Main Codes
@ -614,6 +632,8 @@ class RPGMakerTab(QWidget):
self.brflag_cb.setChecked(config.get("BRFLAG", False))
self.fixtextwrap_cb.setChecked(config.get("FIXTEXTWRAP", True))
self.ignoretltext_cb.setChecked(config.get("IGNORETLTEXT", False))
self.tlsystemvariables_cb.setChecked(config.get("TLSYSTEMVARIABLES", False))
self.tlsystemswitches_cb.setChecked(config.get("TLSYSTEMSWITCHES", False))
self.join408_cb.setChecked(config.get("JOIN408", False))
# Only set SPEAKERS408 for ACE engine

View file

@ -165,6 +165,9 @@ def parseJSON(data, filename):
# RdData format (RdData.json - dgnDatas with dungeon/dialogue data)
elif "dgnDatas" in data:
result = translateRdData(data, filename)
# GameSetting format (Nupu_GameSetting.json - fzCardDatas, fzDeckDatas, rentalDecks)
elif any(k in data for k in ["fzCardDatas", "fzDeckDatas", "rentalDecks"]):
result = translateGameSetting(data, filename)
else:
result = translateJSON(data, filename, [])
else:
@ -726,6 +729,122 @@ def translateRdData(data, filename):
return tokens
def translateGameSetting(data, filename):
"""Translate GameSetting JSON format (e.g. Nupu_GameSetting.json).
Handles card data, deck definitions, and rental decks.
Only translates player-visible text fields.
"""
global LOCK, ESTIMATE, FILENAME, PBAR, MISMATCH
tokens = [0, 0]
def batchTranslate(stringList, context):
"""Translate a list of strings and return translations. Returns [] on mismatch."""
nonlocal tokens
if not stringList:
return []
response = translateAI(stringList, context, True)
tokens[0] += response[1][0]
tokens[1] += response[1][1]
if len(stringList) != len(response[0]):
with LOCK:
if FILENAME not in MISMATCH:
MISMATCH.append(FILENAME)
return []
return response[0]
# ================================================================
# PASS 1: Collect all translatable strings
# ================================================================
# -- fzCardDatas: card descriptions --
desc1S, desc1I = [], []
desc2S, desc2I = [], []
if "fzCardDatas" in data:
for i, card in enumerate(data["fzCardDatas"]):
if card.get("desc1") and re.search(LANGREGEX, card["desc1"]):
desc1S.append(card["desc1"].replace("\r\n", " ").replace("\n", " ").strip())
desc1I.append(i)
if card.get("desc2") and re.search(LANGREGEX, card["desc2"]):
desc2S.append(card["desc2"].replace("\r\n", " ").replace("\n", " ").strip())
desc2I.append(i)
# -- fzDeckDatas: deck name and description --
deckNameS, deckNameI = [], []
deckDescS, deckDescI = [], []
if "fzDeckDatas" in data:
for i, deck in enumerate(data["fzDeckDatas"]):
if deck.get("name") and re.search(LANGREGEX, deck["name"]):
deckNameS.append(deck["name"])
deckNameI.append(i)
if deck.get("desc") and re.search(LANGREGEX, deck["desc"]):
deckDescS.append(deck["desc"].replace("\r\n", " ").replace("\n", " ").strip())
deckDescI.append(i)
# -- rentalDecks: memo label --
rentalMemoS, rentalMemoI = [], []
if "rentalDecks" in data:
for i, rental in enumerate(data["rentalDecks"]):
if rental.get("memo") and re.search(LANGREGEX, rental["memo"]):
rentalMemoS.append(rental["memo"])
rentalMemoI.append(i)
# Set progress bar total
totalItems = (
len(desc1S) + len(desc2S)
+ len(deckNameS) + len(deckDescS)
+ len(rentalMemoS)
)
PBAR.total = totalItems
PBAR.refresh()
# ================================================================
# PASS 2: Translate each batch and apply results back to data
# ================================================================
# -- fzCardDatas --
if "fzCardDatas" in data:
cards = data["fzCardDatas"]
for tl, idx in zip(batchTranslate(desc1S, "Card Description"), desc1I):
cards[idx]["desc1"] = dazedwrap.wrapText(tl, WIDTH)
if desc1S:
save_progress_json(data, filename)
for tl, idx in zip(batchTranslate(desc2S, "Card Description"), desc2I):
cards[idx]["desc2"] = dazedwrap.wrapText(tl, WIDTH)
if desc2S:
save_progress_json(data, filename)
# -- fzDeckDatas --
if "fzDeckDatas" in data:
decks = data["fzDeckDatas"]
for tl, idx in zip(batchTranslate(deckNameS, "Deck Name"), deckNameI):
decks[idx]["name"] = tl
if deckNameS:
save_progress_json(data, filename)
for tl, idx in zip(batchTranslate(deckDescS, "Deck Description"), deckDescI):
decks[idx]["desc"] = dazedwrap.wrapText(tl, WIDTH)
if deckDescS:
save_progress_json(data, filename)
# -- rentalDecks --
if "rentalDecks" in data:
rentals = data["rentalDecks"]
for tl, idx in zip(batchTranslate(rentalMemoS, "Deck Label"), rentalMemoI):
rentals[idx]["memo"] = tl
if rentalMemoS:
save_progress_json(data, filename)
return tokens
def translateJSON(data, filename, translatedList):
global LOCK, ESTIMATE, FILENAME, PBAR, MISMATCH
if translatedList:

View file

@ -91,6 +91,8 @@ FIXTEXTWRAP = True
IGNORETLTEXT = False
# TLSYSTEMVARIABLES: Translate System Variables. (Optional but sometimes necessary. Can break stuff.)
TLSYSTEMVARIABLES = False
# TLSYSTEMSWITCHES: Translate System Switches. (Optional. Translates switch names in System.json.)
TLSYSTEMSWITCHES = False
# Join 408 codes into a single string like 401.
JOIN408 = False
# SPEAKERS408: Process speakers in code 408 the same way as code 401.
@ -1012,6 +1014,7 @@ def parseSystem(data, filename):
if isinstance(gt, str) and gt:
count += 1
count += len(sysobj.get("variables", []) or [])
count += len(sysobj.get("switches", []) or [])
count += len(sysobj.get("weapon_types", []) or [])
count += len(sysobj.get("armor_types", []) or [])
count += len(sysobj.get("skill_types", []) or [])
@ -3551,6 +3554,29 @@ def searchSystem(data, pbar):
if pbar is not None:
pbar.refresh()
# Switches (Optional) — batch translate to reduce calls
if TLSYSTEMSWITCHES and "switches" in data and isinstance(data["switches"], list):
switch_indices = []
switch_values = []
for idx, val in enumerate(data["switches"]):
if isinstance(val, str) and val.strip():
switch_indices.append(idx)
switch_values.append(val)
if switch_values:
response = translateAI(
switch_values,
'Reply with only the ' + LANGUAGE + ' translation of the switch name',
True,
)
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
tl_list = response[0]
# Assign back translations to corresponding indices
for n, idx in enumerate(switch_indices[: len(tl_list)]):
data["switches"][idx] = tl_list[n].replace('"', '').strip()
if pbar is not None:
pbar.refresh()
# Messages — batch translate to reduce calls (check if exists)
if "messages" in data["terms"]:
messages = data["terms"]["messages"]

View file

@ -125,6 +125,8 @@ FIXTEXTWRAP = True
IGNORETLTEXT = False
# TLSYSTEMVARIABLES: Translate System Variables. (Optional but sometimes necessary. Can break stuff.)
TLSYSTEMVARIABLES = False
# TLSYSTEMSWITCHES: Translate System Switches. (Optional. Translates switch names in System.json.)
TLSYSTEMSWITCHES = True
# Join 408 codes into a single string like 401.
JOIN408 = False
@ -892,7 +894,7 @@ def parseNames(data, filename, context):
note_regexes = [
(r"<note:(.*?)>", False),
(r"<PE拡張:(.*?)>", False),
(r"<hint:(.*?)>", False),
(r"<[Hh]int:(.*?)>", False),
(r"<SGDescription:(.*?)>", False),
(r"<SG説明:\n?(.*?)>", True),
(r"<SG説明2:\n?(.*?)>", False),
@ -1083,6 +1085,7 @@ def parseSystem(data, filename):
if isinstance(gt, str) and gt:
count += 1
count += len(sysobj.get("variables", []) or [])
count += len(sysobj.get("switches", []) or [])
count += len(sysobj.get("weaponTypes", []) or [])
count += len(sysobj.get("armorTypes", []) or [])
count += len(sysobj.get("skillTypes", []) or [])
@ -1229,7 +1232,7 @@ def searchNames(data, pbar, context, filename):
note_regexes = [
(r"<note:(.*?)>", False),
(r"<PE拡張:(.*?)>", False),
(r"<hint:(.*?)>", False),
(r"<[Hh]int:(.*?)>", False),
(r"<SGDescription:(.*?)>", False),
(r"<SG説明:\n?(.*?)>", True),
(r"<SG説明2:\n?(.*?)>", False),
@ -3887,6 +3890,32 @@ def searchSystem(data, pbar):
if pbar is not None:
pbar.refresh()
# Switches (Optional) — batch translate to reduce calls
if TLSYSTEMSWITCHES and "switches" in data and isinstance(data["switches"], list):
switch_indices = []
switch_values = []
for idx, val in enumerate(data["switches"]):
if isinstance(val, str) and val.strip():
# Skip if IGNORETLTEXT is enabled and no Japanese text
if IGNORETLTEXT and not re.search(LANGREGEX, val):
continue
switch_indices.append(idx)
switch_values.append(val)
if switch_values:
response = translateAI(
switch_values,
'Reply with only the ' + LANGUAGE + ' translation of the switch name',
True,
)
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
tl_list = response[0]
# Assign back translations to corresponding indices
for n, idx in enumerate(switch_indices[: len(tl_list)]):
data["switches"][idx] = tl_list[n].replace('"', '').strip()
if pbar is not None:
pbar.refresh()
# Messages — batch translate to reduce calls
messages = data["terms"]["messages"]
if messages: