diff --git a/data/behavior_data.c b/data/behavior_data.c index 44a9a4b8d..3a5cb2c0a 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -2011,6 +2011,7 @@ const BehaviorScript bhvBooCage[] = { OR_INT(oFlags, (OBJ_FLAG_SET_FACE_YAW_TO_MOVE_YAW | OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE)), SET_FLOAT(oGraphYOffset, 10), SET_OBJ_PHYSICS(/*Wall hitbox radius*/ 30, /*Gravity*/ -400, /*Bounciness*/ -50, /*Drag strength*/ 0, /*Friction*/ 0, /*Buoyancy*/ 200, /*Unused*/ 0, 0), + CALL_NATIVE(bhv_boo_cage_init), BEGIN_LOOP(), CALL_NATIVE(bhv_boo_cage_loop), END_LOOP(), diff --git a/src/game/behavior_actions.h b/src/game/behavior_actions.h index 7d358ede3..a7cc2cf3c 100644 --- a/src/game/behavior_actions.h +++ b/src/game/behavior_actions.h @@ -142,6 +142,7 @@ void bhv_unused_poundable_platform(void); void bhv_beta_trampoline_top_loop(void); void bhv_beta_trampoline_spring_loop(void); void bhv_jumping_box_loop(void); +void bhv_boo_cage_init(void); void bhv_boo_cage_loop(void); void bhv_bowser_key_init(void); void bhv_bowser_key_loop(void); diff --git a/src/game/behaviors/boo_cage.inc.c b/src/game/behaviors/boo_cage.inc.c index 25d23292f..33db29ece 100644 --- a/src/game/behaviors/boo_cage.inc.c +++ b/src/game/behaviors/boo_cage.inc.c @@ -21,6 +21,25 @@ static struct ObjectHitbox sBooCageHitbox = { /* hurtboxHeight: */ 0, }; +static void bhv_boo_cage_on_received_post(u8 localIndex) { + if (o->oAction > BOO_CAGE_ACT_ON_GROUND) { + o->oAction = BOO_CAGE_ACT_ON_GROUND; + } + o->parentObj = NULL; +} + +void bhv_boo_cage_init(void) { + struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + so->on_received_post = bhv_boo_cage_on_received_post; + network_init_object_field(o, &o->oAction); + 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->oVelX); + network_init_object_field(o, &o->oVelY); + network_init_object_field(o, &o->oVelZ); +} + /** * Update function for bhvBooCage. */ @@ -41,10 +60,17 @@ void bhv_boo_cage_loop(void) { // If the cage's parent boo is killed, set the action to BOO_CAGE_ACT_FALLING, // give the cage an initial Y velocity of 60 units/frame, and play the puzzle jingle. // Otherwise, stay inside the boo. - if (o->parentObj->oBooDeathStatus != BOO_DEATH_STATUS_ALIVE) { + if (o->parentObj == NULL || o->parentObj->behavior != bhvBooWithCage || o->parentObj->oBooDeathStatus != BOO_DEATH_STATUS_ALIVE) { o->oAction++; o->oVelY = 60.0f; - play_puzzle_jingle(); + if (o->parentObj != NULL && o->parentObj->behavior == bhvBooWithCage) { + play_puzzle_jingle(); + } + struct MarioState* marioState = nearest_mario_state_to_object(o); + if (marioState->playerIndex == 0) { + network_send_object(o); + } + o->parentObj = NULL; } else { obj_copy_pos_and_angle(o, o->parentObj); } @@ -75,6 +101,11 @@ void bhv_boo_cage_loop(void) { if (o->oMoveFlags & (OBJ_MOVE_UNDERWATER_ON_GROUND | OBJ_MOVE_AT_WATER_SURFACE | OBJ_MOVE_ON_GROUND)) { o->oAction++; + + struct MarioState* marioState = nearest_mario_state_to_object(o); + if (marioState->playerIndex == 0) { + network_send_object(o); + } } break; diff --git a/src/game/behaviors/coin.inc.c b/src/game/behaviors/coin.inc.c index 3cc8584e5..6f3ed5da6 100644 --- a/src/game/behaviors/coin.inc.c +++ b/src/game/behaviors/coin.inc.c @@ -240,6 +240,11 @@ void coin_inside_boo_act_0(void) { cur_obj_set_model(MODEL_BLUE_COIN); cur_obj_scale(0.7); } + if (parent == NULL || parent->behavior != bhvGhostHuntBoo) { + o->parentObj = NULL; + obj_mark_for_deletion(o); + return; + } obj_copy_pos(o, parent); if (parent->oBooDeathStatus == BOO_DEATH_STATUS_DYING) { o->oAction = 1; @@ -248,6 +253,7 @@ void coin_inside_boo_act_0(void) { o->oVelX = sins(sp26) * sp20; o->oVelZ = coss(sp26) * sp20; o->oVelY = 35.0f; + o->parentObj = NULL; } } diff --git a/src/game/interaction.c b/src/game/interaction.c index 65f989fb0..2663f804d 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -936,12 +936,11 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O } u32 interact_bbh_entrance(struct MarioState *m, UNUSED u32 interactType, struct Object *o) { + if (m->playerIndex != 0) { return FALSE; } if (m->action != ACT_BBH_ENTER_SPIN && m->action != ACT_BBH_ENTER_JUMP) { mario_stop_riding_and_holding(m); - if (m->playerIndex == 0) { - o->oInteractStatus = INT_STATUS_INTERACTED; - } + o->oInteractStatus = INT_STATUS_INTERACTED; m->interactObj = o; m->usedObj = o;