Ejemplo n.º 1
0
    def OnRun(self, msg: JSON) -> None:
        """
        Callback function for whenever a queued messages should be activated. This implementation
        makes sure the effect properly runs for the specified duration, so if you need to overwrite
        it make sure to call this function from your's.

        If the effect is already running then this function will restart the timer.
        """
        AsyncUtil.CancelFutureCallbacks(f"CC-{self.Name}-Stop")
        self.OnStart(msg)
        AsyncUtil.RunIn(self._DurationOption.CurrentValue, self.OnEnd,
                        f"CC-{self.Name}-Stop")
Ejemplo n.º 2
0
 def OnRun(self, msg: JSON) -> None:
     time: float = 0
     for i in range(4):
         time += max(0, random.uniform(
             self.DROP_DELAY - self.DROP_VARIATION,
             self.DROP_DELAY - self.DROP_VARIATION
         ))
         AsyncUtil.RunIn(
             time,
             unrealsdk.GetEngine().GamePlayers[0].Actor.ServerThrowPawnActiveWeapon
         )
         if i == 1:
             AsyncUtil.RunIn(time + self.DISPLAY_DELAY, lambda: self.ShowRedemption(msg))
Ejemplo n.º 3
0
    def ModOptionChanged(self, option: unrealsdk.Options.Boolean, new_value: bool) -> None:
        if option != self.UpdatingOption:
            return

        # If you turn on updating and there are people close to vendors, start updating
        if new_value:
            if len(self.TouchingActors) > 0:
                AsyncUtil.RunEvery(self.UPDATE_DELAY, self.OnUpdate, self.Name)
        # If you turn off updating, stop updating and make sure all vendors are usable at no cost
        else:
            AsyncUtil.CancelFutureCallbacks(self.Name)
            for vendor in unrealsdk.FindAll("WillowVendingMachine"):
                if vendor.ShopType == 1 or vendor.ShopType == 2:
                    vendor.SetUsability(True, 1)
                    vendor.Behavior_ChangeUsabilityCost(1, 0, 0, 1)
Ejemplo n.º 4
0
 def WillowClientDisableLoadingMovie(caller: unrealsdk.UObject, function: unrealsdk.UFunction, params: unrealsdk.FStruct) -> bool:
     # On level change reset all our caching
     self.TouchingActors = {}
     self.VialCosts = {}
     self.AmmoCosts = {}
     self.PlayerAmmoPools = {}
     AsyncUtil.CancelFutureCallbacks(self.Name)
     return True
Ejemplo n.º 5
0
    def OnEnd(self) -> None:
        ShowChatMessage("Crowd Control:",
                        f"{self.Name} wore off.",
                        ShowTimestamp=False)

        unrealsdk.RemoveHook("WillowGame.WillowHUDGFxMovie.Start", "CCHideHUD")
        # Seems the hook sticks around a tick or something, this doesn't work unless I delay it
        AsyncUtil.RunIn(0.05,
                        unrealsdk.GetEngine().GamePlayers[0].Actor.DisplayHUD)
Ejemplo n.º 6
0
 def Disable(self) -> None:
     AsyncUtil.CancelFutureCallbacks(self.Name)
     unrealsdk.RemoveHook("WillowGame.WillowInteractiveObject.ConditionalReactToUse", self.Name)
     unrealsdk.RemoveHook("WillowGame.WillowInteractiveObject.InitializeFromDefinition", self.Name)
     unrealsdk.RemoveHook("WillowGame.WillowInteractiveObject.Touch", self.Name)
     unrealsdk.RemoveHook("WillowGame.WillowInteractiveObject.UnTouch", self.Name)
     unrealsdk.RemoveHook("WillowGame.WillowPlayerController.WillowClientDisableLoadingMovie", self.Name)
     unrealsdk.RemoveHook("WillowGame.WillowVendingMachine.GenerateInventory", self.Name)
     unrealsdk.RemoveHook("WillowGame.WillowPlayerController.PayForUsedObject", self.Name)
