Skip to content

Commit 44519d7

Browse files
committed
try remove tags from pause, switch to sound based
also fix the double sound on opening a menu, since everything's triggered off of playing it anyway
1 parent 695b701 commit 44519d7

File tree

2 files changed

+69
-13
lines changed

2 files changed

+69
-13
lines changed

src/willow1_mod_menu/options.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ def open_new_generic_menu(menu: WillowGFxMenu) -> None:
122122

123123
menu.ScreenStack.append(text)
124124
menu.ActivateTopPage(0)
125-
menu.PlayUISound("Confirm")
126125

127126
if not original_needs_delayed_init:
128127
# Can draw immediately

src/willow1_mod_menu/pause.py

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
# ruff: noqa: D103
22
from typing import Any
33

4-
from unrealsdk.hooks import Block, Type
5-
from unrealsdk.unreal import BoundFunction, UObject, WrappedStruct
4+
from unrealsdk.hooks import Type
5+
from unrealsdk.unreal import BoundFunction, UObject, WeakPointer, WrappedStruct
66

77
from mods_base import hook
88

99
from .options import create_mod_list_options_menu
10+
from .util import find_focused_item
1011

11-
MODS_MENU_TAG = "willow1-mod-menu:mods-pause"
12+
current_menu = WeakPointer()
1213

1314

1415
# In contrast to the frontend menu, the pause menu uses a generic menu screen, so the best place to
@@ -23,14 +24,18 @@ def inject_mods_into_pause_screen(
2324
if args.menuCaption != "$WillowMenu.Pause.Exit":
2425
return
2526

26-
# We also don't seem to have a great way of detecting generic item activate events, so instead
27-
# we hook this to an unused debug function
28-
func(0, "Mods", MODS_MENU_TAG, "extMainDebug")
27+
func(0, "Mods")
2928

3029

3130
@hook("WillowGame.WillowGFxMenuPause:extInitMain", immediately_enable=True)
32-
def open_pause_pre(*_: Any) -> None:
31+
def open_pause_pre(obj: UObject, _args: WrappedStruct, _ret: Any, _func: BoundFunction) -> None:
32+
global current_menu
33+
current_menu = WeakPointer(obj)
34+
3335
inject_mods_into_pause_screen.enable()
36+
pause_play_sound.enable()
37+
reenable_pause_after_nested.enable()
38+
reenable_pause_after_achievements.enable()
3439

3540

3641
@hook(
@@ -42,15 +47,67 @@ def open_pause_post(*_: Any) -> None:
4247
inject_mods_into_pause_screen.disable()
4348

4449

45-
@hook("WillowGame.WillowGFxMenuPause:extMainDebug", immediately_enable=True)
46-
def pause_activate(
50+
# Since we can't safely pass callback names into ActionScript, have to detect when you click mods by
51+
# the menu sound. This has quite some complications trying not to trigger while in other menus...
52+
@hook("GearboxFramework.GearboxGFxMovie:PlaySpecialUISound")
53+
def pause_play_sound(
4754
obj: UObject,
48-
_args: WrappedStruct,
55+
args: WrappedStruct,
4956
_ret: Any,
5057
_func: BoundFunction,
51-
) -> type[Block]:
58+
) -> None:
59+
if args.SoundString != "Confirm":
60+
return
61+
62+
# Disable this hook now, regardless of what screen we actually went into, to try avoid firing
63+
# spuriously. If we back out of the next screen, another hook should re-enable us.
64+
pause_play_sound.disable()
65+
66+
if (menu := current_menu()) is None:
67+
return
68+
69+
if len(menu.ScreenStack) > 1:
70+
# Sanity check, should only be able to fire on the top screen
71+
return
72+
73+
if menu.GetVariableString(find_focused_item(obj) + ".mLabel.text") != "Mods":
74+
return
75+
5276
# We don't seem to be able to open the multiplayer lobby menu from in game - even if we force
5377
# load it's definition - so instead just open a standard options list showing each mod
5478
create_mod_list_options_menu(obj)
5579

56-
return Block
80+
81+
# If we open a nested movie (e.g. lobby, quit), we won't re-init the pause menu when we leave it
82+
# This hook will detect when we return to the pause movie, so we can re-enable the sound hook
83+
@hook("WillowGame.WillowGFxUIManager:UpdateFocus", hook_type=Type.POST)
84+
def reenable_pause_after_nested(
85+
obj: UObject,
86+
_args: WrappedStruct,
87+
_ret: Any,
88+
_func: BoundFunction,
89+
) -> None:
90+
if (menu := current_menu()) is None:
91+
return
92+
93+
# If we've re-enabled the current pause movie
94+
if menu == obj.GetPlayingMovie():
95+
# Re-enable the sound hook
96+
pause_play_sound.enable()
97+
98+
99+
@hook("WillowGame.WillowGFxMenuPause:extViewAchievements")
100+
def reenable_pause_after_achievements(*_: Any) -> None:
101+
# Since the achievements menu just opens the steam overlay, with no in game menus, immediately
102+
# re-enable the sound hook
103+
pause_play_sound.enable()
104+
105+
106+
@hook("WillowGame.WillowGFxMenuPause:OnClose", immediately_enable=True)
107+
def pause_close(*_: Any) -> None:
108+
global current_menu
109+
current_menu = WeakPointer()
110+
111+
pause_play_sound.disable()
112+
reenable_pause_after_nested.disable()
113+
reenable_pause_after_achievements.disable()

0 commit comments

Comments
 (0)