def command(self, caller: unrealsdk.UObject, function: unrealsdk.UFunction, params: unrealsdk.FStruct) -> bool: args: List[str] = params.Command.split() cmd: str = args[0].strip().lower() if cmd == "exec": binaries = self.FILE_PATH while os.path.basename(binaries).lower() != "binaries": binaries = os.path.abspath(os.path.join(binaries, "..")) exec_file = os.path.join( binaries, args[1].lstrip("/").lstrip("\\")) # this is case-sensitive if not os.path.isfile(exec_file): # we could not find the file return True with open(exec_file) as fp: for line in fp: # type: str if line.lower().startswith("set") \ and unrealsdk.FindObject("MaterialInstanceConstant", line.split()[1]) is not None: try: _exec_skins(line) except Exception as e: unrealsdk.Log(e) elif cmd == "set": if len(args) >= 4: if unrealsdk.FindObject("MaterialInstanceConstant", args[1]) is not None: _exec_skins(params.Command) return True
def PlayEmote(self): # up to and including index 16 are animations only, after that come ParticleSystems if self._animation < 17: # We are going to change the animations that are played on melee to play our emotes instead SpecialMoves = [ "GD_Assassin_Streaming.Anims.WeaponAnim_Melee", "GD_Lilac_Psycho_Streaming.Anims.WeaponAnim_Melee", "GD_Mercenary_Streaming.Anims.WeaponAnim_Melee", "GD_PlayerShared.Anims.WeaponAnim_Melee_WeaponBlade", "GD_Siren_Streaming.Anims.WeaponAnim_Melee", "GD_Soldier_Streaming.Anims.WeaponAnim_Melee", "GD_Tulip_Mechro_Streaming.Anims.WeaponAnim_Melee" ] PC = self.GetPlayerController() for Move in SpecialMoves: if unrealsdk.FindObject("SpecialMove_WeaponAction", Move) != None: PC.ConsoleCommand( "set " + Move + " AnimName " + self.ChooseAnimation(), 0) PC.ConsoleCommand( "set " + Move + " EndingCondition EC_Loop", 0) # The first 2 animations are Moxxie only if self._animation in (0, 1): PC.ConsoleCommand( "set " + Move + " AnimSet AnimSet'Anim_Moxxi.Anim_Moxxi'", 0) # Index 2 is Tannis only elif self._animation == 2: PC.ConsoleCommand( "set " + Move + " AnimSet AnimSet'Anim_Tannis.Anim_Tannis'", 0) # Index 3, 4 is Brick only elif self._animation in (3, 4): PC.ConsoleCommand( "set " + Move + " AnimSet AnimSet'Anim_Brick.Anim_Brick'", 0) elif self._animation == 16: PC.ConsoleCommand( "set " + Move + " AnimSet AnimSet'Anim_Assassin.Base_Assassin'", 0) else: PC.ConsoleCommand( "set " + Move + " AnimSet AnimSet'Anim_Generic_NPC.Anim_Generic_NPC'", 0) PC.ConsoleCommand("camera 3rd", 0) PC.Behavior_Melee() else: PlayerMesh = self.GetPlayerController().Pawn.Mesh Particle = unrealsdk.FindObject("ParticleSystem", self.ChooseAnimation()) self.GetPlayerController().ConsoleCommand("camera 3rd", 0) unrealsdk.GetEngine().GetCurrentWorldInfo( ).MyEmitterPool.SpawnEmitterMeshAttachment(Particle, PlayerMesh, "head")
def OnCycle(self) -> None: allegiance = unrealsdk.FindObject( "PawnAllegiance", "GD_AI_Allegiance.Allegiance_Player") allegiance2 = unrealsdk.FindObject( "PawnAllegiance", "GD_AI_Allegiance.Allegiance_Player_NoLevel") allegiance.bForceAllOtherOpinions = self != self.OFF allegiance2.bForceAllOtherOpinions = self != self.OFF allegiance.ForcedOtherOpinion = self.Order.index(self.value) allegiance2.ForcedOtherOpinion = self.Order.index(self.value)
def RandomizeBranch(self, SkillTreeBranchDef): self.PreloadPackages() TierCountOdds = [95, 40, 80, 30, 80, 40] HasBloodlust = False HasHellborn = False for Tier in range(6): Pity = True TierLayout = [False, False, False] MaxPoints = 0 NewSkills = [] for Skill in range(3): if (self.RNG.randint(0, 100) < TierCountOdds[Tier] or Skill == 2 and Pity): if Skill == 2 and Pity: Skill = self.RNG.randint(0, 2) Pity = False TierLayout[Skill] = True SkillDefNum = self.RNG.randint(0, len(self.ValidSkills) - 1) SkillDefName = self.ValidSkills.pop(SkillDefNum) SkillDef = unrealsdk.FindObject("SkillDefinition", SkillDefName) MaxPoints += SkillDef.MaxGrade NewSkills.append(SkillDef) HasHellborn = HasHellborn or "Hellborn" in SkillDef.GetFullName( ) if not HasBloodlust and SkillDef.GetName() in [ "BloodfilledGuns", "BloodyTwitch", ]: HasBloodlust = True self.ValidSkills += self.BloodlustSkills if SkillDef.GetName() == "Anarchy": self.ValidSkills += self.AnarchySkills if HasBloodlust: NewSkills.append( unrealsdk.FindObject( "SkillDefinition", "GD_Lilac_Skills_Bloodlust.Skills._Bloodlust")) if HasHellborn: NewSkills.append( unrealsdk.FindObject( "SkillDefinition", "GD_Lilac_Skills_Hellborn.Skills.FireStatusDetector", )) NewSkills.append( unrealsdk.FindObject( "SkillDefinition", "GD_Lilac_Skills_Hellborn.Skills.AppliedStatusEffectListener", )) SkillTreeBranchDef.Layout.Tiers[Tier].bCellIsOccupied = TierLayout SkillTreeBranchDef.Tiers[Tier].Skills = NewSkills SkillTreeBranchDef.Tiers[Tier].PointsToUnlockNextTier = min( MaxPoints, 5)
def OnCycle(self) -> None: allegiance = unrealsdk.FindObject( "PawnAllegiance", "GD_AI_Allegiance.Allegiance_Player") allegiance2 = unrealsdk.FindObject( "PawnAllegiance", "GD_AI_Allegiance.Allegiance_Player_NoLevel") allegiance.bForceAllOtherOpinions = self.CurrentValue != PassiveMode.OFF allegiance2.bForceAllOtherOpinions = self.CurrentValue != PassiveMode.OFF allegiance.ForcedOtherOpinion = self.AllValues.index(self.CurrentValue) allegiance2.ForcedOtherOpinion = self.AllValues.index( self.CurrentValue)
def set_cmd(line: str) -> None: pattern = re.compile(r"^\s*(set)\s+(\S+)\s+(\S+)\s+\((.*)\)", re.IGNORECASE) # simple array of objects obj = unrealsdk.FindObject("Object", line.split()[1]) if not obj: logging.logger.error(f"Could not find Object: {line}") return re_line = re.match(pattern, line) if re_line: setattr(unrealsdk.FindObject("Object", re_line[2]), re_line[3], [ unrealsdk.FindObject("Object", x.strip()) for x in re_line[4].split(",") ]) else: try: attributes = line.split()[2].split(".") val = unrealsdk.FindObject( "Object", line.split()[3]) # assume our val is an object if not val: try: val = float(line.split()[3]) # assume it's a float except ValueError: # obviously not a float nor object val = line.split()[3] if val.lower() == "true": val = True elif val.lower() == "false": val = False elif val.lower() == "none": val = None while len(attributes) > 1: attribute = attributes.pop(0) if "[" in attribute and "]" in attribute: index = int(attribute[attribute.find("[") + 1:attribute.find("]")]) obj = getattr(obj, attribute[:attribute.find("[")])[index] else: obj = getattr(obj, attribute) if "[" in attributes[0] and "]" in attributes[0]: attribute = attributes[0] index = int(attribute[attribute.find("[") + 1:attribute.find("]")]) obj = getattr(obj, attribute[:attribute.find("[")]) obj[index] = val else: setattr(obj, attributes[0], val) except IndexError: logging.logger.error(f"IndexError in line:\n->{line}") except Exception as e: logging.logger.error(e) logging.logger.error( f"Could not set using following statement: {line}")
def execute(self) -> None: """ Executes our merged file """ file = os.path.join(self.PATH, "merge.txt") # if tps, "set" the skins fix if not self.is_game_bl2: with open(file, "r") as fp: lines: List[str] = fp.readlines() with open(file, "w") as fp: for l in lines: # type: str if l.lower().startswith("set") and unrealsdk.FindObject( "MaterialInstanceConstant", l.split()[1]) is not None: logging.logger.debug( f"TPS skin-fix on: {l.split()[1]}") try: matinstconsts.Materials.exec_skins( l, self.is_game_bl2) except Exception as e: logging.logger.error(e) logging.logger.error(f"Error in: {l}") else: fp.write(l) exec_path = str(file).split("Binaries\\", 1)[1] bl2tools.console_command("exec " + exec_path, False) # Clean up the file os.remove(file)
class Rarity(BaseRestrictionSet): Name: ClassVar[str] = "Rarity" Options: List[OptionsWrapper.Base] Globals: ClassVar[unrealsdk.UObject] = unrealsdk.FindObject( "GlobalsDefinition", "GD_Globals.General.Globals") RarityOptionMap: Dict[int, OptionsWrapper.Boolean] def __init__(self) -> None: self.Options = [] self.RarityOptionMap = {} for rarity in ALL_RARITIES: canBeShown = (IS_BL2 and rarity.InBL2) or (not IS_BL2 and rarity.InTPS) option = OptionsWrapper.Boolean( Caption=rarity.Name, Description=f"Should you be able to equip {rarity.Name} items.", StartingValue=True, IsHidden=not canBeShown, Choices=self.AllowChoices) self.Options.append(option) # Just to prevent seraph/glitch from overwriting each other if canBeShown: self.RarityOptionMap[rarity.Value] = option def CanItemBeEquipped(self, item: unrealsdk.UObject) -> bool: rarity = self.Globals.GetRarityForLevel(item.RarityLevel) if rarity not in self.RarityOptionMap: return True return bool(self.RarityOptionMap[rarity].CurrentValue)
def __init__(self) -> None: # Hopefully I can remove this in a future SDK update self.Author += "\nVersion: " + str(self.Version) # type: ignore self.ScalingObject = unrealsdk.FindObject( "ConstantAttributeValueResolver", "GD_Balance_HealthAndDamage.HealthAndDamage.Att_UniversalBalanceScaler:ConstantAttributeValueResolver_0" ) self.Options = [ OptionsWrapper.Slider( Caption="BL2 Scaling", Description= "The game's base scaling value (multiplied by 100). 113 means every level the numbers get 13% higher.", StartingValue=113, MinValue=0, MaxValue=500, Increment=1, IsHidden=not self.IS_BL2), OptionsWrapper.Slider( Caption="TPS Scaling", Description= "The game's base scaling value (multiplied by 100). 113 means every level the numbers get 13% higher.", StartingValue=111, MinValue=0, MaxValue=500, Increment=1, IsHidden=self.IS_BL2) ] self.ScalingSlider = cast(OptionsWrapper.Slider, self.Options[0 if self.IS_BL2 else 1])
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)
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)
def __init__(self) -> None: self.ScalingObject = unrealsdk.FindObject( "ConstantAttributeValueResolver", "GD_Balance_HealthAndDamage.HealthAndDamage.Att_UniversalBalanceScaler:ConstantAttributeValueResolver_0" ) self.Options = [ Options.Slider( Caption="BL2 Scaling", Description= "The game's base scaling value (multiplied by 100). 113 means every level the numbers get 13% higher.", StartingValue=113, MinValue=0, MaxValue=500, Increment=1, IsHidden=Game.GetCurrent() != Game.BL2), Options.Slider( Caption="TPS Scaling", Description= "The game's base scaling value (multiplied by 100). 111 means every level the numbers get 11% higher.", StartingValue=111, MinValue=0, MaxValue=500, Increment=1, IsHidden=Game.GetCurrent() != Game.TPS) ] self.ScalingSlider = cast( Options.Slider, self.Options[1 if self.Options[0].IsHidden else 0])
def command(caller: unrealsdk.UObject, function: unrealsdk.UFunction, params: unrealsdk.FStruct) -> bool: x = params.Command.split()[0].strip().lower() if x == "update": self.get_free_mat_inst_consts(True) return False elif x == "exec_skin" and not self.is_game_bl2: # we need to read the file and find all MatInstConsts in case we are playing TPS binaries = self.PATH while os.path.basename(binaries).lower() != "binaries": binaries = os.path.abspath(os.path.join(binaries, "..")) exec_file = os.path.join( binaries, params.Command.split()[1].lstrip("/").lstrip( "\\")) # this is case-sensitive if not os.path.isfile(exec_file): # we could not find the file return True with open(exec_file) as fp: for l in fp: if l.lower().startswith( "set") and unrealsdk.FindObject( "MaterialInstanceConstant", l.split()[1]) is not None: try: Materials.exec_skins(l, self.is_game_bl2) except Exception as e: logging.logger.error(e) logging.logger.error(f"Error in: {l}") # we need to return false because f**k TPS. # If the game handles the exec it will sometimes not apply skins for whatever reason return False # we still want to return to the original function return True
def missionreward_helper(self): """ It's not really possible to set constructed items as a mission reward using legacy set commands, thats what this function is for. The .reward files should be easy enough to use for everyone i hope. """ for line in self.reward_files: try: if not line.split() or line[0] == "-": continue elif line.split()[0].lower() == "set": set.set(line) elif line[0] == "#": mission_definition = unrealsdk.FindObject("MissionDefinition", line[1:].strip()) elif line[0] == "+": reward_array = line[1:].strip() else: if reward_array == "RewardItems": mission_definition.Reward.RewardItems = [FindObject("Object", x.strip()) for x in line.split(",")] elif reward_array == "RewardItemPools": mission_definition.Reward.RewardItemPools = [FindObject("Object", x.strip()) for x in line.split(",")] elif reward_array == "AlternativeRewardItems": mission_definition.AlternativeReward.RewardItems = [FindObject("Object", x.strip()) for x in line.split(",")] elif reward_array == "AlternativeRewardItemPools": mission_definition.AlternativeReward.RewardItemPools = [FindObject("Object", x.strip()) for x in line.split(",")] except Exception as e: logging.logger.error(e) logging.logger.error(f"Please check this line: {line}")
def __init__(self, path: os.PathLike): self.PATH = path self.files = [] self.need_mat_inst_const = [] self.b_has_mats = False self.load_files() self.is_game_bl2 = unrealsdk.FindObject( "Object", "GD_Itempools.Runnables.Pool_Bunker") is not None
def append_attr_presentation_def(presentation_def: unrealsdk.UObject) -> None: category = presentation_def.PathName(presentation_def).split(".")[1] if category == "Artifacts": presentation_list = unrealsdk.FindObject("AttributePresentationListDefinition", "GD_AttributePresentation._AttributeList." "ArtifactOverridePresentationList") elif category == "ClassMods_Only": presentation_list = unrealsdk.FindObject("AttributePresentationListDefinition", "GD_AttributePresentation._AttributeList." "ClassModOverridePresentationList") elif category == "GrenadeMod": presentation_list = unrealsdk.FindObject("AttributePresentationListDefinition", "GD_AttributePresentation._AttributeList." "GrenadeModOverridePresentationList") elif category == "Inventory" or category == "Echo": presentation_list = unrealsdk.FindObject("AttributePresentationListDefinition", "GD_AttributePresentation._AttributeList." "ItemOverridePresentationList") elif category == "Weapons": presentation_list = unrealsdk.FindObject("AttributePresentationListDefinition", "GD_AttributePresentation._AttributeList." "WeaponOverridePresentationList") elif category == "Shields": presentation_list = unrealsdk.FindObject("AttributePresentationListDefinition", "GD_AttributePresentation._AttributeList." "ShieldOverridePresentationList") else: presentation_list = unrealsdk.FindObject("AttributePresentationListDefinition", "GD_AttributePresentation._AttributeList." "DefaultPresentationList") temp = [x for x in presentation_list.Attributes] temp.append(presentation_def) presentation_list.Attributes = temp
def CreateIcons(self) -> None: if self.HealthIcon is not None and self.AmmoIcon is not None: return HEALTH_NAME = "Icon_RefillHealth" AMMO_NAME = "Icon_RefillAmmo" # Incase you're re-execing the file and running a new instance self.HealthIcon = unrealsdk.FindObject( "InteractionIconDefinition", f"GD_InteractionIcons.Default.{HEALTH_NAME}") self.AmmoIcon = unrealsdk.FindObject( "InteractionIconDefinition", f"GD_InteractionIcons.Default.{AMMO_NAME}") baseIcon = unrealsdk.FindObject( "InteractionIconDefinition", "GD_InteractionIcons.Default.Icon_DefaultUse") PC = unrealsdk.GetEngine().GamePlayers[0].Actor if self.HealthIcon is None: self.HealthIcon = unrealsdk.ConstructObject(Class=baseIcon.Class, Outer=baseIcon.Outer, Name=HEALTH_NAME, Template=baseIcon) unrealsdk.KeepAlive(self.HealthIcon) self.HealthIcon.Icon = 3 # Setting values directly on the object causes a crash on quitting the game # Everything still works fine, not super necessary to fix, but people get paranoid # https://github.com/bl-sdk/PythonSDK/issues/45 PC.ServerRCon( f"set {PC.PathName(self.HealthIcon)} Action UseSecondary") PC.ServerRCon( f"set {PC.PathName(self.HealthIcon)} Text REFILL HEALTH") if self.AmmoIcon is None: self.AmmoIcon = unrealsdk.ConstructObject(Class=baseIcon.Class, Outer=baseIcon.Outer, Name=AMMO_NAME, Template=baseIcon) unrealsdk.KeepAlive(self.AmmoIcon) self.AmmoIcon.Icon = 7 PC.ServerRCon( f"set {PC.PathName(self.AmmoIcon)} Action UseSecondary") PC.ServerRCon(f"set {PC.PathName(self.AmmoIcon)} Text REFILL AMMO")
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)
def __init__(self, path: str): self.PATH = path self.is_game_bl2 = unrealsdk.FindObject( "Object", "GD_Itempools.Runnables.Pool_Bunker") is not None self.itempool_files = [] self.assign_files = [] self.set_files = [] self.reward_files = [] self.lootable_files = [] self.load_files()
def Enable(self) -> None: hookmanager.instance.register_end_load(self.on_end_load, 5) for file in self.files: with open(file, "r") as File: for line in File: if line.split() and line.split()[0].lower() == "set": self.need_mat_inst_const.append( line.split()[1].strip()) self.need_mat_inst_const = list( unrealsdk.FindObject("Object", x) for x in set(self.need_mat_inst_const)) self.need_mat_inst_const = [ x for x in self.need_mat_inst_const if x is not None ] def command(caller: unrealsdk.UObject, function: unrealsdk.UFunction, params: unrealsdk.FStruct) -> bool: x = params.Command.split()[0].strip().lower() if x == "update": self.get_free_mat_inst_consts(True) return False elif x == "exec_skin" and not self.is_game_bl2: # we need to read the file and find all MatInstConsts in case we are playing TPS binaries = self.PATH while os.path.basename(binaries).lower() != "binaries": binaries = os.path.abspath(os.path.join(binaries, "..")) exec_file = os.path.join( binaries, params.Command.split()[1].lstrip("/").lstrip( "\\")) # this is case-sensitive if not os.path.isfile(exec_file): # we could not find the file return True with open(exec_file) as fp: for l in fp: if l.lower().startswith( "set") and unrealsdk.FindObject( "MaterialInstanceConstant", l.split()[1]) is not None: try: Materials.exec_skins(l, self.is_game_bl2) except Exception as e: logging.logger.error(e) logging.logger.error(f"Error in: {l}") # we need to return false because f**k TPS. # If the game handles the exec it will sometimes not apply skins for whatever reason return False # we still want to return to the original function return True unrealsdk.RegisterHook("Engine.PlayerController.ConsoleCommand", "ConsoleCommand", command)
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 = {}
def start_loading(self, caller: unrealsdk.UObject, function: unrealsdk.UFunction, params: unrealsdk.FStruct): player_level = unrealsdk.GetEngine( ).GamePlayers[0].Actor.GetCachedSaveGame().ExpLevel balance_tvhm = unrealsdk.FindObject( "GameBalanceDefinition", "GD_Aster_GameStages.Balance.Aster_P2_GameBalance") for region in balance_tvhm.BalanceByRegion: region.MinDefaultGameStage.BaseValueConstant = player_level region.MaxDefaultGameStage.BaseValueConstant = player_level return True
def append_classmoddefinitions(com_def: unrealsdk.UObject) -> None: req_player_class = com_def.PathName(com_def.RequiredPlayerClass) com_balance = None if "Assassin" in req_player_class: com_balance = unrealsdk.FindObject("ClassModBalanceDefinition", "GD_ItemGrades.ClassMods.BalDef_ClassMod_Assassin") elif "Mercenary" in req_player_class: com_balance = unrealsdk.FindObject("ClassModBalanceDefinition", "GD_ItemGrades.ClassMods.BalDef_ClassMod_Mercenary") elif "Siren" in req_player_class: com_balance = unrealsdk.FindObject("ClassModBalanceDefinition", "GD_ItemGrades.ClassMods.BalDef_ClassMod_Siren") elif "Soldier" in req_player_class: com_balance = unrealsdk.FindObject("ClassModBalanceDefinition", "GD_ItemGrades.ClassMods.BalDef_ClassMod_Soldier") elif "Psycho" in req_player_class: com_balance = unrealsdk.FindObject("ClassModBalanceDefinition", "GD_Lilac_ClassMods." "BalanceDefs.BalDef_ClassMod_Psycho") elif "Mechromancer" in req_player_class: com_balance = unrealsdk.FindObject("ClassModBalanceDefinition", "GD_Tulip_ItemGrades.ClassMods." "BalDef_ClassMod_Mechromancer") if com_balance: new_class_mod_definitions = [x for x in com_balance.ClassModDefinitions] new_class_mod_definitions.append(com_def) com_balance.ClassModDefinitions = new_class_mod_definitions
def handle_clone(args: argparse.Namespace) -> None: src_match = re_obj_name.match(args.base) if src_match is None: unrealsdk.Log(f"Unable to parse object name {args.base}") return src_class = src_match.group("class") or "Object" src_fullname = src_match.group("fullname") src_object = unrealsdk.FindObject(src_class, src_fullname) if src_object is None: unrealsdk.Log(f"Unable to find object {args.base}") return dst_match = re_obj_name.match(args.clone) if dst_match is None: unrealsdk.Log(f"Unable to parse object name {args.clone}") return dst_class = dst_match.group("class") or "Object" if dst_class != "Object" and dst_class != src_class: unrealsdk.Log( f"Cannot clone object of class {src_class} as class {dst_class}") return dst_outer = dst_match.group("outer") dst_outer_object = None if dst_outer: dst_outer_object = unrealsdk.FindObject("Object", dst_outer) if dst_outer_object is None: unrealsdk.Log(f"Unable to find outer object {dst_outer}") return dst_name = dst_match.group("name") cloned = unrealsdk.ConstructObject(Class=src_object.Class, Outer=dst_outer_object, Name=dst_name, Template=src_object) if cloned is not None: unrealsdk.KeepAlive(cloned)
def cached_obj_find(klass: str, name: str) -> unrealsdk.UObject: if name is None or name == "None": return None if name in obj_cache: return obj_cache[name] obj = unrealsdk.FindObject(klass, name) # Warn about missing objects but still cache them if obj is None: unrealsdk.Log(f"[SanitySaver] Couldn't find {klass}'{name}'") obj_cache[name] = obj return obj
def CreateIcons(self) -> None: if self.HealthIcon is not None and self.AmmoIcon is not None: return HEALTH_NAME = "Icon_RefillHealth" AMMO_NAME = "Icon_RefillAmmo" # Incase you're re-execing the file and running a new instance self.HealthIcon = unrealsdk.FindObject( "InteractionIconDefinition", f"GD_InteractionIcons.Default.{HEALTH_NAME}") self.AmmoIcon = unrealsdk.FindObject( "InteractionIconDefinition", f"GD_InteractionIcons.Default.{AMMO_NAME}") baseIcon = unrealsdk.FindObject( "InteractionIconDefinition", "GD_InteractionIcons.Default.Icon_DefaultUse") if self.HealthIcon is None: self.HealthIcon = unrealsdk.ConstructObject(Class=baseIcon.Class, Outer=baseIcon.Outer, Name=HEALTH_NAME, Template=baseIcon) unrealsdk.KeepAlive(self.HealthIcon) self.HealthIcon.Icon = 3 self.HealthIcon.Action = "UseSecondary" self.HealthIcon.Text = "REFILL HEALTH" if self.AmmoIcon is None: self.AmmoIcon = unrealsdk.ConstructObject(Class=baseIcon.Class, Outer=baseIcon.Outer, Name=AMMO_NAME, Template=baseIcon) unrealsdk.KeepAlive(self.AmmoIcon) self.AmmoIcon.Icon = 7 self.AmmoIcon.Action = "UseSecondary" self.AmmoIcon.Text = "REFILL AMMO"
def _set_smc_attrs(smc: unrealsdk.UObject, attrs: dict) -> None: if not smc: return static_mesh.set_location(smc, attrs.get("Location", (0, 0, 0))) static_mesh.set_rotation(smc, attrs.get("Rotation", (0, 0, 0))) static_mesh.set_scale(smc, attrs.get("Scale", 1)) static_mesh.set_scale3d(smc, attrs.get("Scale3D", (1, 1, 1))) mats = attrs.get("Materials", None) if mats is not None: mats = [ unrealsdk.FindObject("MaterialInstanceConstant", m) for m in mats ] static_mesh.set_materials(smc, mats)
def _set_pawn_attrs(pawn: unrealsdk.UObject, attrs: dict) -> None: if not pawn: return ai_pawn.set_location(pawn, attrs.get("Location", (0, 0, 0))) ai_pawn.set_rotation(pawn, attrs.get("Rotation", (0, 0, 0))) ai_pawn.set_scale(pawn, attrs.get("Scale", 1)) ai_pawn.set_scale3d(pawn, attrs.get("Scale3D", (1, 1, 1))) mats = attrs.get("Materials", None) if mats is not None: mats = [ unrealsdk.FindObject("MaterialInstanceConstant", m) for m in mats ] ai_pawn.set_materials(pawn, mats)
def __init__(self, path: os.PathLike): self.PATH: os.PathLike = path self.file_data = [] self.xyz_pattern = re.compile( r"\(\s*x\s*=(?P<x>.*?),\s*y\s*=(?P<y>.*?),\s*z\s*=(?P<z>.*?)\)", flags=re.IGNORECASE) self.rot_pattern = re.compile( r"\(pitch\s*=(?P<pitch>.*?),\s*yaw\s*=(?P<yaw>.*?),\s*roll\s*=(?P<roll>.*?)\)", flags=re.IGNORECASE) self.lvl_pattern = re.compile( r"\(\s*(?P<low>-?\d*?)\s*,\s*(?P<high>-?\d*?)\s*\)") self.is_game_bl2: bool = unrealsdk.FindObject( "Object", "GD_Itempools.Runnables.Pool_Bunker") is not None self.spawned_pawns: List[unrealsdk.UObject] = []
def handle_keep_alive(args: argparse.Namespace) -> None: match = re_obj_name.match(args.object) if match is None: unrealsdk.Log(f"Unable to parse object name {args.object}") return klass = match.group("class") or "Object" name = match.group("fullname") obj = unrealsdk.FindObject(klass, name) if obj is None: unrealsdk.Log(f"Unable to find object {args.object}") return unrealsdk.KeepAlive(obj)