From 82444bc3bfd1aface3b4aeb9d35c3ce7b8228556 Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:24:47 -0500 Subject: [PATCH 1/5] Add HOOK_HEALED_MARIO and HOOK_HURT_MARIO --- autogen/convert_constants.py | 3 +- autogen/lua_definitions/constants.lua | 30 ++++++++++++++++++- autogen/lua_definitions/functions.lua | 5 ++++ docs/lua/constants.md | 27 ++++++++++++++++- docs/lua/functions-3.md | 20 +++++++++++++ docs/lua/functions.md | 1 + docs/lua/guides/hooks.md | 43 +++++++++++++++++++++------ src/game/mario.c | 17 +++++++++++ src/game/mario.h | 13 ++++++++ src/game/mario_actions_airborne.c | 20 ++----------- src/game/mario_actions_moving.c | 9 +----- src/pc/lua/smlua_constants_autogen.c | 10 ++++++- src/pc/lua/smlua_functions_autogen.c | 18 +++++++++++ src/pc/lua/smlua_hooks.c | 2 +- src/pc/lua/smlua_hooks.h | 4 +++ 15 files changed, 182 insertions(+), 40 deletions(-) diff --git a/autogen/convert_constants.py b/autogen/convert_constants.py index 629a9a815..86c168e6c 100644 --- a/autogen/convert_constants.py +++ b/autogen/convert_constants.py @@ -47,7 +47,8 @@ "src/pc/djui/djui_console.h", "src/game/player_palette.h", "src/pc/network/lag_compensation.h", - "src/pc/djui/djui_panel_menu.h" + "src/pc/djui/djui_panel_menu.h", + "src/game/mario.h" ] exclude_constants = { diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index c5626f87c..282c55325 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -4143,6 +4143,28 @@ HUD_DISPLAY_NONE = 0x0000 --- @type HUDDisplayFlag HUD_DISPLAY_DEFAULT = HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_CAMERA | HUD_DISPLAY_FLAG_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020 +--- @class MarioHealType + +--- @type MarioHealType +HEAL_NORMAL = 0 + +--- @type MarioHealType +HEAL_WATER = 1 + +--- @class MarioHurtType + +--- @type MarioHurtType +HURT_NORMAL = 0 + +--- @type MarioHurtType +HURT_WATER = 1 + +--- @type MarioHurtType +HURT_TOXIC_GAS = 2 + +--- @type MarioHurtType +HURT_BURNING = 3 + --- @class CharacterAnimID --- @type CharacterAnimID @@ -9158,7 +9180,13 @@ HOOK_ON_NAMETAGS_RENDER = 46 HOOK_ON_DJUI_THEME_CHANGED = 47 --- @type LuaHookedEventType -HOOK_MAX = 48 +HOOK_HEALED_MARIO = 48 + +--- @type LuaHookedEventType +HOOK_HURT_MARIO = 49 + +--- @type LuaHookedEventType +HOOK_MAX = 50 --- @class LuaModMenuElementType diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 786e9d104..8db9b1adb 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -5081,6 +5081,11 @@ function transition_submerged_to_walking(m) -- ... end +--- @param m MarioState +function update_burning_health_common(m) + -- ... +end + --- @param m MarioState function update_mario_pos_for_anim(m) -- ... diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 3380e2253..3d596feaf 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -35,6 +35,9 @@ - [enum LevelNum](#enum-LevelNum) - [level_update.h](#level_updateh) - [enum HUDDisplayFlag](#enum-HUDDisplayFlag) +- [mario.h](#marioh) + - [enum MarioHealType](#enum-MarioHealType) + - [enum MarioHurtType](#enum-MarioHurtType) - [mario_animation_ids.h](#mario_animation_idsh) - [enum CharacterAnimID](#enum-CharacterAnimID) - [enum MarioAnimID](#enum-MarioAnimID) @@ -1522,6 +1525,26 @@
+## [mario.h](#mario.h) + +### [enum MarioHealType](#MarioHealType) +| Identifier | Value | +| :--------- | :---- | +| HEAL_NORMAL | 0 | +| HEAL_WATER | 1 | + +### [enum MarioHurtType](#MarioHurtType) +| Identifier | Value | +| :--------- | :---- | +| HURT_NORMAL | 0 | +| HURT_WATER | 1 | +| HURT_TOXIC_GAS | 2 | +| HURT_BURNING | 3 | + +[:arrow_up_small:](#) + +
+ ## [mario_animation_ids.h](#mario_animation_ids.h) ### [enum CharacterAnimID](#CharacterAnimID) @@ -3335,7 +3358,9 @@ | HOOK_ON_MODS_LOADED | 45 | | HOOK_ON_NAMETAGS_RENDER | 46 | | HOOK_ON_DJUI_THEME_CHANGED | 47 | -| HOOK_MAX | 48 | +| HOOK_HEALED_MARIO | 48 | +| HOOK_HURT_MARIO | 49 | +| HOOK_MAX | 50 | ### [enum LuaModMenuElementType](#LuaModMenuElementType) | Identifier | Value | diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index 6589eb44c..29e16e8be 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -7090,6 +7090,26 @@ Creates a warp node in the current level and area with id `id` that goes to the
+## [update_burning_health_common](#update_burning_health_common) + +### Lua Example +`update_burning_health_common(m)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | + +### Returns +- None + +### C Prototype +`void update_burning_health_common(struct MarioState* m);` + +[:arrow_up_small:](#) + +
+ ## [update_mario_pos_for_anim](#update_mario_pos_for_anim) ### Lua Example diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 878e1acbe..d29b3e6a1 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -992,6 +992,7 @@ - [set_steep_jump_action](functions-3.md#set_steep_jump_action) - [set_water_plunge_action](functions-3.md#set_water_plunge_action) - [transition_submerged_to_walking](functions-3.md#transition_submerged_to_walking) + - [update_burning_health_common](functions-3.md#update_burning_health_common) - [update_mario_pos_for_anim](functions-3.md#update_mario_pos_for_anim) - [update_mario_sound_and_camera](functions-3.md#update_mario_sound_and_camera) diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index 8459e3795..121944326 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -4,15 +4,38 @@ Hooks are a way for SM64 to trigger Lua code, whereas the functions listed in [functions](../functions.md) allow Lua to trigger SM64 code. # Supported Hooks -- [hook_behavior](#hook_behavior) -- [hook_chat_command](#hook_chat_command) -- [hook_event](#hook_event) -- [hook_mario_action](#hook_mario_action) -- [hook_on_sync_table_change](#hook_on_sync_table_change) -- [hook_mod_menu_button](#hook_mod_menu_button) -- [hook_mod_menu_checkbox](#hook_mod_menu_checkbox) -- [hook_mod_menu_slider](#hook_mod_menu_slider) -- [hook_mod_menu_inputbox](#hook_mod_menu_inputbox) +- [Hooks](#hooks) +- [Supported Hooks](#supported-hooks) + - [hook\_behavior](#hook_behavior) + - [Parameters](#parameters) + - [Returns](#returns) + - [Lua Example](#lua-example) + - [hook\_chat\_command](#hook_chat_command) + - [Parameters](#parameters-1) + - [Lua Example](#lua-example-1) + - [hook\_event](#hook_event) + - [Hook Event Types](#hook-event-types) + - [Parameters](#parameters-2) + - [Lua Example](#lua-example-2) + - [hook\_mario\_action](#hook_mario_action) + - [Parameters](#parameters-3) + - [Action Hook Types](#action-hook-types) + - [Lua Example](#lua-example-3) + - [hook\_on\_sync\_table\_change](#hook_on_sync_table_change) + - [Parameters](#parameters-4) + - [Lua Example](#lua-example-4) + - [hook\_mod\_menu\_button](#hook_mod_menu_button) + - [Parameters](#parameters-5) + - [Lua Example](#lua-example-5) + - [hook\_mod\_menu\_checkbox](#hook_mod_menu_checkbox) + - [Parameters](#parameters-6) + - [Lua Example](#lua-example-6) + - [hook\_mod\_menu\_slider](#hook_mod_menu_slider) + - [Parameters](#parameters-7) + - [Lua Example](#lua-example-7) + - [hook\_mod\_menu\_inputbox](#hook_mod_menu_inputbox) + - [Parameters](#parameters-8) + - [Lua Example](#lua-example-8)
@@ -139,6 +162,8 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh | HOOK_ON_MODS_LOADED | Called directly after every mod file is loaded in by smlua | None | | HOOK_ON_NAMETAGS_RENDER | Called when nametags are rendered. Return a `string` to change what renders on the nametag, return an empty `string` to render nothing. | `string` playerIndex | | HOOK_ON_DJUI_THEME_CHANGED | Called when the DJUI theme is changed. Run `djui_menu_get_theme()` to get the new theme. | None | +| HOOK_HEALED_MARIO | Called when any player is about to heal from any source. Called once per affected player. | MarioState mario, `integer` healType | +| HOOK_HURT_MARIO | Called when any player is about to take damage from any source. Called once per affected player. | MarioState mario, `integer` hurtType | ### Parameters diff --git a/src/game/mario.c b/src/game/mario.c index 06049177f..2d5aed604 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1689,6 +1689,18 @@ void set_submerged_cam_preset_and_spawn_bubbles(struct MarioState *m) { } } +void update_burning_health_common(struct MarioState* m) { + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_BURNING, NULL); + m->health -= 10; + if (m->health < 0x100) { + extern struct MarioState gMarioStates[]; + if (m == &gMarioStates[0]) { + // never kill remote marios + set_mario_action(m, ACT_STANDING_DEATH, 0); + } + } +} + /** * Both increments and decrements Mario's HP. */ @@ -1701,6 +1713,7 @@ void update_mario_health(struct MarioState *m) { if (((u32) m->healCounter | (u32) m->hurtCounter) == 0) { if ((m->input & INPUT_IN_POISON_GAS) && !(m->action & ACT_FLAG_INTANGIBLE)) { if (!(m->flags & MARIO_METAL_CAP) && !gDebugLevelSelect) { + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_TOXIC_GAS, NULL); m->health -= 4; } } else { @@ -1711,8 +1724,10 @@ void update_mario_health(struct MarioState *m) { // when in snow terrains lose 3 health. // If using the debug level select, do not lose any HP to water. if ((m->pos[1] >= (m->waterLevel - 140)) && !terrainIsSnow) { + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HEALED_MARIO, m, HEAL_WATER, NULL); m->health += 0x1A; } else if (!gDebugLevelSelect) { + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_WATER, NULL); m->health -= (terrainIsSnow ? 3 : 1); } } @@ -1720,10 +1735,12 @@ void update_mario_health(struct MarioState *m) { } if (m->healCounter > 0) { + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HEALED_MARIO, m, HEAL_NORMAL, NULL); m->health += 0x40; m->healCounter--; } if (m->hurtCounter > 0) { + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_NORMAL, NULL); m->health -= 0x40; m->hurtCounter--; } diff --git a/src/game/mario.h b/src/game/mario.h index f0ff3d97f..c61b8f1fb 100644 --- a/src/game/mario.h +++ b/src/game/mario.h @@ -9,6 +9,18 @@ extern u16 gLocalBubbleCounter; struct WallCollisionData; +enum MarioHealType { + HEAL_NORMAL, + HEAL_WATER, +}; + +enum MarioHurtType { + HURT_NORMAL, + HURT_WATER, + HURT_TOXIC_GAS, + HURT_BURNING, +}; + s32 is_anim_at_end(struct MarioState *m); s32 is_anim_past_end(struct MarioState *m); s16 set_mario_animation(struct MarioState *m, s32 targetAnimID); @@ -68,5 +80,6 @@ void init_mario_single_from_save_file(struct MarioState* m, u16 index); void init_mario_from_save_file(void); void set_mario_particle_flags(struct MarioState* m, u32 flags, u8 clear); void mario_update_wall(struct MarioState* m, struct WallCollisionData* wcd); +void update_burning_health_common(struct MarioState* m); #endif // MARIO_H diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index 602727819..ae3a44860 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -1045,15 +1045,7 @@ s32 act_burning_jump(struct MarioState *m) { m->marioObj->oMarioBurnTimer += 3; - m->health -= 10; - if (m->health < 0x100) { - if (m != &gMarioStates[0]) { - // never kill remote marios - m->health = 0x100; - } else { - m->health = 0xFF; - } - } + update_burning_health_common(m); reset_rumble_timers(m); return FALSE; @@ -1072,15 +1064,7 @@ s32 act_burning_fall(struct MarioState *m) { set_mario_particle_flags(m, PARTICLE_FIRE, FALSE); m->marioObj->oMarioBurnTimer += 3; - m->health -= 10; - if (m->health < 0x100) { - if (m != &gMarioStates[0]) { - // never kill remote marios - m->health = 0x100; - } else { - m->health = 0xFF; - } - } + update_burning_health_common(m); reset_rumble_timers(m); return FALSE; diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index c8add04f6..09f131e1f 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -1388,14 +1388,7 @@ s32 act_burning_ground(struct MarioState *m) { set_mario_particle_flags(m, PARTICLE_FIRE, FALSE); play_sound(SOUND_MOVING_LAVA_BURN, m->marioObj->header.gfx.cameraToObject); - m->health -= 10; - if (m->health < 0x100) { - extern struct MarioState gMarioStates[]; - if (m == &gMarioStates[0]) { - // never kill remote marios - set_mario_action(m, ACT_STANDING_DEATH, 0); - } - } + update_burning_health_common(m); m->marioBodyState->eyeState = MARIO_EYES_DEAD; diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index d41e300bc..f58a55abc 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -1545,6 +1545,12 @@ char gSmluaConstants[] = "" "HUD_DISPLAY_FLAG_EMPHASIZE_POWER = 0x8000\n" "HUD_DISPLAY_NONE = 0x0000\n" "HUD_DISPLAY_DEFAULT = HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_CAMERA | HUD_DISPLAY_FLAG_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020\n" +"HEAL_NORMAL = 0\n" +"HEAL_WATER = 1\n" +"HURT_NORMAL = 0\n" +"HURT_WATER = 1\n" +"HURT_TOXIC_GAS = 2\n" +"HURT_BURNING = 3\n" "MARIO_ANIM_SLOW_LEDGE_GRAB = 0\n" "MARIO_ANIM_FALL_OVER_BACKWARDS = 1\n" "MARIO_ANIM_BACKWARD_AIR_KB = 2\n" @@ -3202,7 +3208,9 @@ char gSmluaConstants[] = "" "HOOK_ON_MODS_LOADED = 45\n" "HOOK_ON_NAMETAGS_RENDER = 46\n" "HOOK_ON_DJUI_THEME_CHANGED = 47\n" -"HOOK_MAX = 48\n" +"HOOK_HEALED_MARIO = 48\n" +"HOOK_HURT_MARIO = 49\n" +"HOOK_MAX = 50\n" "ACTION_HOOK_EVERY_FRAME = 0\n" "ACTION_HOOK_GRAVITY = 1\n" "ACTION_HOOK_MAX = 2\n" diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index c3f3f02ae..2ab83ae4b 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -16045,6 +16045,23 @@ int smlua_func_transition_submerged_to_walking(lua_State* L) { return 1; } +int smlua_func_update_burning_health_common(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "update_burning_health_common", 1, top); + return 0; + } + + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "update_burning_health_common"); return 0; } + + update_burning_health_common(m); + + return 1; +} + int smlua_func_update_mario_pos_for_anim(lua_State* L) { if (L == NULL) { return 0; } @@ -34490,6 +34507,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "set_steep_jump_action", smlua_func_set_steep_jump_action); smlua_bind_function(L, "set_water_plunge_action", smlua_func_set_water_plunge_action); smlua_bind_function(L, "transition_submerged_to_walking", smlua_func_transition_submerged_to_walking); + smlua_bind_function(L, "update_burning_health_common", smlua_func_update_burning_health_common); smlua_bind_function(L, "update_mario_pos_for_anim", smlua_func_update_mario_pos_for_anim); smlua_bind_function(L, "update_mario_sound_and_camera", smlua_func_update_mario_sound_and_camera); //smlua_bind_function(L, "vec3f_find_ceil", smlua_func_vec3f_find_ceil); <--- UNIMPLEMENTED diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index f0e834985..a7b3b4d56 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -910,7 +910,7 @@ void smlua_call_event_hooks_mario_param_and_int_ret_bool(enum LuaHookedEventType } // output the return value - if (lua_type(L, -1) == LUA_TBOOLEAN) { + if (lua_type(L, -1) == LUA_TBOOLEAN && returnValue != NULL) { *returnValue = smlua_to_boolean(L, -1); } lua_settop(L, prevTop); diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index 5edeea0d5..5bce8721d 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -59,6 +59,8 @@ enum LuaHookedEventType { HOOK_ON_MODS_LOADED, HOOK_ON_NAMETAGS_RENDER, HOOK_ON_DJUI_THEME_CHANGED, + HOOK_HEALED_MARIO, + HOOK_HURT_MARIO, HOOK_MAX, }; @@ -111,6 +113,8 @@ static const char* LuaHookedEventTypeName[] = { "HOOK_ON_MODS_LOADED", "HOOK_ON_NAMETAGS_RENDER", "HOOK_ON_DJUI_THEME_CHANGED", + "HOOK_HEALED_MARIO", + "HOOK_HURT_MARIO" "HOOK_MAX" }; From 0cdd91592314cd053248018254a75f7d0d9a0628 Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:32:41 -0500 Subject: [PATCH 2/5] Remove unnecessary line --- src/game/mario.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/game/mario.c b/src/game/mario.c index 2d5aed604..b2996fea6 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1693,7 +1693,6 @@ void update_burning_health_common(struct MarioState* m) { smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_BURNING, NULL); m->health -= 10; if (m->health < 0x100) { - extern struct MarioState gMarioStates[]; if (m == &gMarioStates[0]) { // never kill remote marios set_mario_action(m, ACT_STANDING_DEATH, 0); From edeb2d9dd71507a6b3a641aa4e25e0cd7a3eb7f9 Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:49:25 -0500 Subject: [PATCH 3/5] Change when the hooks activate I figured it would be more useful to hook after healing/taking damage rather than before --- docs/lua/guides/hooks.md | 4 ++-- src/game/mario.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index 121944326..350adf882 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -162,8 +162,8 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh | HOOK_ON_MODS_LOADED | Called directly after every mod file is loaded in by smlua | None | | HOOK_ON_NAMETAGS_RENDER | Called when nametags are rendered. Return a `string` to change what renders on the nametag, return an empty `string` to render nothing. | `string` playerIndex | | HOOK_ON_DJUI_THEME_CHANGED | Called when the DJUI theme is changed. Run `djui_menu_get_theme()` to get the new theme. | None | -| HOOK_HEALED_MARIO | Called when any player is about to heal from any source. Called once per affected player. | MarioState mario, `integer` healType | -| HOOK_HURT_MARIO | Called when any player is about to take damage from any source. Called once per affected player. | MarioState mario, `integer` hurtType | +| HOOK_HEALED_MARIO | Called when any player has just healed from any source. Called once per affected player. | MarioState mario, `integer` healType | +| HOOK_HURT_MARIO | Called when any player has just taken damage from any source. Called once per affected player. | MarioState mario, `integer` hurtType | ### Parameters diff --git a/src/game/mario.c b/src/game/mario.c index b2996fea6..b06f0493b 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1690,8 +1690,8 @@ void set_submerged_cam_preset_and_spawn_bubbles(struct MarioState *m) { } void update_burning_health_common(struct MarioState* m) { - smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_BURNING, NULL); m->health -= 10; + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_BURNING, NULL); if (m->health < 0x100) { if (m == &gMarioStates[0]) { // never kill remote marios @@ -1712,8 +1712,8 @@ void update_mario_health(struct MarioState *m) { if (((u32) m->healCounter | (u32) m->hurtCounter) == 0) { if ((m->input & INPUT_IN_POISON_GAS) && !(m->action & ACT_FLAG_INTANGIBLE)) { if (!(m->flags & MARIO_METAL_CAP) && !gDebugLevelSelect) { - smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_TOXIC_GAS, NULL); m->health -= 4; + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_TOXIC_GAS, NULL); } } else { if ((m->action & ACT_FLAG_SWIMMING) && !(m->action & ACT_FLAG_INTANGIBLE)) { @@ -1723,25 +1723,25 @@ void update_mario_health(struct MarioState *m) { // when in snow terrains lose 3 health. // If using the debug level select, do not lose any HP to water. if ((m->pos[1] >= (m->waterLevel - 140)) && !terrainIsSnow) { - smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HEALED_MARIO, m, HEAL_WATER, NULL); m->health += 0x1A; + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HEALED_MARIO, m, HEAL_WATER, NULL); } else if (!gDebugLevelSelect) { - smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_WATER, NULL); m->health -= (terrainIsSnow ? 3 : 1); + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_WATER, NULL); } } } } if (m->healCounter > 0) { - smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HEALED_MARIO, m, HEAL_NORMAL, NULL); m->health += 0x40; m->healCounter--; + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HEALED_MARIO, m, HEAL_NORMAL, NULL); } if (m->hurtCounter > 0) { - smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_NORMAL, NULL); m->health -= 0x40; m->hurtCounter--; + smlua_call_event_hooks_mario_param_and_int_ret_bool(HOOK_HURT_MARIO, m, HURT_NORMAL, NULL); } if (m->health > 0x880) { From 3d2fc6d464b86b44498b42b1ca9ebbf4b2786063 Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Sun, 19 Jan 2025 04:49:13 -0500 Subject: [PATCH 4/5] Complete merge --- autogen/lua_definitions/structs.lua | 1 + docs/lua/functions-4.md | 20 ++++++++++++++++++++ docs/lua/structs.md | 1 + src/pc/lua/smlua_cobject_autogen.c | 3 ++- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index f0d30015d..abbd2cbdd 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -1111,6 +1111,7 @@ --- @field public lightingDirX number --- @field public lightingDirY number --- @field public lightingDirZ number +--- @field public mirrorMario boolean --- @field public modelState integer --- @field public punchState integer --- @field public shadeB integer diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md index d82abe843..591d4dc9c 100644 --- a/docs/lua/functions-4.md +++ b/docs/lua/functions-4.md @@ -1207,6 +1207,26 @@ Transitions Mario from being underwater to a walking state. Resets camera to the
+## [update_burning_health_common](#update_burning_health_common) + +### Lua Example +`update_burning_health_common(m)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | + +### Returns +- None + +### C Prototype +`void update_burning_health_common(struct MarioState* m);` + +[:arrow_up_small:](#) + +
+ ## [update_mario_pos_for_anim](#update_mario_pos_for_anim) ### Description diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 7c186f093..b1fa4ac26 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -1694,6 +1694,7 @@ | lightingDirX | `number` | | | lightingDirY | `number` | | | lightingDirZ | `number` | | +| mirrorMario | `boolean` | | | modelState | `integer` | | | punchState | `integer` | | | shadeB | `integer` | | diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 6bb7e3349..6a69f0080 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -1391,7 +1391,7 @@ static struct LuaObjectField sMarioAnimationFields[LUA_MARIO_ANIMATION_FIELD_COU { "targetAnim", LVT_COBJECT_P, offsetof(struct MarioAnimation, targetAnim), false, LOT_ANIMATION }, }; -#define LUA_MARIO_BODY_STATE_FIELD_COUNT 25 +#define LUA_MARIO_BODY_STATE_FIELD_COUNT 26 static struct LuaObjectField sMarioBodyStateFields[LUA_MARIO_BODY_STATE_FIELD_COUNT] = { { "action", LVT_U32, offsetof(struct MarioBodyState, action), false, LOT_NONE }, { "allowPartRotation", LVT_U8, offsetof(struct MarioBodyState, allowPartRotation), false, LOT_NONE }, @@ -1409,6 +1409,7 @@ static struct LuaObjectField sMarioBodyStateFields[LUA_MARIO_BODY_STATE_FIELD_CO { "lightingDirX", LVT_F32, offsetof(struct MarioBodyState, lightingDirX), false, LOT_NONE }, { "lightingDirY", LVT_F32, offsetof(struct MarioBodyState, lightingDirY), false, LOT_NONE }, { "lightingDirZ", LVT_F32, offsetof(struct MarioBodyState, lightingDirZ), false, LOT_NONE }, + { "mirrorMario", LVT_BOOL, offsetof(struct MarioBodyState, mirrorMario), false, LOT_NONE }, { "modelState", LVT_S16, offsetof(struct MarioBodyState, modelState), false, LOT_NONE }, { "punchState", LVT_U8, offsetof(struct MarioBodyState, punchState), false, LOT_NONE }, { "shadeB", LVT_U16, offsetof(struct MarioBodyState, shadeB), false, LOT_NONE }, From 523a288e262dff7a0be125517ab76e4d8f579dae Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Thu, 20 Feb 2025 11:13:25 -0500 Subject: [PATCH 5/5] Add HOOK_AFTER_QUARTER_STEP --- autogen/lua_definitions/constants.lua | 7 ++++-- docs/lua/constants.md | 3 ++- docs/lua/guides/hooks.md | 1 + src/game/mario_actions_automatic.c | 33 ++++++++++-------------- src/game/mario_actions_submerged.c | 4 ++- src/game/mario_step.c | 6 ++++- src/pc/lua/smlua_constants_autogen.c | 3 ++- src/pc/lua/smlua_hooks.c | 36 +++++++++++++++++++++++++++ src/pc/lua/smlua_hooks.h | 3 +++ 9 files changed, 70 insertions(+), 26 deletions(-) diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index f560733f2..87a0c0106 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -9221,7 +9221,10 @@ HOOK_HURT_MARIO = 53 HOOK_ON_INTERACTIONS = 54 --- @type LuaHookedEventType -HOOK_MAX = 55 +HOOK_AFTER_QUARTER_STEP = 55 + +--- @type LuaHookedEventType +HOOK_MAX = 56 --- @class LuaModMenuElementType @@ -12554,7 +12557,7 @@ MINOR_VERSION_NUMBER = 1 SM64COOPDX_VERSION = "v1.2.1" --- @type integer -VERSION_NUMBER = 38 +VERSION_NUMBER = 39 --- @type string VERSION_TEXT = "v" diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 46df7f667..c13b957eb 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -3376,7 +3376,8 @@ | HOOK_HEALED_MARIO | 52 | | HOOK_HURT_MARIO | 53 | | HOOK_ON_INTERACTIONS | 54 | -| HOOK_MAX | 55 | +| HOOK_AFTER_QUARTER_STEP | 55 | +| HOOK_MAX | 56 | ### [enum LuaModMenuElementType](#LuaModMenuElementType) | Identifier | Value | diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index 8f0d08f0b..d1cf809b0 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -168,6 +168,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh | HOOK_HEALED_MARIO | Called when any player has just healed from any source. Called once per affected player. | MarioState mario, `integer` healType | | HOOK_HURT_MARIO | Called when any player has just taken damage from any source. Called once per affected player. | MarioState mario, `integer` hurtType | | HOOK_ON_INTERACTIONS | Called when the Mario interactions are processed | [MarioState](../structs.md#MarioState) mario | +| HOOK_AFTER_QUARTER_STEP | Called after a single quarter step has been processed. Return a step result to override the current step result. | [MarioState](../structs.md#MarioState) mario, `integer` stepType, `integer` stepResult, `integer` stepNumber | ### Parameters diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 355957bfa..983c69c4c 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -365,26 +365,19 @@ s32 perform_hanging_step(struct MarioState *m, Vec3f nextPos) { floorHeight = find_floor(nextPos[0], nextPos[1], nextPos[2], &floor); ceilHeight = vec3f_mario_ceil(nextPos, floorHeight, &ceil); - if (floor == NULL) { - return HANG_HIT_CEIL_OR_OOB; - } - if (ceil == NULL) { - return HANG_LEFT_CEIL; - } - if (ceilHeight - floorHeight <= 160.0f) { - return HANG_HIT_CEIL_OR_OOB; - } - if (ceil->type != SURFACE_HANGABLE) { - return HANG_LEFT_CEIL; - } - - ceilOffset = ceilHeight - (nextPos[1] + 160.0f); - if (ceilOffset < -30.0f) { - return HANG_HIT_CEIL_OR_OOB; - } - if (ceilOffset > 30.0f) { - return HANG_LEFT_CEIL; - } + s32 stepResult = HANG_NONE; + if (floor == NULL) { stepResult = HANG_HIT_CEIL_OR_OOB; } + else if (ceil == NULL) { stepResult = HANG_LEFT_CEIL; } + else if (ceilHeight - floorHeight <= 160.0f) { stepResult = HANG_HIT_CEIL_OR_OOB; } + else if (ceil->type != SURFACE_HANGABLE) { stepResult = HANG_LEFT_CEIL; } + else { + ceilOffset = ceilHeight - (nextPos[1] + 160.0f); + if (ceilOffset < -30.0f) { stepResult = HANG_HIT_CEIL_OR_OOB; } + if (ceilOffset > 30.0f) { stepResult = HANG_LEFT_CEIL; } + } + + smlua_call_event_hooks_after_quarter_step(HOOK_AFTER_QUARTER_STEP, m, STEP_TYPE_HANG, stepResult, 0, &stepResult); + if (stepResult != HANG_NONE) { return stepResult; } nextPos[1] = m->ceilHeight - 160.0f; vec3f_copy(m->pos, nextPos); diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index 54468b5bc..90aa35616 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -186,7 +186,7 @@ void apply_water_current(struct MarioState *m, Vec3f step) { u32 perform_water_step(struct MarioState *m) { if (!m) { return 0; } UNUSED u32 unused; - u32 stepResult; + s32 stepResult; Vec3f nextPos; Vec3f step; struct Object *marioObj = m->marioObj; @@ -211,6 +211,8 @@ u32 perform_water_step(struct MarioState *m) { stepResult = perform_water_full_step(m, nextPos); + smlua_call_event_hooks_after_quarter_step(HOOK_AFTER_QUARTER_STEP, m, STEP_TYPE_WATER, stepResult, 0, &stepResult); + vec3f_copy(marioObj->header.gfx.pos, m->pos); vec3s_set(marioObj->header.gfx.angle, -m->faceAngle[0], m->faceAngle[1], m->faceAngle[2]); diff --git a/src/game/mario_step.c b/src/game/mario_step.c index 6ac8d33bb..6431aa908 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -353,7 +353,7 @@ static s32 perform_ground_quarter_step(struct MarioState *m, Vec3f nextPos) { s32 perform_ground_step(struct MarioState *m) { if (!m) { return 0; } s32 i; - u32 stepResult; + s32 stepResult; Vec3f intendedPos; s32 returnValue = 0; @@ -382,6 +382,8 @@ s32 perform_ground_step(struct MarioState *m) { stepResult = perform_ground_quarter_step(m, intendedPos); gFindWallDirectionActive = false; + smlua_call_event_hooks_after_quarter_step(HOOK_AFTER_QUARTER_STEP, m, STEP_TYPE_GROUND, stepResult, i, &stepResult); + if (stepResult == GROUND_STEP_LEFT_GROUND || stepResult == GROUND_STEP_HIT_WALL_STOP_QSTEPS) { break; } @@ -753,6 +755,8 @@ s32 perform_air_step(struct MarioState *m, u32 stepArg) { gFindWallDirectionAirborne = false; gFindWallDirectionActive = false; + smlua_call_event_hooks_after_quarter_step(HOOK_AFTER_QUARTER_STEP, m, STEP_TYPE_AIR, quarterStepResult, i, &quarterStepResult); + //! On one qf, hit OOB/ceil/wall to store the 2 return value, and continue // getting 0s until your last qf. Graze a wall on your last qf, and it will // return the stored 2 with a sharply angled reference wall. (some gwks) diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index c9ca2ab74..4f5893c58 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -3221,7 +3221,8 @@ char gSmluaConstants[] = "" "HOOK_HEALED_MARIO = 52\n" "HOOK_HURT_MARIO = 53\n" "HOOK_ON_INTERACTIONS = 54\n" -"HOOK_MAX = 55\n" +"HOOK_AFTER_QUARTER_STEP = 55\n" +"HOOK_MAX = 56\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 653ab183e..82911154e 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -1127,6 +1127,42 @@ void smlua_call_event_hooks_string_param(enum LuaHookedEventType hookType, const } } +void smlua_call_event_hooks_after_quarter_step(enum LuaHookedEventType hookType, struct MarioState* m, s32 stepType, s32 stepResult, s32 stepNumber, s32* newResult) { + 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 mario state + lua_getglobal(L, "gMarioStates"); + lua_pushinteger(L, m->playerIndex); + lua_gettable(L, -2); + lua_remove(L, -2); + + // push params + lua_pushinteger(L, stepType); + lua_pushinteger(L, stepResult); + lua_pushinteger(L, stepNumber); + + // call the callback + if (0 != smlua_call_hook(L, 4, 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) { + *newResult = smlua_to_integer(L, -1); + lua_settop(L, prevTop); + } + lua_settop(L, prevTop); + } +} + //////////////////// // hooked actions // //////////////////// diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index 2e47fb4e1..9e0bf5615 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -67,6 +67,7 @@ enum LuaHookedEventType { HOOK_HEALED_MARIO, HOOK_HURT_MARIO, HOOK_ON_INTERACTIONS, + HOOK_AFTER_QUARTER_STEP, HOOK_MAX, }; @@ -126,6 +127,7 @@ static const char* LuaHookedEventTypeName[] = { "HOOK_HEALED_MARIO", "HOOK_HURT_MARIO", "HOOK_ON_INTERACTIONS", + "HOOK_AFTER_QUARTER_STEP", "HOOK_MAX" }; @@ -206,6 +208,7 @@ void smlua_call_event_hooks_graph_node_and_int_param(enum LuaHookedEventType hoo void smlua_call_event_hooks_on_seq_load(enum LuaHookedEventType hookType, u32 player, u32 seqId, s32 loadAsync, s16* returnValue); const char *smlua_call_event_hooks_int_ret_bool_and_string(enum LuaHookedEventType hookType, s32 param, bool* returnValue); void smlua_call_event_hooks_string_param(enum LuaHookedEventType hookType, const char* string); +void smlua_call_event_hooks_after_quarter_step(enum LuaHookedEventType hookType, struct MarioState* m, s32 stepType, s32 stepResult, s32 stepNumber, s32* newResult); enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior); const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);