diff --git a/include/object_fields.h b/include/object_fields.h index a6d771ce5..0bfed2521 100644 --- a/include/object_fields.h +++ b/include/object_fields.h @@ -310,6 +310,7 @@ #define /*0x108*/ oBowserPuzzlePieceContinuePerformingAction OBJECT_FIELD_S32(0x20) #define /*0x10C*/ oBowserPuzzlePieceActionList OBJECT_FIELD_VPTR(0x21) #define /*0x110*/ oBowserPuzzlePieceNextAction OBJECT_FIELD_VPTR(0x22) +#define /*0x0F4*/ oBowserPuzzlePieceTimer OBJECT_FIELD_U32(0x1B) /* Bubba */ #define /*0x0F4*/ oBubbaUnkF4 OBJECT_FIELD_F32(0x1B) diff --git a/src/game/behaviors/bowser_puzzle_piece.inc.c b/src/game/behaviors/bowser_puzzle_piece.inc.c index f984dbb4e..088074fdf 100644 --- a/src/game/behaviors/bowser_puzzle_piece.inc.c +++ b/src/game/behaviors/bowser_puzzle_piece.inc.c @@ -94,6 +94,8 @@ void bhv_lll_bowser_puzzle_spawn_piece(s16 model, const BehaviorScript *behavior puzzlePiece->oAction = initialAction; // This action never gets executed. puzzlePiece->oBowserPuzzlePieceActionList = actionList; puzzlePiece->oBowserPuzzlePieceNextAction = actionList; + puzzlePiece->oBowserPuzzlePieceTimer = 0; + puzzlePiece->oTimer = 0; } /** @@ -114,69 +116,6 @@ void bhv_lll_bowser_puzzle_spawn_pieces(f32 pieceWidth) { o->oAction++; } -static u8 bowserPuzzleTimer = 0; -static u8 bowserPuzzleOnAction = 0; -static u8 bowserPuzzleServerAction = 0; -static u32 bowserPuzzleTxRxAction = 0; -static u8 bowserPuzzleRx[MAX_PLAYERS] = { 0 }; - -static void bhv_lll_bowser_puzzle_networking_received(u8 fromLocalIndex) { - if (gNetworkType == NT_CLIENT) { - if (bowserPuzzleTxRxAction != (u8)(bowserPuzzleOnAction + 1)) { return; } - bowserPuzzleServerAction = bowserPuzzleTxRxAction; - return; - } - if (bowserPuzzleTxRxAction != bowserPuzzleOnAction) { return; } - bowserPuzzleRx[fromLocalIndex] = bowserPuzzleTxRxAction; -} - -static void bhv_lll_bowser_puzzle_networking(void) { - if (!network_sync_object_initialized(o)) { - bowserPuzzleTimer = 0; - bowserPuzzleOnAction = 0; - bowserPuzzleServerAction = 0; - bowserPuzzleTxRxAction = 0; - for (int i = 0; i < MAX_PLAYERS; i++) { bowserPuzzleRx[i] = 0; } - - struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); - network_init_object_field(o, &bowserPuzzleTxRxAction); - so->on_received_post = bhv_lll_bowser_puzzle_networking_received; - } - - if (bowserPuzzleTimer < 24) { - bowserPuzzleTimer++; - return; - } - - if (gNetworkType == NT_SERVER) { - if (bowserPuzzleTimer == 24) { - bowserPuzzleTimer++; - bowserPuzzleOnAction++; - bowserPuzzleTxRxAction = bowserPuzzleOnAction; - network_send_object(o); - return; - } - - for (int i = 1; i < MAX_PLAYERS; i++) { - if (gNetworkPlayers[i].connected && bowserPuzzleRx[i] != bowserPuzzleOnAction) { return; } - } - - // received from all, continue - bowserPuzzleTimer = 0; - return; - } - - if (gNetworkType == NT_CLIENT) { - if (bowserPuzzleServerAction == (u8)(bowserPuzzleOnAction + 1)) { - bowserPuzzleOnAction++; - bowserPuzzleTimer = 0; - bowserPuzzleTxRxAction = bowserPuzzleServerAction; - network_send_object(o); - } - return; - } -} - /* * Does the initial spawn of the puzzle pieces and then waits to spawn 5 coins. */ @@ -186,8 +125,6 @@ void bhv_lll_bowser_puzzle_loop(void) { struct Object* player = nearest_player_to_object(o); int distanceToPlayer = dist_between_objects(o, player); - bhv_lll_bowser_puzzle_networking(); - switch (o->oAction) { case BOWSER_PUZZLE_ACT_SPAWN_PIECES: bhv_lll_bowser_puzzle_spawn_pieces(480.0f); @@ -229,7 +166,7 @@ void bhv_lll_bowser_puzzle_piece_action_1(void) { * Update the puzzle piece. */ void bhv_lll_bowser_puzzle_piece_update(void) { - s8 *nextAction = o->oBowserPuzzlePieceNextAction; + s8* nextAction = o->oBowserPuzzlePieceNextAction; // If Mario is standing on this puzzle piece, set a flag in the parent. if (cur_obj_is_any_player_on_platform()) @@ -237,11 +174,6 @@ void bhv_lll_bowser_puzzle_piece_update(void) { // If we should advance to the next action... if (o->oBowserPuzzlePieceContinuePerformingAction == 0) { - // if we haven't received an event from everyone, do not continue execution - if (bowserPuzzleTimer >= 24) { - cur_obj_change_action(0); - return; - } // Start doing the next action. cur_obj_change_action(*nextAction); @@ -327,11 +259,27 @@ void (*sBowserPuzzlePieceActions[])(void) = { }; void bhv_lll_bowser_puzzle_piece_loop(void) { - bhv_lll_bowser_puzzle_piece_update(); + // make sure we're loaded and synchronized + if (!gNetworkLevelLoaded) { + o->oTimer = 0; + return; + } else if (o->oBowserPuzzlePieceTimer == 0 && (gNetworkLevelTimer - o->oBowserPuzzlePieceTimer) >= 650) { + o->oBowserPuzzlePieceTimer = ((gNetworkLevelTimer - o->oBowserPuzzlePieceTimer) / 650) * 650; + o->oTimer = 0; + } - cur_obj_call_action_function(sBowserPuzzlePieceActions); + while (o->oBowserPuzzlePieceTimer < gNetworkLevelTimer) { + bhv_lll_bowser_puzzle_piece_update(); - o->oPosX = o->oBowserPuzzlePieceOffsetX + o->oHomeX; - o->oPosY = o->oBowserPuzzlePieceOffsetY + o->oHomeY; - o->oPosZ = o->oBowserPuzzlePieceOffsetZ + o->oHomeZ; + cur_obj_call_action_function(sBowserPuzzlePieceActions); + + o->oPosX = o->oBowserPuzzlePieceOffsetX + o->oHomeX; + o->oPosY = o->oBowserPuzzlePieceOffsetY + o->oHomeY; + o->oPosZ = o->oBowserPuzzlePieceOffsetZ + o->oHomeZ; + + o->oBowserPuzzlePieceTimer++; + if (o->oBowserPuzzlePieceTimer < gNetworkLevelTimer) { + o->oTimer++; + } + } } diff --git a/src/pc/controller/controller_keyboard_debug.c b/src/pc/controller/controller_keyboard_debug.c index 57d91dccc..484ef042b 100644 --- a/src/pc/controller/controller_keyboard_debug.c +++ b/src/pc/controller/controller_keyboard_debug.c @@ -13,7 +13,7 @@ #ifdef DEBUG -static u8 warpToLevel = LEVEL_BOB; +static u8 warpToLevel = LEVEL_LLL; #define SCANCODE_0 0x0B #define SCANCODE_1 0x02 diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 6fcd884d9..a7deed34a 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -27,6 +27,7 @@ struct NetworkSystem* gNetworkSystem = &gNetworkSystemSocket; u16 networkLoadingLevel = 0; bool gNetworkLevelLoaded = false; bool gNetworkLevelSyncing = true; +u32 gNetworkLevelTimer = 0; clock_t gLastNetworkSend = 0; struct StringLinkedList gRegisteredMods = { 0 }; @@ -91,6 +92,7 @@ void network_on_init_level(void) { networkLoadingLevel = 0; gNetworkLevelLoaded = false; gNetworkLevelSyncing = true; + gNetworkLevelTimer = 0; } void network_on_loaded_level(void) { @@ -228,8 +230,11 @@ void network_update(void) { networkLoadingLevel++; if (!gNetworkLevelLoaded && networkLoadingLevel >= LOADING_LEVEL_THRESHOLD) { gNetworkLevelLoaded = true; + gNetworkLevelTimer = 0; network_on_loaded_level(); } + } else if (gNetworkLevelLoaded) { + gNetworkLevelTimer++; } // send out update packets diff --git a/src/pc/network/network.h b/src/pc/network/network.h index fdaa127fa..cfcaadbb2 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -82,6 +82,7 @@ extern struct NetworkSystem* gNetworkSystem; extern enum NetworkType gNetworkType; extern bool gNetworkLevelLoaded; extern bool gNetworkLevelSyncing; +extern u32 gNetworkLevelTimer; extern struct SyncObject gSyncObjects[]; extern struct ServerSettings gServerSettings; extern clock_t gLastNetworkSend; diff --git a/src/pc/network/packets/packet_area.c b/src/pc/network/packets/packet_area.c index b91805fd3..a8f11b68e 100644 --- a/src/pc/network/packets/packet_area.c +++ b/src/pc/network/packets/packet_area.c @@ -43,6 +43,9 @@ void network_send_area(struct NetworkPlayer* toNp) { packet_write(&p, &gCurrLevelNum, sizeof(s16)); packet_write(&p, &gCurrAreaIndex, sizeof(s16)); + // area variables + packet_write(&p, &gNetworkLevelTimer, sizeof(u32)); + // write sync id removals packet_write(&p, &sRemoveSyncIdsIndex, sizeof(u8)); for (int i = 0; i < sRemoveSyncIdsIndex; i++) { @@ -129,6 +132,10 @@ void network_receive_area(struct Packet* p) { packet_read(p, &levelNum, sizeof(s16)); packet_read(p, &areaIndex, sizeof(s16)); + // read area variables + packet_read(p, &gNetworkLevelTimer, sizeof(u32)); + + extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum; if (courseNum != gCurrCourseNum || actNum != gCurrActStarNum || levelNum != gCurrLevelNum || areaIndex != gCurrAreaIndex) { LOG_ERROR("rx area: received an improper location");