Synchronize warp checkpoints

Prevents softlock when dying inside volcano in LLL and pyramid in SSL
This commit is contained in:
MysterD 2020-09-24 21:34:36 -07:00
parent 20631abc7f
commit 9c8a58fa5b
4 changed files with 17 additions and 9 deletions

View file

@ -170,7 +170,7 @@ s8 gShouldNotPlayCastleMusic;
struct MarioState *gMarioState = &gMarioStates[0]; struct MarioState *gMarioState = &gMarioStates[0];
u8 unused1[4] = { 0 }; u8 unused1[4] = { 0 };
s8 D_8032C9E0 = 0; s8 gInWarpCheckpoint = 0;
u8 unused3[4]; u8 unused3[4];
u8 unused4[2]; u8 unused4[2];
@ -675,18 +675,18 @@ struct WarpNode *get_painting_warp_node(void) {
return warpNode; return warpNode;
} }
static void initiate_painting_warp_node(struct WarpNode *pWarpNode, u8 instant) { static void initiate_painting_warp_node(struct WarpNode *pWarpNode) {
struct WarpNode warpNode = *pWarpNode; struct WarpNode warpNode = *pWarpNode;
if (!(warpNode.destLevel & 0x80)) { if (!(warpNode.destLevel & 0x80)) {
D_8032C9E0 = check_warp_checkpoint(&warpNode); gInWarpCheckpoint = check_warp_checkpoint(&warpNode);
} }
initiate_warp(warpNode.destLevel & 0x7F, warpNode.destArea, warpNode.destNode, 0); initiate_warp(warpNode.destLevel & 0x7F, warpNode.destArea, warpNode.destNode, 0);
check_if_should_set_warp_checkpoint(&warpNode); check_if_should_set_warp_checkpoint(&warpNode);
play_transition_after_delay(WARP_TRANSITION_FADE_INTO_COLOR, 30, 255, 255, 255, instant ? 1 : 45); play_transition_after_delay(WARP_TRANSITION_FADE_INTO_COLOR, 30, 255, 255, 255, 45);
level_set_transition(instant ? 1 : 74, basic_update); level_set_transition(74, basic_update);
play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs); play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs);
fadeout_music(398); fadeout_music(398);
@ -705,7 +705,7 @@ void initiate_painting_warp(void) {
if (gMarioState->action & ACT_FLAG_INTANGIBLE) { if (gMarioState->action & ACT_FLAG_INTANGIBLE) {
play_painting_eject_sound(); play_painting_eject_sound();
} else if (pWarpNode->id != 0) { } else if (pWarpNode->id != 0) {
initiate_painting_warp_node(pWarpNode, false); initiate_painting_warp_node(pWarpNode);
set_mario_action(gMarioState, ACT_DISAPPEARED, 0); set_mario_action(gMarioState, ACT_DISAPPEARED, 0);
gMarioState->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; gMarioState->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
} }
@ -1384,9 +1384,9 @@ s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) {
} }
s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) { s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) {
s32 val4 = D_8032C9E0; s32 val4 = gInWarpCheckpoint;
D_8032C9E0 = 0; gInWarpCheckpoint = 0;
gCurrLevelNum = levelNum; gCurrLevelNum = levelNum;
gCurrCourseNum = gLevelToCourseNumTable[levelNum - 1]; gCurrCourseNum = gLevelToCourseNumTable[levelNum - 1];

View file

@ -85,6 +85,7 @@ struct WarpDest {
}; };
extern struct WarpDest sWarpDest; extern struct WarpDest sWarpDest;
extern s8 gInWarpCheckpoint;
extern s16 D_80339EE0; extern s16 D_80339EE0;
extern s16 sDelayedWarpOp; extern s16 sDelayedWarpOp;

View file

@ -5,7 +5,7 @@
#ifdef DEBUG #ifdef DEBUG
static u8 warpToLevel = LEVEL_BITFS; static u8 warpToLevel = LEVEL_SSL;
#define SCANCODE_0 0x0B #define SCANCODE_0 0x0B
#define SCANCODE_3 0x04 #define SCANCODE_3 0x04

