Пример #1
0
def get_named_pio(shop: ParameterIO, shop_type: str) -> ParameterIO:
    named_pio = ParameterIO()
    shop_keys = EXT_PARAMS[shop_type]

    for table_key, table_obj in shop.objects.items():
        if table_key.hash == oead.aamp.Name("Header").hash:
            tablenames = ParameterObject()
            named_pio.objects["TableNames"] = ParameterObject()
            tablenum = table_obj.params["TableNum"].v
            for idx in range(1, tablenum + 1):
                table_name = str(table_obj.params[f"Table{idx:02}"].v)
                tablenames.params[oead.aamp.Name(table_name)] = table_name
            named_pio.objects["TableNames"] = tablenames
            continue
        table_max = table_obj.params["ColumnNum"].v
        table_obj_new = ParameterList()
        for idx in range(1, table_max + 1):
            if shop_type == "brecipe":
                entry_key = "%02d" % idx
            elif shop_type == "bshop":
                entry_key = "%03d" % idx
            else:
                raise KeyError(shop_type)
            entry_value = ParameterObject()
            try:
                for curr_shop_key in shop_keys:
                    no_shop_key = curr_shop_key + entry_key
                    entry_value.params[curr_shop_key] = table_obj.params[
                        no_shop_key]
            except KeyError:
                continue
            table_obj_new.objects[str(
                entry_value.params["ItemName"].v)] = entry_value
        named_pio.lists[table_key] = table_obj_new
    return named_pio
Пример #2
0
 def diff_addres(addres: ParameterList,
                 ref_addres: ParameterList) -> ParameterList:
     diff = ParameterList()
     bfres: List[str] = []
     for _, pobj in addres.objects.items():
         bfres.append(pobj.params["Anim"].v)
     for _, ref_pobj in ref_addres.objects.items():
         try:
             bfres.remove(ref_pobj.params["Anim"].v)
         except ValueError:
             continue
     for i, v in enumerate(bfres):
         key = f"AddRes_{i}"
         diff.objects[key] = ParameterObject()
         diff.objects[key].params["Anim"] = Parameter(v)
     return diff
Пример #3
0
def make_shopdata(pio: ParameterIO) -> ParameterList:
    shopdata = ParameterList()
    tables: List[Parameter] = [
        str(t.v) for _, t in pio.objects["Header"].params.items() if is_string(t)
    ]
    if not tables:
        raise InvalidDataError("A shop file is invalid: has no tables")
    shopdata.objects["TableNames"] = ParameterObject()
    for table in tables:
        table_plist = ParameterList()
        shopdata.objects["TableNames"].params[table] = Parameter(FixedSafeString64(table))
        table_hash = crc32(table.encode())
        items: Dict[str, List[int]] = {
            str(p.v): [k.hash, i]
            for i, (k, p) in enumerate(pio.objects[table_hash].params.items())
            if is_string(p)
        }
        for item in items.keys():
            item_no = int(
                name_table.get_name(items[item][0], items[item][1], table_hash).replace(
                    "ItemName", ""
                )
            )
            item_obj = ParameterObject()
            for shop_key in shop_keys:
                try:
                    item_obj.params[shop_key] = pio.objects[table_hash].params[
                        f"{shop_key}{item_no:03d}"
                    ]
                except KeyError:
                    raise KeyError(f"{shop_key}{item_no:03d}")
            table_plist.objects[item] = item_obj
        if table_plist.objects:
            shopdata.lists[table_hash] = table_plist
    return shopdata
Пример #4
0
 def merge_addres(plist: ParameterList, other_plist: ParameterList):
     bfres: List[str] = []
     for _, pobj in plist.objects.items():
         bfres.append(str(pobj.params["Anim"].v))
     for _, other_pobj in other_plist.objects.items():
         bfres.append(str(other_pobj.params["Anim"].v))
     for i, v in enumerate(list(dict.fromkeys(bfres))):
         key = f"AddRes_{i}"
         if not key in plist.objects:
             plist.objects[key] = ParameterObject()
         plist.objects[key].params["Anim"] = Parameter(FixedSafeString64(v))
