forked from juso40/bl2sdk_Mods
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path__init__.py
145 lines (121 loc) · 4.48 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import re
from dataclasses import dataclass
from typing import List, Tuple
import unrealsdk # type: ignore
from Mods.coroutines import (
PostRenderCoroutine,
Time,
WaitWhile,
start_coroutine_post_render,
)
from Mods.ModMenu import EnabledSaveType, Hook, ModTypes, Options, RegisterMod, SDKMod
MaxMessages = Options.Slider(
Caption="Max Messages",
Description="Maximum number of messages to display at once.",
StartingValue=5,
MinValue=1,
MaxValue=20,
Increment=1,
)
YOffset = Options.Slider(
Caption="Y Offset",
Description="How far down the screen the messages should be displayed in percent of the screen height.",
StartingValue=5,
MinValue=0,
MaxValue=30,
Increment=1,
)
MessageSpacing = Options.Slider(
Caption="MessageSpacing",
Description="How far apart the messages should be displayed vertically in pixels.",
StartingValue=14,
MinValue=9,
MaxValue=30,
Increment=1,
)
MessageDuration = Options.Slider(
Caption="Message Duration",
Description="How long the message should be displayed in seconds.",
StartingValue=5,
MinValue=1,
MaxValue=30,
Increment=1,
)
@dataclass
class Message:
title: str
message: str
message_color: Tuple[int, int, int, int] # BGRA
duration_remaining: float
MESSAGES: List[Message] = []
def hex_to_rgb(hex_color: str) -> tuple:
hex_color = hex_color.lstrip("#")
return tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4))
def coroutine_post_render() -> PostRenderCoroutine:
while True:
yield WaitWhile(
lambda: unrealsdk.GetEngine().GamePlayers[0].Actor.IsPauseMenuOpen()
)
canvas = yield
screen_width = canvas.SizeX
screen_height = canvas.SizeY
start_y = int(screen_height * (YOffset.CurrentValue / 100))
x_center = screen_width // 2
for message in MESSAGES.copy():
message.duration_remaining -= Time.delta_time
if message.duration_remaining <= 0:
MESSAGES.remove(message)
continue
full_message = f"{message.title} {message.message}"
xl, yl = canvas.TextSize(full_message)
title_start_x = x_center - xl // 2
# draw the title in white
canvas.SetPos(title_start_x, start_y)
canvas.SetDrawColorStruct((255, 255, 255, 255))
canvas.DrawText(message.title, False, 1, 1, ())
# draw the message in the specified color
xl, yl = canvas.TextSize(message.title)
title_end_x = title_start_x + xl + 1
canvas.SetPos(title_end_x, start_y)
canvas.SetDrawColorStruct(message.message_color)
canvas.DrawText(message.message, False, 1, 1, ())
start_y += MessageSpacing.CurrentValue
if not mod_instance.IsEnabled:
return None
class PickupMessage(SDKMod):
Name: str = "Pickup Message"
Description: str = "Shows a message with the item you just picked up."
Author: str = "Juso"
Types: ModTypes = ModTypes.Utility
Version: str = "1.1"
SaveEnabledState: EnabledSaveType = EnabledSaveType.LoadOnMainMenu
Options = [MaxMessages, YOffset, MessageSpacing, MessageDuration]
def Enable(self) -> None: # noqa: N802
super().Enable()
start_coroutine_post_render(coroutine_post_render())
@Hook("WillowGame.WillowHUD.DisplayCustomMessage")
def display_custom_hud_message(
self,
caller: unrealsdk.UObject,
function: unrealsdk.UFunction,
params: unrealsdk.FStruct,
) -> bool:
message = params.MessageString
# try to get the hex color from the optional <font> tag
color = re.search(r"<font color = \"#(.*?)\">", message)
if color:
color = hex_to_rgb(color.group(1))
color = (color[2], color[1], color[0], 255)
else:
color = (255, 255, 255, 255)
# Title is everything before the <font> tag
# Message is everything between the <font> </font> tags
title = message[: message.find("<font")]
message_match = re.search(r"<font color = \"#(.*?)\">(.*?)</font>", message)
message = message_match.group(2).replace("INVALID", "") if message_match else ""
MESSAGES.append(Message(title, message, color, MessageDuration.CurrentValue))
if len(MESSAGES) > MaxMessages.CurrentValue:
MESSAGES.pop(0)
return True
mod_instance = PickupMessage()
RegisterMod(mod_instance)