diff --git a/developer/debug.sh b/developer/debug.sh index bfdb0d1ef..432f59290 100644 --- a/developer/debug.sh +++ b/developer/debug.sh @@ -1,2 +1,2 @@ #!/bin/bash -make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 STRICT=1 && winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here' \ No newline at end of file +winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here' diff --git a/src/game/behaviors/flying_bookend_switch.inc.c b/src/game/behaviors/flying_bookend_switch.inc.c index 425eeaee8..17a0a5182 100644 --- a/src/game/behaviors/flying_bookend_switch.inc.c +++ b/src/game/behaviors/flying_bookend_switch.inc.c @@ -146,7 +146,6 @@ void bhv_bookend_spawn_loop(void) { if (book != NULL) { book->oAction = 3; - network_set_sync_id(book); struct Object* spawn_objects[] = { book }; u32 models[] = { MODEL_BOOKEND }; network_send_spawn_objects(spawn_objects, models, 1); @@ -159,6 +158,8 @@ void bhv_bookend_spawn_loop(void) { } void bookshelf_manager_act_0(void) { + // spawn book switches + s32 val04; //if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { @@ -171,13 +172,15 @@ void bookshelf_manager_act_0(void) { } void bookshelf_manager_act_1(void) { + // wait until mario is near + struct MarioState* marioState = nearest_mario_state_to_object(o); if (o->oBookSwitchManagerUnkF8 == 0) { - if (gNetworkType == NT_SERVER && obj_is_near_to_and_facing_mario(marioState, 500.0f, 0x3000)) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned && obj_is_near_to_and_facing_mario(marioState, 500.0f, 0x3000)) { o->oBookSwitchManagerUnkF8 = 1; network_send_object(o); } - } else if (o->oTimer > 60 && gNetworkType == NT_SERVER) { + } else if (o->oTimer > 60 && o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oAction = 2; o->oBookSwitchManagerUnkF8 = 0; network_send_object(o); @@ -185,15 +188,17 @@ void bookshelf_manager_act_1(void) { } void bookshelf_manager_act_2(void) { + // detect if we can open, and open bookshelf if we should + //if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { if (o->oBookSwitchManagerUnkF4 < 0) { if (o->oTimer > 30) { - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oBookSwitchManagerUnkF4 = o->oBookSwitchManagerUnkF8 = 0; network_send_object(o); } } else if (o->oTimer > 10) { - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oBookSwitchManagerUnkF8 = 1; network_send_object(o); } @@ -201,7 +206,7 @@ void bookshelf_manager_act_2(void) { } else { if (o->oBookSwitchManagerUnkF4 >= 3) { if (o->oTimer > 100) { - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->parentObj = cur_obj_nearest_object_with_behavior(bhvHauntedBookshelf); o->parentObj->oAction = 1; o->oPosX = o->parentObj->oPosX; @@ -216,18 +221,17 @@ void bookshelf_manager_act_2(void) { o->oTimer = 0; } } - /*} else if (gNetworkType == NT_SERVER) { - o->oAction = 4; - network_send_object(o); - }*/ + //} } void bookshelf_manager_act_3(void) { + // opening bookshelf + if (o->parentObj == NULL || o->parentObj->behavior != bhvHauntedBookshelf) { o->parentObj = cur_obj_nearest_object_with_behavior(bhvHauntedBookshelf); } if (o->oTimer > 85) { - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oAction = 4; network_send_object(o); } @@ -238,18 +242,32 @@ void bookshelf_manager_act_3(void) { } void bookshelf_manager_act_4(void) { + // bookshelf is done opening + if (o->oBookSwitchManagerUnkF4 >= 3) { obj_mark_for_deletion(o); - } else if (gNetworkType == NT_SERVER) { + } else if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oAction = 0; network_send_object(o); } } +void bhv_haunted_bookshelf_manager_override_ownership(u8* shouldOverride, u8* shouldOwn) { + *shouldOverride = TRUE; + *shouldOwn = get_network_player_smallest_global() == gNetworkPlayerLocal; +} + +static u8 bhv_haunted_bookshelf_manager_ignore_if_true(void) { + if (o->oSyncID == 0) { return true; } + return gSyncObjects[o->oSyncID].owned; +} + void bhv_haunted_bookshelf_manager_loop(void) { if (!network_sync_object_initialized(o)) { struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); so->syncDeathEvent = FALSE; + so->override_ownership = bhv_haunted_bookshelf_manager_override_ownership; + so->ignore_if_true = bhv_haunted_bookshelf_manager_ignore_if_true; network_init_object_field(o, &o->oAction); network_init_object_field(o, &o->activeFlags); network_init_object_field(o, &o->oBookSwitchManagerUnkF8); @@ -280,7 +298,10 @@ void bhv_haunted_bookshelf_manager_loop(void) { void bhv_book_switch_loop(void) { if (!network_sync_object_initialized(o)) { - network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + so->override_ownership = bhv_haunted_bookshelf_manager_override_ownership; + so->ignore_if_true = bhv_haunted_bookshelf_manager_ignore_if_true; + network_init_object_field(o, &o->oAction); network_init_object_field(o, &o->oBookSwitchUnkF4); network_init_object_field(o, &o->oIntangibleTimer); @@ -312,7 +333,7 @@ void bhv_book_switch_loop(void) { cur_obj_become_intangible(); } - if (gNetworkType == NT_SERVER && o->oAction != 1) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned && o->oAction != 1) { o->oAction = 1; network_send_object(o); } @@ -324,7 +345,7 @@ void bhv_book_switch_loop(void) { if (approach_f32_ptr(&o->oBookSwitchUnkF4, 50.0f, 20.0f)) { if (o->parentObj->oBookSwitchManagerUnkF4 >= 0 && o->oTimer > 60) { if (sp3C == 1 || sp3C == 2 || sp3C == 6) { - if (gNetworkType == NT_SERVER && o->oAction != 2) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned && o->oAction != 2) { o->oAction = 2; network_send_object(o); } @@ -339,7 +360,7 @@ void bhv_book_switch_loop(void) { if (o->oAction != 0) { if (o->parentObj->oBookSwitchManagerUnkF4 == o->oBehParams2ndByte) { play_sound(SOUND_GENERAL2_RIGHT_ANSWER, gDefaultSoundArgs); - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->parentObj->oBookSwitchManagerUnkF4 += 1; network_send_object(o->parentObj); } @@ -352,26 +373,25 @@ void bhv_book_switch_loop(void) { sp34 = 0; } - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { book = spawn_object_abs_with_rot(o, 0, MODEL_BOOKEND, bhvFlyingBookend, 0x1FC * sp36 - 0x8CA, 890, sp34, 0, 0x8000 * sp36 + 0x4000, 0); if (book != NULL) { book->oAction = 3; - network_set_sync_id(book); struct Object* spawn_objects[] = { book }; u32 models[] = { MODEL_BOOKEND }; network_send_spawn_objects(spawn_objects, models, 1); } } - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->parentObj->oBookSwitchManagerUnkF4 = -1; network_send_object(o->parentObj); } } - if (gNetworkType == NT_SERVER && o->oAction != 0) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned && o->oAction != 0) { o->oAction = 0; network_send_object(o); } diff --git a/src/pc/controller/controller_keyboard_debug.c b/src/pc/controller/controller_keyboard_debug.c index 57d91dccc..b9fdd1818 100644 --- a/src/pc/controller/controller_keyboard_debug.c +++ b/src/pc/controller/controller_keyboard_debug.c @@ -13,7 +13,12 @@ #ifdef DEBUG -static u8 warpToLevel = LEVEL_BOB; +static u8 warpToLevel = LEVEL_BBH; +static u8 warpToArea = 29; +// warpToArea: 26 = basement +// warpToArea: 27 = upstairs +// warpToArea: 29 = courtyard + #define SCANCODE_0 0x0B #define SCANCODE_1 0x02 @@ -82,17 +87,20 @@ static void debug_warp_area() { if (sCurrPlayMode == PLAY_MODE_CHANGE_LEVEL) { return; } struct ObjectWarpNode* objectNode = gCurrentArea->warpNodes; + u8 onArea = 0; while (objectNode != NULL) { struct WarpNode* node = &objectNode->node; - if (node->destLevel == gCurrLevelNum && node->destArea != gCurrAreaIndex) { - sWarpDest.type = WARP_TYPE_CHANGE_AREA; - sWarpDest.levelNum = node->destLevel; - sWarpDest.areaIdx = node->destArea; - sWarpDest.nodeId = node->destNode; - sWarpDest.arg = 0; + if (gCurrCourseNum == 0 || (node->destLevel == gCurrLevelNum && node->destArea != gCurrAreaIndex)) { + if (gCurrCourseNum != 0 || ++onArea == warpToArea) { + sWarpDest.type = WARP_TYPE_CHANGE_AREA; + sWarpDest.levelNum = node->destLevel; + sWarpDest.areaIdx = node->destArea; + sWarpDest.nodeId = node->destNode; + sWarpDest.arg = 0; - sCurrPlayMode = PLAY_MODE_CHANGE_LEVEL; - return; + sCurrPlayMode = PLAY_MODE_CHANGE_LEVEL; + return; + } } objectNode = objectNode->next; } diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 87cdcd01e..2c7b92bed 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -77,8 +77,7 @@ bool network_init(enum NetworkType inNetworkType) { network_player_connected(NPT_LOCAL, 0); extern u8* gOverrideEeprom; gOverrideEeprom = NULL; - } - else if (gNetworkType == NT_CLIENT) { + } else if (gNetworkType == NT_CLIENT) { network_player_connected(NPT_SERVER, 0); } diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index a0e6bb011..025dda785 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -37,11 +37,11 @@ struct NetworkPlayer* network_player_from_global_index(u8 globalIndex) { struct NetworkPlayer* get_network_player_from_level(s16 courseNum, s16 actNum, s16 levelNum) { for (int i = 0; i < MAX_PLAYERS; i++) { struct NetworkPlayer* np = &gNetworkPlayers[i]; - if (!np->connected) { continue; } - if (!np->currLevelSyncValid) { continue; } + if (!np->connected) { continue; } + if (!np->currLevelSyncValid) { continue; } if (np->currCourseNum != courseNum) { continue; } - if (np->currActNum != actNum) { continue; } - if (np->currLevelNum != levelNum) { continue; } + if (np->currActNum != actNum) { continue; } + if (np->currLevelNum != levelNum) { continue; } return np; } return NULL; @@ -50,18 +50,35 @@ struct NetworkPlayer* get_network_player_from_level(s16 courseNum, s16 actNum, s struct NetworkPlayer* get_network_player_from_area(s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { for (int i = 0; i < MAX_PLAYERS; i++) { struct NetworkPlayer* np = &gNetworkPlayers[i]; - if (!np->connected) { continue; } - if (!np->currLevelSyncValid) { continue; } - if (!np->currAreaSyncValid) { continue; } + if (!np->connected) { continue; } + if (!np->currLevelSyncValid) { continue; } + if (!np->currAreaSyncValid) { continue; } if (np->currCourseNum != courseNum) { continue; } - if (np->currActNum != actNum) { continue; } - if (np->currLevelNum != levelNum) { continue; } + if (np->currActNum != actNum) { continue; } + if (np->currLevelNum != levelNum) { continue; } if (np->currAreaIndex != areaIndex) { continue; } return np; } return NULL; } +struct NetworkPlayer* get_network_player_smallest_global(void) { + struct NetworkPlayer* lNp = gNetworkPlayerLocal; + struct NetworkPlayer* smallest = gNetworkPlayerLocal; + for (int i = 0; i < MAX_PLAYERS; i++) { + struct NetworkPlayer* np = &gNetworkPlayers[i]; + if (!np->connected) { continue; } + if (!np->currLevelSyncValid) { continue; } + if (!np->currAreaSyncValid) { continue; } + if (np->currCourseNum != lNp->currCourseNum) { continue; } + if (np->currActNum != lNp->currActNum) { continue; } + if (np->currLevelNum != lNp->currLevelNum) { continue; } + if (np->currAreaIndex != lNp->currAreaIndex) { continue; } + if (np->globalIndex < smallest->globalIndex) { smallest = np; } + } + return smallest; +} + void network_player_update(void) { float elapsed = (clock() - gLastNetworkSend) / (float)CLOCKS_PER_SEC; if (elapsed > NETWORK_PLAYER_TIMEOUT / 3.0f) { @@ -109,11 +126,15 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) { np->localIndex = 0; np->globalIndex = globalIndex; np->currLevelAreaSeqId = 0; - np->currCourseNum = -1; - np->currActNum = -1; - np->currLevelNum = -1; - np->currAreaIndex = -1; - np->currAreaSyncValid = false; + + extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex; + np->currCourseNum = gCurrCourseNum; + np->currActNum = gCurrActStarNum; + np->currLevelNum = gCurrLevelNum; + np->currAreaIndex = gCurrAreaIndex; + np->currLevelSyncValid = false; + np->currAreaSyncValid = false; + gNetworkPlayerLocal = np; if (gNetworkType == NT_SERVER) { @@ -142,11 +163,14 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) { memset(np, 0, sizeof(struct NetworkPlayer)); np->connected = true; np->currLevelAreaSeqId = 0; - np->currCourseNum = -1; - np->currActNum = -1; - np->currLevelNum = -1; - np->currAreaIndex = -1; - np->currAreaSyncValid = false; + if (!np->currAreaSyncValid) { + np->currCourseNum = -1; + np->currActNum = -1; + np->currLevelNum = -1; + np->currAreaIndex = -1; + np->currLevelSyncValid = false; + np->currAreaSyncValid = false; + } np->fadeOpacity = 0; np->localIndex = i; np->globalIndex = (gNetworkType == NT_SERVER) ? i : globalIndex; @@ -186,6 +210,12 @@ u8 network_player_disconnected(u8 globalIndex) { if (np->globalIndex != globalIndex) { continue; } if (gNetworkType == NT_SERVER) { network_send_leaving(np->globalIndex); } np->connected = false; + np->currCourseNum = -1; + np->currActNum = -1; + np->currLevelNum = -1; + np->currAreaIndex = -1; + np->currLevelSyncValid = false; + np->currAreaSyncValid = false; gNetworkSystem->clear_id(i); for (int j = 0; j < MAX_SYNC_OBJECTS; j++) { gSyncObjects[j].rxEventId[i] = 0; } LOG_INFO("player disconnected, local %d, global %d", i, globalIndex); diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h index 6e5f7b231..7da84bce9 100644 --- a/src/pc/network/network_player.h +++ b/src/pc/network/network_player.h @@ -44,6 +44,7 @@ u8 network_player_connected_count(void); struct NetworkPlayer* network_player_from_global_index(u8 globalIndex); struct NetworkPlayer* get_network_player_from_level(s16 courseNum, s16 actNum, s16 levelNum); struct NetworkPlayer* get_network_player_from_area(s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex); +struct NetworkPlayer* get_network_player_smallest_global(void); void network_player_update(void); u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex); u8 network_player_disconnected(u8 globalIndex); diff --git a/src/pc/network/packets/packet_change_area.c b/src/pc/network/packets/packet_change_area.c index 7534c0d18..8082126df 100644 --- a/src/pc/network/packets/packet_change_area.c +++ b/src/pc/network/packets/packet_change_area.c @@ -12,7 +12,6 @@ static void player_changed_area(struct NetworkPlayer* np, s16 courseNum, s16 act np->currLevelNum = levelNum; np->currAreaIndex = areaIndex; np->currAreaSyncValid = false; - network_send_level_area_inform(np); reservation_area_change(np); // find a NetworkPlayer at that area @@ -21,11 +20,14 @@ static void player_changed_area(struct NetworkPlayer* np, s16 courseNum, s16 act if (npLevelAreaMatch == NULL) { // no NetworkPlayer in the level network_send_sync_valid(np); + network_send_level_area_inform(np); return; } // matching NetworkPlayer is client network_send_area_request(np, npLevelAreaMatch); + + network_send_level_area_inform(np); } void network_send_change_area(void) { diff --git a/src/pc/network/packets/packet_change_level.c b/src/pc/network/packets/packet_change_level.c index 73f98381c..b1264c577 100644 --- a/src/pc/network/packets/packet_change_level.c +++ b/src/pc/network/packets/packet_change_level.c @@ -13,7 +13,6 @@ static void player_changed_level(struct NetworkPlayer* np, s16 courseNum, s16 ac np->currAreaIndex = areaIndex; np->currLevelSyncValid = false; np->currAreaSyncValid = false; - network_send_level_area_inform(np); reservation_area_change(np); // find a NetworkPlayer around that location @@ -24,6 +23,7 @@ static void player_changed_level(struct NetworkPlayer* np, s16 courseNum, s16 ac if (npAny == NULL) { // no NetworkPlayer in the level network_send_sync_valid(np); + network_send_level_area_inform(np); return; } @@ -33,6 +33,7 @@ static void player_changed_level(struct NetworkPlayer* np, s16 courseNum, s16 ac } else { network_send_level_request(np, npAny); } + network_send_level_area_inform(np); } void network_send_change_level(void) { diff --git a/src/pc/network/packets/packet_level_area_inform.c b/src/pc/network/packets/packet_level_area_inform.c index 254ca8d0d..104009cf6 100644 --- a/src/pc/network/packets/packet_level_area_inform.c +++ b/src/pc/network/packets/packet_level_area_inform.c @@ -9,11 +9,13 @@ void network_send_level_area_inform(struct NetworkPlayer* np) { struct Packet p; packet_init(&p, PACKET_LEVEL_AREA_INFORM, true, false); - packet_write(&p, &np->globalIndex, sizeof(u8)); - packet_write(&p, &np->currCourseNum, sizeof(s16)); - packet_write(&p, &np->currActNum, sizeof(s16)); - packet_write(&p, &np->currLevelNum, sizeof(s16)); - packet_write(&p, &np->currAreaIndex, sizeof(s16)); + packet_write(&p, &np->globalIndex, sizeof(u8)); + packet_write(&p, &np->currCourseNum, sizeof(s16)); + packet_write(&p, &np->currActNum, sizeof(s16)); + packet_write(&p, &np->currLevelNum, sizeof(s16)); + packet_write(&p, &np->currAreaIndex, sizeof(s16)); + packet_write(&p, &np->currLevelSyncValid, sizeof(u8)); + packet_write(&p, &np->currAreaSyncValid, sizeof(u8)); network_send(&p); LOG_INFO("tx level area inform"); @@ -26,11 +28,14 @@ void network_receive_level_area_inform(struct Packet* p) { u8 globalIndex; s16 courseNum, actNum, levelNum, areaIndex; - packet_read(p, &globalIndex, sizeof(u8)); - packet_read(p, &courseNum, sizeof(s16)); - packet_read(p, &actNum, sizeof(s16)); - packet_read(p, &levelNum, sizeof(s16)); - packet_read(p, &areaIndex, sizeof(s16)); + u8 levelSyncValid, areaSyncValid; + packet_read(p, &globalIndex, sizeof(u8)); + packet_read(p, &courseNum, sizeof(s16)); + packet_read(p, &actNum, sizeof(s16)); + packet_read(p, &levelNum, sizeof(s16)); + packet_read(p, &areaIndex, sizeof(s16)); + packet_read(p, &levelSyncValid, sizeof(u8)); + packet_read(p, &areaSyncValid, sizeof(u8)); struct NetworkPlayer* np = network_player_from_global_index(globalIndex); if (np == NULL || np->localIndex == UNKNOWN_LOCAL_INDEX || !np->connected) { @@ -38,8 +43,12 @@ void network_receive_level_area_inform(struct Packet* p) { return; } - np->currCourseNum = courseNum; - np->currActNum = actNum; - np->currLevelNum = levelNum; - np->currAreaIndex = areaIndex; + if (np == gNetworkPlayerLocal) { return; } + + np->currCourseNum = courseNum; + np->currActNum = actNum; + np->currLevelNum = levelNum; + np->currAreaIndex = areaIndex; + np->currLevelSyncValid = levelSyncValid; + np->currAreaSyncValid = areaSyncValid; } diff --git a/src/pc/network/packets/packet_level_respawn_info.c b/src/pc/network/packets/packet_level_respawn_info.c index 08b9f7832..a79e1b745 100644 --- a/src/pc/network/packets/packet_level_respawn_info.c +++ b/src/pc/network/packets/packet_level_respawn_info.c @@ -128,12 +128,12 @@ void network_send_level_respawn_info(struct Object* o, u8 respawnInfoBits) { // broadcast for (int i = 0; i < MAX_PLAYERS; i++) { struct NetworkPlayer* np = &gNetworkPlayers[i]; - if (!np->connected) { continue; } - if (!np->currLevelSyncValid) { continue; } + if (!np->connected) { continue; } + if (!np->currLevelSyncValid) { continue; } if (np->currCourseNum != gCurrCourseNum) { continue; } - if (np->currActNum != gCurrActStarNum) { continue; } - if (np->currLevelNum != gCurrLevelNum) { continue; } - if (np == gNetworkPlayerLocal) { continue; } + if (np->currActNum != gCurrActStarNum) { continue; } + if (np->currLevelNum != gCurrLevelNum) { continue; } + if (np == gNetworkPlayerLocal) { continue; } struct Packet p2; packet_duplicate(&p, &p2); network_send_to(np->localIndex, &p2); diff --git a/src/pc/network/packets/packet_network_players.c b/src/pc/network/packets/packet_network_players.c index e6344a5a3..104d757ab 100644 --- a/src/pc/network/packets/packet_network_players.c +++ b/src/pc/network/packets/packet_network_players.c @@ -20,13 +20,15 @@ static void network_send_to_network_players(u8 sendToLocalIndex) { if (npType == NPT_LOCAL) { npType = NPT_SERVER; } else if (i == sendToLocalIndex) { npType = NPT_LOCAL; } s64 networkId = gNetworkSystem->get_id(i); - packet_write(&p, &npType, sizeof(u8)); + packet_write(&p, &npType, sizeof(u8)); packet_write(&p, &gNetworkPlayers[i].globalIndex, sizeof(u8)); packet_write(&p, &gNetworkPlayers[i].currLevelAreaSeqId, sizeof(u16)); packet_write(&p, &gNetworkPlayers[i].currCourseNum, sizeof(s16)); packet_write(&p, &gNetworkPlayers[i].currActNum, sizeof(s16)); packet_write(&p, &gNetworkPlayers[i].currLevelNum, sizeof(s16)); packet_write(&p, &gNetworkPlayers[i].currAreaIndex, sizeof(s16)); + packet_write(&p, &gNetworkPlayers[i].currLevelSyncValid, sizeof(u8)); + packet_write(&p, &gNetworkPlayers[i].currAreaSyncValid, sizeof(u8)); packet_write(&p, &networkId, sizeof(s64)); LOG_INFO("send network player [%d == %d]", gNetworkPlayers[i].globalIndex, npType); } @@ -56,6 +58,7 @@ void network_receive_network_players(struct Packet* p) { u8 npType, globalIndex; u16 levelAreaSeqId; s16 courseNum, actNum, levelNum, areaIndex; + u8 levelSyncValid, areaSyncValid; s64 networkId; packet_read(p, &npType, sizeof(u8)); packet_read(p, &globalIndex, sizeof(u8)); @@ -64,6 +67,8 @@ void network_receive_network_players(struct Packet* p) { packet_read(p, &actNum, sizeof(s16)); packet_read(p, &levelNum, sizeof(s16)); packet_read(p, &areaIndex, sizeof(s16)); + packet_read(p, &levelSyncValid, sizeof(u8)); + packet_read(p, &areaSyncValid, sizeof(u8)); packet_read(p, &networkId, sizeof(s64)); u8 localIndex = network_player_connected(npType, globalIndex); @@ -75,6 +80,8 @@ void network_receive_network_players(struct Packet* p) { np->currActNum = actNum; np->currLevelNum = levelNum; np->currAreaIndex = areaIndex; + np->currLevelSyncValid = levelSyncValid; + np->currAreaSyncValid = areaSyncValid; LOG_INFO("received network player location (%d, %d, %d, %d)", courseNum, actNum, levelNum, areaIndex); if (gNetworkType == NT_CLIENT && globalIndex != 0 && localIndex != 0) { gNetworkSystem->save_id(localIndex, networkId); diff --git a/src/pc/network/packets/packet_sync_valid.c b/src/pc/network/packets/packet_sync_valid.c index 49ddf1ce6..a8553aeac 100644 --- a/src/pc/network/packets/packet_sync_valid.c +++ b/src/pc/network/packets/packet_sync_valid.c @@ -8,9 +8,12 @@ void network_send_sync_valid(struct NetworkPlayer* toNp) { toNp->currLevelSyncValid = true; toNp->currAreaSyncValid = true; - if (toNp == gNetworkPlayerLocal) { - // the player is the server, no need to send it + if (gNetworkType == NT_SERVER && toNp == gNetworkPlayerLocal) { + // the player is the server, no need to send sync valid gNetworkAreaSyncing = false; + + // but we do need to send level area inform + network_send_level_area_inform(toNp); return; } @@ -61,6 +64,11 @@ void network_receive_sync_valid(struct Packet* p) { network_send_sync_valid(gNetworkPlayerServer); } + // inform everyone that this player is valid + if (gNetworkType == NT_SERVER) { + network_send_level_area_inform(np); + } + // we're no longer syncing gNetworkAreaSyncing = false; }