From fac4c20a36c86bd44bc73c4042c3dc67fab3885b Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 6 Aug 2020 18:45:39 -0700 Subject: [PATCH] Synchronized player health/death Now we will never kill remote players locally, they will have to let us know that they died. Synchronized more of the small breakable box Fixed desync where an object wouldn't be dropped sometimes Fixed infinite loop when remote player was squished --- src/game/behaviors/breakable_box_small.inc.c | 2 ++ src/game/mario.c | 11 ++++++-- src/game/mario_actions_airborne.c | 16 +++++++++-- src/game/mario_actions_cutscene.c | 29 ++++++++++++++++++-- src/game/mario_actions_moving.c | 12 +++++--- src/game/spawn_object.c | 4 ++- src/pc/network/packets/packet_player.c | 7 ++++- 7 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/game/behaviors/breakable_box_small.inc.c b/src/game/behaviors/breakable_box_small.inc.c index fc4ec33b3..b0de7edb4 100644 --- a/src/game/behaviors/breakable_box_small.inc.c +++ b/src/game/behaviors/breakable_box_small.inc.c @@ -21,6 +21,8 @@ void bhv_breakable_box_small_init(void) { o->oAnimState = 1; o->activeFlags |= ACTIVE_FLAG_UNK9; network_init_object(o, 500.0f); + network_init_object_field(o, &o->oBreakableBoxSmallReleased); + network_init_object_field(o, &o->oBreakableBoxSmallFramesSinceReleased); } void small_breakable_box_spawn_dust(void) { diff --git a/src/game/mario.c b/src/game/mario.c index 30d0673d4..59ed5585a 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1232,7 +1232,7 @@ void squish_mario_model(struct MarioState *m) { else { vec3f_set(m->marioObj->header.gfx.scale, 1.0f, 1.0f, 1.0f); } - + } // If timer is less than 16, rubber-band Mario's size scale up and down. else if (m->squishTimer <= 16) { @@ -1421,7 +1421,7 @@ void update_mario_inputs(struct MarioState *m) { update_mario_geometry_inputs(m); debug_print_speed_action_normal(m); - + /* Moonjump cheat */ while (Cheats.MoonJump == true && Cheats.EnableCheats == true && m->controller->buttonDown & L_TRIG ){ m->vel[1] = 25; @@ -1536,7 +1536,12 @@ void update_mario_health(struct MarioState *m) { m->health = 0x880; } if (m->health < 0x100) { - m->health = 0xFF; + if (m != &gMarioStates[0]) { + // never kill remote marios + m->health = 0x100; + } else { + m->health = 0xFF; + } } // Play a noise to alert the player when Mario is close to drowning. diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index 970e45f37..5563d531d 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -985,9 +985,14 @@ s32 act_burning_jump(struct MarioState *m) { m->health -= 10; if (m->health < 0x100) { - m->health = 0xFF; + if (m != &gMarioStates[0]) { + // never kill remote marios + m->health = 0x100; + } else { + m->health = 0xFF; + } } - + reset_rumble_timers(); return FALSE; } @@ -1006,7 +1011,12 @@ s32 act_burning_fall(struct MarioState *m) { m->health -= 10; if (m->health < 0x100) { - m->health = 0xFF; + if (m != &gMarioStates[0]) { + // never kill remote marios + m->health = 0x100; + } else { + m->health = 0xFF; + } } reset_rumble_timers(); diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index df3b4dcba..60f9ad973 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -773,7 +773,13 @@ s32 act_eaten_by_bubba(struct MarioState *m) { play_sound_if_no_flag(m, SOUND_MARIO_DYING, MARIO_ACTION_SOUND_PLAYED); set_mario_animation(m, MARIO_ANIM_A_POSE); m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; - m->health = 0xFF; + if (m != &gMarioStates[0]) { + // never kill remote marios + m->health = 0x100; + } else { + m->health = 0xFF; + } + if (m->actionTimer++ == 60) { level_trigger_warp(m, WARP_OP_DEATH); } @@ -1499,6 +1505,7 @@ s32 act_shocked(struct MarioState *m) { } s32 act_squished(struct MarioState *m) { + UNUSED s32 pad; f32 squishAmount; f32 spaceUnderCeil; @@ -1513,7 +1520,13 @@ s32 act_squished(struct MarioState *m) { case 0: if (spaceUnderCeil > 160.0f) { m->squishTimer = 0; - return set_mario_action(m, ACT_IDLE, 0); + // prevent infinite loop for remote players + if (m == &gMarioStates[0]) { + return set_mario_action(m, ACT_IDLE, 0); + } else { + set_mario_action(m, ACT_IDLE, 0); + return FALSE; + } } m->squishTimer = 0xFF; @@ -1587,7 +1600,13 @@ s32 act_squished(struct MarioState *m) { // squished for more than 10 seconds, so kill Mario if (m->actionArg++ > 300) { // 0 units of health - m->health = 0x00FF; + if (m != &gMarioStates[0]) { + // never kill remote marios + m->health = 0x100; + } else { + m->health = 0xFF; + } + m->hurtCounter = 0; level_trigger_warp(m, WARP_OP_DEATH); // woosh, he's gone! @@ -2634,6 +2653,10 @@ static s32 act_end_waving_cutscene(struct MarioState *m) { } static s32 check_for_instant_quicksand(struct MarioState *m) { + if (m != &gMarioStates[0]) { + // never kill remote marios + return FALSE; + } if (m->floor->type == SURFACE_INSTANT_QUICKSAND && m->action & ACT_FLAG_INVULNERABLE && m->action != ACT_QUICKSAND_DEATH) { update_mario_sound_and_camera(m); diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index a6b7ed561..30aba6a3f 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -470,7 +470,7 @@ void update_walking_speed(struct MarioState *m) { } else { m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800); - } + } apply_slope_accel(m); } @@ -1252,7 +1252,7 @@ s32 act_riding_shell_ground(struct MarioState *m) { } adjust_sound_for_speed(m); - + reset_rumble_timers(); return FALSE; } @@ -1353,7 +1353,11 @@ s32 act_burning_ground(struct MarioState *m) { m->health -= 10; if (m->health < 0x100) { - set_mario_action(m, ACT_STANDING_DEATH, 0); + extern struct MarioState gMarioStates[]; + if (m == &gMarioStates[0]) { + // never kill remote marios + set_mario_action(m, ACT_STANDING_DEATH, 0); + } } m->marioBodyState->eyeState = MARIO_EYES_DEAD; @@ -1855,7 +1859,7 @@ s32 act_long_jump_land(struct MarioState *m) { m->forwardVel = 0.0f; } #endif - + if (!(m->input & INPUT_Z_DOWN)) { m->input &= ~INPUT_A_PRESSED; } diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index 843739ddc..af1a3bc57 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -197,7 +197,9 @@ void unload_object(struct Object *obj) { obj->header.gfx.node.flags &= ~GRAPH_RENDER_CYLBOARD; obj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; - if (obj->oSyncID != 0) { network_send_object(obj); } + if (obj->oSyncID != 0) { + network_send_object(obj); + } deallocate_object(&gFreeObjectList, &obj->header); } diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 319ba265a..456f89b79 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -14,6 +14,8 @@ void network_send_player(void) { packet_write(&p, &gMarioStates[0], 96); packet_write(&p, gMarioStates[0].controller, 20); packet_write(&p, gMarioStates[0].marioObj->rawData.asU32, 320); + packet_write(&p, &gMarioStates[0].health, 2); + packet_write(&p, &heldSyncID, 4); network_send(&p); } @@ -26,12 +28,15 @@ void network_receive_player(struct Packet* p) { packet_read(p, &gMarioStates[1], 96); packet_read(p, gMarioStates[1].controller, 20); packet_read(p, &gMarioStates[1].marioObj->rawData.asU32, 320); + packet_write(p, &gMarioStates[1].health, 2); packet_read(p, &heldSyncID, 4); if (heldSyncID != NULL) { assert(syncObjects[heldSyncID].o != NULL); gMarioStates[1].heldObj = syncObjects[heldSyncID].o; gMarioStates[1].heldObj->heldByPlayerIndex = 1; + } else { + gMarioStates[1].heldObj = NULL; } // restore action state, needed for jump kicking @@ -40,4 +45,4 @@ void network_receive_player(struct Packet* p) { void network_update_player(void) { network_send_player(); -} \ No newline at end of file +}