Add HOOK_BEFORE_SET_MARIO_ACTION (#253)

* Small quality of life changes

Disabled fixed collision in sm74 by default.
Popping should now completely set the popped player's speed to 0.

* Add HOOK_BEFORE_SET_MARIO_ACTION

Param: incoming action
Return: changes incoming action
If the return value is 1, prevent the action from happening entirely.
0 can't be used here since it'll break the title screen.

* Update hooks.md

* Revert "Small quality of life changes"

This reverts commit 05dd235cd0.
This commit is contained in:
Sunk 2023-02-22 20:28:23 -05:00 committed by GitHub
parent 756719bb81
commit 9ec75abc60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 47 additions and 4 deletions

View file

@ -8152,7 +8152,10 @@ HOOK_OBJECT_SET_MODEL = 28
HOOK_CHARACTER_SOUND = 29 HOOK_CHARACTER_SOUND = 29
--- @type LuaHookedEventType --- @type LuaHookedEventType
HOOK_MAX = 30 HOOK_BEFORE_SET_MARIO_ACTION = 30
--- @type LuaHookedEventType
HOOK_MAX = 31
--- @class HudDisplayFlags --- @class HudDisplayFlags

View file

@ -760,6 +760,7 @@
--- @field public unkC4 number --- @field public unkC4 number
--- @field public usedObj Object --- @field public usedObj Object
--- @field public vel Vec3f --- @field public vel Vec3f
--- @field public visibleToEnemies integer
--- @field public wall Surface --- @field public wall Surface
--- @field public wallKickTimer integer --- @field public wallKickTimer integer
--- @field public wallNormal Vec3f --- @field public wallNormal Vec3f

View file

@ -2894,7 +2894,8 @@
| HOOK_ON_CHAT_MESSAGE | 27 | | HOOK_ON_CHAT_MESSAGE | 27 |
| HOOK_OBJECT_SET_MODEL | 28 | | HOOK_OBJECT_SET_MODEL | 28 |
| HOOK_CHARACTER_SOUND | 29 | | HOOK_CHARACTER_SOUND | 29 |
| HOOK_MAX | 30 | | HOOK_BEFORE_SET_MARIO_ACTION | 30 |
| HOOK_MAX | 31 |
[:arrow_up_small:](#) [:arrow_up_small:](#)

View file

@ -116,6 +116,7 @@ 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 | | 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_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_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. | `integer` incomingAction |
### Parameters ### Parameters

View file

@ -1086,6 +1086,7 @@
| unkC4 | `number` | | | unkC4 | `number` | |
| usedObj | [Object](structs.md#Object) | | | usedObj | [Object](structs.md#Object) | |
| vel | [Vec3f](structs.md#Vec3f) | read-only | | vel | [Vec3f](structs.md#Vec3f) | read-only |
| visibleToEnemies | `integer` | |
| wall | [Surface](structs.md#Surface) | | | wall | [Surface](structs.md#Surface) | |
| wallKickTimer | `integer` | | | wallKickTimer | `integer` | |
| wallNormal | [Vec3f](structs.md#Vec3f) | read-only | | wallNormal | [Vec3f](structs.md#Vec3f) | read-only |

View file

@ -1093,6 +1093,10 @@ static u32 set_mario_action_cutscene(struct MarioState *m, u32 action, UNUSED u3
* specific function if needed. * specific function if needed.
*/ */
u32 set_mario_action(struct MarioState *m, u32 action, u32 actionArg) { u32 set_mario_action(struct MarioState *m, u32 action, u32 actionArg) {
u32 returnValue = 0;
smlua_call_event_hooks_int_param_ret_int(HOOK_BEFORE_SET_MARIO_ACTION, action, &returnValue);
if (returnValue == 1) { return TRUE; } else if (returnValue) { action = returnValue; }
switch (action & ACT_GROUP_MASK) { switch (action & ACT_GROUP_MASK) {
case ACT_GROUP_MOVING: case ACT_GROUP_MOVING:
action = set_mario_action_moving(m, action, actionArg); action = set_mario_action_moving(m, action, actionArg);

View file

@ -800,7 +800,7 @@ static struct LuaObjectField sMarioBodyStateFields[LUA_MARIO_BODY_STATE_FIELD_CO
{ "wingFlutter", LVT_S8, offsetof(struct MarioBodyState, wingFlutter), false, LOT_NONE }, { "wingFlutter", LVT_S8, offsetof(struct MarioBodyState, wingFlutter), false, LOT_NONE },
}; };
#define LUA_MARIO_STATE_FIELD_COUNT 76 #define LUA_MARIO_STATE_FIELD_COUNT 77
static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = {
{ "action", LVT_U32, offsetof(struct MarioState, action), false, LOT_NONE }, { "action", LVT_U32, offsetof(struct MarioState, action), false, LOT_NONE },
{ "actionArg", LVT_U32, offsetof(struct MarioState, actionArg), false, LOT_NONE }, { "actionArg", LVT_U32, offsetof(struct MarioState, actionArg), false, LOT_NONE },
@ -873,6 +873,7 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = {
{ "unkC4", LVT_F32, offsetof(struct MarioState, unkC4), false, LOT_NONE }, { "unkC4", LVT_F32, offsetof(struct MarioState, unkC4), false, LOT_NONE },
{ "usedObj", LVT_COBJECT_P, offsetof(struct MarioState, usedObj), false, LOT_OBJECT }, { "usedObj", LVT_COBJECT_P, offsetof(struct MarioState, usedObj), false, LOT_OBJECT },
{ "vel", LVT_COBJECT, offsetof(struct MarioState, vel), true, LOT_VEC3F }, { "vel", LVT_COBJECT, offsetof(struct MarioState, vel), true, LOT_VEC3F },
{ "visibleToEnemies", LVT_U8, offsetof(struct MarioState, visibleToEnemies), false, LOT_NONE },
{ "wall", LVT_COBJECT_P, offsetof(struct MarioState, wall), false, LOT_SURFACE }, { "wall", LVT_COBJECT_P, offsetof(struct MarioState, wall), false, LOT_SURFACE },
{ "wallKickTimer", LVT_U8, offsetof(struct MarioState, wallKickTimer), false, LOT_NONE }, { "wallKickTimer", LVT_U8, offsetof(struct MarioState, wallKickTimer), false, LOT_NONE },
{ "wallNormal", LVT_COBJECT, offsetof(struct MarioState, wallNormal), true, LOT_VEC3F }, { "wallNormal", LVT_COBJECT, offsetof(struct MarioState, wallNormal), true, LOT_VEC3F },

View file

@ -2893,7 +2893,8 @@ char gSmluaConstants[] = ""
"HOOK_ON_CHAT_MESSAGE = 27\n" "HOOK_ON_CHAT_MESSAGE = 27\n"
"HOOK_OBJECT_SET_MODEL = 28\n" "HOOK_OBJECT_SET_MODEL = 28\n"
"HOOK_CHARACTER_SOUND = 29\n" "HOOK_CHARACTER_SOUND = 29\n"
"HOOK_MAX = 30\n" "HOOK_BEFORE_SET_MARIO_ACTION = 30\n"
"HOOK_MAX = 31\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

@ -676,6 +676,33 @@ bool smlua_call_event_hooks_mario_charactersound_param_ret_int(enum LuaHookedEve
return false; return false;
} }
void smlua_call_event_hooks_int_param_ret_int(enum LuaHookedEventType hookType, u32 param, u32* 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_TNUMBER) {
*returnValue = smlua_to_integer(L, -1);
}
lua_settop(L, prevTop);
}
}
//////////////////// ////////////////////
// hooked actions // // hooked actions //
//////////////////// ////////////////////

View file

@ -41,6 +41,7 @@ enum LuaHookedEventType {
HOOK_ON_CHAT_MESSAGE, HOOK_ON_CHAT_MESSAGE,
HOOK_OBJECT_SET_MODEL, HOOK_OBJECT_SET_MODEL,
HOOK_CHARACTER_SOUND, HOOK_CHARACTER_SOUND,
HOOK_BEFORE_SET_MARIO_ACTION,
HOOK_MAX, HOOK_MAX,
}; };
@ -75,6 +76,7 @@ static const char* LuaHookedEventTypeName[] = {
"HOOK_ON_CHAT_MESSAGE", "HOOK_ON_CHAT_MESSAGE",
"HOOK_OBJECT_SET_MODEL", "HOOK_OBJECT_SET_MODEL",
"HOOK_CHARACTER_SOUND", "HOOK_CHARACTER_SOUND",
"HOOK_BEFORE_SET_MARIO_ACTION",
"HOOK_MAX" "HOOK_MAX"
}; };
@ -113,6 +115,7 @@ void smlua_call_event_hooks_use_act_select(enum LuaHookedEventType hookType, int
void smlua_call_event_hooks_ret_bool(enum LuaHookedEventType hookType, 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_on_chat_message(enum LuaHookedEventType hookType, struct MarioState* m, const char* message, bool* returnValue);
bool smlua_call_event_hooks_mario_charactersound_param_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, enum CharacterSound characterSound, s32* returnValue); bool smlua_call_event_hooks_mario_charactersound_param_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, enum CharacterSound characterSound, s32* returnValue);
void smlua_call_event_hooks_int_param_ret_int(enum LuaHookedEventType hookType, u32 param, u32* returnValue);
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);