Beispiel #1
0
    def bank_on_close(self, caller: unrealsdk.UObject) -> bool:
        if caller.MaxSlots == 4:
            read_f = open(self.STASH_PATH, "r")
            save_json = json.load(read_f)
        elif caller.MaxSlots == 3:  # the grinder in TPS
            return True
        else:
            read_f = open(self.LOAD_PATH, "r")
            save_json = json.load(read_f)
        read_f.close()
        wweapon_class = unrealsdk.FindClass("WillowWeapon")

        bank = {"Weapons": list(), "Items": list()}
        for chest_data in caller.TheChest:
            if not chest_data.Inventory:
                break

            mark: int = chest_data.Inventory.Mark
            if chest_data.Inventory.Class == wweapon_class:
                bank["Weapons"].append(get_weapon_from_data(chest_data.Inventory.DefinitionData, mark=mark))
            else:
                bank["Items"].append(get_item_from_data(chest_data.Inventory.DefinitionData, mark=mark))
            chest_data.Inventory.Destroy()
            chest_data.Inventory = None

        bl2tools.get_player_controller().OnChestClosing(caller)
        caller.ChestIsOpen = False

        with open(self.LOAD_PATH if caller.MaxSlots != 4 else self.STASH_PATH, "w") as f:
            if caller.MaxSlots == 4:
                json.dump(bank, f, indent=4)
            else:
                save_json["Bank"] = bank
                json.dump(save_json, f, indent=4)
        return False
Beispiel #2
0
    def bank_on_open(self, caller: unrealsdk.UObject) -> bool:
        if caller.MaxSlots == 4:
            caller.ChestSlots = self.stash_size
            # we opened the stash
            read_f = open(self.STASH_PATH, "r")
            bank = json.load(read_f)
        elif caller.MaxSlots == 3:  # the grinder in TPS
            return True
        else:
            read_f = open(self.LOAD_PATH, "r")
            bank = json.load(read_f).get("Bank", dict())
        read_f.close()
        owner = bl2tools.get_player_controller().Pawn

        static_wweapon: unrealsdk.UObject = unrealsdk.FindAll("WillowWeapon")[0]
        static_witem: unrealsdk.UObject = unrealsdk.FindAll("WillowItem")[0]

        bank_things: list = []
        for weapon in bank.get("Weapons", list()):
            wpn_data, mark = load_weapon_data(weapon)
            new_weapon: unrealsdk.UObject = static_wweapon.CreateWeaponFromDef(wpn_data, owner, True)
            new_weapon.Mark = mark

            bank_things.append((new_weapon.Class, tuple(), new_weapon))

        for item in bank.get("Items", list()):
            item_data, mark = load_item_data(item)
            new_item: unrealsdk.UObject = static_witem.CreateItemFromDef(item_data, owner, 1, True)
            new_item.Mark = mark

            bank_things.append((new_item.Class, tuple(), new_item))

        caller.TheChest = bank_things
        caller.ChestIsOpen = True
        return False
Beispiel #3
0
def Open(caller: unrealsdk.UObject, function: unrealsdk.UFunction,
         params: unrealsdk.FStruct) -> bool:
    if caller.ChestIsOpen:
        return False
    # We'll set this later cause we re-call this function and don't want it to early exit

    PC = caller.Outer.GetOwningPlayerController()
    if PC is None:
        return False
    inv_manager = PC.GetPawnInventoryManager()

    save_manager: SaveManager
    if caller == inv_manager.TheBank:
        save_manager = SaveManager(PC.SaveGameName, True)
    elif caller == inv_manager.TheStash:
        save_manager = SaveManager(STASH_NAME)
    else:
        unrealsdk.Log("[SanitySaver] Could not identify opened container!")
        return False
    save_manager.load()

    PC.OnChestOpened(caller)
    """
    This is a bit of a mess.

    All items are stored as serial number structs, which contain a static array. This means we can't
    ever pass one of these structs, or even whole the list, from Python back into UnrealScript.

    So how do we convert these to a useable format?
    `WillowInventory.CreateInventoryFromSerialNumber`

    We still can't call this ourself though, we have to get something else to. And unfortuantly it
    happens to only be called by the very function we have to overwrite to remove the sanity check
    in the first place.

    The only way we can actually extract item references is by hooking the sanity check functions.
    Hooking them means we have to force all items to get sanity checked and be destroyed, but
    luckily there's handy functions to recreate them  from the definition with our changes.
    """

    inv_list = []

    def ValidateItemWeaponDefinition(caller: unrealsdk.UObject,
                                     function: unrealsdk.UFunction,
                                     params: unrealsdk.FStruct) -> bool:
        is_weapon = function.Name == "ValidateWeaponDefinition"
        inv_list.append(
            (save_manager.apply_replacements(params.DefinitionData,
                                             is_weapon), is_weapon))
        return False

    unrealsdk.RunHook("WillowGame.WillowPlayerController.OnChestOpened",
                      __name__, Block)
    unrealsdk.RunHook(
        "WillowGame.WillowPlayerController.ValidateItemDefinition", __name__,
        ValidateItemWeaponDefinition)
    unrealsdk.RunHook(
        "WillowGame.WillowPlayerController.ValidateWeaponDefinition", __name__,
        ValidateItemWeaponDefinition)

    caller.Open()

    unrealsdk.RemoveHook("WillowGame.WillowPlayerController.OnChestOpened",
                         __name__)
    unrealsdk.RemoveHook(
        "WillowGame.WillowPlayerController.ValidateItemDefinition", __name__)
    unrealsdk.RemoveHook(
        "WillowGame.WillowPlayerController.ValidateWeaponDefinition", __name__)

    save_manager.write()
    caller.ChestIsOpen = True

    for def_data, is_weapon in inv_list:
        if is_weapon:
            caller.AddWeaponFromDef(def_data, False, False)
        else:
            caller.AddItemFromDef(def_data, False, False)
    """
    Technically we should get this function to return True, which should be doable by blocking more
    function calls and caching some stuff, but nothing that calls this function relies on that value
    anyway.
    """
    return False