mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 05:25:14 +00:00
Cached network IDs for each area to prevent area swapping from assigning a different set of sync IDs
This commit is contained in:
parent
7c9b9a60d5
commit
9363de073f
4 changed files with 84 additions and 9 deletions
|
@ -227,6 +227,8 @@ void clear_areas(void) {
|
|||
gAreaData[i].dialog[1] = 255;
|
||||
gAreaData[i].musicParam = 0;
|
||||
gAreaData[i].musicParam2 = 0;
|
||||
memset(gAreaData[i].cachedBehaviors, 0, sizeof(u8) * 256);
|
||||
memset(gAreaData[i].cachedPositions, 0, sizeof(Vec3f) * 256);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,8 @@ struct Area
|
|||
/*0x34*/ u8 dialog[2]; // Level start dialog number (set by level script cmd 0x30)
|
||||
/*0x36*/ u16 musicParam;
|
||||
/*0x38*/ u16 musicParam2;
|
||||
/*????*/ u8 cachedBehaviors[256];
|
||||
/*????*/ Vec3f cachedPositions[256];
|
||||
};
|
||||
|
||||
// All the transition data to be used in screen_transition.c
|
||||
|
|
|
@ -39,8 +39,9 @@ void network_send_chat(char* message, u8 globalIndex) {
|
|||
network_send(&p);
|
||||
|
||||
#ifdef DEVELOPMENT
|
||||
print_network_player_table();
|
||||
reservation_area_debug();
|
||||
//print_network_player_table();
|
||||
//reservation_area_debug();
|
||||
print_sync_object_table();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,42 @@ void forget_ent_reliable_packet(struct Object* o) {
|
|||
}
|
||||
}
|
||||
|
||||
struct DelayedPacketObject {
|
||||
struct Packet p;
|
||||
struct DelayedPacketObject* next;
|
||||
};
|
||||
|
||||
struct DelayedPacketObject* delayedPacketObjectHead = NULL;
|
||||
struct DelayedPacketObject* delayedPacketObjectTail = NULL;
|
||||
|
||||
void network_delayed_packet_object_remember(struct Packet* p) {
|
||||
struct DelayedPacketObject* node = malloc(sizeof(struct DelayedPacketObject));
|
||||
packet_duplicate(p, &node->p);
|
||||
node->next = NULL;
|
||||
LOG_INFO("saving delayed object");
|
||||
|
||||
if (delayedPacketObjectHead == NULL) {
|
||||
delayedPacketObjectHead = node;
|
||||
delayedPacketObjectTail = node;
|
||||
} else {
|
||||
delayedPacketObjectTail->next = node;
|
||||
delayedPacketObjectTail = node;
|
||||
}
|
||||
}
|
||||
|
||||
void network_delayed_packet_object_execute(void) {
|
||||
struct DelayedPacketObject* node = delayedPacketObjectHead;
|
||||
while (node != NULL) {
|
||||
struct DelayedPacketObject* next = node->next;
|
||||
LOG_INFO("executing delayed object");
|
||||
network_receive_object(&node->p);
|
||||
free(node);
|
||||
node = next;
|
||||
}
|
||||
delayedPacketObjectHead = NULL;
|
||||
delayedPacketObjectTail = NULL;
|
||||
}
|
||||
|
||||
// todo: move this to somewhere more general
|
||||
static float player_distance(struct MarioState* marioState, struct Object* o) {
|
||||
if (marioState->marioObj == NULL) { return 0; }
|
||||
|
@ -149,18 +185,42 @@ void network_clear_sync_objects(void) {
|
|||
}
|
||||
}
|
||||
|
||||
u8 network_find_cached_sync_id(struct Object* o) {
|
||||
u8 behaviorId = get_id_from_behavior(o->behavior);
|
||||
for (int i = 1; i < 256; i++) {
|
||||
if (gSyncObjects[i].o != NULL) { continue; }
|
||||
u8 cachedBehaviorId = gCurrentArea->cachedBehaviors[i];
|
||||
if (cachedBehaviorId != behaviorId) { continue; }
|
||||
|
||||
f32 dist = dist_between_object_and_point(o, gCurrentArea->cachedPositions[i][0], gCurrentArea->cachedPositions[i][1], gCurrentArea->cachedPositions[i][2]);
|
||||
if (dist > 1) { continue; }
|
||||
//LOG_INFO("get cached sync id for %02X: %d", behaviorId, i);
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void network_set_sync_id(struct Object* o) {
|
||||
if (o->oSyncID != 0) { return; }
|
||||
|
||||
u8 syncId = 0;
|
||||
if (!gNetworkAreaLoaded) {
|
||||
// while loading, just fill in sync ids from 1 to MAX_SYNC_OBJECTS
|
||||
for (int i = 1; i < MAX_SYNC_OBJECTS; i++) {
|
||||
sNextSyncId++;
|
||||
sNextSyncId = sNextSyncId % RESERVED_IDS_SYNC_OBJECT_OFFSET;
|
||||
if (gSyncObjects[sNextSyncId].o != NULL) { continue; }
|
||||
syncId = sNextSyncId;
|
||||
break;
|
||||
syncId = network_find_cached_sync_id(o);
|
||||
if (syncId == 0) {
|
||||
// while loading, just fill in sync ids from 1 to MAX_SYNC_OBJECTS
|
||||
for (int i = 1; i < MAX_SYNC_OBJECTS; i++) {
|
||||
sNextSyncId++;
|
||||
sNextSyncId = sNextSyncId % RESERVED_IDS_SYNC_OBJECT_OFFSET;
|
||||
if (gSyncObjects[sNextSyncId].o != NULL) { continue; }
|
||||
syncId = sNextSyncId;
|
||||
break;
|
||||
}
|
||||
// cache this object's id
|
||||
gCurrentArea->cachedBehaviors[syncId] = get_id_from_behavior(o->behavior);
|
||||
gCurrentArea->cachedPositions[syncId][0] = o->oPosX;
|
||||
gCurrentArea->cachedPositions[syncId][1] = o->oPosY;
|
||||
gCurrentArea->cachedPositions[syncId][2] = o->oPosZ;
|
||||
//LOG_INFO("set cached sync id for %02X: %d", gCurrentArea->cachedBehaviors[syncId], syncId);
|
||||
}
|
||||
} else {
|
||||
// no longer loading, require reserved id
|
||||
|
@ -480,6 +540,12 @@ void network_receive_object(struct Packet* p) {
|
|||
// prevent receiving objects during credits sequence
|
||||
if (gCurrActStarNum == 99) { return; }
|
||||
|
||||
// delay any objects received while we're loading the area
|
||||
if (!gNetworkAreaLoaded) {
|
||||
network_delayed_packet_object_remember(p);
|
||||
return;
|
||||
}
|
||||
|
||||
// read the header and sanity check the packet
|
||||
u8 fromLocalIndex = 0;
|
||||
struct SyncObject* so = packet_read_object_header(p, &fromLocalIndex);
|
||||
|
@ -560,6 +626,10 @@ void network_forget_sync_object(struct SyncObject* so) {
|
|||
}
|
||||
|
||||
void network_update_objects(void) {
|
||||
if (gNetworkAreaLoaded && delayedPacketObjectHead != NULL) {
|
||||
network_delayed_packet_object_execute();
|
||||
}
|
||||
|
||||
for (u32 i = 1; i < MAX_SYNC_OBJECTS; i++) {
|
||||
struct SyncObject* so = &gSyncObjects[i];
|
||||
if (so->o == NULL) { continue; }
|
||||
|
|
Loading…
Reference in a new issue