added HOOK_MIRROR_MARIO_RENDER to Lua (#514)

* added HOOK_MIRROR_MARIO_RENDER to Lua

Previously there was no way to interact with mirror Mario using the Lua api, so this fixes that.

* remove premature optimisation

* revert that
This commit is contained in:
Isaac0-dev 2023-11-20 11:21:15 +10:00 committed by Agent X
parent 0fcfaa147d
commit 23193887db
8 changed files with 74 additions and 45 deletions

View file

@ -9104,7 +9104,10 @@ HOOK_ON_HUD_RENDER_BEHIND = 36
HOOK_ON_COLLIDE_LEVEL_BOUNDS = 37 HOOK_ON_COLLIDE_LEVEL_BOUNDS = 37
--- @type LuaHookedEventType --- @type LuaHookedEventType
HOOK_MAX = 38 HOOK_MIRROR_MARIO_RENDER = 38
--- @type LuaHookedEventType
HOOK_MAX = 39
--- @class HudDisplayFlags --- @class HudDisplayFlags

View file

@ -3253,7 +3253,8 @@
| HOOK_DIALOG_SOUND | 35 | | HOOK_DIALOG_SOUND | 35 |
| HOOK_ON_HUD_RENDER_BEHIND | 36 | | HOOK_ON_HUD_RENDER_BEHIND | 36 |
| HOOK_ON_COLLIDE_LEVEL_BOUNDS | 37 | | HOOK_ON_COLLIDE_LEVEL_BOUNDS | 37 |
| HOOK_MAX | 38 | | HOOK_MIRROR_MARIO_RENDER | 38 |
| HOOK_MAX | 39 |
[:arrow_up_small:](#) [:arrow_up_small:](#)

View file

@ -117,12 +117,15 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
| 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, `string` messageSent | | 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, `string` messageSent |
| HOOK_OBJECT_SET_MODEL | Called when a behavior changes models. Also runs when a behavior spawns | [Object](structs.md#Object) obj, `integer` modelID | | 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 | | 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 |
| HOOK_JOINED_GAME | Called when the local player finishes the join process (if the player isn't the host) | None |
| 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_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_JOINED_GAME | Called when the local player finishes the join process (if the player isn't the host) | None |
| HOOK_ON_OBJECT_ANIM_UPDATE | Called when an object's animation is updated | [Object](structs.md#Object) objNode | | 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_ON_DIALOG | Called when a dialog appears. Return `false` to prevent it from appearing | `integer` dialogId |
| HOOK_ON_EXIT | Called before the game shuts down | None | | HOOK_ON_EXIT | Called before the game shuts down | None |
| HOOK_DIALOG_SOUND | Called when a dialog box sound is going to play, return a `DS_*` constant to override the sound | `integer` dialogSound | | HOOK_DIALOG_SOUND | Called when a dialog box sound is going to play, return a `DS_*` constant to override the sound | `integer` dialogSound |
| HOOK_ON_HUD_RENDER_BEHIND | Called when the HUD is being rendered, every HUD call in this hook renders behind the vanilla HUD | None |
| HOOK_ON_COLLIDE_LEVEL_BOUNDS | Called when a mario collides with the level boundaries | [MarioState](structs.md#MarioState)mario |
| HOOK_MIRROR_MARIO_RENDER | Called when a Mirror Mario is rendered. | [GraphNodeObject](structs.md#GraphNodeObject) mirrorMario | `integer` mirrorMarioIndex |
### Parameters ### Parameters

View file

@ -25,6 +25,7 @@
#include "hardcoded.h" #include "hardcoded.h"
#include "sound_init.h" #include "sound_init.h"
#include "pc/network/network.h" #include "pc/network/network.h"
#include "pc/lua/smlua_hooks.h"
#define TOAD_STAR_1_REQUIREMENT gBehaviorValues.ToadStar1Requirement #define TOAD_STAR_1_REQUIREMENT gBehaviorValues.ToadStar1Requirement
#define TOAD_STAR_2_REQUIREMENT gBehaviorValues.ToadStar2Requirement #define TOAD_STAR_2_REQUIREMENT gBehaviorValues.ToadStar2Requirement
@ -705,6 +706,8 @@ Gfx* geo_render_mirror_mario(s32 callContext, struct GraphNode* node, UNUSED Mat
gMirrorMario[i].scale[0] *= -1.0f; gMirrorMario[i].scale[0] *= -1.0f;
// TODO: does rendering the mirror room still crash? // TODO: does rendering the mirror room still crash?
gMirrorMario[i].node.flags |= GRAPH_RENDER_ACTIVE; 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 { } else {
gMirrorMario[i].node.flags &= ~GRAPH_RENDER_ACTIVE; gMirrorMario[i].node.flags &= ~GRAPH_RENDER_ACTIVE;
} }

View file

@ -604,54 +604,47 @@ void smlua_cobject_init_globals(void) {
} }
{ {
smlua_push_object(L, LOT_GLOBALTEXTURES, &gGlobalTextures); lua_newtable(L);
lua_setglobal(L, "gTextures"); int t = lua_gettop(gLuaState);
for (s32 i = 0; i < PALETTE_PRESET_MAX; i++) {
lua_pushinteger(L, i);
smlua_push_object(L, LOT_PLAYERPALETTE, &gPalettePresets[i]);
lua_settable(L, t);
}
lua_setglobal(L, "gPalettePresets");
} }
{ #define EXPOSE_GLOBAL(lot, ptr) \
smlua_push_object(L, LOT_GLOBALOBJECTANIMATIONS, &gGlobalObjectAnimations); { \
lua_setglobal(L, "gObjectAnimations"); smlua_push_object(L, lot, &ptr); \
} lua_setglobal(L, #ptr); \
} \
{ #define EXPOSE_GLOBAL_WITH_NAME(lot, ptr, name) \
smlua_push_object(L, LOT_GLOBALOBJECTCOLLISIONDATA, &gGlobalObjectCollisionData); { \
lua_setglobal(L, "gGlobalObjectCollisionData"); smlua_push_object(L, lot, &ptr); \
} lua_setglobal(L, name); \
} \
{ 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_PAINTINGVALUES, gPaintingValues);
smlua_push_object(L, LOT_NAMETAGSSETTINGS, &gNametagsSettings);
lua_setglobal(L, "gNametagsSettings");
}
{ EXPOSE_GLOBAL(LOT_GLOBALOBJECTCOLLISIONDATA, gGlobalObjectCollisionData); // I wish we named this gObjectCollisionData
smlua_push_object(L, LOT_LEVELVALUES, &gLevelValues);
lua_setglobal(L, "gLevelValues");
}
{ EXPOSE_GLOBAL(LOT_LEVELVALUES, gLevelValues);
smlua_push_object(L, LOT_BEHAVIORVALUES, &gBehaviorValues);
lua_setglobal(L, "gBehaviorValues");
}
{ EXPOSE_GLOBAL(LOT_BEHAVIORVALUES, gBehaviorValues);
smlua_push_object(L, LOT_PAINTINGVALUES, &gPaintingValues);
lua_setglobal(L, "gPaintingValues");
}
{ EXPOSE_GLOBAL(LOT_FIRSTPERSONCAMERA, gFirstPersonCamera);
smlua_push_object(L, LOT_FIRSTPERSONCAMERA, &gFirstPersonCamera);
lua_setglobal(L, "gFirstPersonCamera"); EXPOSE_GLOBAL(LOT_LAKITUSTATE, gLakituState);
}
EXPOSE_GLOBAL(LOT_SERVERSETTINGS, gServerSettings);
EXPOSE_GLOBAL(LOT_NAMETAGSSETTINGS, gNametagsSettings);
} }
void smlua_cobject_init_per_file_globals(const char* path) { void smlua_cobject_init_per_file_globals(const char* path) {

View file

@ -3226,7 +3226,8 @@ char gSmluaConstants[] = ""
"HOOK_DIALOG_SOUND = 35\n" "HOOK_DIALOG_SOUND = 35\n"
"HOOK_ON_HUD_RENDER_BEHIND = 36\n" "HOOK_ON_HUD_RENDER_BEHIND = 36\n"
"HOOK_ON_COLLIDE_LEVEL_BOUNDS = 37\n" "HOOK_ON_COLLIDE_LEVEL_BOUNDS = 37\n"
"HOOK_MAX = 38\n" "HOOK_MIRROR_MARIO_RENDER = 38\n"
"HOOK_MAX = 39\n"
"ACTION_HOOK_EVERY_FRAME = 0\n" "ACTION_HOOK_EVERY_FRAME = 0\n"
"ACTION_HOOK_GRAVITY = 1\n" "ACTION_HOOK_GRAVITY = 1\n"
"ACTION_HOOK_MAX = 2\n" "ACTION_HOOK_MAX = 2\n"

View file

@ -916,6 +916,28 @@ bool smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(enum LuaHookedEv
return false; 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 // // hooked actions //
//////////////////// ////////////////////

View file

@ -49,6 +49,7 @@ enum LuaHookedEventType {
HOOK_DIALOG_SOUND, HOOK_DIALOG_SOUND,
HOOK_ON_HUD_RENDER_BEHIND, HOOK_ON_HUD_RENDER_BEHIND,
HOOK_ON_COLLIDE_LEVEL_BOUNDS, HOOK_ON_COLLIDE_LEVEL_BOUNDS,
HOOK_MIRROR_MARIO_RENDER,
HOOK_MAX, HOOK_MAX,
}; };
@ -91,6 +92,7 @@ static const char* LuaHookedEventTypeName[] = {
"HOOK_DIALOG_SOUND", "HOOK_DIALOG_SOUND",
"HOOK_ON_HUD_RENDER_BEHIND", "HOOK_ON_HUD_RENDER_BEHIND",
"HOOK_ON_COLLIDE_LEVEL_BOUNDS", "HOOK_ON_COLLIDE_LEVEL_BOUNDS",
"HOOK_MIRROR_MARIO_RENDER",
"HOOK_MAX" "HOOK_MAX"
}; };
@ -136,6 +138,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); 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_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); 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); enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior);
const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior); const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);