diff --git a/src/game/behaviors/boo.inc.c b/src/game/behaviors/boo.inc.c index 74592967..a95ff67e 100644 --- a/src/game/behaviors/boo.inc.c +++ b/src/game/behaviors/boo.inc.c @@ -349,7 +349,7 @@ static void boo_chase_mario(f32 a0, s16 a1, f32 a2) { cur_obj_rotate_yaw_toward(sp1A, a1); o->oVelY = 0.0f; - if (mario_is_in_air_action() == 0) { + if (mario_is_in_air_action(&gMarioStates[0]) == 0) { sp1C = o->oPosY - gMarioObject->oPosY; if (a0 < sp1C && sp1C < 500.0f) { o->oVelY = increment_velocity_toward_range(o->oPosY, gMarioObject->oPosY + 50.0f, 10.f, 2.0f); diff --git a/src/game/behaviors/elevator.inc.c b/src/game/behaviors/elevator.inc.c index f9df6856..28226462 100644 --- a/src/game/behaviors/elevator.inc.c +++ b/src/game/behaviors/elevator.inc.c @@ -68,7 +68,7 @@ void elevator_act_4(void) { cur_obj_shake_screen(SHAKE_POS_SMALL); cur_obj_play_sound_2(SOUND_GENERAL_METAL_POUND); } - if (!mario_is_in_air_action() && !cur_obj_is_mario_on_platform()) + if (!mario_is_in_air_action(&gMarioStates[0]) && !cur_obj_is_mario_on_platform()) o->oAction = 1; } @@ -79,7 +79,7 @@ void elevator_act_3(void) // nearly identical to action 2 cur_obj_shake_screen(SHAKE_POS_SMALL); cur_obj_play_sound_2(SOUND_GENERAL_METAL_POUND); } - if (!mario_is_in_air_action() && !cur_obj_is_mario_on_platform()) + if (!mario_is_in_air_action(&gMarioStates[0]) && !cur_obj_is_mario_on_platform()) o->oAction = 0; } diff --git a/src/game/behaviors/koopa.inc.c b/src/game/behaviors/koopa.inc.c index a653a9c4..4287abd9 100644 --- a/src/game/behaviors/koopa.inc.c +++ b/src/game/behaviors/koopa.inc.c @@ -65,8 +65,8 @@ static struct KoopaTheQuickProperties sKoopaTheQuickProperties[] = { { DIALOG_009, DIALOG_031, thi_seg7_trajectory_koopa, { 7100, -1300, -6000 } } }; -static u32 forceStartRace = FALSE; -static u32 forceEndRace = FALSE; +static u32 koopaForceStartRace = FALSE; +static u32 koopaForceEndRace = FALSE; /** * Initialization function. @@ -84,6 +84,9 @@ void bhv_koopa_init(void) { o->oKoopaTheQuickRaceIndex = o->oKoopaMovementType - KOOPA_BP_KOOPA_THE_QUICK_BASE; o->oKoopaAgility = 4.0f; cur_obj_scale(3.0f); + + koopaForceStartRace = FALSE; + koopaForceEndRace = FALSE; } else { o->oKoopaAgility = 1.0f; } @@ -91,7 +94,7 @@ void bhv_koopa_init(void) { if (o->oKoopaMovementType >= KOOPA_BP_KOOPA_THE_QUICK_BASE) { // koopa the quick network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); - network_init_object_field(o, &forceStartRace); + network_init_object_field(o, &koopaForceStartRace); } else { // normal koopa @@ -556,7 +559,7 @@ static void koopa_the_quick_act_wait_before_race(void) { } static void koopa_the_quick_force_start_race(void) { - forceStartRace = FALSE; + koopaForceStartRace = FALSE; gMarioShotFromCannon = FALSE; o->oAction = KOOPA_THE_QUICK_ACT_RACE; o->oForwardVel = 0.0f; @@ -591,9 +594,9 @@ static void koopa_the_quick_act_show_init_text(void) { o->oKoopaTurningAwayFromWall = FALSE; o->oFlags |= OBJ_FLAG_ACTIVE_FROM_AFAR; - forceStartRace = TRUE; + koopaForceStartRace = TRUE; network_send_object(o); - forceStartRace = FALSE; + koopaForceStartRace = FALSE; ; } else if (response == 2) { o->oAction = KOOPA_THE_QUICK_ACT_WAIT_BEFORE_RACE; @@ -822,7 +825,7 @@ static void koopa_the_quick_update(void) { cur_obj_update_floor_and_walls(); obj_update_blinking(&o->oKoopaBlinkTimer, 10, 15, 3); - if (forceStartRace) { koopa_the_quick_force_start_race(); } + if (koopaForceStartRace) { koopa_the_quick_force_start_race(); } switch (o->oAction) { case KOOPA_THE_QUICK_ACT_WAIT_BEFORE_RACE: @@ -907,7 +910,7 @@ void koopa_the_quick_force_end_race(void) { o->oKoopaRaceEndpointRaceStatus = 1; } } - forceEndRace = FALSE; + koopaForceEndRace = FALSE; } /** @@ -916,10 +919,10 @@ void koopa_the_quick_force_end_race(void) { void bhv_koopa_race_endpoint_update(void) { if (o->oSyncID == 0) { network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); - network_init_object_field(o, &forceEndRace); + network_init_object_field(o, &koopaForceEndRace); } - if (forceEndRace) { koopa_the_quick_force_end_race(); } + if (koopaForceEndRace) { koopa_the_quick_force_end_race(); } if (o->oKoopaRaceEndpointRaceBegun && !o->oKoopaRaceEndpointRaceEnded) { struct Object* player = nearest_player_to_object(o); @@ -929,9 +932,9 @@ void bhv_koopa_race_endpoint_update(void) { level_control_timer(TIMER_CONTROL_STOP); if (!o->oKoopaRaceEndpointKoopaFinished) { - forceEndRace = TRUE; + koopaForceEndRace = TRUE; network_send_object(o); - forceEndRace = FALSE; + koopaForceEndRace = FALSE; play_race_fanfare(); if (gMarioShotFromCannon) { diff --git a/src/game/behaviors/racing_penguin.inc.c b/src/game/behaviors/racing_penguin.inc.c index db211b8d..71975670 100644 --- a/src/game/behaviors/racing_penguin.inc.c +++ b/src/game/behaviors/racing_penguin.inc.c @@ -9,12 +9,21 @@ static struct RacingPenguinData sRacingPenguinData[] = { { DIALOG_164, 350.0f, 250.0f }, }; +static u32 penguinForceStartRace = FALSE; + void bhv_racing_penguin_init(void) { if (gMarioState->numStars == 120) { cur_obj_scale(8.0f); o->header.gfx.scale[1] = 5.0f; o->oBehParams2ndByte = 1; } + penguinForceStartRace = FALSE; + + network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + network_init_object_field(o, &penguinForceStartRace); + network_init_object_field(o, &o->oAction); + network_init_object_field(o, &o->oRacingPenguinMarioWon); + network_init_object_field(o, &o->oRacingPenguinMarioCheated); } static void racing_penguin_act_wait_for_mario(void) { @@ -24,6 +33,24 @@ static void racing_penguin_act_wait_for_mario(void) { } } +static void racing_penguin_force_start_race(void) { + struct Object* child; + child = cur_obj_nearest_object_with_behavior(bhvPenguinRaceFinishLine); + child->parentObj = o; + + child = cur_obj_nearest_object_with_behavior(bhvPenguinRaceShortcutCheck); + child->parentObj = o; + + o->oPathedStartWaypoint = o->oPathedPrevWaypoint = + segmented_to_virtual(ccm_seg7_trajectory_penguin_race); + o->oPathedPrevWaypointFlags = 0; + + o->oAction = RACING_PENGUIN_ACT_PREPARE_FOR_RACE; + o->oVelY = 60.0f; + + penguinForceStartRace = FALSE; +} + static void racing_penguin_act_show_init_text(void) { s32 response; struct Object *child; @@ -42,7 +69,11 @@ static void racing_penguin_act_show_init_text(void) { o->oAction = RACING_PENGUIN_ACT_PREPARE_FOR_RACE; o->oVelY = 60.0f; - ; + + penguinForceStartRace = TRUE; + network_send_object(o); + penguinForceStartRace = FALSE; + } else if (response == 2) { o->oAction = RACING_PENGUIN_ACT_WAIT_FOR_MARIO; o->oRacingPenguinInitTextCooldown = 60; @@ -93,9 +124,15 @@ static void racing_penguin_act_race(void) { } } - if (mario_is_in_air_action()) { - if (o->oTimer > 60) { + u8 isInAir = FALSE; + for (int i = 0; i < MAX_PLAYERS; i++) { + isInAir = isInAir || mario_is_in_air_action(&gMarioStates[i]); + } + + if (isInAir) { + if (o->oTimer > 60 && !o->oRacingPenguinMarioCheated) { o->oRacingPenguinMarioCheated = TRUE; + network_send_object(o); } } else { o->oTimer = 0; @@ -161,6 +198,8 @@ static void racing_penguin_act_show_final_text(void) { void bhv_racing_penguin_update(void) { cur_obj_update_floor_and_walls(); + if (penguinForceStartRace) { racing_penguin_force_start_race(); } + switch (o->oAction) { case RACING_PENGUIN_ACT_WAIT_FOR_MARIO: racing_penguin_act_wait_for_mario(); @@ -189,16 +228,23 @@ void bhv_racing_penguin_update(void) { } void bhv_penguin_race_finish_line_update(void) { + struct Object* player = nearest_player_to_object(o); + int distanceToPlayer = dist_between_objects(o, player); + if (o->parentObj->oRacingPenguinReachedBottom - || (o->oDistanceToMario < 1000.0f && gMarioObject->oPosZ - o->oPosZ < 0.0f)) { - if (!o->parentObj->oRacingPenguinReachedBottom) { + || (distanceToPlayer < 1000.0f && player->oPosZ - o->oPosZ < 0.0f)) { + if (!o->parentObj->oRacingPenguinReachedBottom && !o->parentObj->oRacingPenguinMarioWon) { o->parentObj->oRacingPenguinMarioWon = TRUE; + network_send_object(o->parentObj); } } } void bhv_penguin_race_shortcut_check_update(void) { - if (o->oDistanceToMario < 500.0f) { + struct Object* player = nearest_player_to_object(o); + int distanceToPlayer = dist_between_objects(o, player); + if (distanceToPlayer < 500.0f && !o->parentObj->oRacingPenguinMarioCheated) { o->parentObj->oRacingPenguinMarioCheated = TRUE; + network_send_object(o->parentObj); } } diff --git a/src/game/behaviors/shock_wave.inc.c b/src/game/behaviors/shock_wave.inc.c index e40c7eff..7c12c803 100644 --- a/src/game/behaviors/shock_wave.inc.c +++ b/src/game/behaviors/shock_wave.inc.c @@ -13,7 +13,7 @@ void bhv_bowser_shock_wave_loop(void) { o->oOpacity -= 5; if (o->oOpacity <= 0) obj_mark_for_deletion(o); - if (o->oTimer < sp1E && mario_is_in_air_action() == 0) { + if (o->oTimer < sp1E && mario_is_in_air_action(&gMarioStates[0]) == 0) { sp2C = o->oBowserShockWaveUnkF4 * D_8032F420[0]; sp28 = o->oBowserShockWaveUnkF4 * D_8032F420[1]; sp24 = o->oBowserShockWaveUnkF4 * D_8032F420[2]; diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index aa42cd68..68a08ee8 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -1062,8 +1062,8 @@ s32 cur_obj_check_frame_prior_current_frame(s16 *a0) { return FALSE; } -s32 mario_is_in_air_action(void) { - if (gMarioStates[0].action & ACT_FLAG_AIR) { +s32 mario_is_in_air_action(struct MarioState* m) { + if (m->action & ACT_FLAG_AIR) { return TRUE; } else { return FALSE; diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index da88e3a0..b0fa7d31 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -153,7 +153,7 @@ s32 cur_obj_check_if_at_animation_end(void); s32 cur_obj_check_anim_frame(s32 frame); s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength); s32 cur_obj_check_frame_prior_current_frame(s16 *a0); -s32 mario_is_in_air_action(void); +s32 mario_is_in_air_action(struct MarioState* m); s32 mario_is_dive_sliding(struct MarioState* m); void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C); void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C);