Пример #5
0
 def diff_asdefine(asdef: ParameterList,
                   ref_asdef: ParameterList) -> ParameterList:
     diff = ParameterList()
     defs: Dict[str, str] = {}
     for _, pobj in asdef.objects.items():
         defs[str(pobj.params["Name"].v)] = str(pobj.params["Filename"].v)
     for _, ref_pobj in ref_asdef.objects.items():
         try:
             if (defs[str(ref_pobj.params["Name"].v)] == str(
                     ref_pobj.params["Filename"].v)):
                 defs.pop(str(ref_pobj.params["Name"].v))
         except (ValueError, KeyError):
             continue
     for i, (k, v) in enumerate(defs.items()):
         key = f"ASDefine_{i}"
         diff.objects[key] = ParameterObject()
         diff.objects[key].params["Name"] = Parameter(FixedSafeString64(k))
         diff.objects[key].params["Filename"] = Parameter(
             FixedSafeString64(v))
     return diff
Пример #6
0
def gen_diffs(ref: ParameterIO, mod: ParameterIO) -> ParameterList:
    diffs = ParameterList()
    tablenames_key = oead.aamp.Name("TableNames")
    # generate additions, modifications
    additions = nand_pio_into_plist(ref, mod)
    if len(additions.lists) != 0:
        additions.objects[tablenames_key] = ParameterObject()
        add_names = additions.objects[tablenames_key]
        mod_names = mod.objects[tablenames_key]
        for table_key in additions.lists.keys():
            add_names.params[table_key] = mod_names.params[table_key]
    diffs.lists["Additions"] = additions
    # generate deletions
    removals = nand_pio_into_plist(mod, ref)
    if len(removals.lists) != 0:
        removals.objects[tablenames_key] = ParameterObject()
        rem_names = removals.objects[tablenames_key]
        ref_names = ref.objects[tablenames_key]
        for table_key in removals.lists.keys():
            rem_names.params[table_key] = ref_names.params[table_key]
    diffs.lists["Removals"] = removals
    return diffs
Пример #7
0
 def merge_asdefine(plist: ParameterList, other_plist: ParameterList):
     defs: Dict[str, str] = {}
     for _, pobj in plist.objects.items():
         defs[str(pobj.params["Name"].v)] = pobj.params["Filename"].v
     for _, other_pobj in other_plist.objects.items():
         defs[str(
             other_pobj.params["Name"].v)] = other_pobj.params["Filename"].v
     for i, (k, v) in enumerate(defs.items()):
         key = f"ASDefine_{i}"
         if not key in plist.objects:
             plist.objects[key] = ParameterObject()
         plist.objects[key].params["Name"] = Parameter(FixedSafeString64(k))
         plist.objects[key].params["Filename"] = Parameter(v)
Пример #8
0
def get_shop_diff(pio: ParameterIO, ref_pio: ParameterIO) -> ParameterList:
    def diff_plist(
        plist: Union[ParameterList, ParameterIO],
        ref_plist: Union[ParameterIO, ParameterList],
    ) -> ParameterList:
        diff = ParameterList()
        for key, sublist in plist.lists.items():
            if key not in ref_plist.lists:
                diff.lists[key] = sublist
            elif ref_plist.lists[key] != sublist:
                diff.lists[key] = diff_plist(sublist, ref_plist.lists[key])
        for key, obj in plist.objects.items():
            if key not in ref_plist.objects:
                diff.objects[key] = obj
            elif ref_plist.objects[key] != obj:
                diff.objects[key] = diff_pobj(obj, ref_plist.objects[key])
        return diff

    def diff_pobj(pobj: ParameterObject,
                  ref_pobj: ParameterObject) -> ParameterObject:
        diff = ParameterObject()
        for param, value in pobj.params.items():
            if param not in ref_pobj.params or ref_pobj.params[param] != value:
                diff.params[param] = value
        return diff

    diff = ParameterList()
    shopdata = make_shopdata(pio)
    ref_shopdata = make_shopdata(ref_pio)
    adds = diff_plist(shopdata, ref_shopdata)
    if adds:
        diff.lists["Additions"] = adds
    rems = diff_plist(ref_shopdata, shopdata)
    if rems:
        subtract_plists(rems, adds)
        diff.lists["Removals"] = rems
    return diff
