示例#1
0
    def Enable(self) -> None:
        def WillowClientDisableLoadingMovie(caller: unrealsdk.UObject,
                                            function: unrealsdk.UFunction,
                                            params: unrealsdk.FStruct) -> bool:
            for clas, handler in self.CLASS_HANDLER_MAP.items():
                for obj in unrealsdk.FindAll(clas):
                    if obj not in self.MenuObjects:
                        handler(obj)
            return True

        unrealsdk.RegisterHook(
            "WillowGame.WillowPlayerController.WillowClientDisableLoadingMovie",
            self.Name, WillowClientDisableLoadingMovie)

        # If you're re-enabling then we can exit right here, the rest of this is non-reversible
        if len(self.MenuObjects) > 0:
            return

        # Objects we load here will still be alive for all the FindAll commands, we don't need to
        #  parse them yet
        for package, objects in self.FORCE_LOAD.items():
            unrealsdk.LoadPackage(package)
            for obj_name in objects:
                obj = unrealsdk.FindObject(obj_name[0], obj_name[1])
                if obj is None:
                    unrealsdk.Log(
                        f"[{self.Name}] Unable to find object '{obj_name[1]}'")

                unrealsdk.KeepAlive(obj)

        # Do our inital parse over everything, saving what we can access
        for clas, handler in self.CLASS_HANDLER_MAP.items():
            for obj in unrealsdk.FindAll(clas):
                self.MenuObjects.add(obj)
                handler(obj)
示例#2
0
    def Enable(self) -> None:
        def CreateWeaponScopeMovie(caller: unrealsdk.UObject,
                                   function: unrealsdk.UFunction,
                                   params: unrealsdk.FStruct) -> bool:
            for clas, handler in self.CLASS_HANDLER_MAP.items():
                for obj in unrealsdk.FindAll(clas):
                    if obj not in self.MenuObjects:
                        handler(obj)
            return True

        unrealsdk.RegisterHook("WillowGame.WillowHUD.CreateWeaponScopeMovie",
                               "ItemLevelUncapper", CreateWeaponScopeMovie)

        # If you're re-enabling then we can exit right here, the rest of this is non-reversible
        if len(self.MenuObjects) > 0:
            return

        # Objects we load here will still be alive for all the FindAll commands, we don't need to
        #  parse them yet
        for package, objects in self.FORCE_LOAD.items():
            unrealsdk.LoadPackage(package)
            for obj in objects:
                unrealsdk.KeepAlive(unrealsdk.FindObject(obj[0], obj[1]))

        # Do our inital parse over everything, saving what we can access
        for clas, handler in self.CLASS_HANDLER_MAP.items():
            for obj in unrealsdk.FindAll(clas):
                self.MenuObjects.add(obj)
                handler(obj)
示例#3
0
 def load_packages(self, packages):
     """
     Load the specified packages, then wait for the given delay
     """
     for pkg in packages:
         unrealsdk.LoadPackage(pkg)
     self.setNextDelay(self.pkgload_delay)
示例#4
0
def handle_load_package(args: argparse.Namespace) -> None:
    upks = fnmatch.filter(all_upks, args.package)
    if len(upks) <= 0:
        unrealsdk.Log(f"Could not find package '{args.package}'!")
    elif len(upks) > 10:
        unrealsdk.Log(f"'{args.package}' matches more than 10 packages!")
    else:
        for package in upks:
            unrealsdk.LoadPackage(package)
