Add mod menu text hook and make hook functions return index
Some checks are pending
Build coop / build-ubuntu (push) Waiting to run
Build coop / build-windows (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run

This commit is contained in:
Agent X 2025-03-15 18:04:59 -04:00
parent ab49c33d86
commit 0f0997a2ac
8 changed files with 109 additions and 22 deletions

View file

@ -10364,19 +10364,22 @@ HOOK_MAX = 53
--- @class LuaModMenuElementType
--- @type LuaModMenuElementType
MOD_MENU_ELEMENT_BUTTON = 0
MOD_MENU_ELEMENT_TEXT = 0
--- @type LuaModMenuElementType
MOD_MENU_ELEMENT_CHECKBOX = 1
MOD_MENU_ELEMENT_BUTTON = 1
--- @type LuaModMenuElementType
MOD_MENU_ELEMENT_SLIDER = 2
MOD_MENU_ELEMENT_CHECKBOX = 2
--- @type LuaModMenuElementType
MOD_MENU_ELEMENT_INPUTBOX = 3
MOD_MENU_ELEMENT_SLIDER = 3
--- @type LuaModMenuElementType
MOD_MENU_ELEMENT_MAX = 4
MOD_MENU_ELEMENT_INPUTBOX = 4
--- @type LuaModMenuElementType
MOD_MENU_ELEMENT_MAX = 5
--- @class HudDisplayFlags

View file

@ -160,8 +160,16 @@ function hook_on_sync_table_change(syncTable, field, tag, func)
-- ...
end
--- @param message string The message for the text to show
--- @return integer
--- Hooks DJUI text into the mod menu
function hook_mod_menu_text(message)
-- ...
end
--- @param name string The text to show on the button
--- @param func fun(index:integer) The function that is called when the button is pressed
--- @return integer
--- Hooks a DJUI button into the mod menu
function hook_mod_menu_button(name, func)
-- ...
@ -170,6 +178,7 @@ end
--- @param name string The text to show on the left
--- @param defaultValue boolean The default state of the checkbox
--- @param func fun(index:integer, value:boolean) The function that is called when the checkbox is changed
--- @return integer
--- Hooks a DJUI checkbox into the mod menu
function hook_mod_menu_checkbox(name, defaultValue, func)
-- ...
@ -180,6 +189,7 @@ end
--- @param min integer The lowest the slider can go
--- @param max integer The highest the slider can go
--- @param func fun(index:integer, value:integer) The function that is called when the value of the slider changes
--- @return integer
--- Hooks a DJUI slider into the mod menu
function hook_mod_menu_slider(name, defaultValue, min, max, func)
-- ...
@ -189,6 +199,7 @@ end
--- @param defaultValue string The default text in the inputbox
--- @param stringLength integer The max length of the inputbox
--- @param func fun(index:integer, value:string) The function that is called when the value of the inputbox changes
--- @return integer
--- Hooks a DJUI inputbox into the mod menu
function hook_mod_menu_inputbox(name, defaultValue, stringLength, func)
-- ...

View file

@ -3756,11 +3756,12 @@
### [enum LuaModMenuElementType](#LuaModMenuElementType)
| Identifier | Value |
| :--------- | :---- |
| MOD_MENU_ELEMENT_BUTTON | 0 |
| MOD_MENU_ELEMENT_CHECKBOX | 1 |
| MOD_MENU_ELEMENT_SLIDER | 2 |
| MOD_MENU_ELEMENT_INPUTBOX | 3 |
| MOD_MENU_ELEMENT_MAX | 4 |
| MOD_MENU_ELEMENT_TEXT | 0 |
| MOD_MENU_ELEMENT_BUTTON | 1 |
| MOD_MENU_ELEMENT_CHECKBOX | 2 |
| MOD_MENU_ELEMENT_SLIDER | 3 |
| MOD_MENU_ELEMENT_INPUTBOX | 4 |
| MOD_MENU_ELEMENT_MAX | 5 |
[:arrow_up_small:](#)

View file

@ -9,6 +9,7 @@ Hooks are a way for SM64 to trigger Lua code, whereas the functions listed in [f
- [hook_event](#hook_event)
- [hook_mario_action](#hook_mario_action)
- [hook_on_sync_table_change](#hook_on_sync_table_change)
- [hook_mod_menu_text](#hook_mod_menu_text)
- [hook_mod_menu_button](#hook_mod_menu_button)
- [hook_mod_menu_checkbox](#hook_mod_menu_checkbox)
- [hook_mod_menu_slider](#hook_mod_menu_slider)
@ -286,6 +287,25 @@ gGlobalSyncTable.testingField = "hello"
<br />
## [hook_mod_menu_text](#hook_mod_menu_text)
`hook_mod_menu_text()` allows Lua to add text labels to their designated mod menu submenu.
### Parameters
| Field | Type |
| ----- | ---- |
| message | `string` |
### Lua Example
```lua
hook_mod_menu_text("Rise and shine, Mr. Freeman.")
```
[:arrow_up_small:](#)
<br />
## [hook_mod_menu_button](#hook_mod_menu_button)
`hook_mod_menu_button()` allows Lua to add buttons to their designated mod menu submenu.
@ -293,7 +313,7 @@ gGlobalSyncTable.testingField = "hello"
| Field | Type |
| ----- | ---- |
| message | `string` |
| name | `string` |
| func | `Lua Function` (`integer` index) |
### Lua Example
@ -329,7 +349,7 @@ hook_mod_menu_button("Open Menu 2", on_open_menu)
| Field | Type |
| ----- | ---- |
| message | `string` |
| name | `string` |
| defaultValue | `boolean` |
| func | `Lua Function` (`integer` index, `boolean` value) |
@ -365,7 +385,7 @@ hook_mod_menu_checkbox("Noclip Mode", false, on_set_player_mode)
| Field | Type |
| ----- | ---- |
| message | `string` |
| name | `string` |
| defaultValue | `integer` |
| min | `integer` |
| max | `integer` |
@ -394,7 +414,7 @@ hook_mod_menu_slider("Time Scale", 1, 0, 10, on_set_time_scale)
| Field | Type |
| ----- | ---- |
| message | `string` |
| name | `string` |
| defaultValue | `string` |
| stringLength | `integer` |
| func | `Lua Function` (`integer` index, `string` value) |

View file

@ -28,14 +28,14 @@ void djui_panel_mod_menu_mod_button(struct DjuiBase* caller) {
}
}
void djui_panel_mod_menu_mod_checkbox(struct DjuiBase* caller) {
static void djui_panel_mod_menu_mod_checkbox(struct DjuiBase* caller) {
struct LuaHookedModMenuElement* hooked = &gHookedModMenuElements[caller->tag];
smlua_call_mod_menu_element_hook(hooked, caller->tag);
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)caller;
djui_text_set_text(checkbox->text, hooked->name);
}
void djui_panel_mod_menu_mod_slider(struct DjuiBase* caller) {
static void djui_panel_mod_menu_mod_slider(struct DjuiBase* caller) {
struct LuaHookedModMenuElement* hooked = &gHookedModMenuElements[caller->tag];
smlua_call_mod_menu_element_hook(hooked, caller->tag);
struct DjuiSlider* slider = (struct DjuiSlider*)caller;
@ -52,6 +52,17 @@ static void djui_panel_mod_menu_mod_inputbox(struct DjuiBase* caller) {
static void djui_panel_mod_menu_mod_create_element(struct DjuiBase* parent, int i) {
struct LuaHookedModMenuElement* hooked = &gHookedModMenuElements[i];
switch (hooked->element) {
case MOD_MENU_ELEMENT_TEXT: {
struct DjuiText* text = djui_text_create(parent, hooked->name);
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_color(&text->base, 220, 220, 220, 255);
djui_base_set_size(&text->base, 1.0f, 64);
djui_base_set_alignment(&text->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP);
djui_text_set_drop_shadow(text, 64, 64, 64, 100);
text->base.tag = i;
break;
}
case MOD_MENU_ELEMENT_BUTTON: {
struct DjuiButton* button = djui_button_create(parent, hooked->name, DJUI_BUTTON_STYLE_NORMAL, djui_panel_mod_menu_mod_button);
button->base.tag = i;

View file

@ -3621,11 +3621,12 @@ char gSmluaConstants[] = ""
"ACTION_HOOK_EVERY_FRAME=0\n"
"ACTION_HOOK_GRAVITY=1\n"
"ACTION_HOOK_MAX=2\n"
"MOD_MENU_ELEMENT_BUTTON=0\n"
"MOD_MENU_ELEMENT_CHECKBOX=1\n"
"MOD_MENU_ELEMENT_SLIDER=2\n"
"MOD_MENU_ELEMENT_INPUTBOX=3\n"
"MOD_MENU_ELEMENT_MAX=4\n"
"MOD_MENU_ELEMENT_TEXT=0\n"
"MOD_MENU_ELEMENT_BUTTON=1\n"
"MOD_MENU_ELEMENT_CHECKBOX=2\n"
"MOD_MENU_ELEMENT_SLIDER=3\n"
"MOD_MENU_ELEMENT_INPUTBOX=4\n"
"MOD_MENU_ELEMENT_MAX=5\n"
"HUD_DISPLAY_LIVES=0\n"
"HUD_DISPLAY_COINS=1\n"
"HUD_DISPLAY_STARS=2\n"

View file

@ -1984,6 +1984,38 @@ int smlua_hook_on_sync_table_change(lua_State* L) {
struct LuaHookedModMenuElement gHookedModMenuElements[MAX_HOOKED_MOD_MENU_ELEMENTS] = { 0 };
int gHookedModMenuElementsCount = 0;
int smlua_hook_mod_menu_text(lua_State* L) {
if (L == NULL) { return 0; }
if (!smlua_functions_valid_param_count(L, 1)) { return 0; }
if (gHookedModMenuElementsCount >= MAX_HOOKED_MOD_MENU_ELEMENTS) {
LOG_LUA_LINE("Hooked mod menu element exceeded maximum references!");
return 0;
}
const char* name = smlua_to_string(L, 1);
if (name == NULL || strlen(name) == 0 || !gSmLuaConvertSuccess) {
LOG_LUA_LINE("Hook mod menu element: tried to hook invalid element");
return 0;
}
struct LuaHookedModMenuElement* hooked = &gHookedModMenuElements[gHookedModMenuElementsCount];
hooked->element = MOD_MENU_ELEMENT_TEXT;
snprintf(hooked->name, 64, "%s", name);
hooked->boolValue = false;
hooked->uintValue = 0;
hooked->stringValue[0] = '\0';
hooked->length = 0;
hooked->sliderMin = 0;
hooked->sliderMax = 0;
hooked->reference = 0;
hooked->mod = gLuaActiveMod;
lua_pushinteger(L, gHookedModMenuElementsCount);
gHookedModMenuElementsCount++;
return 1;
}
int smlua_hook_mod_menu_button(lua_State* L) {
if (L == NULL) { return 0; }
if (!smlua_functions_valid_param_count(L, 2)) { return 0; }
@ -2017,6 +2049,7 @@ int smlua_hook_mod_menu_button(lua_State* L) {
hooked->reference = ref;
hooked->mod = gLuaActiveMod;
lua_pushinteger(L, gHookedModMenuElementsCount);
gHookedModMenuElementsCount++;
return 1;
}
@ -2060,6 +2093,7 @@ int smlua_hook_mod_menu_checkbox(lua_State* L) {
hooked->reference = ref;
hooked->mod = gLuaActiveMod;
lua_pushinteger(L, gHookedModMenuElementsCount);
gHookedModMenuElementsCount++;
return 1;
}
@ -2115,6 +2149,7 @@ int smlua_hook_mod_menu_slider(lua_State* L) {
hooked->reference = ref;
hooked->mod = gLuaActiveMod;
lua_pushinteger(L, gHookedModMenuElementsCount);
gHookedModMenuElementsCount++;
return 1;
}
@ -2165,6 +2200,7 @@ int smlua_hook_mod_menu_inputbox(lua_State* L) {
hooked->reference = ref;
hooked->mod = gLuaActiveMod;
lua_pushinteger(L, gHookedModMenuElementsCount);
gHookedModMenuElementsCount++;
return 1;
}
@ -2275,6 +2311,8 @@ void smlua_call_mod_menu_element_hook(struct LuaHookedModMenuElement* hooked, in
u8 params = 2;
lua_pushinteger(L, index);
switch (hooked->element) {
case MOD_MENU_ELEMENT_TEXT:
params = 1;
case MOD_MENU_ELEMENT_BUTTON:
params = 1;
break;
@ -2336,7 +2374,7 @@ void smlua_clear_hooks(void) {
for (int i = 0; i < gHookedModMenuElementsCount; i++) {
struct LuaHookedModMenuElement* hooked = &gHookedModMenuElements[i];
hooked->element = MOD_MENU_ELEMENT_BUTTON;
hooked->element = MOD_MENU_ELEMENT_TEXT;
hooked->name[0] = '\0';
hooked->boolValue = false;
hooked->uintValue = 0;
@ -2388,6 +2426,7 @@ void smlua_bind_hooks(void) {
smlua_bind_function(L, "hook_chat_command", smlua_hook_chat_command);
smlua_bind_function(L, "hook_on_sync_table_change", smlua_hook_on_sync_table_change);
smlua_bind_function(L, "hook_behavior", smlua_hook_behavior);
smlua_bind_function(L, "hook_mod_menu_text", smlua_hook_mod_menu_text);
smlua_bind_function(L, "hook_mod_menu_button", smlua_hook_mod_menu_button);
smlua_bind_function(L, "hook_mod_menu_checkbox", smlua_hook_mod_menu_checkbox);
smlua_bind_function(L, "hook_mod_menu_slider", smlua_hook_mod_menu_slider);

View file

@ -140,6 +140,7 @@ static const char* LuaActionHookTypeArgName[] = {
#define MAX_HOOKED_MOD_MENU_ELEMENTS 256
enum LuaModMenuElementType {
MOD_MENU_ELEMENT_TEXT,
MOD_MENU_ELEMENT_BUTTON,
MOD_MENU_ELEMENT_CHECKBOX,
MOD_MENU_ELEMENT_SLIDER,