Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,15 @@
- Moved a few warnings to go through Python's system, so they get attributed to the right place.

### UI Utils v1.3
- Linting fixes.
- Added several new helper functions:
- `show_blocking_message`, `hide_blocking_message`
- `show_button_prompt`, `hide_button_prompt`
- `show_coop_message`, `hide_coop_message`
- `show_discovery_message`
- `show_reward_popup`
- `show_second_wind_notification`

[See examples here](https://bl-sdk.github.io/developing/ui_utils/willow2/).

### [unrealsdk v2.0.0](https://github.com/bl-sdk/unrealsdk/blob/master/changelog.md#v200)
> - Now supports Borderlands 1. Big thanks to Ry for doing basically all the reverse engineering.
Expand Down
28 changes: 26 additions & 2 deletions src/ui_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,28 @@

from .chat import show_chat_message
from .clipboard import clipboard_copy, clipboard_paste
from .hud_message import show_hud_message
from .hud_message import (
ERewardPopup,
hide_button_prompt,
show_button_prompt,
show_discovery_message,
show_hud_message,
show_reward_popup,
show_second_wind_notification,
)
from .online_message import (
hide_blocking_message,
hide_coop_message,
show_blocking_message,
show_coop_message,
)
from .option_box import OptionBox, OptionBoxButton
from .reorder_box import ReorderBox
from .training_box import EBackButtonScreen, TrainingBox

__all__: tuple[str, ...] = (
"EBackButtonScreen",
"ERewardPopup",
"OptionBox",
"OptionBoxButton",
"ReorderBox",
Expand All @@ -18,11 +33,20 @@
"__version_info__",
"clipboard_copy",
"clipboard_paste",
"hide_blocking_message",
"hide_button_prompt",
"hide_coop_message",
"show_blocking_message",
"show_button_prompt",
"show_chat_message",
"show_coop_message",
"show_discovery_message",
"show_hud_message",
"show_reward_popup",
"show_second_wind_notification",
)

__version_info__: tuple[int, int] = (1, 3)
__version_info__: tuple[int, int] = (1, 4)
__version__: str = f"{__version_info__[0]}.{__version_info__[1]}"
__author__: str = "bl-sdk"

Expand Down
139 changes: 138 additions & 1 deletion src/ui_utils/hud_message.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
from types import EllipsisType
from typing import TYPE_CHECKING

import unrealsdk
from unrealsdk import unreal

from mods_base import get_pc

__all__: tuple[str, ...] = ("show_hud_message",)
if TYPE_CHECKING:
from enum import IntEnum

class ERewardPopup(IntEnum):
ERP_BadassToken = 0
ERP_CharacterHead = 1
ERP_CharacterSkin = 2
ERP_VehicleSkin = 3
ERP_MAX = 4

else:
ERewardPopup = unrealsdk.find_enum("ERewardPopup")

__all__: tuple[str, ...] = (
"ERewardPopup",
"hide_button_prompt",
"show_button_prompt",
"show_discovery_message",
"show_hud_message",
"show_reward_popup",
"show_second_wind_notification",
)


def show_hud_message(title: str, msg: str, duration: float = 2.5) -> None:
Expand Down Expand Up @@ -39,3 +64,115 @@ def show_hud_message(title: str, msg: str, duration: float = 2.5) -> None:
True,
0,
)


def show_second_wind_notification(
msg: str,
ui_sound: unreal.UObject | None | EllipsisType = ...,
) -> None:
"""
Displays a big notification message in the main in game hud.

Uses the message style of the Second Wind notification.

Note this should not be used for critical messages, it may silently fail at any point.

Args:
msg: The message to display.
ui_sound: An optional AkEvent to play when the message is displayed.
If Ellipsis, default sound will be used.
"""
if (hud_movie := get_pc().GetHUDMovie()) is None:
return

sound_backup = None
sw_interaction = None
for interaction in hud_movie.InteractionOverrideSounds:
if interaction.Interaction == "SecondWind":
sound_backup = interaction.AkEvent
sw_interaction = interaction
break

if ui_sound is not Ellipsis and sw_interaction:
sw_interaction.AkEvent = ui_sound

backup_string = hud_movie.SecondWindString
hud_movie.SecondWindString = msg
hud_movie.DisplaySecondWind()
hud_movie.SecondWindString = backup_string
if sw_interaction:
sw_interaction.AkEvent = sound_backup