Ejemplo n.º 7
0
    def Enable(self) -> None:
        if self.Token is None:
            return

        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= STARTF_USESHOWWINDOW
        startupinfo.wShowWindow = SW_SHOWMINNOACTIVE

        self._listener = subprocess.Popen(
            ["python", "-m", "Listener", self.Token],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=self.BASE_PATH,
            startupinfo=startupinfo)

        def OnTick() -> None:
            if self._listener is None:
                return
            if self._listener.poll() is not None:
                # Since the lister has quit we can safely call read without blocking
                # Only do this on stderr though cause that's where exceptions go
                if self._listener.stderr is not None:
                    line = self._listener.stderr.read()
                    if len(line) > 0:
                        self.HandleStderr(
                            line.decode("utf8").replace("\\n", "\n")[:-2])
                self.HandleChildQuit()
                return

            if self._listener.stdout is not None and GetPipeAvailableLen(
                    self._listener.stdout) > 0:
                line = self._listener.stdout.readline()
                self.HandleStdout(
                    line.decode("utf8").replace("\\n", "\n")[:-2])

            if self._listener.stderr is not None and GetPipeAvailableLen(
                    self._listener.stderr) > 0:
                line = self._listener.stderr.readline()
                self.HandleStderr(
                    line.decode("utf8").replace("\\n", "\n")[:-2])

        def OnQuit(caller: unrealsdk.UObject, function: unrealsdk.UFunction,
                   params: unrealsdk.FStruct) -> bool:
            if self._listener is not None:
                self._listener.kill()

            return True

        AsyncUtil.RunEveryTick(OnTick, self.Name)

        # TODO: better quit hook
        unrealsdk.RegisterHook(
            "WillowGame.FrontendGFxMovie.ConfirmQuit_Clicked", self.Name,
            OnQuit)

        for callback in Effects.ON_ENABLE:
            callback()
Ejemplo n.º 8
0
    def Disable(self) -> None:
        AsyncUtil.CancelFutureCallbacks("CrowdControl")
        unrealsdk.RemoveHook("WillowGame.FrontendGFxMovie.ConfirmQuit_Clicked",
                             "CrowdControl")
        if self._listener is not None:
            self._listener.kill()
            self._listener = None

        for callback in Effects.ON_DISABLE:
            callback()
Ejemplo n.º 9
0
 def Disable(self) -> None:
     AsyncUtil.CancelFutureCallbacks(self.Name)
     unrealsdk.RemoveHook(
         "WillowGame.WillowInteractiveObject.ConditionalReactToUse",
         self.Name)
     unrealsdk.RemoveHook(
         "WillowGame.WillowInteractiveObject.InitializeFromDefinition",
         self.Name)
     unrealsdk.RemoveHook("WillowGame.WillowInteractiveObject.Touch",
                          self.Name)
     unrealsdk.RemoveHook("WillowGame.WillowInteractiveObject.UnTouch",
                          self.Name)
Ejemplo n.º 10
0
    def OnRun(self, msg: JSON) -> None:
        # Replicate `self.ShowRedemption()` but using the fake name
        def Internal() -> None:
            user = "******"
            try:
                user = msg["data"]["redemption"]["user"]["login"]
            except KeyError:
                pass
            ShowHUDMessage("Crowd Control",
                           f"{user} redeemed '{self.FakeName}'")

        AsyncUtil.RunIn(0.1, Internal)
Ejemplo n.º 11
0
        def Touch(caller: unrealsdk.UObject, function: unrealsdk.UFunction,
                  params: unrealsdk.FStruct) -> bool:
            if not self.UpdatingOption.CurrentValue:
                return True
            if str(caller).split(" ")[0] != "WillowVendingMachine":
                return True

            self.TouchingActors.add(params.Other)
            if self.UpdatingOption.CurrentValue and len(
                    self.TouchingActors) == 1:
                AsyncUtil.RunEvery(self.UPDATE_DELAY, self.OnUpdate, self.Name)

            return True
Ejemplo n.º 12
0
    def ShowFailedMessage(self, msg: JSON) -> None:
        def Internal() -> None:
            user = "******"
            try:
                user = msg["data"]["redemption"]["user"]["login"]
            except KeyError:
                pass
            ShowHUDMessage(
                "Crowd Control",
                f"{user} tried to redeem '{self.Name}', but forgot that this world doesn't have any enemies."
            )

        # There's a small delay after closing menus before we can properly show a message
        AsyncUtil.RunIn(0.1, Internal)
Ejemplo n.º 13
0
        def UnTouch(caller: unrealsdk.UObject, function: unrealsdk.UFunction,
                    params: unrealsdk.FStruct) -> bool:
            if str(caller).split(" ")[0] != "WillowVendingMachine":
                return True

            try:
                self.TouchingActors.remove(params.Other)
            except KeyError:  # If the player is not already in the set
                pass

            if self.UpdatingOption.CurrentValue and len(
                    self.TouchingActors) == 0:
                AsyncUtil.CancelFutureCallbacks(self.Name)

            return True
