diff --git a/modules/rpgmakermvmz.py b/modules/rpgmakermvmz.py index 8b8a73e..6dfa913 100644 --- a/modules/rpgmakermvmz.py +++ b/modules/rpgmakermvmz.py @@ -983,7 +983,7 @@ def searchCodes(page, pbar, jobList, filename): # Remove any RPGMaker Code at start ffMatchNS = re.search( - r"^((?:[\\]+[^cCnNiIkKvVSs{}]+\[[\d\w\W]+?\]?\])+)", + r"^((?:[\\]+[^cCnNiIkKvVSs{}]+?\[[\d\w\W]+?\]?\])+)", nextString, ) if ffMatchNS != None: @@ -1105,7 +1105,7 @@ def searchCodes(page, pbar, jobList, filename): # Remove any RPGMaker Code at start ffMatch = re.search( - r"^((?:[\\]+[^cCnNiIkKvVSs{}]+\[[\d\w\W]+?\]?\])+)", + r"^((?:[\\]+[^cCnNiIkKvVSs{}]+?\[[\d\w\W]+?\]?\])+)", finalJAString, ) if ffMatch != None: diff --git a/modules/wolf.py b/modules/wolf.py index e0ff045..746008d 100644 --- a/modules/wolf.py +++ b/modules/wolf.py @@ -65,14 +65,14 @@ PBAR = None FILENAME = None # Dialogue / Choices -CODE101 = False -CODE102 = False +CODE101 = True +CODE102 = True # Picture CODE150 = False # Set String (Fragile but necessary) -CODE122 = True +CODE122 = False # Other CODE210 = False @@ -81,8 +81,8 @@ CODE250 = False # Database SCENARIOFLAG = False -OPTIONSFLAG = True -NPCFLAG = True +OPTIONSFLAG = False +NPCFLAG = False DBNAMEFLAG = False DBVALUEFLAG = False ITEMFLAG = False @@ -501,8 +501,8 @@ def searchCodes(events, pbar, jobList, filename): and jaString != "" and "_" not in jaString and '",' not in jaString - and ">" not in jaString - and "<" not in jaString + # and ">" not in jaString + # and "<" not in jaString ): # Pass 1 (Save Text to List) if not setData: @@ -557,7 +557,7 @@ def searchCodes(events, pbar, jobList, filename): codeList[i]["stringArgs"][1] = translatedText # Dialogue - elif codeList[i]["stringArgs"][0] == "サイド通知": + elif codeList[i]["stringArgs"][0] == "サイド通知" or codeList[i]["stringArgs"][0] == "X[移]メニュー時文章表示": jaString = codeList[i]["stringArgs"][1] # Pass 1 @@ -909,7 +909,7 @@ def searchDB(events, pbar, jobList, filename): try: for table in tableList: # Grab NPCs - if table["name"] == "主人公ステータス" and NPCFLAG == True: + if table["name"] == "戦闘コマンド" and NPCFLAG == True: with open("translations.txt", "a", encoding="utf-8") as file: if setData: file.write(f"\n#Actors\n") @@ -919,7 +919,7 @@ def searchDB(events, pbar, jobList, filename): # Parse for j in range(len(dataList)): # Name - if dataList[j].get("name") == "キャラ名": + if dataList[j].get("name") == "コマンド名": # Pass 1 (Grab Data) if setData == False: if dataList[j].get("value") != "": @@ -936,7 +936,7 @@ def searchDB(events, pbar, jobList, filename): npcList[0].pop(0) # Description - if dataList[j].get("name") == "肩書き": + if dataList[j].get("name") == "コマンドの説明文": # Pass 1 (Grab Data) if setData == False: if dataList[j].get("value") != "": @@ -1258,7 +1258,7 @@ def searchDB(events, pbar, jobList, filename): dbValueList[0].pop(0) # Grab Items - if table["name"] == "勲章コモン" and ITEMFLAG == True: + if table["name"] == "アイテム" and ITEMFLAG == True: # Write Category if setData: with open("translations.txt", "a", encoding="utf-8") as file: @@ -1272,7 +1272,7 @@ def searchDB(events, pbar, jobList, filename): font = 20 for j in range(len(dataList)): # Name - if dataList[j].get("name") == "勲章名": + if dataList[j].get("name") == "アイテム名": jaString = dataList[j].get("value") if jaString != "": # Pass 1 (Grab Data) @@ -1290,7 +1290,7 @@ def searchDB(events, pbar, jobList, filename): itemList[0].pop(0) # Description - if dataList[j].get("name") == "説明文": + if dataList[j].get("name") == "説明文[2行まで可]": # Pass 1 (Grab Data) if setData == False: if dataList[j].get("value") != "": @@ -1356,7 +1356,7 @@ def searchDB(events, pbar, jobList, filename): itemList[2].pop(0) # Description - if dataList[j].get("name") == "クエスト概要": + if dataList[j].get("name") == "使用後文章[移動]": # Pass 1 (Grab Data) if setData == False: if dataList[j].get("value") != "": @@ -1646,11 +1646,13 @@ def searchDB(events, pbar, jobList, filename): # Textwrap translatedText = skillList[3][0] translatedText = dazedwrap.wrapText(translatedText, LISTWIDTH) - translatedText = font + translatedText # Remove Taro translatedText = re.sub(r"\bTaro\b", "", translatedText) + # Font + translatedText = font + translatedText + # Set Data dataList[j].update({"value": translatedText}) skillList[3].pop(0) diff --git a/prompt.txt b/prompt.txt index 11e1d38..ce7ee72 100644 --- a/prompt.txt +++ b/prompt.txt @@ -78,11 +78,13 @@ Output: Input: { "Line1": "ハートが可愛いピンク色のチャーム。\n女の子らしさが増すワンポイントアクセサリー。\\\\n\\}\\C[16]«効果»\\C[0] [防御力+1][敏捷性+1][魅力+8][最大HP+10]" - "Line2": " \\{\\{\\{“滅茶苦茶に汚してやりてぇ”" + "Line2": " \\{\\{\\{“滅茶苦茶に汚してやりてぇ”", + "Line3": "イぐぅぅぅう~~~~~~♡♡♡" } Output: { "Line1": "A cute pink heart charm.\nA girly accessory that adds a feminine touch.\\\\n\\}\\C[16]«Effect»\\C[0] [Defense +1][Agility +1][Charm +8][Max HP +10]" - "Line2": " \\{\\{\\{“I wanna mess her up so fucking bad.”" + "Line2": " \\{\\{\\{“I wanna mess her up so fucking bad.”", + "Line3": "I'm cummingggg~~~~~~♡♡♡" } diff --git a/util/translation.py b/util/translation.py index 9ac5e9e..df44165 100644 --- a/util/translation.py +++ b/util/translation.py @@ -254,7 +254,30 @@ Output ONLY the {config.language} translation in the following format: `Translat return system, user -def translateText(system, user, history, penalty, formatType, model): +def createTranslationSchema(numLines): + """Create a JSON schema for translation response based on number of lines""" + properties = {} + required = [] + + for i in range(1, numLines + 1): + line_key = f"Line{i}" + properties[line_key] = { + "type": "string", + "description": f"The translated text for Line{i}" + } + required.append(line_key) + + schema = { + "type": "object", + "properties": properties, + "required": required, + "additionalProperties": False + } + + return schema + + +def translateText(system, user, history, penalty, formatType, model, numLines=None): """Send translation request to OpenAI API""" # Ensure system content is not empty if not system or not str(system).strip(): @@ -276,8 +299,17 @@ def translateText(system, user, history, penalty, formatType, model): msg.append({"role": "assistant", "content": history}) # Response Format - if formatType == "json": - responseFormat = {"type": "json_object"} + if formatType == "json" and numLines is not None: + # Use structured output with JSON schema + schema = createTranslationSchema(numLines) + responseFormat = { + "type": "json_schema", + "json_schema": { + "name": "translation_response", + "strict": True, + "schema": schema + } + } else: responseFormat = {"type": "text"} @@ -292,21 +324,44 @@ def translateText(system, user, history, penalty, formatType, model): raise ValueError(f"Message {i} has empty content: {message}") # Call OpenAI API - if "gpt-5" in model: - response = openai.chat.completions.create( - model=model, - response_format=responseFormat, - messages=msg, - reasoning_effort="minimal" - ) - else: - response = openai.chat.completions.create( - model=model, - response_format=responseFormat, - messages=msg, - temperature=0, - frequency_penalty=penalty - ) + try: + if "gpt-5" in model: + response = openai.chat.completions.create( + model=model, + response_format=responseFormat, + messages=msg, + reasoning_effort="minimal" + ) + else: + response = openai.chat.completions.create( + model=model, + response_format=responseFormat, + messages=msg, + temperature=0, + frequency_penalty=penalty + ) + except Exception as e: + # If structured output fails, fallback to json_object + if formatType == "json" and "json_schema" in str(responseFormat): + responseFormat = {"type": "json_object"} + if "gpt-5" in model: + response = openai.chat.completions.create( + model=model, + response_format=responseFormat, + messages=msg, + reasoning_effort="minimal" + ) + else: + response = openai.chat.completions.create( + model=model, + response_format=responseFormat, + messages=msg, + temperature=0, + frequency_penalty=penalty + ) + else: + raise e + return response @@ -326,6 +381,7 @@ def cleanTranslatedText(translatedText, language): "】": "]", "【": "[", "é": "e", + "’": "'", "this guy": "this bastard", "This guy": "This bastard", "Placeholder Text": "", @@ -363,8 +419,6 @@ def elongateCharacters(text): def extractTranslation(translatedTextList, isList, pbar=None): """Extract translation from JSON response""" try: - translatedTextList = re.sub(r'\\"+\"([^,\n}])', r'\\"\1', translatedTextList) - translatedTextList = re.sub(r"(?