diff --git a/src/game/behaviors/bobomb.inc.c b/src/game/behaviors/bobomb.inc.c index eebae12f9..64d36aad7 100644 --- a/src/game/behaviors/bobomb.inc.c +++ b/src/game/behaviors/bobomb.inc.c @@ -179,6 +179,7 @@ void bobomb_free_loop(void) { void bobomb_held_loop(void) { o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; cur_obj_init_animation(1); + // LUIGI TODO: we need to be able to get the player that is actually holding it. struct Object* player = nearest_player_to_object(o); cur_obj_set_pos_relative(player, 0, 60.0f, 100.0); diff --git a/src/game/interaction.c b/src/game/interaction.c index 7ad1d4884..8d8d10f84 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -285,6 +285,7 @@ void mario_stop_riding_object(struct MarioState *m) { } void mario_grab_used_object(struct MarioState *m) { + if (m->usedObj == NULL || m->usedObj->oHeldState == HELD_HELD) { return; } if (m->heldObj == NULL) { m->heldObj = m->usedObj; obj_set_held_state(m->heldObj, bhvCarrySomething3); @@ -418,6 +419,8 @@ u32 mario_check_object_grab(struct MarioState *m) { u32 result = FALSE; void *script; + if (m->interactObj == NULL || m->interactObj->oHeldState == HELD_HELD) { return FALSE; } + if (m->input & INPUT_INTERACT_OBJ_GRABBABLE) { script = virtual_to_segmented(0x13, m->interactObj->behavior); diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index e8c1e2140..970e45f37 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -719,9 +719,11 @@ s32 act_dive(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_DIVE); if (mario_check_object_grab(m)) { mario_grab_used_object(m); - m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ; - if (m->action != ACT_DIVE) { - return TRUE; + if (m->heldObj != NULL) { + m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ; + if (m->action != ACT_DIVE) { + return TRUE; + } } } diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 0ccbccf10..a6b7ed561 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -1581,7 +1581,9 @@ s32 act_dive_slide(struct MarioState *m) { if (mario_check_object_grab(m)) { mario_grab_used_object(m); - m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ; + if (m->heldObj != NULL) { + m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ; + } return TRUE; } diff --git a/src/game/mario_actions_object.c b/src/game/mario_actions_object.c index e34192a50..ff2e03aab 100644 --- a/src/game/mario_actions_object.c +++ b/src/game/mario_actions_object.c @@ -187,8 +187,10 @@ s32 act_picking_up(struct MarioState *m) { // to unload. This allows you to pick up a vacant or newly loaded object // slot (cloning via fake object). mario_grab_used_object(m); - play_sound_if_no_flag(m, SOUND_MARIO_HRMM, MARIO_MARIO_SOUND_PLAYED); - m->actionState = 1; + if (m->heldObj != NULL) { + play_sound_if_no_flag(m, SOUND_MARIO_HRMM, MARIO_MARIO_SOUND_PLAYED); + m->actionState = 1; + } } if (m->actionState == 1) { @@ -315,8 +317,10 @@ s32 act_picking_up_bowser(struct MarioState *m) { m->angleVel[1] = 0; m->marioBodyState->grabPos = GRAB_POS_BOWSER; mario_grab_used_object(m); - queue_rumble_data(5, 80); - play_sound(SOUND_MARIO_HRMM, m->marioObj->header.gfx.cameraToObject); + if (m->heldObj != NULL) { + queue_rumble_data(5, 80); + play_sound(SOUND_MARIO_HRMM, m->marioObj->header.gfx.cameraToObject); + } } set_mario_animation(m, MARIO_ANIM_GRAB_BOWSER); diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index f03e4a93d..e6cbdf24b 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -778,8 +778,10 @@ static s32 check_water_grab(struct MarioState *m) { if (dAngleToObject >= -0x2AAA && dAngleToObject <= 0x2AAA) { m->usedObj = object; mario_grab_used_object(m); - m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ; - return TRUE; + if (m->heldObj != NULL) { + m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ; + return TRUE; + } } }