diff --git a/src/game/behaviors/breakable_box_small.inc.c b/src/game/behaviors/breakable_box_small.inc.c index fc4ec33b..b0de7edb 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 30d0673d..59ed5585 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 970e45f3..5563d531 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 df3b4dcb..60f9ad97 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 a6b7ed56..30aba6a3 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 843739dd..af1a3bc5 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 319ba265..456f89b7 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 +}