From 05dd235cd0e3633bf1da48bc2f9f0b8a3db087ee Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Sat, 14 Jan 2023 14:07:53 -0500 Subject: [PATCH 1/5] Small quality of life changes Disabled fixed collision in sm74 by default. Popping should now completely set the popped player's speed to 0. --- mods/sm74/main.lua | 2 +- src/game/mario_actions_automatic.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mods/sm74/main.lua b/mods/sm74/main.lua index 92b10598..2b867da4 100644 --- a/mods/sm74/main.lua +++ b/mods/sm74/main.lua @@ -29,7 +29,7 @@ gBehaviorValues.dialogs.KoopaQuickThiWinDialog = DIALOG_031 -- force server settings -- --------------------------- -gLevelValues.fixCollisionBugs = 1 +gServerSettings.skipIntro = 1 -------------- -- movtexs -- diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index ecea7404..5eaca685 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -1047,9 +1047,7 @@ s32 act_bubbled(struct MarioState* m) { m->health = 0x100; m->marioObj->oIntangibleTimer = 0; m->peakHeight = m->pos[1]; - m->vel[0] = 0; - m->vel[1] = 0; - m->vel[2] = 0; + mario_set_forward_vel(m, 0.0f); m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; if (m->playerIndex == 0) { soft_reset_camera(m->area->camera); From 3002b0ca0f02e71a7132276885755d1a72fc47cb Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Sun, 15 Jan 2023 19:16:14 -0500 Subject: [PATCH 2/5] 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. --- autogen/lua_definitions/constants.lua | 5 ++++- autogen/lua_definitions/structs.lua | 1 + docs/lua/constants.md | 3 ++- docs/lua/structs.md | 1 + src/game/mario.c | 4 ++++ src/pc/lua/smlua_cobject_autogen.c | 3 ++- src/pc/lua/smlua_constants_autogen.c | 3 ++- src/pc/lua/smlua_hooks.c | 27 +++++++++++++++++++++++++++ src/pc/lua/smlua_hooks.h | 3 +++ 9 files changed, 46 insertions(+), 4 deletions(-) diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 3dbb3bd4..6f0eff76 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -8137,7 +8137,10 @@ HOOK_OBJECT_SET_MODEL = 28 HOOK_CHARACTER_SOUND = 29 --- @type LuaHookedEventType -HOOK_MAX = 30 +HOOK_BEFORE_SET_MARIO_ACTION = 30 + +--- @type LuaHookedEventType +HOOK_MAX = 31 --- @class HudDisplayFlags diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index e42ab363..df94b4ef 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -748,6 +748,7 @@ --- @field public unkC4 number --- @field public usedObj Object --- @field public vel Vec3f +--- @field public visibleToEnemies integer --- @field public wall Surface --- @field public wallKickTimer integer --- @field public wallNormal Vec3f diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 6061d451..f4e9892e 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -2881,7 +2881,8 @@ | HOOK_ON_CHAT_MESSAGE | 27 | | HOOK_OBJECT_SET_MODEL | 28 | | HOOK_CHARACTER_SOUND | 29 | -| HOOK_MAX | 30 | +| HOOK_BEFORE_SET_MARIO_ACTION | 30 | +| HOOK_MAX | 31 | [:arrow_up_small:](#) diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 1a4456ad..5ccc57d9 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -1071,6 +1071,7 @@ | unkC4 | `number` | | | usedObj | [Object](structs.md#Object) | | | vel | [Vec3f](structs.md#Vec3f) | read-only | +| visibleToEnemies | `integer` | | | wall | [Surface](structs.md#Surface) | | | wallKickTimer | `integer` | | | wallNormal | [Vec3f](structs.md#Vec3f) | read-only | diff --git a/src/game/mario.c b/src/game/mario.c index c6bd9557..33915df7 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1093,6 +1093,10 @@ static u32 set_mario_action_cutscene(struct MarioState *m, u32 action, UNUSED u3 * specific function if needed. */ 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) { case ACT_GROUP_MOVING: action = set_mario_action_moving(m, action, actionArg); diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 9b0e0716..25c5ad4b 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -787,7 +787,7 @@ static struct LuaObjectField sMarioBodyStateFields[LUA_MARIO_BODY_STATE_FIELD_CO { "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] = { { "action", LVT_U32, offsetof(struct MarioState, action), false, LOT_NONE }, { "actionArg", LVT_U32, offsetof(struct MarioState, actionArg), false, LOT_NONE }, @@ -860,6 +860,7 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "unkC4", LVT_F32, offsetof(struct MarioState, unkC4), false, LOT_NONE }, { "usedObj", LVT_COBJECT_P, offsetof(struct MarioState, usedObj), false, LOT_OBJECT }, { "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 }, { "wallKickTimer", LVT_U8, offsetof(struct MarioState, wallKickTimer), false, LOT_NONE }, { "wallNormal", LVT_COBJECT, offsetof(struct MarioState, wallNormal), true, LOT_VEC3F }, diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index e8eaf9a5..ce761e17 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -2888,7 +2888,8 @@ char gSmluaConstants[] = "" "HOOK_ON_CHAT_MESSAGE = 27\n" "HOOK_OBJECT_SET_MODEL = 28\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_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 0e61d43a..26a5bdf1 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -671,6 +671,33 @@ bool smlua_call_event_hooks_mario_charactersound_param_ret_int(enum LuaHookedEve 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 // //////////////////// diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index f1838117..f522d867 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -41,6 +41,7 @@ enum LuaHookedEventType { HOOK_ON_CHAT_MESSAGE, HOOK_OBJECT_SET_MODEL, HOOK_CHARACTER_SOUND, + HOOK_BEFORE_SET_MARIO_ACTION, HOOK_MAX, }; @@ -75,6 +76,7 @@ static const char* LuaHookedEventTypeName[] = { "HOOK_ON_CHAT_MESSAGE", "HOOK_OBJECT_SET_MODEL", "HOOK_CHARACTER_SOUND", + "HOOK_BEFORE_SET_MARIO_ACTION", "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_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); +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); const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior); From f40e714cb817fbbdba5cbd00117e99c28f39aa89 Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Sun, 15 Jan 2023 19:24:36 -0500 Subject: [PATCH 3/5] Update hooks.md --- docs/lua/guides/hooks.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index 04a8dd10..61a13695 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -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_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_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 From b229d2d79d9598aa339ddbea30f1aba7b2866c4a Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Sat, 11 Feb 2023 15:18:01 -0500 Subject: [PATCH 4/5] Revert "Small quality of life changes" This reverts commit 05dd235cd0e3633bf1da48bc2f9f0b8a3db087ee. --- mods/sm74/main.lua | 2 +- src/game/mario_actions_automatic.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mods/sm74/main.lua b/mods/sm74/main.lua index 2b867da4..92b10598 100644 --- a/mods/sm74/main.lua +++ b/mods/sm74/main.lua @@ -29,7 +29,7 @@ gBehaviorValues.dialogs.KoopaQuickThiWinDialog = DIALOG_031 -- force server settings -- --------------------------- -gServerSettings.skipIntro = 1 +gLevelValues.fixCollisionBugs = 1 -------------- -- movtexs -- diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 5eaca685..ecea7404 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -1047,7 +1047,9 @@ s32 act_bubbled(struct MarioState* m) { m->health = 0x100; m->marioObj->oIntangibleTimer = 0; m->peakHeight = m->pos[1]; - mario_set_forward_vel(m, 0.0f); + m->vel[0] = 0; + m->vel[1] = 0; + m->vel[2] = 0; m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; if (m->playerIndex == 0) { soft_reset_camera(m->area->camera); From 6c362312f74fde48ccfbb2b85c6da1edbdf26f22 Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Wed, 1 Mar 2023 20:24:12 -0500 Subject: [PATCH 5/5] Fix inaccuracies in hooks.md --- docs/lua/guides/hooks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index 61a13695..09362200 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -112,8 +112,8 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh | HOOK_USE_ACT_SELECT | Called when the level changes, return `true` to show act selection screen and `false` otherwise | `integer` levelNum | | HOOK_ON_CHANGE_CAMERA_ANGLE | Called when the player changes the camera mode to Lakitu cam or Mario cam, return `false` to prevent the change. | `integer` mode | | HOOK_ON_SCREEN_TRANSITION | Called when the game is about to play a transition, return `false` to prevent the transition from playing. | `integer` type | -| 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_ALLOW_HAZARD_SURFACE | Called once per player per frame. Return `false` to prevent the player from being affected by lava or quicksand. | [MarioState](structs.md#MarioState) mario | +| 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_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 |