Ejemplo n.º 14
0
        def Touch(caller: unrealsdk.UObject, function: unrealsdk.UFunction, params: unrealsdk.FStruct) -> bool:
            if caller.Class.Name != "WillowVendingMachine":
                return True
            if params.Other.Class.Name != "WillowPlayerPawn":
                return True

            # If no one's currently near a vendor, but is about to be, and if updating costs are on,
            #  start the update loop
            if self.UpdatingOption.CurrentValue and len(self.TouchingActors) == 0:
                AsyncUtil.RunEvery(self.UPDATE_DELAY, self.OnUpdate, self.Name)

            if caller not in self.TouchingActors:
                self.TouchingActors[caller] = set()
            self.TouchingActors[caller].add(params.Other)

            return True
Ejemplo n.º 15
0
        def UnTouch(caller: unrealsdk.UObject, function: unrealsdk.UFunction, params: unrealsdk.FStruct) -> bool:
            if caller.Class.Name != "WillowVendingMachine":
                return True
            if params.Other.Class.Name != "WillowPlayerPawn":
                return True

            try:
                self.TouchingActors[caller].remove(params.Other)
                if len(self.TouchingActors[caller]) == 0:
                    del self.TouchingActors[caller]
            except (KeyError, ValueError):  # If the player or vendor aren't in the dict
                pass

            if self.UpdatingOption.CurrentValue and len(self.TouchingActors) == 0:
                AsyncUtil.CancelFutureCallbacks(self.Name)

            return True
Ejemplo n.º 16
0
    def OnRedeem(self, msg: JSON) -> None:
        """
        Callback function called whenever someone redeems the reward associated with this effect.
        This implementation adds messages to the queue - if you need to overwrite it make sure to
        call this function from your's.
        """
        def _RunFront() -> None:
            self.OnRun(self._Queue[0])
            AsyncUtil.RunIn(self._IntervalOption.CurrentValue, _Loop)

        def _Loop() -> None:
            self._Queue.pop(0)
            if len(self._Queue) > 0:
                AsyncUtil.RunWhen(self.Condition, _RunFront)

        self._Queue.append(msg)
        if len(self._Queue) == 1:
            AsyncUtil.RunWhen(self.Condition, _RunFront)
Ejemplo n.º 17
0
    def OnRun(self, msg: JSON) -> None:
        def Internal() -> None:
            self.ShowRedemption(msg)
            PC = unrealsdk.GetEngine().GamePlayers[0].Actor

            wanted_vel = max(self.MIN_VELOCITY, maths.sqrt(PC.Pawn.Velocity.X ** 2 + PC.Pawn.Velocity.Y ** 2))
            conversion = maths.pi / 0x7fff

            PC.Pawn.DoJump(PC.bUpdating)

            PC.Pawn.Velocity = (
                maths.cos(PC.Rotation.Yaw * conversion) * wanted_vel,
                maths.sin(PC.Rotation.Yaw * conversion) * wanted_vel,
                PC.Pawn.Velocity.Z  # This now includes jumping velocity
            )

        # There's a bit of a delay after unpausing before this works right
        AsyncUtil.RunIn(0.2, Internal)
Ejemplo n.º 18
0
    def ShowRedemption(self, msg: JSON) -> None:
        """
        Small helper function that displays a UserFeedback HUDMessage with info about who redeemed
        this effect.

        Args:
            msg: The decoded JSON channel points event message.
        """
        def Internal() -> None:
            user = "******"
            try:
                user = msg["data"]["redemption"]["user"]["login"]
            except KeyError:
                pass
            ShowHUDMessage("Crowd Control", f"{user} redeemed '{self.Name}'")

        # There's a small delay after closing menus before we can properly show a message
        AsyncUtil.RunIn(0.1, Internal)
Ejemplo n.º 19
0
 def _RunFront() -> None:
     self.OnRun(self._Queue[0])
     AsyncUtil.RunIn(self._IntervalOption.CurrentValue, _Loop)
Ejemplo n.º 20
0
 def OnRun(self, msg: JSON) -> None:
     unrealsdk.GetEngine().GamePlayers[0].Actor.ServerThrowPawnActiveWeapon()
     AsyncUtil.RunIn(self.DISPLAY_DELAY, lambda: self.ShowRedemption(msg))
Ejemplo n.º 21
0
 def OnRun(self, msg: JSON) -> None:
     self.ShowRedemption(msg)
     AsyncUtil.RunIn(self.TIME_BEFORE_ACTIVATE,
                     lambda: AsyncUtil.RunWhen(IsInGame, self.Activate))
Ejemplo n.º 22
0
 def _Loop() -> None:
     self._Queue.pop(0)
     if len(self._Queue) > 0:
         AsyncUtil.RunWhen(self.Condition, _RunFront)
Ejemplo n.º 23
0
 def Execute(self) -> None:
     AsyncUtil.RunIn(self.Delay, self.OnFinishExecution)