diff --git a/include/object_constants.h b/include/object_constants.h index 0fa9b7db8..71d186f13 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -744,7 +744,8 @@ #define PYRAMID_ELEVATOR_IDLE 0 #define PYRAMID_ELEVATOR_START_MOVING 1 #define PYRAMID_ELEVATOR_CONSTANT_VELOCITY 2 - #define PYRAMID_ELEVATOR_AT_BOTTOM 3 + #define PYRAMID_ELEVATOR_END_MOVING 3 + #define PYRAMID_ELEVATOR_AT_BOTTOM 4 /* Pyramid top */ #define PYRAMID_TOP_ACT_CHECK_IF_SOLVED 0 diff --git a/src/game/behaviors/bowser.inc.c b/src/game/behaviors/bowser.inc.c index d39e9e7bd..49182883b 100644 --- a/src/game/behaviors/bowser.inc.c +++ b/src/game/behaviors/bowser.inc.c @@ -855,6 +855,7 @@ void bowser_spawn_grand_star_key(void) { reward->oHomeX = reward->oPosX; reward->oHomeY = reward->oPosY; reward->oHomeZ = reward->oPosZ; + network_set_sync_id(reward); struct Object* spawn_objects[] = { reward }; u32 models[] = { MODEL_STAR }; network_send_spawn_objects(spawn_objects, models, 1); @@ -951,7 +952,6 @@ u8 bowser_dead_not_bits_end_continue_dialog(void) { return o->oAction == 4 && o- s32 bowser_dead_not_bits_end(void) { struct MarioState* marioState = nearest_mario_state_to_object(o); - s32 ret = 0; if (o->oBowserUnkF8 < 2) { if (o->oBowserUnkF8 == 0) { seq_player_lower_volume(SEQ_PLAYER_LEVEL, 60, 40); @@ -970,23 +970,21 @@ s32 bowser_dead_not_bits_end(void) { spawn_triangle_break_particles(20, 116, 1.0f, 0); bowser_spawn_grand_star_key(); set_mario_npc_dialog(&gMarioStates[0], 0, NULL); - ret = 1; + return 1; } - return ret; + return 0; } u8 bowser_dead_bits_end_continue_dialog(void) { return o->oAction == 4 && o->oBowserUnkF8 < 2; } s32 bowser_dead_bits_end(void) { - struct MarioState* marioState = nearest_mario_state_to_object(o); - UNUSED s32 unused; - s32 ret = 0; - s32 dialogID; + struct MarioState *marioState = nearest_mario_state_to_object(o); + if (o->oBowserUnkF8 < 2) { - if (gHudDisplay.stars < 120) + s32 dialogID = DIALOG_163; + if (gHudDisplay.stars < 120) { dialogID = DIALOG_121; - else - dialogID = DIALOG_163; + } if (o->oBowserUnkF8 == 0) { seq_player_lower_volume(SEQ_PLAYER_LEVEL, 60, 40); o->oBowserUnkF8++; @@ -1002,9 +1000,9 @@ s32 bowser_dead_bits_end(void) { o->oOpacity -= 4; else { bowser_dead_hide(); - ret = 1; + return 1; } - return ret; + return 0; } void bowser_act_dead(void) { diff --git a/src/game/behaviors/clam.inc.c b/src/game/behaviors/clam.inc.c index ac3693e82..fb836ce88 100644 --- a/src/game/behaviors/clam.inc.c +++ b/src/game/behaviors/clam.inc.c @@ -14,7 +14,7 @@ struct ObjectHitbox sClamShellHitbox = { void clam_act_0(void) { struct Object* player = nearest_player_to_object(o); - int distanceToPlayer = dist_between_objects(o, player); + s32 distanceToPlayer = dist_between_objects(o, player); if (cur_obj_init_anim_check_frame(0, 25)) { cur_obj_play_sound_2(SOUND_GENERAL_CLAM_SHELL3); diff --git a/src/game/behaviors/grand_star.inc.c b/src/game/behaviors/grand_star.inc.c index 799343afc..4cd8060fc 100644 --- a/src/game/behaviors/grand_star.inc.c +++ b/src/game/behaviors/grand_star.inc.c @@ -4,11 +4,10 @@ s32 arc_to_goal_pos(Vec3f a0, Vec3f a1, f32 yVel, f32 gravity) { f32 dx = a0[0] - a1[0]; f32 dz = a0[2] - a1[2]; f32 planarDist = sqrtf(dx * dx + dz * dz); - s32 time; o->oMoveAngleYaw = atan2s(dz, dx); o->oVelY = yVel; o->oGravity = gravity; - time = -2.0f / o->oGravity * yVel - 1.0f; + s32 time = -2.0f / o->oGravity * yVel - 1.0f; o->oForwardVel = planarDist / time; return time; } @@ -20,28 +19,56 @@ void grand_star_zero_velocity(void) { } void bhv_grand_star_init(void) { - struct Object* other = cur_obj_nearest_object_with_behavior(bhvGrandStar); - if (other == NULL) { return; } + struct Object *other = cur_obj_nearest_object_with_behavior(bhvGrandStar); + if (other == NULL) { + if (!network_sync_object_initialized(o)) { + struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + if (so) { + network_init_object_field(o, &o->activeFlags); + network_init_object_field(o, &o->oPrevAction); + network_init_object_field(o, &o->oAction); + network_init_object_field(o, &o->oSubAction); + network_init_object_field(o, &o->oTimer); + network_init_object_field(o, &o->oHomeX); + network_init_object_field(o, &o->oHomeY); + network_init_object_field(o, &o->oHomeZ); + network_init_object_field(o, &o->oPosX); + network_init_object_field(o, &o->oPosY); + network_init_object_field(o, &o->oPosZ); + network_init_object_field(o, &o->oGravity); + network_init_object_field(o, &o->oVelY); + network_init_object_field(o, &o->oForwardVel); + network_init_object_field(o, &o->oAngleVelYaw); + network_init_object_field(o, &o->oMoveAngleYaw); + network_init_object_field(o, &o->oFaceAngleYaw); + network_init_object_field(o, &o->oGrandStarUnk108); + } + } + return; + } + obj_mark_for_deletion(o); if (gSecondCameraFocus == o) { gSecondCameraFocus = other; } } void bhv_grand_star_loop(void) { if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { return; } - UNUSED s32 unused; - Vec3f sp28; - sp28[0] = sp28[1] = sp28[2] = 0.0f; + if (o->oAction == 0) { if (o->oTimer == 0) { obj_set_angle(o, 0, 0, 0); o->oAngleVelYaw = 0x400; cur_obj_play_sound_2(SOUND_GENERAL2_STAR_APPEARS); } - if (o->oTimer > 70) + if (o->oTimer > 70) { o->oAction++; + } spawn_sparkle_particles(3, 200, 80, -60); } else if (o->oAction == 1) { if (o->oTimer == 0) { + Vec3f sp28; + sp28[0] = sp28[1] = sp28[2] = 0.0f; + cur_obj_play_sound_2(SOUND_GENERAL_GRAND_STAR); cutscene_object(CUTSCENE_STAR_SPAWN, o); o->oGrandStarUnk108 = arc_to_goal_pos(sp28, &o->oPosX, 80.0f, -2.0f); @@ -75,8 +102,9 @@ void bhv_grand_star_loop(void) { o->oInteractStatus = 0; } } - if (o->oAngleVelYaw > 0x400) + if (o->oAngleVelYaw > 0x400) { o->oAngleVelYaw -= 0x100; + } o->oFaceAngleYaw += o->oAngleVelYaw; cur_obj_scale(2.0f); o->oGraphYOffset = 110.0f; diff --git a/src/game/behaviors/klepto.inc.c b/src/game/behaviors/klepto.inc.c index 64c40c245..2ba8679bc 100644 --- a/src/game/behaviors/klepto.inc.c +++ b/src/game/behaviors/klepto.inc.c @@ -21,7 +21,7 @@ static u8 sKleptoAttackHandlers[] = { 2, 2, 5, 5, 2, 2 }; static void klepto_target_mario(void) { struct MarioState* marioState = nearest_mario_state_to_object(o); struct Object* player = marioState->marioObj; - int angleToPlayer = obj_angle_to_object(o, player); + s32 angleToPlayer = obj_angle_to_object(o, player); o->oKleptoDistanceToTarget = lateral_dist_between_objects(player, o); o->oKleptoUnk1B0 = obj_turn_pitch_toward_mario(marioState, 250.0f, 0); o->oKleptoYawToTarget = angleToPlayer; @@ -129,23 +129,18 @@ void bhv_klepto_init(void) { static void klepto_change_target(void) { s32 newTarget = 0; - s32 i; - f32 dx; - f32 dz; - f32 targetDist; - f32 minTargetDist; struct Object* player = nearest_player_to_object(o); - int distanceToPlayer = dist_between_objects(o, player); + s32 distanceToPlayer = dist_between_objects(o, player); if (distanceToPlayer > 2000.0f) { - minTargetDist = 99999.0f; + f32 minTargetDist = 99999.0f; - for (i = 0; i < 3; i++) { - dx = player->oPosX - sKleptoTargetPositions[i][0]; - dz = player->oPosZ - sKleptoTargetPositions[i][2]; + for (s32 i = 0; i < 3; i++) { + f32 dx = player->oPosX - sKleptoTargetPositions[i][0]; + f32 dz = player->oPosZ - sKleptoTargetPositions[i][2]; - targetDist = sqrtf(dx * dx + dz * dz); + f32 targetDist = sqrtf(dx * dx + dz * dz); if (targetDist < minTargetDist) { minTargetDist = targetDist; newTarget = i; @@ -166,11 +161,8 @@ static void klepto_change_target(void) { } static void klepto_circle_target(f32 radius, f32 targetSpeed) { - s16 turnAmount; - f32 accel; - struct Object* player = nearest_player_to_object(o); - int distanceToPlayer = dist_between_objects(o, player); + s32 distanceToPlayer = dist_between_objects(o, player); if (o->oAnimState != KLEPTO_ANIM_STATE_HOLDING_NOTHING && ((o->oTimer > 60 && distanceToPlayer > 2000.0f) @@ -179,8 +171,8 @@ static void klepto_circle_target(f32 radius, f32 targetSpeed) { o->oKleptoTimeUntilTargetChange = random_linear_offset(300, 300); o->oAction = KLEPTO_ACT_APPROACH_TARGET_HOLDING; } else { - turnAmount = 0x4000 - atan2s(radius, o->oKleptoDistanceToTarget - radius); - accel = 0.05f; + s16 turnAmount = 0x4000 - atan2s(radius, o->oKleptoDistanceToTarget - radius); + f32 accel = 0.05f; if ((s16)(o->oMoveAngleYaw - o->oKleptoYawToTarget) < 0) { turnAmount = -turnAmount; } @@ -235,7 +227,7 @@ static void klepto_act_turn_toward_mario(void) { klepto_target_mario(); struct Object* player = nearest_player_to_object(o); - int angleToPlayer = obj_angle_to_object(o, player); + s32 angleToPlayer = obj_angle_to_object(o, player); if (klepto_set_and_check_if_anim_at_end() && cur_obj_check_if_at_animation_end() && o->oKleptoDistanceToTarget > 800.0f && abs_angle_diff(angleToPlayer, o->oFaceAngleYaw) < 0x800 && o->oKleptoUnk1B0 < 0x400) { @@ -254,8 +246,8 @@ static void klepto_act_turn_toward_mario(void) { static void klepto_act_dive_at_mario(void) { struct MarioState* marioState = nearest_mario_state_to_object(o); struct Object* player = marioState->marioObj; - int distanceToPlayer = dist_between_objects(o, player); - int angleToPlayer = obj_angle_to_object(o, player); + s32 distanceToPlayer = dist_between_objects(o, player); + s32 angleToPlayer = obj_angle_to_object(o, player); approach_f32_ptr(&o->oKleptoSpeed, 60.0f, 10.0f); if (o->oSoundStateID == 2) { @@ -373,11 +365,9 @@ void obj_set_speed_to_zero(void) { } void bhv_klepto_update(void) { - struct MarioState* marioState = nearest_mario_state_to_object(o); - struct Object* player = marioState->marioObj; - int angleToPlayer = obj_angle_to_object(o, player); - - UNUSED s32 unused; + struct MarioState *marioState = nearest_mario_state_to_object(o); + struct Object *player = marioState->marioObj; + s32 angleToPlayer = obj_angle_to_object(o, player); cur_obj_update_floor_and_walls(); @@ -437,7 +427,13 @@ void bhv_klepto_update(void) { } } else if (o->oAnimState == KLEPTO_ANIM_STATE_HOLDING_STAR) { - spawn_default_star(-5550.0f, 300.0f, -930.0f); + struct Object *star = spawn_default_star(-5550.0f, 300.0f, -930.0f); + + // If we're not the closet to Klepto, + // Don't play the cutscene! + if (star != NULL && marioState != &gMarioStates[0]) { + star->oStarSpawnExtCutsceneFlags = 0; + } } if (network_owns_object(o)) { diff --git a/src/game/behaviors/pyramid_elevator.inc.c b/src/game/behaviors/pyramid_elevator.inc.c index 984420e7c..296a9103a 100644 --- a/src/game/behaviors/pyramid_elevator.inc.c +++ b/src/game/behaviors/pyramid_elevator.inc.c @@ -5,31 +5,26 @@ * well as the small marker balls that demarcate its trajactory. */ -u8 bhv_pyramid_elevator_ignore_if_true(void) { - return (o->oAction != PYRAMID_ELEVATOR_IDLE); -} - /** * Generate the ten trajectory marker balls that indicate where the elevator * moves. */ void bhv_pyramid_elevator_init(void) { - s32 i; - struct Object *ball; - - for (i = 0; i < 10; i++) { - ball = spawn_object(o, MODEL_TRAJECTORY_MARKER_BALL, bhvPyramidElevatorTrajectoryMarkerBall); + for (s32 i = 0; i < 10; i++) { + struct Object *ball = spawn_object(o, MODEL_TRAJECTORY_MARKER_BALL, bhvPyramidElevatorTrajectoryMarkerBall); if (ball == NULL) { continue; } ball->oPosY = 4600 - i * 460; } - - struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); - if (so) { - so->ignore_if_true = bhv_pyramid_elevator_ignore_if_true; - network_init_object_field(o, &o->oAction); - network_init_object_field(o, &o->oPrevAction); - network_init_object_field(o, &o->oTimer); - network_init_object_field(o, &o->oPosY); + + if (!network_sync_object_initialized(o)) { + struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + if (so) { + network_init_object_field(o, &o->oPrevAction); + network_init_object_field(o, &o->oAction); + network_init_object_field(o, &o->oTimer); + network_init_object_field(o, &o->oPosY); + network_init_object_field(o, &o->oVelY); + } } } @@ -52,8 +47,10 @@ void bhv_pyramid_elevator_loop(void) { */ case PYRAMID_ELEVATOR_START_MOVING: o->oPosY = o->oHomeY - sins(o->oTimer * 0x1000) * 10.0f; - if (o->oTimer == 8) + if (o->oTimer == 8) { o->oAction = PYRAMID_ELEVATOR_CONSTANT_VELOCITY; + if (cur_obj_is_mario_on_platform()) { network_send_object(o); } + } break; /** @@ -65,7 +62,8 @@ void bhv_pyramid_elevator_loop(void) { o->oPosY += o->oVelY; if (o->oPosY < 128.0f) { o->oPosY = 128.0f; - o->oAction = PYRAMID_ELEVATOR_AT_BOTTOM; + o->oAction = PYRAMID_ELEVATOR_END_MOVING; + if (cur_obj_is_mario_on_platform()) { network_send_object(o); } } break; @@ -73,13 +71,22 @@ void bhv_pyramid_elevator_loop(void) { * Use a sine wave to stop the elevator's movement with a small jolt. * Then, remain at the bottom of the track. */ - case PYRAMID_ELEVATOR_AT_BOTTOM: + case PYRAMID_ELEVATOR_END_MOVING: o->oPosY = sins(o->oTimer * 0x1000) * 10.0f + 128.0f; if (o->oTimer >= 8) { - o->oVelY = 0; - o->oPosY = 128.0f; + o->oAction = PYRAMID_ELEVATOR_AT_BOTTOM; + network_send_object(o); } break; + + /** + * The elevator is now at the bottom and finished it's moving + * We will no longer move from this point. + */ + case PYRAMID_ELEVATOR_AT_BOTTOM: + o->oVelY = 0; + o->oPosY = 128.0f; + break; } } @@ -88,10 +95,8 @@ void bhv_pyramid_elevator_loop(void) { * Otherwise, set their scale. */ void bhv_pyramid_elevator_trajectory_marker_ball_loop(void) { - struct Object *elevator; - cur_obj_scale(0.15f); - elevator = cur_obj_nearest_object_with_behavior(bhvPyramidElevator); + struct Object *elevator = cur_obj_nearest_object_with_behavior(bhvPyramidElevator); if (elevator != NULL) { if (elevator->oAction != PYRAMID_ELEVATOR_IDLE) { diff --git a/src/game/behaviors/pyramid_top.inc.c b/src/game/behaviors/pyramid_top.inc.c index d4b642197..8d7570478 100644 --- a/src/game/behaviors/pyramid_top.inc.c +++ b/src/game/behaviors/pyramid_top.inc.c @@ -14,14 +14,10 @@ * Spawn the four pillars' touch detectors. */ void bhv_pyramid_top_init(void) { - spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvPyramidPillarTouchDetector, 1789, 1024, 764, 0, 0, - 0); - spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvPyramidPillarTouchDetector, 1789, 896, -2579, 0, 0, - 0); - spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvPyramidPillarTouchDetector, -5883, 1024, -2579, 0, 0, - 0); - spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvPyramidPillarTouchDetector, -5883, 1024, 764, 0, 0, - 0); + spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvPyramidPillarTouchDetector, 1789, 1024, 764, 0, 0, 0); + spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvPyramidPillarTouchDetector, 1789, 896, -2579, 0, 0, 0); + spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvPyramidPillarTouchDetector, -5883, 1024, -2579, 0, 0, 0); + spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvPyramidPillarTouchDetector, -5883, 1024, 764, 0, 0, 0); } /** @@ -71,16 +67,11 @@ void bhv_pyramid_top_spinning(void) { * Explode the pyramid top, generating dust and pyramid fragments. */ void bhv_pyramid_top_explode(void) { - struct Object *pyramidFragment; - s16 i; - spawn_mist_particles_variable(0, 0, 690); // Generate 30 pyramid fragments with random properties. - for (i = 0; i < 30; i++) { - pyramidFragment = spawn_object( - o, MODEL_DIRT_ANIMATION, bhvPyramidTopFragment - ); + for (s16 i = 0; i < 30; i++) { + struct Object *pyramidFragment = spawn_object(o, MODEL_DIRT_ANIMATION, bhvPyramidTopFragment); if (pyramidFragment != NULL) { pyramidFragment->oForwardVel = random_float() * 50 + 80; pyramidFragment->oVelY = random_float() * 80 + 20; @@ -92,22 +83,21 @@ void bhv_pyramid_top_explode(void) { // Deactivate the pyramid top. o->activeFlags = ACTIVE_FLAG_DEACTIVATED; -} - -static u8 bhv_pyramid_top_ignore_if_true(void) { - return (o->oAction != PYRAMID_TOP_ACT_SPINNING); + // Make sure the object is set to be disabled for others. + network_send_object(o); } void bhv_pyramid_top_loop(void) { if (!network_sync_object_initialized(o)) { - struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); if (so) { - so->ignore_if_true = bhv_pyramid_top_ignore_if_true; + network_init_object_field(o, &o->activeFlags); network_init_object_field(o, &o->oAction); network_init_object_field(o, &o->oPrevAction); network_init_object_field(o, &o->oTimer); } } + switch (o->oAction) { case PYRAMID_TOP_ACT_CHECK_IF_SOLVED: if (o->oPyramidTopPillarsTouched == 4) { diff --git a/src/game/behaviors/pyramid_wall.inc.c b/src/game/behaviors/pyramid_wall.inc.c index ab640eeb5..faa4aeb79 100644 --- a/src/game/behaviors/pyramid_wall.inc.c +++ b/src/game/behaviors/pyramid_wall.inc.c @@ -11,7 +11,6 @@ * positions. */ void bhv_ssl_moving_pyramid_wall_init(void) { - switch (o->oBehParams2ndByte) { case PYRAMID_WALL_BP_POSITION_HIGH: break; @@ -26,12 +25,17 @@ void bhv_ssl_moving_pyramid_wall_init(void) { o->oAction = PYRAMID_WALL_ACT_MOVING_UP; break; } - network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); - network_init_object_field(o, &o->oPrevAction); - network_init_object_field(o, &o->oAction); - network_init_object_field(o, &o->oTimer); - network_init_object_field(o, &o->oVelY); - network_init_object_field(o, &o->oPosY); + + if (!network_sync_object_initialized(o)) { + struct SyncObject *so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + if (so) { + network_init_object_field(o, &o->oPrevAction); + network_init_object_field(o, &o->oAction); + network_init_object_field(o, &o->oTimer); + network_init_object_field(o, &o->oVelY); + network_init_object_field(o, &o->oPosY); + } + } } /** diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 62ebf1fcc..58da148ad 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -2462,9 +2462,8 @@ void stub_obj_helpers_4(void) { s32 cur_obj_is_mario_on_platform(void) { if (gMarioObject->platform == o) { return TRUE; - } else { - return FALSE; } + return FALSE; } s32 cur_obj_is_any_player_on_platform(void) {