Пример #9
0
 def diff_plist(
     plist: Union[ParameterList, ParameterIO],
     ref_plist: Union[ParameterIO, ParameterList],
 ) -> ParameterList:
     diff = ParameterList()
     for key, sublist in plist.lists.items():
         if key.hash == 2777926231:  # "AddReses"
             diff.lists[key] = diff_addres(sublist, ref_plist.lists[key])
         elif key.hash == 3752287078:  # "ASDefines"
             diff.lists[key] = diff_asdefine(sublist, ref_plist.lists[key])
         elif key.hash == 3305786543:  # "CFDefines"
             diff.lists[key] = sublist
         elif key not in ref_plist.lists:
             diff.lists[key] = sublist
         elif ref_plist.lists[key] != sublist:
             diff.lists[key] = diff_plist(sublist, ref_plist.lists[key])
     for key, obj in plist.objects.items():
         if key not in ref_plist.objects:
             diff.objects[key] = obj
         elif ref_plist.objects[key] != obj:
             diff.objects[key] = diff_pobj(obj, ref_plist.objects[key])
     return diff
Пример #10
0
 def diff_plist(
     plist: Union[ParameterList, ParameterIO],
     ref_plist: Union[ParameterIO, ParameterList],
 ) -> ParameterList:
     diff = ParameterList()
     for key, sublist in plist.lists.items():
         if key not in ref_plist.lists:
             diff.lists[key] = sublist
         elif ref_plist.lists[key] != sublist:
             diff.lists[key] = diff_plist(sublist, ref_plist.lists[key])
     for key, obj in plist.objects.items():
         if key not in ref_plist.objects:
             diff.objects[key] = obj
         elif ref_plist.objects[key] != obj:
             diff.objects[key] = diff_pobj(obj, ref_plist.objects[key])
     return diff
Пример #11
0
 def _to_plist(self, obj) -> ParameterList:
     plist = ParameterList()
     if isinstance(obj, ParameterList):
         return obj
     if "lists" in obj and obj["lists"]:
         for name, content in obj["lists"].items():
             if name.isnumeric():
                 plist.lists[int(name)] = self._to_plist(content)
             else:
                 plist.lists[name] = self._to_plist(content)
     if "objects" in obj and obj["objects"]:
         for name, content in obj["objects"].items():
             if content["params"]:
                 if name.isnumeric():
                     plist.objects[int(name)] = self._to_pobj(content)
                 else:
                     plist.objects[name] = self._to_pobj(content)
     return plist
Пример #12
0
def nand_pio_into_plist(
    ref: Union[ParameterIO, ParameterList],
    mod: Union[ParameterIO, ParameterList],
) -> ParameterList:
    res_plist = ParameterList()
    for key, plist in mod.lists.items():
        if key not in ref.lists:
            res_plist.lists[key] = plist
        else:
            processed_list = nand_pio_into_plist(ref.lists[key], plist)
            if processed_list.lists or processed_list.objects:
                res_plist.lists[key] = processed_list
    for key, pobj in mod.objects.items():
        if key not in ref.objects:
            res_plist.objects[key] = pobj
        else:
            ref_pobj = ref.objects[key]
            res_plist.objects[key] = ref_pobj
            for param_key, param_value in pobj.params.items():
                if param_key not in ref_pobj.params:
                    continue  # new keys are garbage the game can't use, skip them
                if not param_value.v == ref_pobj.params[param_key].v:
                    res_plist.objects[key].params[param_key] = param_value
    return res_plist
Пример #13
0
    def generate_pio(self) -> ParameterIO:
        from zlib import crc32

        pio = ParameterIO.from_binary(self._aiprog.to_binary())
        if self._ais:
            ais_list = ParameterList()
            for idx, ai in enumerate(self._ais):
                ais_list.lists[f"AI_{idx}"] = ai
            pio.lists["AI"] = ais_list
        if self._actions:
            actions_list = ParameterList()
            for idx, action in enumerate(self._actions):
                actions_list.lists[f"Action_{idx}"] = action
            pio.lists["Action"] = actions_list
        if self._behaviors:
            behaviors_list = ParameterList()
            for idx, behavior in enumerate(self._behaviors):
                behaviors_list.lists[f"Behavior_{idx}"] = behavior
            pio.lists["Behavior"] = behaviors_list
        if self._queries:
            queries_list = ParameterList()
            for idx, query in enumerate(self._queries):
                queries_list.lists[f"Query_{idx}"] = query
            pio.lists["Query"] = queries_list
        self._aiprog = pio
        return pio