Fix softlock when player is grabbed by enemy

This commit is contained in:
MysterD 2022-03-28 18:57:52 -07:00
parent 26bd3d67c5
commit 0a5d4cd215
8 changed files with 73 additions and 18 deletions

View File

@ -219,6 +219,7 @@ struct Object
/*?????*/ u32 areaTimerDuration;
/*?????*/ void (*areaTimerRunOnceCallback)(void);
/*?????*/ u8 globalPlayerIndex;
/*?????*/ struct Object* usingObj;
};
struct ObjectHitbox

View File

@ -4,7 +4,7 @@ void common_anchor_mario_behavior(f32 sp28, f32 sp2C, s32 sp30) {
for (int i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
struct MarioState* marioState = &gMarioStates[i];
struct Object* player = gMarioStates[i].marioObj;
struct Object* player = marioState->marioObj;
if (marioState->heldByObj != o->parentObj && marioState->heldByObj != o) { continue; }
if (marioState->action != ACT_GRABBED) { continue; }
switch (o->parentObj->oChuckyaUnk88) {
@ -150,6 +150,7 @@ void chuckya_act_1(void) {
o->oChuckyaUnk88 = 3;
o->oAction = 3;
o->oInteractStatus &= ~(INT_STATUS_GRABBED_MARIO);
o->usingObj = NULL;
} else {
cur_obj_init_animation_with_sound(1);
o->oMoveAngleYaw += INT_STATUS_GRABBED_MARIO;
@ -165,6 +166,7 @@ void chuckya_act_1(void) {
o->oChuckyaUnk88 = 2;
o->oAction = 3;
o->oInteractStatus &= ~(INT_STATUS_GRABBED_MARIO);
o->usingObj = NULL;
}
}
}
@ -196,17 +198,33 @@ void chuckya_move(void) {
o->oAction = 1;
o->oChuckyaUnk88 = 1;
cur_obj_play_sound_2(SOUND_OBJ_UNKNOWN3);
o->usingObj = nearest_player_to_object(o);
}
}
void bhv_chuckya_override_ownership(u8* shouldOverride, u8* shouldOwn) {
*shouldOverride = (gMarioStates[0].heldByObj == o);
if (*shouldOverride) {
*shouldOwn = true;
}
}
u8 bhv_chuckya_ignore_if_true(void) {
return (gMarioStates[0].heldByObj == o);
}
void bhv_chuckya_loop(void) {
if (!network_sync_object_initialized(o)) {
network_init_object(o, 4000.0f);
network_init_object_field(o, &o->oChuckyaUnk88);
network_init_object_field(o, &o->oChuckyaUnkF8);
network_init_object_field(o, &o->oChuckyaUnkFC);
network_init_object_field(o, &o->oChuckyaUnk100);
network_init_object_field(o, &o->oFaceAnglePitch);
struct SyncObject* so = network_init_object(o, 4000.0f);
if (so != NULL) {
so->override_ownership = bhv_chuckya_override_ownership;
so->ignore_if_true = bhv_chuckya_ignore_if_true;
network_init_object_field(o, &o->oChuckyaUnk88);
network_init_object_field(o, &o->oChuckyaUnkF8);
network_init_object_field(o, &o->oChuckyaUnkFC);
network_init_object_field(o, &o->oChuckyaUnk100);
network_init_object_field(o, &o->oFaceAnglePitch);
}
}
f32 sp2C = 20.0f;

View File

@ -5,6 +5,8 @@ s16 D_8032F460[][2] = { { 30, 0 }, { 42, 1 }, { 52, 0 }, { 64, 1 }, { 74, 0 },
void bhv_heave_ho_throw_mario_loop(void) {
struct MarioState* marioState = nearest_mario_state_to_object(o);
if (gMarioStates[0].heldByObj == o->parentObj) { marioState = &gMarioStates[0]; }
struct Object* player = marioState->marioObj;
o->oParentRelativePosX = 200.0f;
o->oParentRelativePosY = -50.0f;
@ -21,6 +23,7 @@ void bhv_heave_ho_throw_mario_loop(void) {
marioState->forwardVel = -45.0f;
marioState->vel[1] = 95.0f;
o->parentObj->oHeaveHoUnk88 = 0;
o->parentObj->usingObj = NULL;
break;
}
}
@ -106,17 +109,33 @@ void heave_ho_move(void) {
o->oInteractStatus = 0;
o->oHeaveHoUnk88 = 1;
o->oAction = 3;
o->usingObj = nearest_player_to_object(o);
}
}
void bhv_heave_ho_override_ownership(u8* shouldOverride, u8* shouldOwn) {
*shouldOverride = (gMarioStates[0].heldByObj == o);
if (*shouldOverride) {
*shouldOwn = true;
}
}
u8 bhv_heave_ho_ignore_if_true(void) {
return (gMarioStates[0].heldByObj == o);
}
void bhv_heave_ho_loop(void) {
if (!network_sync_object_initialized(o)) {
network_init_object(o, 4000.0f);
network_init_object_field(o, &o->oHeaveHoUnk88);
network_init_object_field(o, &o->oHeaveHoUnkF4);
network_init_object_field(o, &o->oInteractStatus);
network_init_object_field(o, &o->oGraphYOffset);
network_init_object_field(o, &o->oFaceAngleYaw);
struct SyncObject* so = network_init_object(o, 4000.0f);
if (so != NULL) {
so->override_ownership = bhv_heave_ho_override_ownership;
so->ignore_if_true = bhv_heave_ho_ignore_if_true;
network_init_object_field(o, &o->oHeaveHoUnk88);
network_init_object_field(o, &o->oHeaveHoUnkF4);
network_init_object_field(o, &o->oInteractStatus);
network_init_object_field(o, &o->oGraphYOffset);
network_init_object_field(o, &o->oFaceAngleYaw);
}
}
cur_obj_scale(2.0f);

View File

@ -133,6 +133,7 @@ void king_bobomb_act_3(void) {
o->oAction = 2;
o->oKingBobombUnk108 = 35;
o->oInteractStatus &= ~(INT_STATUS_GRABBED_MARIO);
o->usingObj = NULL;
} else {
o->oForwardVel = 3.0f;
if (o->oKingBobombUnk104 > 20 && cur_obj_rotate_yaw_toward(0, 0x400)) {
@ -149,6 +150,7 @@ void king_bobomb_act_3(void) {
} else if (cur_obj_check_if_near_animation_end()) {
o->oAction = 1;
o->oInteractStatus &= ~(INT_STATUS_GRABBED_MARIO);
o->usingObj = NULL;
}
}
}
@ -367,15 +369,23 @@ void king_bobomb_move(void) {
cur_obj_disable_rendering();
}
u8 king_bobomb_ignore_if_true(void) {
return o->oAction == 8;
void bhv_king_bobomb_override_ownership(u8* shouldOverride, u8* shouldOwn) {
*shouldOverride = (gMarioStates[0].heldByObj == o);
if (*shouldOverride) {
*shouldOwn = true;
}
}
u8 bhv_king_bobomb_ignore_if_true(void) {
return (o->oAction == 8) || (gMarioStates[0].heldByObj == o);
}
void bhv_king_bobomb_loop(void) {
if (!network_sync_object_initialized(o)) {
struct SyncObject* so = network_init_object(o, 4000.0f);
if (so) {
so->ignore_if_true = king_bobomb_ignore_if_true;
so->override_ownership = bhv_king_bobomb_override_ownership;
so->ignore_if_true = bhv_king_bobomb_ignore_if_true;
network_init_object_field(o, &o->oKingBobombUnk88);
network_init_object_field(o, &o->oFlags);
network_init_object_field(o, &o->oHealth);

View File

@ -1836,6 +1836,8 @@ u32 interact_koopa_shell(struct MarioState *m, UNUSED u32 interactType, struct O
}
u32 check_object_grab_mario(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
if (m != &gMarioStates[0]) { return false; }
if ((!(m->action & (ACT_FLAG_AIR | ACT_FLAG_INVULNERABLE | ACT_FLAG_ATTACKING)) || !sInvulnerable)
&& (o->oInteractionSubtype & INT_SUBTYPE_GRABS_MARIO)) {
if (object_facing_mario(m, o, 0x2AAA)) {
@ -1849,6 +1851,7 @@ u32 check_object_grab_mario(struct MarioState *m, UNUSED u32 interactType, struc
update_mario_sound_and_camera(m);
play_character_sound(m, CHAR_SOUND_OOOF);
queue_rumble_data_mario(m, 5, 80);
o->usingObj = m->marioObj;
return set_mario_action(m, ACT_GRABBED, 0);
}
}

View File

@ -704,12 +704,14 @@ s32 act_grabbed(struct MarioState *m) {
}
// error state, get out of grab
if (heldObjIsHeld || m->heldByObj == NULL || !(m->heldByObj->oInteractStatus | INT_STATUS_GRABBED_MARIO)) {
if (heldObjIsHeld || m->heldByObj == NULL || !(m->heldByObj->oInteractStatus | INT_STATUS_GRABBED_MARIO) || (m->heldByObj->usingObj != m->marioObj && m->actionArg != 0)) {
m->heldByObj = NULL;
return set_mario_action(m, (m->forwardVel >= 0.0f) ? ACT_THROWN_FORWARD : ACT_THROWN_BACKWARD, FALSE);
}
}
if (m->actionArg == 0) { m->actionArg = 1; }
return FALSE;
}

View File

@ -312,6 +312,8 @@ struct Object *allocate_object(struct ObjectNode *objList) {
obj->areaTimerDuration = 0;
obj->areaTimerRunOnceCallback = NULL;
obj->usingObj = NULL;
return obj;
}

View File

@ -46,7 +46,7 @@ static void debug_warp_level1() {
}
static void debug_warp_level2() {
dynos_warp_to_level(LEVEL_BOWSER_1, 1, 1);
dynos_warp_to_level(LEVEL_WDW, 1, 1);
}
static void debug_grand_star(void) {