BBH bookshelf manager no longer requires the server to be in BBH

Instead of only allowing the server to update the bookshelf manager, allow the
lowest global ID player to update it.
This commit is contained in:
MysterD 2021-06-15 21:01:28 -07:00
parent 4c401f9ba8
commit f60b861d73
12 changed files with 160 additions and 75 deletions

View File

@ -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'
winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here'

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}