diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index d12523bc..39340d5d 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -9026,7 +9026,10 @@ HOOK_ON_DIALOG = 33 HOOK_ON_HUD_RENDER_BEHIND = 34 --- @type LuaHookedEventType -HOOK_MAX = 35 +HOOK_MIRROR_MARIO_RENDER = 35 + +--- @type LuaHookedEventType +HOOK_MAX = 36 --- @class HudDisplayFlags diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 3703660c..85f05fb7 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -3207,7 +3207,8 @@ | HOOK_ON_OBJECT_ANIM_UPDATE | 32 | | HOOK_ON_DIALOG | 33 | | HOOK_ON_HUD_RENDER_BEHIND | 34 | -| HOOK_MAX | 35 | +| HOOK_MIRROR_MARIO_RENDER | 35 | +| HOOK_MAX | 36 | [:arrow_up_small:](#) diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index 22198c86..36e05fa9 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -121,6 +121,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh | HOOK_BEFORE_SET_MARIO_ACTION | Called before Mario's action changes. Return an action to change the incoming action or `1` to cancel the action change. | [MarioState](structs.md#MarioState) mario, `integer` incomingAction | | HOOK_ON_OBJECT_ANIM_UPDATE | Called when an object's animation is updated. | [Object](structs.md#Object) objNode | | HOOK_ON_DIALOG | Called when a dialog appears. Return `false` to prevent it from appearing. | `integer` dialogId | +| HOOK_MIRROR_MARIO_RENDER | Called when a Mirror Mario is rendered. | [GraphNodeObject](structs.md#GraphNodeObject) mirrorMario | `integer` mirrorMarioIndex | ### Parameters diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 99a8ad3e..80189b64 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -25,6 +25,7 @@ #include "hardcoded.h" #include "sound_init.h" #include "pc/network/network.h" +#include "pc/lua/smlua_hooks.h" #define TOAD_STAR_1_REQUIREMENT gBehaviorValues.ToadStar1Requirement #define TOAD_STAR_2_REQUIREMENT gBehaviorValues.ToadStar2Requirement @@ -704,6 +705,8 @@ Gfx* geo_render_mirror_mario(s32 callContext, struct GraphNode* node, UNUSED Mat gMirrorMario[i].scale[0] *= -1.0f; // TODO: does rendering the mirror room still crash? gMirrorMario[i].node.flags |= GRAPH_RENDER_ACTIVE; + + smlua_call_event_hooks_graph_node_object_and_int_param(HOOK_MIRROR_MARIO_RENDER, &gMirrorMario[i], i); } else { gMirrorMario[i].node.flags &= ~GRAPH_RENDER_ACTIVE; } diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c index 0a59a4c0..6122fd40 100644 --- a/src/pc/lua/smlua_cobject.c +++ b/src/pc/lua/smlua_cobject.c @@ -602,45 +602,33 @@ void smlua_cobject_init_globals(void) { lua_setglobal(L, "gCharacters"); } - { - smlua_push_object(L, LOT_GLOBALTEXTURES, &gGlobalTextures); - lua_setglobal(L, "gTextures"); - } +#define EXPOSE_GLOBAL(lot, ptr) \ + { \ + smlua_push_object(L, lot, &ptr); \ + lua_setglobal(L, #ptr); \ + } \ - { - smlua_push_object(L, LOT_GLOBALOBJECTANIMATIONS, &gGlobalObjectAnimations); - lua_setglobal(L, "gObjectAnimations"); - } +#define EXPOSE_GLOBAL_WITH_NAME(lot, ptr, name) \ + { \ + smlua_push_object(L, lot, &ptr); \ + lua_setglobal(L, name); \ + } \ - { - smlua_push_object(L, LOT_GLOBALOBJECTCOLLISIONDATA, &gGlobalObjectCollisionData); - lua_setglobal(L, "gGlobalObjectCollisionData"); - } + EXPOSE_GLOBAL_WITH_NAME(LOT_GLOBALTEXTURES, gGlobalTextures, "gTextures"); - { - smlua_push_object(L, LOT_LAKITUSTATE, &gLakituState); - lua_setglobal(L, "gLakituState"); - } + EXPOSE_GLOBAL_WITH_NAME(LOT_GLOBALOBJECTANIMATIONS, gGlobalObjectAnimations, "gObjectAnimations"); - { - smlua_push_object(L, LOT_SERVERSETTINGS, &gServerSettings); - lua_setglobal(L, "gServerSettings"); - } + EXPOSE_GLOBAL(LOT_GLOBALOBJECTCOLLISIONDATA, gGlobalObjectCollisionData); - { - smlua_push_object(L, LOT_LEVELVALUES, &gLevelValues); - lua_setglobal(L, "gLevelValues"); - } + EXPOSE_GLOBAL(LOT_LAKITUSTATE, gLakituState); - { - smlua_push_object(L, LOT_BEHAVIORVALUES, &gBehaviorValues); - lua_setglobal(L, "gBehaviorValues"); - } + EXPOSE_GLOBAL(LOT_SERVERSETTINGS, gServerSettings); - { - smlua_push_object(L, LOT_PAINTINGVALUES, &gPaintingValues); - lua_setglobal(L, "gPaintingValues"); - } + EXPOSE_GLOBAL(LOT_LEVELVALUES, gLevelValues); + + EXPOSE_GLOBAL(LOT_BEHAVIORVALUES, gBehaviorValues); + + EXPOSE_GLOBAL(LOT_PAINTINGVALUES, gPaintingValues); } void smlua_cobject_init_per_file_globals(const char* path) { diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index ec7c0e0c..a9ec55c7 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -3238,7 +3238,8 @@ char gSmluaConstants[] = "" "HOOK_ON_OBJECT_ANIM_UPDATE = 32\n" "HOOK_ON_DIALOG = 33\n" "HOOK_ON_HUD_RENDER_BEHIND = 34\n" -"HOOK_MAX = 35\n" +"HOOK_MIRROR_MARIO_RENDER = 35\n" +"HOOK_MAX = 36\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 b1a32b12..5ae08fd1 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -891,6 +891,28 @@ bool smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(enum LuaHookedEv return false; } +void smlua_call_event_hooks_graph_node_object_and_int_param(enum LuaHookedEventType hookType, struct GraphNodeObject* node, s32 param) { + lua_State* L = gLuaState; + if (L == NULL) { return; } + struct LuaHookedEvent* hook = &sHookedEvents[hookType]; + for (int i = 0; i < hook->count; i++) { + // push the callback onto the stack + lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]); + + // push graph node object + smlua_push_object(L, LOT_GRAPHNODEOBJECT, node); + + // push param + lua_pushinteger(L, param); + + // call the callback + if (0 != smlua_call_hook(L, 2, 0, 0, hook->mod[i])) { + LOG_LUA("Failed to call the callback: %u", hookType); + continue; + } + } +} + //////////////////// // hooked actions // //////////////////// @@ -1529,7 +1551,7 @@ s32 sort_alphabetically(const void *a, const void *b) { } char** smlua_get_chat_player_list(void) { - char* playerNames[MAX_PLAYERS] = { NULL }; + char* playerNames[MAX_PLAYERS] = { NULL }; s32 playerCount = 0; for (s32 i = 0; i < MAX_PLAYERS; i++) { @@ -1642,7 +1664,7 @@ bool smlua_maincommand_exists(const char* maincommand) { free(commands[j]); } free(commands); - + return result; } @@ -1667,7 +1689,7 @@ bool smlua_subcommand_exists(const char* maincommand, const char* subcommand) { free(subcommands[j]); } free(subcommands); - + return result; } diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index aecb9b75..28b47e20 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -46,6 +46,7 @@ enum LuaHookedEventType { HOOK_ON_OBJECT_ANIM_UPDATE, HOOK_ON_DIALOG, HOOK_ON_HUD_RENDER_BEHIND, + HOOK_MIRROR_MARIO_RENDER, HOOK_MAX, }; @@ -85,6 +86,7 @@ static const char* LuaHookedEventTypeName[] = { "HOOK_ON_OBJECT_ANIM_UPDATE", "HOOK_ON_DIALOG", "HOOK_ON_HUD_RENDER_BEHIND", + "HOOK_MIRROR_MARIO_RENDER", "HOOK_MAX" }; @@ -129,6 +131,7 @@ void smlua_call_event_hooks_mario_action_params_ret_int(enum LuaHookedEventType void smlua_call_event_hooks_mario_param_and_int_ret_bool(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, bool* returnValue); bool smlua_call_event_hooks_mario_param_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, s32* returnValue); bool smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, u32 args, s32* returnValue); +void smlua_call_event_hooks_graph_node_object_and_int_param(enum LuaHookedEventType hookType, struct GraphNodeObject* node, s32 param); enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior); const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);