def get_dungeonstatic_diff(mod_pos: Array) -> dict: try: base_pos = oead.byml.from_binary( util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" / "Static.smubin").read_bytes()))["StartPos"] except FileNotFoundError: base_pos = oead.byml.from_binary( util.get_nested_file_bytes( f"{util.get_game_file('Pack/Bootup.pack')}//Map/CDungeon/Static.smubin" ))["StartPos"] base_dungeons = [str(dungeon["Map"]) for dungeon in base_pos] diffs = {} for dungeon in mod_pos: if str(dungeon["Map"]) not in base_dungeons: diffs[dungeon["Map"]] = dungeon else: base_dungeon = base_pos[base_dungeons.index(str(dungeon["Map"]))] if dungeon["Rotate"] != base_dungeon["Rotate"]: diffs[dungeon["Map"]] = {"Rotate": dungeon["Rotate"]} if dungeon["Translate"] != base_dungeon["Translate"]: if dungeon["Map"] not in diffs: diffs[dungeon["Map"]] = {} diffs[dungeon["Map"]]["Translate"] = dungeon["Translate"] return diffs
def get_dungeonstatic_diff(mod_pos: Array) -> dict: try: base_pos = oead.byml.from_binary( util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" / "Static.smubin").read_bytes()))["StartPos"] except FileNotFoundError: base_pos = oead.byml.from_binary( util.get_nested_file_bytes( f"{util.get_game_file('Pack/Bootup.pack')}//Map/CDungeon/Static.smubin" ))["StartPos"] base_names = [ f"{str(spawn_point['Map'])}___{str(spawn_point['PosName'])}" for spawn_point in base_pos ] diffs = {} for mod_spawn in mod_pos: spawn_name = f"{str(mod_spawn['Map'])}___{str(mod_spawn['PosName'])}" if spawn_name not in base_names: diffs[spawn_name] = mod_spawn else: base_spawn = base_pos[base_names.index(spawn_name)] diff = {} if mod_spawn["Rotate"] != base_spawn["Rotate"]: diff["Rotate"] = mod_spawn["Rotate"] if mod_spawn["Translate"] != base_spawn["Translate"]: diff["Translate"] = mod_spawn["Translate"] if diff: diffs[spawn_name] = diff return diffs
def generate_diff(self, mod_dir: Path, modded_files: List[Union[str, Path]]): mod_data: bytes stock_data: bytes if (mod_dir / util.get_dlc_path() / ("0010" if util.get_settings("wiiu") else "") / STATIC_PATH) in modded_files: mod_data = (mod_dir / util.get_dlc_path() / ("0010" if util.get_settings("wiiu") else "") / STATIC_PATH).read_bytes() stock_data = util.get_game_file("Map/MainField/Static.smubin", aoc=True).read_bytes() elif (f"{util.get_content_path()}/Pack/Bootup.pack//Map/MainField/Static.smubin" ) in modded_files: mod_data = util.get_nested_file_bytes( (str(mod_dir / util.get_content_path() / "Pack" / "Bootup.pack") + "//Map/MainField/Static.smubin"), unyaz=False, ) stock_data = util.get_nested_file_bytes( (str(util.get_game_file("Pack/Bootup.pack")) + "//Map/MainField/Static.smubin"), unyaz=False, ) else: return None stock_static: Hash = oead.byml.from_binary(util.decompress(stock_data)) mod_static: Hash = oead.byml.from_binary(util.decompress(mod_data)) diffs = Hash() for cat in stock_static: if cat not in stock_static: continue stock_items = {get_id(item): item for item in stock_static[cat]} mod_items = {get_id(item): item for item in mod_static[cat]} diffs[cat] = Hash({ item_id: item for item_id, item in mod_items.items() if item_id not in stock_items or item != stock_items[item_id] }) for item_id, item in [(i1, i2) for i1, i2 in stock_items.items() if i1 not in mod_items]: item["remove"] = True diffs[cat][item_id] = item if not diffs[cat]: del diffs[cat] return diffs
def merge_dungeonstatic(diffs: dict = None): """Merges all changes to the CDungeon Static.smubin""" if not diffs: try: (util.get_master_modpack_dir() / "logs" / "dungeonstatic.smubin").unlink() except: pass return try: new_static = oead.byml.from_binary( util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" / "Static.smubin").read_bytes())) except FileNotFoundError: new_static = oead.byml.from_binary( util.get_nested_file_bytes( f"{util.get_game_file('Pack/Bootup.pack')}//Map/CDungeon/Static.smubin" )) base_names = [ f"{str(spawn_point['Map'])}___{str(spawn_point['PosName'])}" for spawn_point in new_static["StartPos"] ] for spawn_name, diff in diffs.items(): if "___" not in spawn_name: spawn_name = f"{spawn_name}___Entrance_1" if spawn_name not in base_names: new_static["StartPos"].append(diff) else: for key, value in diff.items(): new_static["StartPos"][base_names.index( spawn_name)][key] = value data = util.compress( oead.byml.to_binary(new_static, big_endian=util.get_settings("wiiu"))) try: util.get_aoc_dir() output_static = (util.get_master_modpack_dir() / util.get_dlc_path() / ("0010" if util.get_settings("wiiu") else "") / "Map" / "CDungeon" / "Static.smubin") except FileNotFoundError: output_static = util.get_master_modpack_dir( ) / "logs" / "dungeonstatic.smubin" util.inject_file_into_sarc( "Map/CDungeon/Static.smubin", data, "Pack/Bootup.pack", create_sarc=True, ) output_static.parent.mkdir(parents=True, exist_ok=True) output_static.write_bytes(data)
def perform_merge(self): diffs = self.consolidate_diffs(self.get_all_diffs()) output: Path static_data: Path try: util.get_aoc_dir() output = (util.get_master_modpack_dir() / util.get_dlc_path() / ("0010" if util.get_settings("wiiu") else "") / STATIC_PATH) static_data = util.get_game_file("Map/MainField/Static.smubin", aoc=True).read_bytes() except FileNotFoundError: output = util.get_master_modpack_dir( ) / "logs" / "mainstatic.smubin" static_data = util.get_nested_file_bytes( (str(util.get_game_file("Pack/Bootup.pack")) + "//Map/MainField/Static.smubin"), unyaz=False, ) if not diffs: try: output.unlink() except: pass return stock_static = oead.byml.from_binary(util.decompress(static_data)) merged = Hash() for cat in stock_static: if cat in diffs: items = {get_id(item): item for item in stock_static[cat]} util.dict_merge(items, diffs[cat]) merged[cat] = Array([ item for _, item in items.items() if "remove" not in item ]) else: merged[cat] = stock_static[cat] data = util.compress( oead.byml.to_binary(merged, big_endian=util.get_settings("wiiu"))) output.parent.mkdir(parents=True, exist_ok=True) output.write_bytes(data) if "mainstatic" in str(output): util.inject_file_into_sarc( "Map/MainField/Static.smubin", data, "Pack/Bootup.pack", create_sarc=True, )
def generate_diff(self, mod_dir: Path, modded_files: List[Union[Path, str]]): dstatic_path = (mod_dir / util.get_dlc_path() / "0010" / "Map" / "CDungeon" / "Static.smubin") if dstatic_path.exists(): print("Logging changes to shrine entry coordinates...") return get_dungeonstatic_diff( oead.byml.from_binary( util.decompress(dstatic_path.read_bytes()))["StartPos"]) elif (f"{util.get_content_path()}/Pack/Bootup.pack//Map/CDungeon/Static.smubin" in modded_files): return get_dungeonstatic_diff( oead.byml.from_binary( util.get_nested_file_bytes( f"{mod_dir}/{util.get_content_path()}/Pack/Bootup.pack//Map/CDungeon/Static.smubin" ))["StartPos"]) else: return {}