def diff_objs() -> Hash: base_hashes = [int(obj["HashId"]) for obj in base_map["Objs"]] base_links = (set() if link_del else { int(link["DestUnitHashId"]) for obj in base_map["Objs"] for link in obj.get("LinksToObj", Array()) if "LinksToObj" in obj }) mod_hashes = [int(obj["HashId"]) for obj in mod_map["Objs"]] diffs = Hash() diffs["add"] = Array([ obj for obj in mod_map["Objs"] if int(obj["HashId"]) not in base_hashes ]) diffs["mod"] = Hash({ str(obj["HashId"]): obj for obj in mod_map["Objs"] if int(obj["HashId"]) in base_hashes and obj != base_map["Objs"][base_hashes.index(int(obj["HashId"]))] }) diffs["del"] = Array([ oead.U32(h) for h in { hash_id for hash_id in base_hashes if hash_id not in {*mod_hashes, *base_links} } ] if not no_del else set()) return diffs
def diff_objs() -> Hash: base_hashes = [int(obj["HashId"]) for obj in base_map["Objs"]] mod_hashes = [int(obj["HashId"]) for obj in mod_map["Objs"]] diffs = Hash() diffs["add"] = Array([ obj for obj in mod_map["Objs"] if int(obj["HashId"]) not in base_hashes ]) diffs["mod"] = Hash({ str(obj["HashId"]): obj for obj in mod_map["Objs"] if int(obj["HashId"]) in base_hashes and obj != base_map["Objs"][base_hashes.index(int(obj["HashId"]))] }) diffs["del"] = Array([ oead.U32(h) for h in {hash_id for hash_id in base_hashes if hash_id not in mod_hashes} ]) if new_hashes: hash_map: Dict[int, int] = {} for obj in diffs["add"]: new_hash = crc32(oead.byml.to_text(obj).encode("utf8")) hash_map[obj["HashId"].v] = new_hash obj["HashId"] = oead.U32(new_hash) for obj in [*diffs["add"], *[v for k, v in diffs["mod"].items()]]: if "LinksToObj" in obj: for link in obj["LinksToObj"]: if link["DestUnitHashId"].v in hash_map: link["DestUnitHashId"] = oead.U32( hash_map[link["DestUnitHashId"].v]) return diffs
def to_Hash(self) -> Hash: r = super(F32ArrayFlag, self).to_Hash() array_one = Array() array_one.append(Hash()) array_two = Array([F32(value) for value in self._init_value]) array_one[0]["Values"] = array_two r["InitValue"] = array_one r["MaxValue"] = F32(self._max_value) r["MinValue"] = F32(self._min_value) return r
def to_Hash(self) -> Hash: r = super(String256ArrayFlag, self).to_Hash() array_one = Array() array_one.append(Hash()) # array_two = [FixedSafeString256(value) for value in self._init_value] array_two = Array(self._init_value) array_one[0]["Values"] = array_two r["InitValue"] = array_one # r["MaxValue"] = FixedSafeString256(self._max_value) r["MaxValue"] = self._max_value # r["MinValue"] = FixedSafeString256(self._min_value) r["MinValue"] = self._min_value return r
def flags_to_svdata_Array(self) -> Array: flag_list: list = [] for _, flagdict in self._store.items(): flag_list += [ flag.to_sv_Hash() for _, flag in flagdict.items() if flag.is_save and not flag.data_name in IGNORED_SAVE_FLAGS ] return Array(sorted(flag_list, key=lambda f: f["HashValue"]))
def diff_objs() -> Hash: base_hashes = [int(obj["HashId"]) for obj in base_map["Objs"]] mod_hashes = [int(obj["HashId"]) for obj in mod_map["Objs"]] diffs = Hash() diffs["add"] = Array([ obj for obj in mod_map["Objs"] if int(obj["HashId"]) not in base_hashes ]) diffs["mod"] = Hash({ str(obj["HashId"]): obj for obj in mod_map["Objs"] if int(obj["HashId"]) in base_hashes and obj != base_map["Objs"][base_hashes.index(int(obj["HashId"]))] }) diffs["del"] = Array([ oead.U32(h) for h in {hash_id for hash_id in base_hashes if hash_id not in mod_hashes} ]) return diffs
def get_map_diff(map_unit: Map, tmp_dir: Path, no_del: bool = False, link_del: bool = False) -> Hash: mod_map = get_modded_map(map_unit, tmp_dir) stock_map = True for obj in mod_map["Objs"]: str_obj = oead.byml.to_text(obj) if "IsHardModeActor" in str_obj or "AoC_HardMode_Enabled" in str_obj: stock_map = False break base_map = get_stock_map(map_unit, force_vanilla=stock_map) base_hashes = [int(obj["HashId"]) for obj in base_map["Objs"]] base_links = (set() if link_del else { int(link["DestUnitHashId"]) for obj in base_map["Objs"] for link in obj.get("LinksToObj", Array()) if "LinksToObj" in obj }) mod_hashes = [int(obj["HashId"]) for obj in mod_map["Objs"]] diffs = Hash() diffs["add"] = Array({ obj for obj in mod_map["Objs"] if int(obj["HashId"]) not in base_hashes }) diffs["mod"] = Hash({ str(obj["HashId"]): obj for obj in mod_map["Objs"] if int(obj["HashId"]) in base_hashes and obj != base_map["Objs"][base_hashes.index(int(obj["HashId"]))] }) diffs["del"] = Array({ oead.U32(hash_id) for hash_id in base_hashes if hash_id not in {*mod_hashes, *base_links} } if not no_del else set()) del mod_map del base_map del base_links del mod_hashes return "_".join(map_unit), oead.byml.to_text(diffs)
def diff_rails() -> Hash: base_hashes = [int(rail["HashId"]) for rail in base_map["Rails"]] mod_hashes = [int(rail["HashId"]) for rail in mod_map["Rails"]] diffs = Hash() diffs["add"] = Array([ rail for rail in mod_map["Rails"] if int(rail["HashId"]) not in base_hashes ]) diffs["mod"] = Hash({ str(rail["HashId"]): rail for rail in mod_map["Rails"] if int(rail["HashId"]) in base_hashes and rail != base_map["Rails"][base_hashes.index(int(rail["HashId"]))] }) diffs["del"] = Array([ oead.U32(h) for h in {hash_id for hash_id in base_hashes if hash_id not in mod_hashes} ]) 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 flags_to_bgdata_Array(self, prefix: str) -> Array: ftype = BGDATA_MAPPING[prefix] if prefix == "revival_bool_data" or prefix == "revival_s32_data": flag_list = [ flag.to_Hash() for _, flag in self._store[ftype].items() if flag.is_revival ] elif prefix == "bool_data" or prefix == "s32_data": flag_list = [ flag.to_Hash() for _, flag in self._store[ftype].items() if not flag.is_revival ] else: flag_list = [ flag.to_Hash() for _, flag in self._store[ftype].items() ] return Array(sorted(flag_list, key=lambda f: f["HashValue"]))
def consolidate_diffs(self, diffs: list): a_diffs = Hash() for mod_diff in diffs: for file, diff in mod_diff.items(): # a_map = Map(*file.split("_")) if file not in a_diffs: a_diffs[file] = Array() a_diffs[file].append(diff) c_diffs = Hash() for file, mods in a_diffs.items(): c_diffs[file] = Hash({ "Objs": Hash({ "add": Array(), "mod": Hash(), "del": Array([ oead.U32(h) for h in set([ hash_id.v for hashes in [ mod["Objs"]["del"] for mod in mods if "Objs" in mod and "del" in mod["Objs"] ] for hash_id in hashes ]) ]), }), "Rails": Hash({ "add": Array(), "mod": Hash(), "del": Array([ oead.U32(h) for h in set([ hash_id.v for hashes in [ mod["Rails"]["del"] for mod in mods if "Rails" in mod and "del" in mod["Rails"] ] for hash_id in hashes ]) ]), }), }) for mod in [m for m in mods if "Objs" in m and "mod" in m["Objs"]]: for hash_id, actor in mod["Objs"]["mod"].items(): c_diffs[file]["Objs"]["mod"][hash_id] = actor for mod in [ m for m in mods if "Rails" in m and "mod" in m["Rails"] ]: for hash_id, actor in mod["Rails"]["mod"].items(): c_diffs[file]["Rails"]["mod"][hash_id] = actor add_obj_hashes = [] add_rail_hashes = [] for mod in reversed(mods): if "add" in mod["Objs"]: for actor in mod["Objs"]["add"]: if actor["HashId"] not in add_obj_hashes: add_obj_hashes.append(actor["HashId"]) c_diffs[file]["Objs"]["add"].append(actor) if "add" in mod["Rails"]: for actor in mod["Rails"]["add"]: if actor["HashId"] not in add_rail_hashes: add_rail_hashes.append(actor["HashId"]) c_diffs[file]["Rails"]["add"].append(actor) return c_diffs
def to_Hash(self) -> Hash: r = super(Vec2ArrayFlag, self).to_Hash() vec_array = Array() vec_array.append(Hash()) vec_array[0]["Values"] = Array() for i in range(len(self._init_value)): vector = self._init_value[i] vec = Array() vec.append(F32(vector[0])) vec.append(F32(vector[1])) vec_array[0]["Values"].append(Array()) vec_array[0]["Values"][i].append(vec) r["InitValue"] = vec_array vec_array = Array() vec = Array() vec.append(F32(self._max_value[0])) vec.append(F32(self._max_value[1])) vec_array.append(vec) r["MaxValue"] = vec_array vec_array = Array() vec = Array() vec.append(F32(self._min_value[0])) vec.append(F32(self._min_value[1])) vec_array.append(vec) r["MinValue"] = vec_array return r
def to_Hash(self) -> Hash: r = super(Vec2Flag, self).to_Hash() array = Array() vec = Array() vec.append(F32(self._init_value[0])) vec.append(F32(self._init_value[1])) array.append(vec) r["InitValue"] = array array = Array() vec = Array() vec.append(F32(self._max_value[0])) vec.append(F32(self._max_value[1])) array.append(vec) r["MaxValue"] = array array = Array() vec = Array() vec.append(F32(self._min_value[0])) vec.append(F32(self._min_value[1])) array.append(vec) r["MinValue"] = array return r