示例#5
0
 def ForceLoad(self):
     # Needed for the cool Katana moves
     unrealsdk.LoadPackage("GD_Assassin_Streaming_SF")
     unrealsdk.KeepAlive(
         unrealsdk.FindObject(
             "WillowAnimDefinition",
             "GD_Assassin_Hologram.SpecialMove.SpecialMove_HologramScrewAround"
         ))
     unrealsdk.KeepAlive(
         unrealsdk.FindObject("AnimSet", "Anim_Assassin.Base_Assassin"))
     # We dont want these animations to unload
     Objects = [
         "GD_NPCShared.Perches.Perch_NPC_ArmsCrossedForever:SpecialMove_PerchLoop_0",
         "GD_NPCShared.Perches.Perch_NPC_BangOnSomething:SpecialMove_PerchLoop_0",
         "GD_NPCShared.Perches.Perch_NPC_BarrelSitForever:SpecialMove_PerchLoop_0",
         "GD_NPCShared.Perches.Perch_NPC_ChairSitForever:SpecialMove_PerchLoop_0",
         "GD_NPCShared.Perches.Perch_NPC_DartsHit:SpecialMove_PerchLoop_0",
         "GD_NPCShared.Perches.Perch_NPC_KickGround:SpecialMove_PerchLoop_0",
         "GD_NPCShared.Perches.Perch_NPC_LeanOnCounterForever:SpecialMove_PerchLoop_0",
         "GD_NPCShared.Perches.Perch_NPC_LeanOnWallNonRandom:SpecialMove_PerchLoop_0",
         "GD_NPCShared.Perches.Perch_NPC_LookAtGround:SpecialMove_PerchLoop_0",
         "GD_NPCShared.Perches.Perch_NPC_PeerUnder:SpecialMove_PerchLoop_0",
         "GD_Moxxi.Perches.Perch_Moxxi_Dance:SpecialMove_PerchLoop_0",
         "GD_Moxxi.Perches.Perch_Moxxi_WipeBar:SpecialMove_PerchLoop_0",
         "GD_TannisNPC.Perches.Perch_Tannis_HandsOnHips:SpecialMove_PerchLoop_0",
         "GD_BrickNPC.Perches.Perch_Brick_Pushups:SpecialMove_PerchLoop_0"
     ]
     unrealsdk.LoadPackage("SanctuaryAir_Dynamic")
     for Object in Objects:
         x = unrealsdk.FindObject("SpecialMove_PerchLoop", Object)
         unrealsdk.KeepAlive(x)
     # This are our Particles that can be used
     Particles = [
         "FX_ENV_Misc.Particles.Part_Confetti",
         "FX_Distillery.Particles.PS_Hearts_Looping_8-Bit",
         "FX_CHAR_Merc.Particles.Part_Merc_MoneyShotImpact",
         "FX_Distillery.Particles.PS_Nast_Drunk_Thresher"
     ]
     unrealsdk.LoadPackage("Distillery_Dynamic")
     unrealsdk.LoadPackage("Distillery_Mission")
     unrealsdk.LoadPackage("GD_Mercenary_Streaming_SF")
     for Particle in Particles:
         x = unrealsdk.FindObject("ParticleSystem", Particle)
         unrealsdk.KeepAlive(x)
示例#6
0
    def __init__(self) -> None:
        unrealsdk.LoadPackage("GD_Mercenary_Streaming_SF")
        self.NumWeapObj = unrealsdk.FindObject(
            "NumberWeaponsEquippedExpressionEvaluator",
            "GD_Mercenary_Skills.ActionSkill.Skill_Gunzerking:ExpressionTree_0.NumberWeaponsEquippedExpressionEvaluator_0"
        )
        unrealsdk.KeepAlive(self.NumWeapObj)

        if self.NumWeapObj is None:
            del self.SettingsInputs["Enter"]

        self.WeaponMap = {}
示例#7
0
    def PreloadPackages(self):
        packages = [
            "GD_Assassin_Streaming_SF",
            "GD_Mercenary_Streaming_SF",
            "GD_Siren_Streaming_SF",
            "GD_Lilac_Psycho_Streaming_SF",
            "GD_Tulip_Mechro_Streaming_SF",
            "GD_Soldier_Streaming_SF",
        ]

        for package in packages:
            unrealsdk.LoadPackage(package)
