diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 7e3fecf6d..e1ca3fda8 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -8134,7 +8134,10 @@ HOOK_ON_CHAT_MESSAGE = 27 HOOK_OBJECT_SET_MODEL = 28 --- @type LuaHookedEventType -HOOK_MAX = 29 +HOOK_CHARACTER_SOUND = 29 + +--- @type LuaHookedEventType +HOOK_MAX = 30 --- @class HudDisplayFlags diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 657eb6fea..98e471197 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -2880,7 +2880,8 @@ | HOOK_ALLOW_HAZARD_SURFACE | 26 | | HOOK_ON_CHAT_MESSAGE | 27 | | HOOK_OBJECT_SET_MODEL | 28 | -| HOOK_MAX | 29 | +| HOOK_CHARACTER_SOUND | 29 | +| HOOK_MAX | 30 | [:arrow_up_small:](#) diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index 533b4f818..04a8dd108 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -115,6 +115,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh | HOOK_ALLOW_HAZARD_SURFACE | Called once per frame. Return `false` to prevent Mario from being affected by lava or quicksand. | [MarioState](structs.md#MarioState) localMario | | HOOK_ON_CHAT_MESSAGE | Called when a chat message gets sent. Return `false` to prevent the message from being sent. | [MarioState](structs.md#MarioState) messageSender | | HOOK_OBJECT_SET_MODEL | Called when a behavior changes models. Also runs when a behavior spawns. | [Object](structs.md#Object) obj, `integer` modelID | +| HOOK_CHARACTER_SOUND | Called when mario retrieves a character sound to play, return a character sound or `0` to override it. | [MarioState](structs.md#MarioState) mario, [enum CharacterSound](constants.md#enum-CharacterSound) characterSound | ### Parameters diff --git a/src/game/characters.c b/src/game/characters.c index 268006e0b..841a3170e 100644 --- a/src/game/characters.c +++ b/src/game/characters.c @@ -11,6 +11,7 @@ #include "audio/external.h" #include "engine/graph_node.h" #include "characters_bass_sounds.h" +#include "pc/lua/smlua.h" extern Gfx mario_cap_seg3_dl_03022F48[]; extern Gfx luigi_cap_seg3_dl_03022F48[]; @@ -455,6 +456,12 @@ struct Character* get_character(struct MarioState* m) { static s32 get_character_sound(struct MarioState* m, enum CharacterSound characterSound) { if (m == NULL || m->marioObj == NULL) { return 0; } + + s32 override = 0; + if (smlua_call_event_hooks_mario_charactersound_param_ret_int(HOOK_CHARACTER_SOUND, m, characterSound, &override)) { + return override; + } + struct Character* character = ((m == NULL || m->character == NULL) ? &gCharacters[CT_MARIO] : m->character); switch (characterSound) { case CHAR_SOUND_YAH_WAH_HOO: return character->soundYahWahHoo; diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 8d2638590..fb170e037 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -2887,7 +2887,8 @@ char gSmluaConstants[] = "" "HOOK_ALLOW_HAZARD_SURFACE = 26\n" "HOOK_ON_CHAT_MESSAGE = 27\n" "HOOK_OBJECT_SET_MODEL = 28\n" -"HOOK_MAX = 29\n" +"HOOK_CHARACTER_SOUND = 29\n" +"HOOK_MAX = 30\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 f4e8abcec..0e61d43a4 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -634,6 +634,43 @@ void smlua_call_event_hooks_on_chat_message(enum LuaHookedEventType hookType, st } } +bool smlua_call_event_hooks_mario_charactersound_param_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, enum CharacterSound characterSound, s32* returnValue) { + lua_State* L = gLuaState; + if (L == NULL) { return false; } + 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 mario state + lua_getglobal(L, "gMarioStates"); + lua_pushinteger(L, m->playerIndex); + lua_gettable(L, -2); + lua_remove(L, -2); + + // push character sound + lua_pushinteger(L, characterSound); + + // call the callback + if (0 != smlua_call_hook(L, 2, 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_TNUMBER) { + *returnValue = smlua_to_integer(L, -1); + lua_settop(L, prevTop); + return true; + } else { + lua_settop(L, prevTop); + } + } + return false; +} + //////////////////// // hooked actions // //////////////////// diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index ad193bf37..f18381179 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -40,6 +40,7 @@ enum LuaHookedEventType { HOOK_ALLOW_HAZARD_SURFACE, HOOK_ON_CHAT_MESSAGE, HOOK_OBJECT_SET_MODEL, + HOOK_CHARACTER_SOUND, HOOK_MAX, }; @@ -73,6 +74,7 @@ static const char* LuaHookedEventTypeName[] = { "HOOK_ALLOW_HAZARD_SURFACE", "HOOK_ON_CHAT_MESSAGE", "HOOK_OBJECT_SET_MODEL", + "HOOK_CHARACTER_SOUND", "HOOK_MAX" }; @@ -102,6 +104,7 @@ void smlua_call_event_hooks_mario_params_ret_bool(enum LuaHookedEventType hookTy void smlua_call_event_hooks_interact_params(enum LuaHookedEventType hookType, struct MarioState* m, struct Object* obj, u32 interactType, bool interactValue); void smlua_call_event_hooks_interact_params_ret_bool(enum LuaHookedEventType hookType, struct MarioState* m, struct Object* obj, u32 interactType, bool* returnValue); void smlua_call_event_hooks_object_param(enum LuaHookedEventType hookType, struct Object* obj); +void smlua_call_event_hooks_object_model_param(enum LuaHookedEventType hookType, struct Object* obj, s32 modelID); bool smlua_call_event_hooks_ret_int(enum LuaHookedEventType hookType, s32* returnValue); 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); @@ -109,7 +112,7 @@ void smlua_call_event_hooks_value_param(enum LuaHookedEventType hookType, int mo void smlua_call_event_hooks_use_act_select(enum LuaHookedEventType hookType, int value, bool* foundHook, bool* returnValue); void smlua_call_event_hooks_ret_bool(enum LuaHookedEventType hookType, bool* returnValue); void smlua_call_event_hooks_on_chat_message(enum LuaHookedEventType hookType, struct MarioState* m, const char* message, bool* returnValue); -void smlua_call_event_hooks_object_model_param(enum LuaHookedEventType hookType, struct Object* obj, s32 modelID); +bool smlua_call_event_hooks_mario_charactersound_param_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, enum CharacterSound characterSound, s32* returnValue); enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior); const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);