From 74f027b3e6290c3c83469c05ec53487b5171be12 Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 8 Oct 2020 22:14:17 -0700 Subject: [PATCH] Synchronized enemy lakitu and spiny --- src/game/behaviors/enemy_lakitu.inc.c | 70 +++++++++++++++++++-------- src/game/behaviors/spiny.inc.c | 30 +++++++++++- 2 files changed, 80 insertions(+), 20 deletions(-) diff --git a/src/game/behaviors/enemy_lakitu.inc.c b/src/game/behaviors/enemy_lakitu.inc.c index cacd732f..f9a5d2fe 100644 --- a/src/game/behaviors/enemy_lakitu.inc.c +++ b/src/game/behaviors/enemy_lakitu.inc.c @@ -25,7 +25,9 @@ static struct ObjectHitbox sEnemyLakituHitbox = { */ static void enemy_lakitu_act_uninitialized(void) { #ifndef NODRAWINGDISTANCE - if (o->oDistanceToMario < 2000.0f) { + struct Object* player = nearest_player_to_object(o); + int distanceToPlayer = dist_between_objects(o, player); + if (distanceToPlayer < 2000.0f) { #endif spawn_object_relative_with_scale(CLOUD_BP_LAKITU_CLOUD, 0, 0, 0, 2.0f, o, MODEL_MIST, bhvCloud); @@ -49,7 +51,8 @@ static void enemy_lakitu_update_vel_y(f32 offsetY) { margin = 3.0f; } - if (o->oPosY < gMarioObject->oPosY + offsetY + margin) { + struct Object* player = nearest_player_to_object(o); + if (o->oPosY < player->oPosY + offsetY + margin) { obj_y_vel_approach(4.0f, 0.4f); } else { obj_y_vel_approach(-4.0f, 0.4f); @@ -61,16 +64,21 @@ static void enemy_lakitu_update_vel_y(f32 offsetY) { * angle toward mario. */ static void enemy_lakitu_update_speed_and_angle(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); + f32 minSpeed; s16 turnSpeed; - f32 distToMario = o->oDistanceToMario; + f32 distToMario = distanceToPlayer; if (distToMario > 500.0f) { distToMario = 500.0f; } // Move faster the farther away mario is and the faster mario is moving - if ((minSpeed = 1.2f * gMarioStates[0].forwardVel) < 8.0f) { + if ((minSpeed = 1.2f * marioState->forwardVel) < 8.0f) { minSpeed = 8.0f; } o->oForwardVel = distToMario * 0.04f; @@ -83,13 +91,13 @@ static void enemy_lakitu_update_speed_and_angle(void) { if (o->oEnemyLakituFaceForwardCountdown != 0) { o->oEnemyLakituFaceForwardCountdown -= 1; } else { - obj_face_yaw_approach(o->oAngleToMario, 0x600); + obj_face_yaw_approach(angleToPlayer, 0x600); } // Change move angle toward mario faster when farther from mario turnSpeed = (s16)(distToMario * 2); clamp_s16(&turnSpeed, 0xC8, 0xFA0); - cur_obj_rotate_yaw_toward(o->oAngleToMario, turnSpeed); + cur_obj_rotate_yaw_toward(angleToPlayer, turnSpeed); } /** @@ -97,21 +105,35 @@ static void enemy_lakitu_update_speed_and_angle(void) { * hold it, then enter the hold spiny sub-action. */ static void enemy_lakitu_sub_act_no_spiny(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); + cur_obj_init_animation_with_sound(1); if (o->oEnemyLakituSpinyCooldown != 0) { o->oEnemyLakituSpinyCooldown -= 1; - } else if (o->oEnemyLakituNumSpinies < 3 && o->oDistanceToMario < 800.0f - && abs_angle_diff(o->oAngleToMario, o->oFaceAngleYaw) < 0x4000) { - struct Object *spiny = spawn_object(o, MODEL_SPINY_BALL, bhvSpiny); - if (spiny != NULL) { - o->prevObj = spiny; - spiny->oAction = SPINY_ACT_HELD_BY_LAKITU; - obj_init_animation_with_sound(spiny, spiny_egg_seg5_anims_050157E4, 0); + } else if (o->oEnemyLakituNumSpinies < 3 && distanceToPlayer < 800.0f + && abs_angle_diff(angleToPlayer, o->oFaceAngleYaw) < 0x4000) { - o->oEnemyLakituNumSpinies += 1; - o->oSubAction = ENEMY_LAKITU_SUB_ACT_HOLD_SPINY; - o->oEnemyLakituSpinyCooldown = 30; + if (marioState->playerIndex == 0) { + struct Object* spiny = spawn_object(o, MODEL_SPINY_BALL, bhvSpiny); + if (spiny != NULL) { + o->prevObj = spiny; + spiny->oAction = SPINY_ACT_HELD_BY_LAKITU; + obj_init_animation_with_sound(spiny, spiny_egg_seg5_anims_050157E4, 0); + + o->oEnemyLakituNumSpinies += 1; + o->oSubAction = ENEMY_LAKITU_SUB_ACT_HOLD_SPINY; + o->oEnemyLakituSpinyCooldown = 30; + network_send_object(o); + + network_set_sync_id(spiny); + struct Object* spawn_objects[] = { spiny }; + u32 models[] = { MODEL_SPINY_BALL }; + network_send_spawn_objects(spawn_objects, models, 1); + } } } } @@ -121,15 +143,19 @@ static void enemy_lakitu_sub_act_no_spiny(void) { * enter the throw spiny sub-action. */ static void enemy_lakitu_sub_act_hold_spiny(void) { + struct Object* player = nearest_player_to_object(o); + int distanceToPlayer = dist_between_objects(o, player); + int angleToPlayer = obj_angle_to_object(o, player); + cur_obj_init_anim_extend(3); if (o->oEnemyLakituSpinyCooldown != 0) { o->oEnemyLakituSpinyCooldown -= 1; } // TODO: Check if anything interesting happens if we bypass this with speed - else if (o->oDistanceToMario > o->oDrawingDistance - 100.0f - || (o->oDistanceToMario < 500.0f - && abs_angle_diff(o->oAngleToMario, o->oFaceAngleYaw) < 0x2000)) { + else if (distanceToPlayer > o->oDrawingDistance - 100.0f + || (distanceToPlayer < 500.0f + && abs_angle_diff(angleToPlayer, o->oFaceAngleYaw) < 0x2000)) { o->oSubAction = ENEMY_LAKITU_SUB_ACT_THROW_SPINY; o->oEnemyLakituFaceForwardCountdown = 20; } @@ -191,6 +217,12 @@ static void enemy_lakitu_act_main(void) { */ void bhv_enemy_lakitu_update(void) { // PARTIAL_UPDATE + if (!network_sync_object_initialized(o)) { + network_init_object(o, 4000.0f); + network_init_object_field(o, &o->oEnemyLakituBlinkTimer); + network_init_object_field(o, &o->oEnemyLakituSpinyCooldown); + network_init_object_field(o, &o->oEnemyLakituFaceForwardCountdown); + } treat_far_home_as_mario(2000.0f); diff --git a/src/game/behaviors/spiny.inc.c b/src/game/behaviors/spiny.inc.c index 3d894bfc..1c323d19 100644 --- a/src/game/behaviors/spiny.inc.c +++ b/src/game/behaviors/spiny.inc.c @@ -37,8 +37,10 @@ static u8 sSpinyWalkAttackHandlers[] = { * If the spiny was spawned by lakitu and mario is far away, despawn. */ static s32 spiny_check_active(void) { + struct Object* player = nearest_player_to_object(o); + int distanceToPlayer = dist_between_objects(o, player); if (o->parentObj != o) { - if (o->oDistanceToMario > 2500.0f) { + if (distanceToPlayer > 2500.0f) { //! It's possible for the lakitu to despawn while the spiny still // references it. This line allows us to decrement the 0x1B field // in an object that loads into the lakitu's former slot. @@ -177,11 +179,37 @@ static void spiny_act_thrown_by_lakitu(void) { } } +void bhv_spiny_override_ownership(u8* shouldOverride, u8* shouldOwn) { + *shouldOverride = (o->parentObj->behavior == bhvEnemyLakitu); + *shouldOwn = network_owns_object(o->parentObj); +} + /** * Update function for bhvSpiny. */ void bhv_spiny_update(void) { // PARTIAL_UPDATE + if (!network_sync_object_initialized(o)) { + struct SyncObject* so = network_init_object(o, 4000.0f); + so->syncDeathEvent = FALSE; + so->override_ownership = bhv_spiny_override_ownership; + network_init_object_field(o, &o->oGraphYOffset); + network_init_object_field(o, &o->oFaceAngleYaw); + network_init_object_field(o, &o->oSpinyTimeUntilTurn); + network_init_object_field(o, &o->oSpinyTargetYaw); + network_init_object_field(o, &o->oSpinyTurningAwayFromWall); + network_init_object_field(o, &o->oMoveFlags); + network_init_object_field(o, &o->oInteractType); + network_init_object_field(o, &o->oFaceAnglePitch); + + + struct Object* lakitu = cur_obj_nearest_object_with_behavior(bhvEnemyLakitu); + if (lakitu != NULL) { + lakitu->prevObj = o; + o->oAction = SPINY_ACT_HELD_BY_LAKITU; + obj_init_animation_with_sound(o, spiny_egg_seg5_anims_050157E4, 0); + } + } switch (o->oAction) { case SPINY_ACT_WALK: