diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 3c6e3af9..68e4cfb9 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -9230,7 +9230,10 @@ HOOK_ON_LANGUAGE_CHANGED = 44 HOOK_ON_MODS_LOADED = 45 --- @type LuaHookedEventType -HOOK_MAX = 46 +HOOK_ON_NAMETAGS_RENDER = 46 + +--- @type LuaHookedEventType +HOOK_MAX = 47 --- @class LuaModMenuElementType diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 6dce0480..ff544ae3 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -3297,7 +3297,8 @@ | HOOK_ON_ATTACK_OBJECT | 43 | | HOOK_ON_LANGUAGE_CHANGED | 44 | | HOOK_ON_MODS_LOADED | 45 | -| HOOK_MAX | 46 | +| HOOK_ON_NAMETAGS_RENDER | 46 | +| HOOK_MAX | 47 | ### [enum LuaModMenuElementType](#LuaModMenuElementType) | Identifier | Value | diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index 554ba2f3..9fbfa6a3 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -137,6 +137,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh | HOOK_ON_ATTACK_OBJECT | Called when a player attacks an object. May be double-fired in some cases, you'll need to write special code for this | [MarioState](structs.md#MarioState) attacker, [Object](structs.md#Object) victim, `integer` interactionId | | HOOK_ON_LANGUAGE_CHANGED | Called when the language is changed | `string` language | | HOOK_ON_MODS_LOADED | Called directly after every mod file is loaded in by smlua | None | +| HOOK_ON_NAMETAGS_RENDER | Called when nametags are rendered. Return a `string` to change what renders on the nametag, return an empty `string` to render nothing. | `string` playerIndex | ### Parameters diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 8852a580..ee603a17 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -3290,7 +3290,8 @@ char gSmluaConstants[] = "" "HOOK_ON_ATTACK_OBJECT = 43\n" "HOOK_ON_LANGUAGE_CHANGED = 44\n" "HOOK_ON_MODS_LOADED = 45\n" -"HOOK_MAX = 46\n" +"HOOK_ON_NAMETAGS_RENDER = 46\n" +"HOOK_MAX = 47\n" "ACTION_HOOK_EVERY_FRAME = 0\n" "ACTION_HOOK_GRAVITY = 1\n" "ACTION_HOOK_MAX = 2\n" diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index 4d90aa92..f7c086ee 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -16,6 +16,7 @@ #include "pc/chat_commands.h" #include "pc/pc_main.h" #include "pc/djui/djui_panel.h" +#include "pc/configfile.h" #include "../mods/mods.h" #include "game/print.h" @@ -690,6 +691,36 @@ void smlua_call_event_hooks_int_params_ret_int(enum LuaHookedEventType hookType, } } +void smlua_call_event_hooks_int_params_ret_string(enum LuaHookedEventType hookType, s32 param, char** returnValue) { + lua_State* L = gLuaState; + if (L == NULL) { return; } + struct LuaHookedEvent* hook = &sHookedEvents[hookType]; + for (int i = 0; i < hook->count; i++) { + s32 prevTop = lua_gettop(L); + + // push the callback onto the stack + lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]); + + // push params + lua_pushinteger(L, param); + + // call the callback + if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) { + LOG_LUA("Failed to call the callback: %u", hookType); + continue; + } + + // output the return value + if (lua_type(L, -1) == LUA_TSTRING) { + *returnValue = (char *)smlua_to_string(L, -1); + lua_settop(L, prevTop); + return; + } else { + lua_settop(L, prevTop); + } + } +} + void smlua_call_event_hooks_value_param(enum LuaHookedEventType hookType, int modIndex, int valueIndex) { lua_State* L = gLuaState; if (L == NULL) { return; } diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index 933a50a6..e36fc065 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -57,6 +57,7 @@ enum LuaHookedEventType { HOOK_ON_ATTACK_OBJECT, HOOK_ON_LANGUAGE_CHANGED, HOOK_ON_MODS_LOADED, + HOOK_ON_NAMETAGS_RENDER, HOOK_MAX, }; @@ -107,6 +108,7 @@ static const char* LuaHookedEventTypeName[] = { "HOOK_ON_ATTACK_OBJECT", "HOOK_ON_LANGUAGE_CHANGED", "HOOK_ON_MODS_LOADED", + "HOOK_ON_NAMETAGS_RENDER", "HOOK_MAX" }; @@ -170,6 +172,7 @@ bool smlua_call_event_hooks_ret_int(enum LuaHookedEventType hookType, s32* retur void smlua_call_event_hooks_set_camera_mode_params(enum LuaHookedEventType hookType, struct Camera *c, s16 mode, s16 frames, bool* returnValue); void smlua_call_event_hooks_int_params_ret_bool(enum LuaHookedEventType hookType, s16 param, bool* returnValue); void smlua_call_event_hooks_int_params_ret_int(enum LuaHookedEventType hookType, s32 param, s32* returnValue); +void smlua_call_event_hooks_int_params_ret_string(enum LuaHookedEventType hookType, s32 param, char** returnValue); void smlua_call_event_hooks_value_param(enum LuaHookedEventType hookType, int modIndex, int valueIndex); void smlua_call_event_hooks_on_play_sound(enum LuaHookedEventType hookType, s32 soundBits, f32* pos, s32* returnValue); void smlua_call_event_hooks_use_act_select(enum LuaHookedEventType hookType, int value, bool* foundHook, bool* returnValue); diff --git a/src/pc/nametags.c b/src/pc/nametags.c index ef499581..6bf0f81f 100644 --- a/src/pc/nametags.c +++ b/src/pc/nametags.c @@ -8,6 +8,7 @@ #include "game/camera.h" #include "pc/lua/utils/smlua_math_utils.h" #include "pc/lua/utils/smlua_misc_utils.h" +#include "pc/lua/smlua_hooks.h" #define NAMETAG_MAX_SCALE 0.32f #define NAMETAG_DIST 7000.0f @@ -93,8 +94,14 @@ void nametags_render(void) { } char name[MAX_CONFIG_STRING]; - snprintf(name, MAX_CONFIG_STRING, "%s", np->name); - name_without_hex(name); + char* hookedString = NULL; + smlua_call_event_hooks_int_params_ret_string(HOOK_ON_NAMETAGS_RENDER, i, &hookedString); + if (hookedString) { + snprintf(name, MAX_CONFIG_STRING, "%s", hookedString); + } else { + snprintf(name, MAX_CONFIG_STRING, "%s", np->name); + name_without_hex(name); + } Color color = { np->overridePalette.parts[CAP][0], np->overridePalette.parts[CAP][1],