View file

@ -20,6 +20,7 @@ extern struct WarpDest gReceiveWarpDest;
s16 saved_D_80339EE0 = 0; s16 saved_D_80339EE0 = 0;
struct WarpDest savedWarpNode = { 0 }; struct WarpDest savedWarpNode = { 0 };
s8 savedInWarpCheckpoint = 0;
static clock_t lastDoneEvent = 0; static clock_t lastDoneEvent = 0;
static bool isInWarp = FALSE; static bool isInWarp = FALSE;
@ -31,6 +32,7 @@ struct PacketLevelWarpData {
u8 done; u8 done;
u8 controlledWarp; u8 controlledWarp;
struct WarpDest warpDest; struct WarpDest warpDest;
s8 inWarpCheckpoint;
s16 D_80339EE0; s16 D_80339EE0;
}; };
@ -40,12 +42,14 @@ static void populate_packet_data(struct PacketLevelWarpData* data, bool done, u8
data->done = done; data->done = done;
data->controlledWarp = gControlledWarp; data->controlledWarp = gControlledWarp;
data->warpDest = savedWarpNode; data->warpDest = savedWarpNode;
data->inWarpCheckpoint = savedInWarpCheckpoint;
data->D_80339EE0 = saved_D_80339EE0; data->D_80339EE0 = saved_D_80339EE0;
} }
void network_send_level_warp_begin(void) { void network_send_level_warp_begin(void) {
isInWarp = TRUE; isInWarp = TRUE;
savedWarpNode = sWarpDest; savedWarpNode = sWarpDest;
savedInWarpCheckpoint = gInWarpCheckpoint;
saved_D_80339EE0 = D_80339EE0; saved_D_80339EE0 = D_80339EE0;
float elapsedSinceDone = (clock() - lastDoneEvent) / CLOCKS_PER_SEC; float elapsedSinceDone = (clock() - lastDoneEvent) / CLOCKS_PER_SEC;
@ -103,6 +107,7 @@ static void network_send_level_warp_done(u8 remoteEventId) {
static void do_warp(void) { static void do_warp(void) {
gReceiveWarpDest = savedWarpNode; gReceiveWarpDest = savedWarpNode;
gInWarpCheckpoint = savedInWarpCheckpoint;
D_80339EE0 = saved_D_80339EE0; D_80339EE0 = saved_D_80339EE0;
gReceiveWarp = TRUE; gReceiveWarp = TRUE;
} }
@ -143,6 +148,7 @@ void network_receive_level_warp(struct Packet* p) {
LOG_INFO("client initiated warp!"); LOG_INFO("client initiated warp!");
gControlledWarp = !remote.controlledWarp; // two-player hack gControlledWarp = !remote.controlledWarp; // two-player hack
savedWarpNode = remote.warpDest; savedWarpNode = remote.warpDest;
savedInWarpCheckpoint = remote.inWarpCheckpoint;
saved_D_80339EE0 = remote.D_80339EE0; saved_D_80339EE0 = remote.D_80339EE0;
do_warp(); do_warp();
network_send_level_warp_done(remote.eventId); network_send_level_warp_done(remote.eventId);
@ -167,6 +173,7 @@ void network_receive_level_warp(struct Packet* p) {
LOG_INFO("server initiated warp!"); LOG_INFO("server initiated warp!");
gControlledWarp = !remote.controlledWarp; // two-player hack gControlledWarp = !remote.controlledWarp; // two-player hack
savedWarpNode = remote.warpDest; savedWarpNode = remote.warpDest;
savedInWarpCheckpoint = remote.inWarpCheckpoint;
saved_D_80339EE0 = remote.D_80339EE0; saved_D_80339EE0 = remote.D_80339EE0;
LOG_INFO("finished event [%d]!", remote.eventId); LOG_INFO("finished event [%d]!", remote.eventId);
do_warp(); do_warp();