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 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 merge_dungeonstatic(diffs: dict = None): """Merges all changes to the CDungeon Static.smubin""" if not diffs: return new_static = oead.byml.from_binary( util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" / "Static.smubin").read_bytes())) base_dungeons = [str(dungeon["Map"]) for dungeon in new_static["StartPos"]] for dungeon, diff in diffs.items(): if dungeon not in base_dungeons: new_static["StartPos"].append(diff) else: for key, value in diff.items(): new_static["StartPos"][base_dungeons.index( dungeon)][key] = value output_static = (util.get_master_modpack_dir() / util.get_dlc_path() / ("0010" if util.get_settings("wiiu") else "") / "Map" / "CDungeon" / "Static.smubin") output_static.parent.mkdir(parents=True, exist_ok=True) output_static.write_bytes( util.compress( oead.byml.to_binary(new_static, big_endian=util.get_settings("wiiu"))))
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 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 get_dungeonstatic_diff(file: Path) -> dict: base_pos = oead.byml.from_binary( util.decompress((util.get_aoc_dir() / "Map" / "CDungeon" / "Static.smubin").read_bytes()))["StartPos"] mod_pos = oead.byml.from_binary(util.decompress( file.read_bytes()))["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 is_bootup_injector(): try: util.get_aoc_dir() return False except FileNotFoundError: return True
def get_stock_map(map_unit: Union[Map, tuple], force_vanilla: bool = False) -> Hash: if isinstance(map_unit, tuple): map_unit = Map(*map_unit) try: aoc_dir = util.get_aoc_dir() except FileNotFoundError: force_vanilla = True map_bytes = None map_path: Union[str, Path] if force_vanilla: try: if util.get_settings("wiiu"): update = util.get_update_dir() else: update = util.get_game_dir() map_path = ( update / "Map/MainField/" f"{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin" ) if not map_path.exists(): map_path = ( util.get_game_dir() / "Map/MainField/" f"{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin" ) map_bytes = map_path.read_bytes() except FileNotFoundError: try: title_pack = oead.Sarc( util.get_game_file("Pack/TitleBG.pack").read_bytes()) map_bytes = title_pack.get_file( f"Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}" ".smubin").data except (KeyError, RuntimeError, AttributeError): map_bytes = None else: if (aoc_dir / "Pack" / "AocMainField.pack").exists(): try: map_pack = oead.Sarc( (aoc_dir / "Pack" / "AocMainField.pack").read_bytes()) map_bytes = map_pack.get_file( f"Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}" ".smubin").data except (KeyError, RuntimeError, AttributeError): map_bytes = None if not map_bytes: map_path = f"Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin" try: map_bytes = util.get_game_file(map_path, aoc=True).read_bytes() except FileNotFoundError: try: map_bytes = util.get_game_file(map_path).read_bytes() except FileNotFoundError: try: title_pack = oead.Sarc( util.get_game_file( "Pack/TitleBG.pack").read_bytes()) map_bytes = bytes( title_pack.get_file( f"Map/MainField/{map_unit.section}/" f"{map_unit.section}_{map_unit.type}.smubin"). data) except (KeyError, RuntimeError, AttributeError): map_bytes = None if not map_bytes: raise FileNotFoundError( f"The stock map file {map_unit.section}_{map_unit.type}.smubin could not be found." ) map_bytes = util.decompress(map_bytes) return oead.byml.from_binary(map_bytes)
def get_stock_map(map_unit: Union[Map, tuple], force_vanilla: bool = False) -> dict: """ Finds the most significant available map unit from the unmodded game and returns its contents as a dict. :param map: The map section and type. :type map: class:`bcml.mubin.Map` :return: Returns a dict representation of the requested map unit. :rtype: dict """ if isinstance(map_unit, tuple): map_unit = Map(*map_unit) try: aoc_dir = util.get_aoc_dir() except FileNotFoundError: force_vanilla = True map_bytes = None if force_vanilla: try: map_path = ( util.get_update_dir() / 'Map/MainField/' f'{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin' ) if not map_path.exists(): map_path = ( util.get_game_dir() / 'Map/MainField/' f'{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin' ) map_bytes = map_path.read_bytes() except FileNotFoundError: with util.get_game_file('Pack/TitleBG.pack').open('rb') \ as s_file: title_pack = sarc.read_file_and_make_sarc(s_file) if title_pack: try: map_bytes = title_pack.get_file_data( f'Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}' '.smubin').tobytes() except KeyError: map_bytes = None else: if (aoc_dir / 'Pack' / 'AocMainField.pack').exists(): with (aoc_dir / 'Pack' / 'AocMainField.pack').open('rb') as s_file: map_pack = sarc.read_file_and_make_sarc(s_file) if map_pack: try: map_bytes = map_pack.get_file_data( f'Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}' '.smubin').tobytes() except KeyError: map_bytes = None if not map_bytes: map_path = f'Map/MainField/{map_unit.section}/{map_unit.section}_{map_unit.type}.smubin' try: map_bytes = util.get_game_file(map_path, aoc=True).read_bytes() except FileNotFoundError: try: map_bytes = util.get_game_file(map_path).read_bytes() except FileNotFoundError: with util.get_game_file('Pack/TitleBG.pack').open('rb') \ as s_file: title_pack = sarc.read_file_and_make_sarc(s_file) if title_pack: try: map_bytes = title_pack.get_file_data( f'Map/MainField/{map_unit.section}/' f'{map_unit.section}_{map_unit.type}.smubin' ).tobytes() except KeyError: map_bytes = None if not map_bytes: raise FileNotFoundError( f'The stock map file {map_unit.section}_{map_unit.type}.smubin could not be found.' ) map_bytes = util.decompress(map_bytes) return byml.Byml(map_bytes).parse()