diff --git a/src/game/camera.c b/src/game/camera.c index 53814e8c..5420f643 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -678,7 +678,7 @@ f32 calc_y_to_curr_floor(f32 *posOff, f32 posMul, f32 posBound, f32 *focOff, f32 } if (sMarioCamState->action & ACT_FLAG_ON_POLE) { - if (sMarioGeometry.currFloorHeight >= gMarioStates[0].usedObj->oPosY && sMarioCamState->pos[1] + if (gMarioStates[0].usedObj != NULL && sMarioGeometry.currFloorHeight >= gMarioStates[0].usedObj->oPosY && sMarioCamState->pos[1] < 0.7f * gMarioStates[0].usedObj->hitboxHeight + gMarioStates[0].usedObj->oPosY) { posBound = 1200; } @@ -2341,7 +2341,7 @@ s16 update_default_camera(struct Camera *c) { vec3f_copy(c->focus, sMarioCamState->pos); } - if (sMarioCamState->action & ACT_FLAG_ON_POLE) { + if ((sMarioCamState->action & ACT_FLAG_ON_POLE) && gMarioStates[0].usedObj != NULL) { camFloorHeight = gMarioStates[0].usedObj->oPosY + 125.f; if (sMarioCamState->pos[1] - 100.f > camFloorHeight) { camFloorHeight = sMarioCamState->pos[1] - 100.f; diff --git a/src/game/interaction.c b/src/game/interaction.c index 1cf16d3e..d5b23b09 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -299,7 +299,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) { + if (m->heldObj == NULL && m->usedObj != NULL) { m->heldObj = m->usedObj; m->heldObj->heldByPlayerIndex = m->playerIndex; obj_set_held_state(m->heldObj, bhvCarrySomething3); @@ -349,7 +349,7 @@ void mario_stop_riding_and_holding(struct MarioState *m) { mario_drop_held_object(m); mario_stop_riding_object(m); - if (m->action == ACT_RIDING_HOOT) { + if (m->action == ACT_RIDING_HOOT && m->usedObj != NULL) { m->usedObj->oInteractStatus = 0; m->usedObj->oHootMarioReleaseTime = gGlobalTimer; } @@ -421,7 +421,7 @@ struct Object *mario_get_collided_object(struct MarioState *m, u32 interactType) for (i = 0; i < m->marioObj->numCollidedObjs; i++) { object = m->marioObj->collidedObjs[i]; - if (object->oInteractType == interactType) { + if (object != NULL && object->oInteractType == interactType) { return object; } } @@ -574,6 +574,10 @@ static u32 unused_determine_knockback_action(struct MarioState *m) { } u32 determine_knockback_action(struct MarioState *m, UNUSED s32 arg) { + if (m->interactObj == NULL) { + return sForwardKnockbackActions[0][0]; + } + u32 bonkAction; s16 terrainIndex = 0; // 1 = air, 2 = water, 0 = default @@ -707,6 +711,7 @@ u32 should_push_or_pull_door(struct MarioState *m, struct Object *o) { } u32 take_damage_from_interact_object(struct MarioState *m) { + if (m->interactObj == NULL) { return 0; } s32 shake; s32 damage = m->interactObj->oDamageOrCoinValue; @@ -1688,7 +1693,7 @@ u32 interact_hoot(struct MarioState *m, UNUSED u32 interactType, struct Object * //! Can pause to advance the global timer without falling too far, allowing // you to regrab after letting go. - if (actionId >= 0x080 && actionId < 0x098 + if (m->usedObj != NULL && actionId >= 0x080 && actionId < 0x098 && (gGlobalTimer - m->usedObj->oHootMarioReleaseTime > 30)) { mario_stop_riding_and_holding(m); o->oInteractStatus = INT_STATUS_HOOT_GRABBED_BY_MARIO; diff --git a/src/game/level_update.c b/src/game/level_update.c index 497abef8..b30fa5eb 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -793,12 +793,14 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) { break; case WARP_OP_UNKNOWN_02: // bbh enter + if (m->usedObj == NULL) { break; } sDelayedWarpTimer = 30; sSourceWarpNodeId = (m->usedObj->oBehParams & 0x00FF0000) >> 16; play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x1E, 0xFF, 0xFF, 0xFF); break; case WARP_OP_TELEPORT: + if (m->usedObj == NULL) { break; } sDelayedWarpTimer = 20; sSourceWarpNodeId = (m->usedObj->oBehParams & 0x00FF0000) >> 16; val04 = !music_changed_through_warp(sSourceWarpNodeId); @@ -806,6 +808,7 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) { break; case WARP_OP_WARP_DOOR: + if (m->usedObj == NULL) { break; } sDelayedWarpTimer = 20; sDelayedWarpArg = m->actionArg; sSourceWarpNodeId = (m->usedObj->oBehParams & 0x00FF0000) >> 16; @@ -814,6 +817,7 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) { break; case WARP_OP_WARP_OBJECT: + if (m->usedObj == NULL) { break; } sDelayedWarpTimer = 20; sSourceWarpNodeId = (m->usedObj->oBehParams & 0x00FF0000) >> 16; val04 = !music_changed_through_warp(sSourceWarpNodeId); diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index 0d16c34d..d8d64351 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -1928,12 +1928,12 @@ s32 act_flying(struct MarioState *m) { s32 act_riding_hoot(struct MarioState *m) { if (m->usedObj == NULL || m->usedObj->behavior != bhvHoot) { m->usedObj = cur_obj_nearest_object_with_behavior(bhvHoot); - for (int i = 0; i < MAX_PLAYERS; i++) { - if (m != &gMarioStates[i]) { continue; } - m->usedObj->heldByPlayerIndex = i; - } + if (m->usedObj == NULL) { return FALSE; } + m->usedObj->heldByPlayerIndex = m->playerIndex; } + if (m->usedObj == NULL) { return FALSE; } + if (!(m->input & INPUT_A_DOWN) || (m->marioObj->oInteractStatus & INT_STATUS_MARIO_UNK7)) { m->usedObj->oInteractStatus = 0; m->usedObj->oHootMarioReleaseTime = gGlobalTimer; diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 5e5f9256..7ec01064 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -32,7 +32,7 @@ void add_tree_leaf_particles(struct MarioState *m) { f32 leafHeight; - if (m->usedObj->behavior == segmented_to_virtual(bhvTree)) { + if (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(bhvTree)) { // make leaf effect spawn higher on the Shifting Sand Land palm tree if (gCurrLevelNum == LEVEL_SSL) { leafHeight = 250.0f; @@ -46,7 +46,7 @@ void add_tree_leaf_particles(struct MarioState *m) { } void play_climbing_sounds(struct MarioState *m, s32 b) { - s32 isOnTree = (m->usedObj->behavior == segmented_to_virtual(bhvTree)); + s32 isOnTree = (m->usedObj != NULL && m->usedObj->behavior == segmented_to_virtual(bhvTree)); if (b == 1) { if (is_anim_past_frame(m, 1)) { @@ -61,6 +61,7 @@ void play_climbing_sounds(struct MarioState *m, s32 b) { s32 set_pole_position(struct MarioState *m, f32 offsetY) { if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } + if (m->usedObj == NULL) { return POLE_NONE; } UNUSED s32 unused1; UNUSED s32 unused2; @@ -121,6 +122,7 @@ s32 set_pole_position(struct MarioState *m, f32 offsetY) { s32 act_holding_pole(struct MarioState *m) { struct Object *marioObj = m->marioObj; if (m->usedObj == NULL) { m->usedObj = cur_obj_find_nearest_pole(); } + if (m->usedObj == NULL) { return FALSE; } #ifdef VERSION_JP if (m->input & INPUT_A_PRESSED) { diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index aff21d2d..b16d339a 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -377,7 +377,7 @@ s32 set_mario_npc_dialog(struct MarioState* m, s32 actionArg) { } else if (actionArg != 0 && mario_ready_to_speak(m)) { m->usedObj = gCurrentObject; set_mario_action(m, ACT_READING_NPC_DIALOG, actionArg); - if (m->playerIndex == 0) { localDialogNPCBehavior = (BehaviorScript*)m->usedObj->behavior; } + if (m->playerIndex == 0 && m->usedObj != NULL) { localDialogNPCBehavior = (BehaviorScript*)m->usedObj->behavior; } dialogState = 1; // starting dialog } @@ -559,7 +559,7 @@ s32 act_reading_sign(struct MarioState *m) { m->pos[2] += marioObj->oMarioReadingSignDPosZ / 11.0f; // create the text box if (m->actionTimer++ == 10) { - if (m == &gMarioStates[0]) { + if (m == &gMarioStates[0] && m->usedObj != NULL) { create_dialog_inverted_box(m->usedObj->oBehParams2ndByte); } m->actionState = 2; @@ -831,10 +831,12 @@ s32 launch_mario_until_land(struct MarioState *m, s32 endAction, s32 animation, } s32 act_unlocking_key_door(struct MarioState *m) { - m->faceAngle[1] = m->usedObj->oMoveAngleYaw; + if (m->usedObj != NULL) { + m->faceAngle[1] = m->usedObj->oMoveAngleYaw; - m->pos[0] = m->usedObj->oPosX + coss(m->faceAngle[1]) * 75.0f; - m->pos[2] = m->usedObj->oPosZ + sins(m->faceAngle[1]) * 75.0f; + m->pos[0] = m->usedObj->oPosX + coss(m->faceAngle[1]) * 75.0f; + m->pos[2] = m->usedObj->oPosZ + sins(m->faceAngle[1]) * 75.0f; + } if (m->actionArg & 2) { m->faceAngle[1] += 0x8000; @@ -858,7 +860,7 @@ s32 act_unlocking_key_door(struct MarioState *m) { stop_and_set_height_to_floor(m); if (is_anim_at_end(m)) { - if (m->usedObj->oBehParams >> 24 == 1) { + if (m->usedObj != NULL && ((m->usedObj->oBehParams >> 24) == 1)) { save_file_set_flags(SAVE_FLAG_UNLOCKED_UPSTAIRS_DOOR); save_file_clear_flags(SAVE_FLAG_HAVE_KEY_2); } else { @@ -875,7 +877,9 @@ s32 act_unlocking_key_door(struct MarioState *m) { s32 act_unlocking_star_door(struct MarioState *m) { switch (m->actionState) { case 0: - m->faceAngle[1] = m->usedObj->oMoveAngleYaw; + if (m->usedObj != NULL) { + m->faceAngle[1] = m->usedObj->oMoveAngleYaw; + } if (m->actionArg & 2) { m->faceAngle[1] += 0x8000; } @@ -920,10 +924,12 @@ s32 act_entering_star_door(struct MarioState *m) { s16 targetAngle; if (m->actionTimer++ == 0) { - m->interactObj->oInteractStatus = 0x00010000; + if (m->interactObj != NULL) { + m->interactObj->oInteractStatus = 0x00010000; + } // ~30 degrees / 1/12 rot - targetAngle = m->usedObj->oMoveAngleYaw + 0x1555; + if (m->usedObj != NULL) { targetAngle = m->usedObj->oMoveAngleYaw + 0x1555; } if (m->actionArg & 2) { targetAngle += 0x5556; // ~120 degrees / 1/3 rot (total 150d / 5/12) } @@ -931,8 +937,10 @@ s32 act_entering_star_door(struct MarioState *m) { // targetDX and targetDZ are the offsets to add to Mario's position to // have Mario stand 150 units in front of the door - targetDX = m->usedObj->oPosX + 150.0f * sins(targetAngle) - m->pos[0]; - targetDZ = m->usedObj->oPosZ + 150.0f * coss(targetAngle) - m->pos[2]; + if (m->usedObj != NULL) { + targetDX = m->usedObj->oPosX + 150.0f * sins(targetAngle) - m->pos[0]; + targetDZ = m->usedObj->oPosZ + 150.0f * coss(targetAngle) - m->pos[2]; + } m->marioObj->oMarioReadingSignDPosX = targetDX / 20.0f; m->marioObj->oMarioReadingSignDPosZ = targetDZ / 20.0f; @@ -954,7 +962,9 @@ s32 act_entering_star_door(struct MarioState *m) { } else { - m->faceAngle[1] = m->usedObj->oMoveAngleYaw; + if (m->usedObj != NULL) { + m->faceAngle[1] = m->usedObj->oMoveAngleYaw; + } if (m->actionArg & 2) { m->faceAngle[1] += 0x8000; @@ -978,10 +988,14 @@ s32 act_entering_star_door(struct MarioState *m) { s32 act_going_through_door(struct MarioState *m) { if (m->actionTimer == 0) { if (m->actionArg & 1) { - m->interactObj->oInteractStatus = 0x00010000; + if (m->interactObj != NULL) { + m->interactObj->oInteractStatus = 0x00010000; + } set_mario_animation(m, MARIO_ANIM_PULL_DOOR_WALK_IN); } else { - m->interactObj->oInteractStatus = 0x00020000; + if (m->interactObj != NULL) { + m->interactObj->oInteractStatus = 0x00020000; + } set_mario_animation(m, MARIO_ANIM_PUSH_DOOR_WALK_IN); } }