示例#8
0
 def keep_loaded(self) -> None:
     """
     Small helper function for easily keeping objects loaded.
     "#" defines what Package to load, "-" are comments.
     Searches for any text file with the custom ending ".loaded" and tries to
      keep the objects listet in the file loaded.
     """
     for file in self.l_files:
         with open(file, "r") as TemplateFile:
             for line in TemplateFile:
                 if not line.split() or line[0] == "-":
                     continue
                 elif line[0] == "#":
                     package = line[1:].strip()
                     unrealsdk.LoadPackage(package)
                 else:
                     unrealsdk.KeepAlive(unrealsdk.FindObject("Object", line.strip()))
示例#9
0
    def __init__(self) -> None:
        # Hopefully I can remove this in a future SDK update
        self.Author += "\nVersion: " + str(self.Version)  # type: ignore

        unrealsdk.LoadPackage("GD_Mercenary_Streaming_SF")
        obj = unrealsdk.FindObject(
            "NumberWeaponsEquippedExpressionEvaluator",
            "GD_Mercenary_Skills.ActionSkill.Skill_Gunzerking:ExpressionTree_0.NumberWeaponsEquippedExpressionEvaluator_0"
        )

        # Almost certainly because you tried to load this in TPS
        if obj is None:
            unrealsdk.Log(
                "[Onezerker] Unable to find NumberWeaponsEquiped object, assuming loaded in TPS"
            )
            self.Name = f"<font color='#ff0000'>{self.Name}</font>"  # type: ignore
            self.Description += "\n<font color='#ff0000'>Incompatible with TPS</font>"  # type: ignore
            self.SettingsInputs = {}
            self.NumWeapObj = None
        else:
            unrealsdk.KeepAlive(obj)
            self.NumWeapObj = obj

        self.WeaponMap = {}
示例#10
0
    def on_end_load(self, curr_map: str) -> None:
        if logging.logger.level in logging.logger.levels[:2]:
            self.load_files()

        # After the map loads, we want to check our loaded file data for things to spawn.
        random_spawn_group = {}
        add_to_group = None
        in_class = None
        region_game_stage: int = set_iterpreter.get_current_region_stage()
        b_skip_to_next: bool = False
        b_skip_once: bool = False
        for line in self.file_data:  # type: str
            try:
                if line[0] == "/":  # we now want to check if it's the map we just loaded in
                    if line[1:].strip().lower() == curr_map or line[1:].strip(
                    ).lower() == "none":
                        b_skip_to_next = False
                        continue
                    else:
                        b_skip_to_next = True
                elif line[0] == "-" or b_skip_to_next:
                    continue

                elif line[0] == "!":
                    unrealsdk.LoadPackage(line[1:].strip())
                elif line[
                        0] == "#":  # We now have the class of the objects that we will spawn
                    in_class: str
                    in_class = line[1:].lstrip()
                elif line[0] == "+":  # check the given conditions
                    __conditional_ret = set_iterpreter.check_conditions(
                        line[1:])
                    if isinstance(__conditional_ret, bool):
                        b_skip_once = __conditional_ret
                    else:
                        add_to_group = __conditional_ret
                else:  # This should now be the "<Object> <Location> <Rotation> [level offset]
                    if b_skip_once:  # earlier given conditions failed, skip this
                        b_skip_once = False
                        continue

                    if add_to_group is not None:
                        random_spawn_group.setdefault(
                            in_class, {add_to_group: []})[add_to_group].append(
                                (line, region_game_stage))
                        add_to_group = None  # we always only want to add the next line to the group
                    else:  # if not added to randomGroup just exec now
                        if in_class.lower() == "WeaponBalanceDefinition".lower() \
                                or in_class.lower() == "InventoryBalanceDefinition".lower():
                            self.spawn_item_from_balance_definition(
                                in_class, line, region_game_stage)
                        elif in_class.lower(
                        ) == "AIPawnBalanceDefinition".lower():
                            self.spawn_ai_pawn(line, region_game_stage)
                        elif in_class.lower() == "InteractiveObjectBalanceDefinition".lower() \
                                or in_class.lower() == "InteractiveObjectDefinition".lower():
                            self.spawn_interactive_object(
                                line, region_game_stage)
            except Exception as e:
                logging.logger.error(repr(e))
                logging.logger.error(
                    f"Please check the following line in your .spawn file:\n-> {line}"
                )

        for cls, group in random_spawn_group.items():
            for g_name, choice_of in group.items():
                l: Tuple[str, int] = random.choice(choice_of)
                try:
                    if cls.lower() == "WeaponBalanceDefinition".lower() \
                            or cls.lower() == "InventoryBalanceDefinition".lower():
                        self.spawn_item_from_balance_definition(cls, *l)
                    elif cls.lower() == "AIPawnBalanceDefinition".lower():
                        self.spawn_ai_pawn(*l)
                    elif in_class.lower() == "InteractiveObjectBalanceDefinition".lower() \
                            or in_class.lower() == "InteractiveObjectDefinition".lower():
                        self.spawn_interactive_object(*l)
                except Exception as e:
                    logging.logger.error(repr(e))
                    logging.logger.error(
                        f"Please check the following line in your .spawn file:\n-> {l}"
                    )