def show_discovery_message(msg: str, show_discovered_message: bool = False) -> None:
"""
Displays a message in the top center of the screen.

Uses the style of the new area discovered message.

Note this should not be used for critical messages, it may silently fail at any point.

Args:
msg: The message to display.
show_discovered_message: If True, the message 'You have discovered' header will show.
"""
if (hud_movie := get_pc().GetHUDMovie()) is None:
return
hud_movie.ShowWorldDiscovery("", msg, show_discovered_message, False)


def show_reward_popup(
msg: str,
reward_type: ERewardPopup = ERewardPopup.ERP_BadassToken,
) -> None:
"""
Displays a reward popup with the given message and reward type.

Note this should not be used for critical messages, it may silently fail at any point.

Args:
msg: The message to display in the popup.
reward_type: The type of reward to display. Defaults to ERewardPopup.ERP_BadassToken.
"""
if (hud_movie := get_pc().GetHUDMovie()) is None:
return

icon = {
ERewardPopup.ERP_BadassToken: "token",
ERewardPopup.ERP_CharacterHead: "head",
ERewardPopup.ERP_CharacterSkin: "playerSkin",
ERewardPopup.ERP_VehicleSkin: "vehicleSkin",
}.get(reward_type, "token")

hud_movie.SingleArgInvokeS("p1.badassToken.gotoAndStop", "stop")
hud_movie.SingleArgInvokeS("p1.badassToken.gotoAndStop", "go")
hud_movie.SingleArgInvokeS("p1.badassToken.inner.gotoAndStop", icon)
hud_movie.SetVariableString("p1.badassToken.inner.dispText.text", msg)


def show_button_prompt(reason: str, button: str) -> None:
"""
Displays a contextual prompt with the given text and button string.

This will stay visible until it is explicitly hidden, see `hide_contextual_prompt`.

Note this should not be used for critical messages, it may silently fail at any point.

Args:
reason: The text top to display in the prompt.
button: The button string to display in the prompt.
"""

if (hud_movie := get_pc().GetHUDMovie()) is None:
return
contextual_prompt = hud_movie.ContextualPromptButtonString
hud_movie.ContextualPromptButtonString = button
hud_movie.ToggleContextualPrompt(reason, True)
hud_movie.ContextualPromptButtonString = contextual_prompt


def hide_button_prompt() -> None:
"""Hides the currently displayed contextual prompt, if any."""
if (hud_movie := get_pc().GetHUDMovie()) is None:
return
hud_movie.ToggleContextualPrompt("", False)
61 changes: 61 additions & 0 deletions src/ui_utils/online_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from mods_base import get_pc

__all__: tuple[str, ...] = (
"hide_blocking_message",
"hide_coop_message",
"show_blocking_message",
"show_coop_message",
)


def show_blocking_message(msg: str, reason: str | None = None) -> None:
"""
Displays a blocking message with the given text.

This message blocks all user input until it is hidden.

This message will stay until it is explicitly hidden, see `hide_blocking_message`.

Args:
msg: The message to display.
reason: An optional reason for the blocking message, which will be displayed as a subtitle.
If None, the default text will show.
"""
if (msg_movie := get_pc().GetOnlineMessageMovie()) is None:
return

backup = msg_movie.BlockingSubtitle
msg_movie.BlockingSubtitle = reason if reason is not None else backup
msg_movie.DisplayBlockingMessage(msg)
msg_movie.BlockingSubtitle = backup


def hide_blocking_message() -> None:
"""Hides the currently displayed blocking message, if any."""
if (msg_movie := get_pc().GetOnlineMessageMovie()) is None:
return

msg_movie.HideBlocking()


def show_coop_message(msg: str) -> None:
"""
Displays a short message on the left of the screen, like those used when coop players join.

This message will stay until it is explicitly hidden, see `hide_coop_message`.

Args:
msg: The message to display.
"""
if (msg_movie := get_pc().GetOnlineMessageMovie()) is None:
return

msg_movie.DisplayMessage(msg)


def hide_coop_message() -> None:
"""Hides the currently displayed coop message, if any."""
if (msg_movie := get_pc().GetOnlineMessageMovie()) is None:
return

msg_movie.Hide()