From 2096b9354059e062d03c47248b74b76af09af4f6 Mon Sep 17 00:00:00 2001 From: Faraphel Date: Mon, 17 Jan 2022 09:43:42 +0100 Subject: [PATCH] default_track is now supported, color of the original track are now handled by the tags_color of the ct_config.json file --- ct_config.json | 102 +++++-------------------------------------- source/CT_Config.py | 35 +++++++-------- source/Cup.py | 12 ++--- source/Game.py | 82 +++++++++++++++++++--------------- source/Track.py | 15 +++++-- source/definition.py | 54 ----------------------- source/wszst/lec.py | 19 +++++--- translation.json | 2 +- 8 files changed, 108 insertions(+), 213 deletions(-) diff --git a/ct_config.json b/ct_config.json index 48427bb..ae80a32 100644 --- a/ct_config.json +++ b/ct_config.json @@ -103,6 +103,17 @@ "Boost":"YOR3" }, "tag_retro": "Retro", + "default_track": + { + "name":"", + "music":"T32", + "special":"T32", + "author":"MrFluffy", + "since_version":"0.1", + "sha1":"54a1621fef2b137adcbe20b6dd710b5bc5f981a1", + "version":"v1.1", + "tags":[] + }, "cup":[ { "name":"Switch1", @@ -211,19 +222,6 @@ "Retro", "Wii U" ] - }, - { - "name":"_", - "music":"T32", - "special":"T32", - "score":0, - "author":"MrFluffy", - "since_version":"0.1", - "sha1":"54a1621fef2b137adcbe20b6dd710b5bc5f981a1", - "version":"v1.1", - "tags":[ - "Retro" - ] } ] }, @@ -1159,32 +1157,6 @@ "Retro", "GBA" ] - }, - { - "name":"_", - "music":"T44", - "special":"T44", - "score":0, - "author":"MrFluffy", - "since_version":"0.1", - "sha1":"54a1621fef2b137adcbe20b6dd710b5bc5f981a1", - "version":"v1.1", - "tags":[ - "Retro" - ] - }, - { - "name":"_", - "music":"T44", - "special":"T44", - "score":0, - "author":"MrFluffy", - "since_version":"0.1", - "sha1":"54a1621fef2b137adcbe20b6dd710b5bc5f981a1", - "version":"v1.1", - "tags":[ - "Retro" - ] } ] }, @@ -1668,32 +1640,6 @@ "Retro", "SNES" ] - }, - { - "name":"_", - "music":"T44", - "special":"T44", - "score":0, - "author":"MrFluffy", - "since_version":"0.1", - "sha1":"54a1621fef2b137adcbe20b6dd710b5bc5f981a1", - "version":"v1.1", - "tags":[ - "Retro" - ] - }, - { - "name":"_", - "music":"T44", - "special":"T44", - "score":0, - "author":"MrFluffy", - "since_version":"0.1", - "sha1":"54a1621fef2b137adcbe20b6dd710b5bc5f981a1", - "version":"v1.1", - "tags":[ - "Retro" - ] } ] }, @@ -1793,32 +1739,6 @@ "Retro", "RMX" ] - }, - { - "name":"_", - "music":"T44", - "special":"T44", - "score":0, - "author":"MrFluffy", - "since_version":"0.1", - "sha1":"54a1621fef2b137adcbe20b6dd710b5bc5f981a1", - "version":"v1.1", - "tags":[ - "Retro" - ] - }, - { - "name":"_", - "music":"T44", - "special":"T44", - "score":0, - "author":"MrFluffy", - "since_version":"0.1", - "sha1":"54a1621fef2b137adcbe20b6dd710b5bc5f981a1", - "version":"v1.1", - "tags":[ - "Retro" - ] } ] }, diff --git a/source/CT_Config.py b/source/CT_Config.py index e638add..0744d91 100644 --- a/source/CT_Config.py +++ b/source/CT_Config.py @@ -31,9 +31,9 @@ def get_cup_icon(cup_id: [str, int], font_path: str = "./file/SuperMario256.ttf" class CT_Config: def __init__(self, version: str = None, name: str = None, nickname: str = None, - game_variant: str = None, gui=None, region: int = None, cheat_region: int = None, + game_variant: str = "01", gui=None, region: int = None, cheat_region: int = None, tags_color: dict = {}, prefix_list: list = [], suffix_list: list = [], - tag_retro: str = "Retro"): + tag_retro: str = "Retro", default_track: Track = None): self.version = version self.name = name @@ -51,6 +51,7 @@ class CT_Config: self.prefix_list = prefix_list self.suffix_list = suffix_list self.tag_retro = tag_retro + self.default_track = default_track def add_ordered_cup(self, cup: Cup) -> None: """ @@ -104,7 +105,7 @@ class CT_Config: for i, track in enumerate(track_list): if i % 4 == 0: - _actual_cup = Cup(name=f"TL{i // 4}") + _actual_cup = Cup(name=f"TL{i // 4}", default_track=self.default_track) unordered_cups.append(_actual_cup) _actual_cup.tracks[i % 4] = track @@ -153,35 +154,35 @@ class CT_Config: self.unordered_tracks = [] self.all_tracks = [] - for cup_json in ctconfig_json["cup"]: # tracks with defined order - cup = Cup() + # default track + self.default_track = Track() + if "default_track" in ctconfig_json: self.default_track.load_from_json(ctconfig_json["default_track"]) + + for cup_json in ctconfig_json["cup"] if "cup" in ctconfig_json else []: # tracks with defined order + cup = Cup(default_track=self.default_track) cup.load_from_json(cup_json) if not cup.locked: # locked cup are not useful (they are original track or random track) self.ordered_cups.append(cup) self.all_tracks.extend(cup.tracks) - for track_json in ctconfig_json["tracks_list"]: # unordered tracks + for track_json in ctconfig_json["tracks_list"] if "tracks_list" in ctconfig_json else []: # unordered tracks track = Track() track.load_from_json(track_json) self.unordered_tracks.append(track) self.all_tracks.append(track) - self.version = ctconfig_json["version"] + self.version = ctconfig_json.get("version") self.all_version = set() - for track in self.all_tracks: - self.all_version.add(track.since_version) + for track in self.all_tracks: self.all_version.add(track.since_version) self.all_version = sorted(self.all_version) - self.name = ctconfig_json["name"] + if "name" in ctconfig_json: self.name = ctconfig_json["name"] self.nickname = ctconfig_json["nickname"] if "nickname" in ctconfig_json else self.name - self.game_variant = ctconfig_json["game_variant"] if "game_variant" in ctconfig_json else "01" - self.region = ctconfig_json.get("region") - self.cheat_region = ctconfig_json.get("cheat_region") - self.tags_color = ctconfig_json.get("tags_color") - self.prefix_list = ctconfig_json.get("prefix_list") - self.suffix_list = ctconfig_json.get("suffix_list") - self.tag_retro = ctconfig_json.get("tag_retro") + if "game_variant" in ctconfig_json: self.game_variant = ctconfig_json["game_variant"] + + for param in ["region", "cheat_region", "tags_color", "prefix_list", "suffix_list", "tag_retro"]: + setattr(self, param, ctconfig_json.get(param)) def search_tracks(self, values_list=False, not_value=False, only_unordered_track=False, **kwargs) -> list: """ diff --git a/source/Cup.py b/source/Cup.py index b172d6e..67b65a0 100644 --- a/source/Cup.py +++ b/source/Cup.py @@ -2,7 +2,9 @@ from .Track import Track class Cup: - def __init__(self, name: str = None, + def __init__(self, + default_track: Track, + name: str = None, track1: Track = None, track2: Track = None, track3: Track = None, @@ -24,10 +26,10 @@ class Cup: self.name = name self.locked = locked self.tracks = [ - track1 if track1 else Track(), - track2 if track2 else Track(), - track3 if track3 else Track(), - track4 if track4 else Track() + track1 if track1 else default_track.copy(), + track2 if track2 else default_track.copy(), + track3 if track3 else default_track.copy(), + track4 if track4 else default_track.copy() ] def get_ctfile_cup(self, *args, **kwargs) -> str: diff --git a/source/Game.py b/source/Game.py index d872ffe..0ef4a7a 100644 --- a/source/Game.py +++ b/source/Game.py @@ -285,14 +285,14 @@ class Game: """ self.gui.progress(statut=self.gui.translate("Patch lecode.bin"), add=1) - shutil.copytree("./file/Track/", self.path + "/files/Race/Course/", dirs_exist_ok=True) lpar_path = "./file/lpar-debug.txt" if self.gui.boolvar_use_debug_mode.get() else "./file/lpar-default.txt" lec.patch( lecode_file=f"./file/lecode-{self.region}.bin", dest_lecode_file=f"{self.path}/files/rel/lecode-{self.region}.bin", game_track_path=f"{self.path}/files/Race/Course/", - move_track_path=f"{self.path}/files/Race/Course/", + copy_track_paths=[f"./file/Track/"], + move_track_paths=[f"{self.path}/files/Race/Course/"], ctfile_path="./file/CTFILE.txt", lpar_path=lpar_path, ) @@ -320,7 +320,7 @@ class Game: self.install_patch_lecode() self.install_convert_rom() - messagebox.showinfo(self.gui.translate("End"), self.gui.translate("The mod has been installed !")) + messagebox.showinfo(self.gui.translate("End"), self.gui.translate("The mod have been installed !")) except: self.gui.log_error() @@ -336,6 +336,49 @@ class Game: if os.path.exists(auto_add_dir): shutil.rmtree(auto_add_dir) szs.autoadd(path=self.path, dest_dir=auto_add_dir) + def create_extra_common(self, bmgtracks: str, extra_common_path: str = "./file/ExtraCommon.txt") -> None: + """ + this function create an "extra common" file : it contain modification about the original tracks name + (the color modification) and allow the modification to be applied by overwritting the normal common + file by this one. + :param bmgtracks: bmg containing the track list + :param extra_common_path: destination path to the extra common file + """ + + with open(extra_common_path, "w", encoding="utf8") as f: + f.write("#BMG\n") + + for bmgtrack in bmgtracks.split("\n"): + if "=" in bmgtrack: + + prefix = "" + track_name = bmgtrack[bmgtrack.find("= ") + 2:] + + if "T" in bmgtrack[:bmgtrack.find("=")]: + start_track_id: int = bmgtrack.find("T") # index where the bmg track definition start + track_id = bmgtrack[start_track_id:start_track_id + 3] + if track_id[1] in "1234": # if the track is a original track from the wii + prefix = "Wii" + if prefix in self.ctconfig.tags_color: + prefix = "\\\\c{" + self.ctconfig.tags_color[prefix] + "}" + prefix + "\\\\c{off}" + prefix += " " + + elif track_id[1] in "5678": # if the track is a retro track from the original game + prefix, *track_name = track_name.split(" ") + track_name = " ".join(track_name) + if prefix in self.ctconfig.tags_color: + prefix = "\\\\c{" + self.ctconfig.tags_color[prefix] + "}" + prefix + "\\\\c{off}" + prefix += " " + + track_id = hex(bmgID_track_move[track_id])[2:] + + else: # Arena + start_track_id = bmgtrack.find("U") + 1 # index where the bmg arena definition start + track_id = bmgtrack[start_track_id:start_track_id + 2] + track_id = hex((int(track_id[0]) - 1) * 5 + (int(track_id[1]) - 1) + 0x7020)[2:] + + f.write(f" {track_id}\t= {prefix}{track_name}\n") + def patch_bmg(self, gamefile: str) -> None: """ Patch bmg file (text file) @@ -362,38 +405,7 @@ class Game: bmgtracks = bmg.cat(path=gamefile, subfile=".d/message/Common.bmg") # Common.bmg bmgtracks = bmgtracks[bmgtracks.find(trackheader) + len(trackheader):bmgtracks.find(trackend)] - def create_extra_common(extra_common_path: str = "./file/ExtraCommon.txt") -> None: - """ - this function create an "extra common" file : it contain modification about the original tracks name - (the color modification) and allow the modification to be applied by overwritting the normal common - file by this one. - :param extra_common_path: destination path to the extra common file - """ - with open(extra_common_path, "w", encoding="utf8") as f: - f.write("#BMG\n") - - for bmgtrack in bmgtracks.split("\n"): - if "=" in bmgtrack: - - prefix = "" - track_name = bmgtrack[bmgtrack.find("= ") + 2:] - - if "T" in bmgtrack[:bmgtrack.find("=")]: - start_track_id: int = bmgtrack.find("T") # index where the bmg track definition start - track_id = bmgtrack[start_track_id:start_track_id + 3] - if track_id[1] in "1234": # if the track is a original track from the wii - prefix = trackname_color["Wii"] + " " - elif track_id[1] in "5678": # if the track is a retro track from the original game - for color_prefix, rep_color_prefix in trackname_color.items(): # color retro track prefix - track_name = track_name.replace(color_prefix, rep_color_prefix) - track_id = hex(bmgID_track_move[track_id])[2:] - else: # Arena - start_track_id = bmgtrack.find("U") + 1 # index where the bmg arena definition start - track_id = bmgtrack[start_track_id:start_track_id + 2] - track_id = hex((int(track_id[0]) - 1) * 5 + (int(track_id[1]) - 1) + 0x7020)[2:] - - f.write(f" {track_id}\t= {prefix}{track_name}\n") - create_extra_common() + self.create_extra_common(bmgtracks=bmgtracks, extra_common_path="./file/ExtraCommon.txt") bmgcommon = ctc.patch_bmg(ctfile="./file/CTFILE.txt", bmgs=[gamefile + ".d/message/Common.bmg", "./file/ExtraCommon.txt"]) diff --git a/source/Track.py b/source/Track.py index 3a6bedf..56540db 100644 --- a/source/Track.py +++ b/source/Track.py @@ -23,7 +23,7 @@ def check_file_sha1(file: str, excepted_sha1: str) -> int: class Track: - def __init__(self, name: str = "_", author: str = "Nintendo", special: str = "T11", music: str = "T11", + def __init__(self, name: str = "", author: str = "Nintendo", special: str = "T11", music: str = "T11", sha1: str = None, since_version: str = None, score: int = 0, warning: int = 0, note: str = "", track_wu8_dir: str = "./file/Track-WU8/", track_szs_dir: str = "./file/Track/", track_version: str = None, tags: list = [], *args, **kwargs): @@ -180,8 +180,7 @@ class Track: if prefix: prefix = "\\\\c{"+ct_config.tags_color[prefix]+"}"+prefix+"\\\\c{off} " if suffix: suffix = " (\\\\c{"+ct_config.tags_color[suffix]+"}"+suffix+"\\\\c{off})" - name = (star_prefix + star_text + star_suffix + prefix + hl_prefix + self.name + hl_suffix + suffix) - name = name.replace("_", " ") + name = star_prefix + star_text + star_suffix + prefix + hl_prefix + self.name + hl_suffix + suffix return name def get_track_name(self, ct_config, *args, **kwargs) -> str: @@ -191,7 +190,7 @@ class Track: """ return self.select_tag(ct_config.prefix_list) + self.name + self.select_tag(ct_config.suffix_list) - def load_from_json(self, track_json: dict) -> None: + def load_from_json(self, track_json: dict): """ load the track from a dictionary :param track_json: track's dictionary @@ -202,5 +201,13 @@ class Track: self.file_wu8 = f"{self.track_wu8_dir}/{self.sha1}.wu8" self.file_szs = f"{self.track_szs_dir}/{self.sha1}.szs" + return self + def create_from_track_file(self, track_file: str) -> None: pass + + def copy(self): + new = type(self)() + for k, v in self.__dict__.items(): + setattr(new, k, v) + return new diff --git a/source/definition.py b/source/definition.py index d8f51db..7f228df 100644 --- a/source/definition.py +++ b/source/definition.py @@ -19,8 +19,6 @@ get_nodir = lambda file: file.replace("\\", "/").split("/")[-1] get_dir = lambda file: "/".join(file.replace("\\", "/").split("/")[:-1]) get_extension = lambda file: file.split(".")[-1] -EMPTY_TRACK = ' T T44; T44; 0x00; "_"; ""; "-"\n' - bmgID_track_move = { "T11": 0x7008, "T12": 0x7001, "T13": 0x7002, "T14": 0x7004, "T21": 0x7000, "T22": 0x7005, "T23": 0x7006, "T24": 0x7007, @@ -33,57 +31,6 @@ bmgID_track_move = { "T81": 0x7018, "T82": 0x7016, "T83": 0x7013, "T84": 0x701c, } -trackname_color = { - "MSRDS": "\\\\c{green}MSRDS\\\\c{off}", - "CTR": "\\\\c{YOR4}CTR\\\\c{off}", - "CTTR": "\\\\c{YOR5}CTTR\\\\c{off}", - "CNR": "\\\\c{YOR5}CNR\\\\c{off}", - "DKR": "\\\\c{YOR6}DKR\\\\c{off}", - "LCP": "\\\\c{green}LCP\\\\c{off}", - "LEGO-R": "\\\\c{red2}LEGO-R\\\\c{off}", - "MP9": "\\\\c{YOR0}MP9\\\\c{off}", - "MSUSA": "\\\\c{green}MSUSA\\\\c{off}", - "FZMV": "\\\\c{YOR2}FZMV\\\\c{off}", - "KAR": "\\\\c{green}KAR\\\\c{off}", - "KO": "\\\\c{YOR5}KO\\\\c{off}", - "FZ": "\\\\c{YOR2}FZ\\\\c{off}", - "RV": "\\\\c{white}RV\\\\c{off}", - "SADX": "\\\\c{blue2}SADX\\\\c{off}", - "SCR": "\\\\c{YOR2}SCR\\\\c{off}", - "SH": "\\\\c{red}SH\\\\c{off}", - "SM64": "\\\\c{red1}SM64\\\\c{off}", - "SMB1": "\\\\c{red2}SMB1\\\\c{off}", - "SMB2": "\\\\c{red3}SMB2\\\\c{off}", - "SSBB": "\\\\c{red4}SSBB\\\\c{off}", - "SMS": "\\\\c{YOR6}SMS\\\\c{off}", - "SMO": "\\\\c{YOR7}SMO\\\\c{off}", - "VVVVVV": "\\\\c{blue}VVVVVV\\\\c{off}", - "WF": "\\\\c{green}WF\\\\c{off}", - "WP": "\\\\c{yellow}WP\\\\c{off}", - "Zelda OoT": "\\\\c{green}Zelda OoT\\\\c{off}", - "Zelda TP": "\\\\c{green}Zelda TP\\\\c{off}", - "Zelda WW": "\\\\c{green}Zelda WW\\\\c{off}", - "PMWR": "\\\\c{yellow}PMWR\\\\c{off}", - "SHR": "\\\\c{green}SHR\\\\c{off}", - "SK64": "\\\\c{green}SK64\\\\c{off}", - "SMG": "\\\\c{red2}SMG\\\\c{off}", - "Spyro 1": "\\\\c{blue}Spyro 1\\\\c{off}", - - "Wii U": "\\\\c{red4}Wii U\\\\c{off}", - "Wii": "\\\\c{blue}Wii\\\\c{off}", - - "3DS": "\\\\c{YOR3}3DS\\\\c{off}", - "DS": "\\\\c{white}DS\\\\c{off}", - "GCN": "\\\\c{blue2}GCN\\\\c{off}", - "GBA": "\\\\c{blue1}GBA\\\\c{off}", - "N64": "\\\\c{red}N64\\\\c{off}", - "SNES": "\\\\c{green}SNES\\\\c{off}", - "RMX": "\\\\c{YOR4}RMX\\\\c{off}", - "MKT": "\\\\c{YOR5}MKT\\\\c{off}", - "GP": "\\\\c{YOR6}GP\\\\c{off}", - - "Boost": "\\\\c{YOR3}Boost\\\\c{off}", -} region_id_to_name = { "J": "JAP", @@ -106,7 +53,6 @@ gamelang_to_lang = { "K": "en", # korean - no translation } - warning_color = { 1: "\\\\c{YOR4}", 2: "\\\\c{YOR6}", diff --git a/source/wszst/lec.py b/source/wszst/lec.py index a2c9c4e..417d1e3 100644 --- a/source/wszst/lec.py +++ b/source/wszst/lec.py @@ -8,7 +8,8 @@ WLECT_PATH = "./tools/szs/wlect" def patch(lecode_file: str = f"./file/lecode-PAL.bin", dest_lecode_file: str = f"./files/rel/lecode-PAL.bin", game_track_path: str = "./files/Race/Course/", - move_track_path: str = "./files/Race/Course/", + copy_track_paths: list = [], + move_track_paths: list = [], ctfile_path: str = "./file/CTFILE.txt", lpar_path: str = "./file/lpar-default.txt") -> None: """ @@ -16,11 +17,17 @@ def patch(lecode_file: str = f"./file/lecode-PAL.bin", :param lecode_file: path to the lecode file :param dest_lecode_file: destination of the lecode file :param game_track_path: subpath to the track directory - :param move_track_path: where are stored the track to move + :param copy_track_paths: where are stored the track to move :param ctfile_path: where is the ctfile (track and cup definition) :param lpar_path: where is the lpar_path (game modification like speed, speedometer, ...) """ - subprocess.run( - [WLECT_PATH, "patch", lecode_file, "-od", dest_lecode_file, "--track-dir", game_track_path, - "--move-tracks", move_track_path, "--le-define", ctfile_path, "--lpar", lpar_path, "--overwrite"], - creationflags=subprocess.CREATE_NO_WINDOW, check=True, stdout=subprocess.PIPE) + cmd = [ + WLECT_PATH, "patch", lecode_file, "-od", dest_lecode_file, "--track-dir", game_track_path, + "--le-define", ctfile_path, "--lpar", lpar_path, "--overwrite" + ] + for path in copy_track_paths: + cmd.extend(["--copy-tracks", path]) + for path in move_track_paths: + cmd.extend(["--move-tracks", path]) + + subprocess.run(cmd, creationflags=subprocess.CREATE_NO_WINDOW, check=True, stdout=subprocess.PIPE) diff --git a/translation.json b/translation.json index 64f955f..7d0b9f2 100644 --- a/translation.json +++ b/translation.json @@ -43,7 +43,7 @@ "Converting to": "Conversion en", "Changing game's ID": "Changement de l'ID du jeu", "End": "Fin", - "The mod has been installed !": "L'installation est terminé !", + "The mod have been installed !": "L'installation est terminé !", "An error occured": "Une erreur est survenue", "Patching text": "Patch des textes", "Converting files": "Conversion des fichiers",