示例#11
0
    def Enable(self) -> None:
        unrealsdk.LoadPackage("GD_Mercenary_Streaming_SF")
        self.NumWeapObj = unrealsdk.FindObject(
            "NumberWeaponsEquippedExpressionEvaluator",
            "GD_Mercenary_Skills.ActionSkill.Skill_Gunzerking:ExpressionTree_0.NumberWeaponsEquippedExpressionEvaluator_0"
        )
        unrealsdk.KeepAlive(self.NumWeapObj)

        if self.NumWeapObj is None:
            unrealsdk.Log(f"[{self.Name}] Didn't load correctly, not enabling")
            self.SettingsInputPressed("Disable")
            return

        self.NumWeapObj.NumberOfWeapons = 1

        def OnActionSkillEnded(caller: unrealsdk.UObject,
                               function: unrealsdk.UFunction,
                               params: unrealsdk.FStruct) -> bool:
            if caller.MyWillowPC != unrealsdk.GetEngine().GamePlayers[0].Actor:
                return True

            self.WeaponMap = {}
            return True

        def EquipInitialWeapons(caller: unrealsdk.UObject,
                                function: unrealsdk.UFunction,
                                params: unrealsdk.FStruct) -> bool:
            if caller.MyWillowPC != unrealsdk.GetEngine().GamePlayers[0].Actor:
                return True

            if caller.MyWillowPawn is None:
                return True
            weap = caller.MyWillowPawn.Weapon
            if weap is None:
                return False

            # This is the only real bit of the function we overwrite
            weap_alt = self.DupeWeapon(weap)
            caller.MyWillowPawn.OffHandWeapon = weap_alt

            caller.MyWillowPawn.InvManager.SetCurrentWeapon(weap, False)
            caller.MyWillowPawn.InvManager.SetCurrentWeapon(weap_alt, True)
            weap.RefillClip()
            weap_alt.RefillClip()
            if caller.MyWillowPC.bInSprintState:
                caller.SetTimer(
                    min(weap.GetEquipTime(), weap_alt.GetEquipTime()), False,
                    "SprintTransition")
            caller.SetLeftSideControl()

            return False

        # Called when switching weapons by scrolling/controller quick switch
        def NextWeapon(caller: unrealsdk.UObject,
                       function: unrealsdk.UFunction,
                       params: unrealsdk.FStruct) -> bool:
            return ScrollWeapons(caller, True)

        def PrevWeapon(caller: unrealsdk.UObject,
                       function: unrealsdk.UFunction,
                       params: unrealsdk.FStruct) -> bool:
            return ScrollWeapons(caller, False)

        def ScrollWeapons(caller: unrealsdk.UObject, next: bool) -> bool:
            pawn = unrealsdk.GetEngine().GamePlayers[0].Actor.Pawn
            if caller.Owner != pawn:
                return True

            if pawn.MyActionSkill is None:
                return True
            if pawn.MyActionSkill.Class.Name != "DualWieldActionSkill":
                return True

            weapon_list = [None, None, None, None]
            weapon = pawn.InvManager.InventoryChain
            while weapon is not None:
                weapon_list[weapon.QuickSelectSlot - 1] = weapon
                weapon = weapon.Inventory

            # Don't think this could actually happen but to be safe
            if weapon_list.count(None) >= 4:
                return True

            index = pawn.Weapon.QuickSelectSlot - 1
            if next:
                index = (index + 1) % 4
                while weapon_list[index] is None:
                    index = (index + 1) % 4
            else:
                index = (index - 1) % 4
                while weapon_list[index] is None:
                    index = (index - 1) % 4
            weapon = weapon_list[index]

            weap_alt = self.DupeWeapon(weapon)
            pawn.InvManager.SetCurrentWeapon(weapon, False)
            pawn.InvManager.SetCurrentWeapon(weap_alt, True)
            pawn.MyActionSkill.SetOffHandCrosshair(weap_alt)

            return False

        # Called when switching weapons (while gunzerking) using the number keys/dpad
        def SwitchToWeapon(caller: unrealsdk.UObject,
                           function: unrealsdk.UFunction,
                           params: unrealsdk.FStruct) -> bool:
            if caller.MyWillowPC != unrealsdk.GetEngine().GamePlayers[0].Actor:
                return True

            if params.NewWeapon != caller.MyWillowPawn.Weapon:
                caller.MyWillowPawn.InvManager.SetCurrentWeapon(
                    params.NewWeapon, False)

                weap_alt = self.DupeWeapon(params.NewWeapon)
                caller.MyWillowPawn.InvManager.SetCurrentWeapon(weap_alt, True)
                caller.SetOffHandCrosshair(weap_alt)

            return False

        # Called on exiting menus
        def BringWeaponsUpAfterPutDown(caller: unrealsdk.UObject,
                                       function: unrealsdk.UFunction,
                                       params: unrealsdk.FStruct) -> bool:
            if caller.MyWillowPC != unrealsdk.GetEngine().GamePlayers[0].Actor:
                return True

            weapon = caller.MyWillowPawn.InvManager.InventoryChain
            while weapon is not None:
                if weapon.QuickSelectSlot == params.MainHandWeaponSlot:
                    break
                weapon = weapon.Inventory

            # If you dropped the equiped slot default to the start of the list - not sure if other
            #  behaviour might be better?
            if weapon is None:
                weapon = caller.MyWillowPawn.InvManager.InventoryChain
                # If you dropped all weapons just let the game handle it
                if weapon is None:
                    return True

            caller.ForceRefreshSkills()
            caller.ClientBringWeaponsUpAfterPutDown(weapon,
                                                    self.DupeWeapon(weapon))

            return False

        def ApplyBehaviorToContext(caller: unrealsdk.UObject,
                                   function: unrealsdk.UFunction,
                                   params: unrealsdk.FStruct) -> bool:
            """
            The only `Behavior_RefillWeapon` is auto loader - this is only called when it triggers

            All the other hooks guarentee that items only get duplicated if they're from the local
             player, so we can assume that if an item is in the map, the local player owns it.

            Auto loader only reloads unequipped weapons, so we can also guarentee that you will have
             to go through one of the other hooks to switch back to it.
            Because of this we can just remove the object from the map, it'll get recreated.
            For some reason just replicating the `.RefillClip()` call doesn't work.

            Now this might break if you do inventory merging, but really that's kinda on you.
            """
            if params.ContextObject in self.WeaponMap:
                del self.WeaponMap[params.ContextObject]
            return True

        # These two are identical except for the bit where I re-call the hooked function
        # I wish there was a neat way to merge them
        def TossInventory(caller: unrealsdk.UObject,
                          function: unrealsdk.UFunction,
                          params: unrealsdk.FStruct) -> bool:
            pawn = unrealsdk.GetEngine().GamePlayers[0].Actor.Pawn
            if caller != pawn:
                return True
            if pawn.MyActionSkill is None:
                return True
            if pawn.MyActionSkill.Class.Name != "DualWieldActionSkill":
                return True

            unrealsdk.DoInjectedCallNext()
            caller.TossInventory(
                params.Inv, (params.ForceVelocity.X, params.ForceVelocity.Y,
                             params.ForceVelocity.Z))

            if pawn.Weapon is not None:
                pawn.InvManager.SetCurrentWeapon(self.DupeWeapon(pawn.Weapon),
                                                 True)

            return False

        def EndClimbLadder(caller: unrealsdk.UObject,
                           function: unrealsdk.UFunction,
                           params: unrealsdk.FStruct) -> bool:
            pawn = unrealsdk.GetEngine().GamePlayers[0].Actor.Pawn
            if caller != pawn:
                return True
            if pawn.MyActionSkill is None:
                return True
            if pawn.MyActionSkill.Class.Name != "DualWieldActionSkill":
                return True

            unrealsdk.DoInjectedCallNext()
            caller.EndClimbLadder(params.OldLadder)

            if pawn.Weapon is not None:
                pawn.InvManager.SetCurrentWeapon(self.DupeWeapon(pawn.Weapon),
                                                 True)

            return False

        """
        Called whenever anyone:
         1. Picks up a weapon while having empty slots available
         2. Equips a new weapon in your inventory screen
         3. Force equip a new weapon
        Very conviniently, in case 3 alone the paramater "bDoNotActivate" is false
        """

        def ClientGivenTo(caller: unrealsdk.UObject,
                          function: unrealsdk.UFunction,
                          params: unrealsdk.FStruct) -> bool:
            pawn = unrealsdk.GetEngine().GamePlayers[0].Actor.Pawn
            if params.NewOwner != pawn:
                return True
            if params.bDoNotActivate:
                return True
            if pawn.MyActionSkill is None:
                return True
            if pawn.MyActionSkill.Class.Name != "DualWieldActionSkill":
                return True

            pawn.InvManager.SetCurrentWeapon(self.DupeWeapon(caller), True)
            return True

        unrealsdk.RegisterHook(
            "WillowGame.DualWieldActionSkill.OnActionSkillEnded", self.Name,
            OnActionSkillEnded)
        unrealsdk.RegisterHook(
            "WillowGame.DualWieldActionSkill.EquipInitialWeapons", self.Name,
            EquipInitialWeapons)
        unrealsdk.RegisterHook("WillowGame.WillowInventoryManager.NextWeapon",
                               self.Name, NextWeapon)
        unrealsdk.RegisterHook("WillowGame.WillowInventoryManager.PrevWeapon",
                               self.Name, PrevWeapon)
        unrealsdk.RegisterHook(
            "WillowGame.DualWieldActionSkill.SwitchToWeapon", self.Name,
            SwitchToWeapon)
        unrealsdk.RegisterHook(
            "WillowGame.DualWieldActionSkill.BringWeaponsUpAfterPutDown",
            self.Name, BringWeaponsUpAfterPutDown)
        unrealsdk.RegisterHook(
            "WillowGame.Behavior_RefillWeapon.ApplyBehaviorToContext",
            self.Name, ApplyBehaviorToContext)
        unrealsdk.RegisterHook("WillowGame.WillowPawn.TossInventory",
                               self.Name, TossInventory)
        unrealsdk.RegisterHook("WillowGame.WillowPlayerPawn.EndClimbLadder",
                               self.Name, EndClimbLadder)
        unrealsdk.RegisterHook("Engine.Weapon.ClientGivenTo", self.Name,
                               ClientGivenTo)