From eaa1a59996b93abfdd0f6297e02b7b6c83e3e679 Mon Sep 17 00:00:00 2001 From: Isaac0-dev <62234577+Isaac0-dev@users.noreply.github.com> Date: Tue, 14 May 2024 09:45:33 +1000 Subject: [PATCH] fixed some mario cutscene action related bugs (#43) - fixed a bug where remote players would show mario's head repeatedly twitching up and down while reading automatic dialog - fixed a bug where remote mario's would sometimes not update while unlocking a star door, resulting in the previous animation playing during that action - fixed a bug where players exiting a warp door could get stuck for a few extra frames due to other players opening that same door. - added dialogId to MarioState, which is synced for remote players the dialog id that player has active. this can be used by Lua mods - don't access the local player's dialog id because that isn't updated as that is unnecessary --- autogen/convert_structs.py | 2 +- autogen/lua_definitions/structs.lua | 1 + docs/lua/structs.md | 1 + include/types.h | 1 + src/game/mario_actions_cutscene.c | 20 ++++++++++++++++++-- src/pc/lua/smlua_cobject_autogen.c | 3 ++- src/pc/network/packets/packet_player.c | 6 ++++++ 7 files changed, 30 insertions(+), 4 deletions(-) diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py index 6da1b20d..ba204a8f 100644 --- a/autogen/convert_structs.py +++ b/autogen/convert_structs.py @@ -91,7 +91,7 @@ override_field_deprecated = { } override_field_immutable = { - "MarioState": [ "playerIndex", "controller", "marioObj", "marioBodyState", "statusForCamera", "area" ], + "MarioState": [ "playerIndex", "controller", "marioObj", "marioBodyState", "statusForCamera", "area", "dialogId" ], "MarioAnimation": [ "animDmaTable" ], "ObjectNode": [ "next", "prev" ], "Character": [ "*" ], diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index 3eb27ce4..f39f25ba 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -983,6 +983,7 @@ --- @field public controller Controller --- @field public curAnimOffset number --- @field public currentRoom integer +--- @field public dialogId integer --- @field public doubleJumpTimer integer --- @field public faceAngle Vec3s --- @field public fadeWarpOpacity integer diff --git a/docs/lua/structs.md b/docs/lua/structs.md index d6f62fe7..bededb1e 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -1344,6 +1344,7 @@ | controller | [Controller](structs.md#Controller) | read-only | | curAnimOffset | `number` | | | currentRoom | `integer` | | +| dialogId | `integer` | read-only | | doubleJumpTimer | `integer` | | | faceAngle | [Vec3s](structs.md#Vec3s) | read-only | | fadeWarpOpacity | `integer` | | diff --git a/include/types.h b/include/types.h index 2d77d927..9c7efcc2 100644 --- a/include/types.h +++ b/include/types.h @@ -432,6 +432,7 @@ struct MarioState /*????*/ u32 cap; /*????*/ u8 bounceSquishTimer; /*????*/ u8 skipWarpInteractionsTimer; + /*????*/ s16 dialogId; }; struct TextureInfo diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 30a101b0..898bf5ad 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -540,7 +540,7 @@ s32 act_reading_automatic_dialog(struct MarioState *m) { // set Mario dialog if (m->actionState == 9) { // only show dialog for local player - if (m == &gMarioStates[0]) { + if (m->playerIndex == 0) { u32 actionArg = m->actionArg; if (GET_HIGH_U16_OF_32(actionArg) == 0) { create_dialog_box(GET_LOW_U16_OF_32(actionArg)); @@ -549,7 +549,8 @@ s32 act_reading_automatic_dialog(struct MarioState *m) { } } } else if (m->actionState == 10) { // wait until dialog is done - if (get_dialog_id() >= 0) { + if ((m->playerIndex == 0 && get_dialog_id() >= 0) || + (m->playerIndex != 0 && m->dialogId != 0)) { m->actionState--; } } else if (m->actionState < 19) { // wait until dialog is done @@ -1006,6 +1007,7 @@ s32 act_unlocking_star_door(struct MarioState *m) { m->actionState++; break; case 1: + set_character_animation(m, CHAR_ANIM_SUMMON_STAR); if (is_anim_at_end(m)) { if (m->playerIndex == 0 || allowRemoteStarSpawn) { if (m->playerIndex != 0) { allowRemoteStarSpawn = FALSE; } @@ -1021,6 +1023,7 @@ s32 act_unlocking_star_door(struct MarioState *m) { } break; case 3: + set_character_animation(m, CHAR_ANIM_RETURN_STAR_APPROACH_DOOR); if (m->playerIndex != 0) { allowRemoteStarSpawn = TRUE; } if (is_anim_at_end(m)) { save_file_set_flags(get_door_save_file_flag(m->usedObj)); @@ -1142,6 +1145,19 @@ s32 act_going_through_door(struct MarioState *m) { s32 act_warp_door_spawn(struct MarioState *m) { if (!m) { return 0; } + + // Check if other players are also using this door + // if they are, cancel our interaction with the door + if (m->usedObj) { + for (u8 i = 0; i < MAX_PLAYERS; i++) { + struct MarioState *m2 = &gMarioStates[i]; + if (is_player_active(m2) && (m2->action == ACT_PULLING_DOOR || m2->action == ACT_PUSHING_DOOR) && m->usedObj == m2->usedObj) { + m->usedObj = NULL; + break; + } + } + } + if (m->actionState == 0) { m->actionState = 1; if (m->usedObj != NULL) { diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index ac929ca0..1dd7ce11 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -1087,7 +1087,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 79 +#define LUA_MARIO_STATE_FIELD_COUNT 80 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 }, @@ -1107,6 +1107,7 @@ static struct LuaObjectField sMarioStateFields[LUA_MARIO_STATE_FIELD_COUNT] = { { "controller", LVT_COBJECT_P, offsetof(struct MarioState, controller), true, LOT_CONTROLLER }, { "curAnimOffset", LVT_F32, offsetof(struct MarioState, curAnimOffset), false, LOT_NONE }, { "currentRoom", LVT_S16, offsetof(struct MarioState, currentRoom), false, LOT_NONE }, + { "dialogId", LVT_S16, offsetof(struct MarioState, dialogId), true, LOT_NONE }, { "doubleJumpTimer", LVT_U8, offsetof(struct MarioState, doubleJumpTimer), false, LOT_NONE }, { "faceAngle", LVT_COBJECT, offsetof(struct MarioState, faceAngle), true, LOT_VEC3S }, { "fadeWarpOpacity", LVT_U8, offsetof(struct MarioState, fadeWarpOpacity), false, LOT_NONE }, diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 38f44cb7..4a04a896 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -73,6 +73,8 @@ struct PacketPlayerData { u8 levelSyncValid; u8 areaSyncValid; u8 knockbackTimer; + + s16 dialogId; }; #pragma pack() @@ -142,6 +144,8 @@ static void read_packet_data(struct PacketPlayerData* data, struct MarioState* m data->levelSyncValid = np->currLevelSyncValid; data->knockbackTimer = m->knockbackTimer; + + data->dialogId = get_dialog_id(); } static void write_packet_data(struct PacketPlayerData* data, struct MarioState* m, @@ -206,6 +210,8 @@ static void write_packet_data(struct PacketPlayerData* data, struct MarioState* } m->knockbackTimer = data->knockbackTimer; + + m->dialogId = data->dialogId; } void network_send_player(u8 localIndex) {