Prevented softlock and entity duplication when both grab at the same time

As reported by somario360:
After grabbing the small box at the same time, one of two results can happen.
There will be a fake cloned box that will only be visually in the other
player's hands, or one player will be stuck in the punching animation until
the other player lets go of the box, in which the box goes into the stuck
player's hands.

Now escapes from action if the grab fails, preventing a softlock.
And now if both players report having the same object, the client
will drop their copy.

Fixes #14
This commit is contained in:
MysterD 2020-09-03 18:11:42 -07:00
parent 920c0674d9
commit f367ed2167
3 changed files with 22 additions and 0 deletions

View File

@ -1854,6 +1854,14 @@ s32 execute_mario_action(UNUSED struct Object *o) {
if (gFreezeMario < 1 && gDialogID != -1) { gFreezeMario = 1; }
}
// two-player hack: drop held object if server is holding it
if (networkType == NT_CLIENT && gMarioState->playerIndex == 0 && gMarioState->heldObj != NULL) {
u8 inCutscene = ((gMarioState->action & ACT_GROUP_MASK) != ACT_GROUP_CUTSCENE);
if (!inCutscene && gMarioState->heldObj == gMarioStates[0].heldObj) {
drop_and_set_mario_action(gMarioState, ACT_IDLE, 0);
}
}
u32 hangPreventionActions[MAX_HANG_PREVENTION];
u8 hangPreventionIndex = 0;

View File

@ -11,6 +11,7 @@
#include "engine/math_util.h"
#include "thread6.h"
#include "behavior_data.h"
#include "pc/network/network.h"
/**
* Used by act_punching() to determine Mario's forward velocity during each
@ -191,6 +192,9 @@ s32 act_picking_up(struct MarioState *m) {
if (m->heldObj != NULL) {
play_sound_if_no_flag(m, SOUND_MARIO_HRMM, MARIO_MARIO_SOUND_PLAYED);
m->actionState = 1;
} else {
set_mario_action(m, ACT_IDLE, 0);
return FALSE;
}
}
@ -326,6 +330,9 @@ s32 act_picking_up_bowser(struct MarioState *m) {
play_sound(SOUND_MARIO_HRMM, m->marioObj->header.gfx.cameraToObject);
if (m->playerIndex == 0) {
network_send_object(m->heldObj);
} else {
set_mario_action(m, ACT_IDLE, 0);
return FALSE;
}
}
}
@ -350,6 +357,9 @@ s32 act_holding_bowser(struct MarioState *m) {
if (m->heldObj != NULL) {
queue_rumble_data_mario(m, 5, 80);
play_sound(SOUND_MARIO_HRMM, m->marioObj->header.gfx.cameraToObject);
} else {
set_mario_action(m, ACT_IDLE, 0);
return FALSE;
}
}
}
@ -451,6 +461,8 @@ s32 act_releasing_bowser(struct MarioState *m) {
}
s32 check_common_object_cancels(struct MarioState *m) {
if (m->playerIndex != 0) { return FALSE; }
f32 waterSurface = m->waterLevel - 100;
if (m->pos[1] < waterSurface) {
return set_water_plunge_action(m);

View File

@ -1108,6 +1108,8 @@ s32 act_first_person(struct MarioState *m) {
}
s32 check_common_stationary_cancels(struct MarioState *m) {
if (m->playerIndex != 0) { return FALSE; }
if (m->pos[1] < m->waterLevel - 100) {
if (m->action == ACT_SPAWN_SPIN_LANDING) {
load_level_init_text(0);