From 3d055255bccb96c193ded0fb61f6d0e6273fb1ff Mon Sep 17 00:00:00 2001 From: MysterD Date: Sun, 2 Aug 2020 16:09:32 -0700 Subject: [PATCH] Added ability to sync multiple objects --- levels/castle_grounds/script.c | 1 + src/pc/network/network.c | 2 +- src/pc/network/network.h | 17 ++-- src/pc/network/packets/packet_object.c | 116 +++++++++++++++++-------- src/pc/network/packets/packet_player.c | 4 +- 5 files changed, 94 insertions(+), 46 deletions(-) diff --git a/levels/castle_grounds/script.c b/levels/castle_grounds/script.c index 374c5fd6..684aec35 100644 --- a/levels/castle_grounds/script.c +++ b/levels/castle_grounds/script.c @@ -91,6 +91,7 @@ static const LevelScript script_func_local_4[] = { OBJECT(/*model*/ MODEL_YOSHI, /*pos*/ 0, 3174, -5625, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvYoshi), // TESTING BELOW OBJECT(/*model*/ MODEL_BLACK_BOBOMB, /*pos*/ -2028, 260, 4664, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvBobomb), + OBJECT(/*model*/ MODEL_BLACK_BOBOMB, /*pos*/ -1028, 260, 3664, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvBobomb), //OBJECT(/*model*/ MODEL_NONE, /*pos*/ -2028, 260, 3264, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvGoombaTripletSpawner), RETURN(), }; diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 878ad0af..76a0fd02 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -77,7 +77,7 @@ void network_update(void) { if (networkType == NT_NONE) { return; } network_send_player(); - network_send_object(NULL); + network_update_objects(); do { struct sockaddr_in rxAddr; diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 4ecc951d..9d7acbde 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -9,10 +9,6 @@ #define PACKET_LENGTH 1024 #define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server") -extern struct MarioState gMarioStates[]; -extern enum NetworkType networkType; -extern struct Object* syncObjects[]; - enum PacketType { PACKET_PLAYER, PACKET_OBJECT @@ -24,6 +20,17 @@ struct Packet { char buffer[PACKET_LENGTH]; }; +struct SyncObject { + struct Object* o; + bool owned; + unsigned int ticksSinceUpdate; + unsigned int syncDeactive; +}; + +extern struct MarioState gMarioStates[]; +extern enum NetworkType networkType; +extern struct SyncObject syncObjects[]; + void network_init(enum NetworkType networkType); void network_init_object(struct Object *object); void network_send(struct Packet* p); @@ -39,7 +46,7 @@ void packet_read(struct Packet* packet, void* data, int length); void network_send_player(void); void network_receive_player(struct Packet* p); -void network_send_object(struct Object* o); +void network_update_objects(void); void network_receive_object(struct Packet* p); #endif diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c index 8d3255be..0161163b 100644 --- a/src/pc/network/packets/packet_object.c +++ b/src/pc/network/packets/packet_object.c @@ -4,7 +4,58 @@ #include "object_constants.h" u32 nextSyncID = 1; -struct Object* syncObjects[MAX_SYNC_OBJECTS] = { 0 }; +struct SyncObject syncObjects[MAX_SYNC_OBJECTS] = { 0 }; + +void network_init_object(struct Object *o) { + if (o->oSyncID == 0) { + o->oSyncID = nextSyncID++; + } + assert(o->oSyncID < MAX_SYNC_OBJECTS); + syncObjects[o->oSyncID].o = o; + syncObjects[o->oSyncID].owned = false; + syncObjects[o->oSyncID].ticksSinceUpdate = -1; + syncObjects[o->oSyncID].syncDeactive = 0; +} + +void network_send_object(struct SyncObject* so) { + struct Object* o = so->o; + + struct Packet p; + packet_init(&p, PACKET_OBJECT); + packet_write(&p, &o->oSyncID, 4); + packet_write(&p, &o->activeFlags, 2); + packet_write(&p, &o->oPosX, 28); + packet_write(&p, &o->oAction, 4); + packet_write(&p, &o->oHeldState, 4); + packet_write(&p, &o->oMoveAngleYaw, 4); + + if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { so->syncDeactive++; } + network_send(&p); +} + +void network_receive_object(struct Packet* p) { + // get sync ID + u32 syncId; + packet_read(p, &syncId, 4); + assert(syncId < MAX_SYNC_OBJECTS); + + // retrieve SyncObject + struct SyncObject* so = &syncObjects[syncId]; + so->ticksSinceUpdate = 0; + + // extract Object + struct Object* o = syncObjects[syncId].o; + if (o == NULL) { printf("%s failed to receive object!\n", NETWORKTYPESTR); return; } + + // write object flags + packet_read(p, &o->activeFlags, 2); + packet_read(p, &o->oPosX, 28); + packet_read(p, &o->oAction, 4); + packet_read(p, &o->oHeldState, 4); + packet_read(p, &o->oMoveAngleYaw, 4); + + if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { so->syncDeactive++; } +} float player_distance(struct MarioState* marioState, struct Object* o) { if (marioState->marioObj == NULL) { return 0; } @@ -17,42 +68,31 @@ float player_distance(struct MarioState* marioState, struct Object* o) { return sqrt(mx + my + mz); } -void network_init_object(struct Object *o) { - if (o->oSyncID == 0) { - o->oSyncID = nextSyncID++; +bool should_own_object(struct SyncObject* so) { + if (player_distance(&gMarioStates[0], so->o) > player_distance(&gMarioStates[1], so->o)) { return false; } + if (so->o->oHeldState == HELD_HELD && so->o->heldByPlayerIndex != 0) { return false; } + return true; +} + +void forget_sync_object(struct SyncObject* so) { + so->o = NULL; + so->owned = false; + so->ticksSinceUpdate = -1; + so->syncDeactive = 0; +} + +void network_update_objects(void) { + for (int i = 0; i < MAX_SYNC_OBJECTS; i++) { + if (syncObjects[i].o == NULL) { continue; } + + if (syncObjects[i].o->oSyncID != i || syncObjects[i].syncDeactive > 10) { + forget_sync_object(&syncObjects[i]); + continue; + } + + if (!should_own_object(&syncObjects[i])) { continue; } + + network_send_object(&syncObjects[i]); } - assert(o->oSyncID < MAX_SYNC_OBJECTS); - syncObjects[o->oSyncID] = o; -} -void network_send_object(struct Object* o) { - int expectedID = 1; - o = syncObjects[expectedID]; - if (o == NULL) { return; } - //if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { return; } - if (o->oSyncID != expectedID) { return; } - if (player_distance(&gMarioStates[0], o) > player_distance(&gMarioStates[1], o)) { return; } - - struct Packet p; - packet_init(&p, PACKET_OBJECT); - packet_write(&p, &o->oSyncID, 4); - packet_write(&p, &o->oPosX, 28); - packet_write(&p, &o->oAction, 4); - packet_write(&p, &o->oHeldState, 4); - packet_write(&p, &o->oMoveAngleYaw, 4); - - network_send(&p); -} - -void network_receive_object(struct Packet* p) { - u32 syncId; - packet_read(p, &syncId, 4); - assert(syncId < MAX_SYNC_OBJECTS); - struct Object* o = syncObjects[syncId]; - assert(o != NULL); - - packet_read(p, &o->oPosX, 28); - packet_read(p, &o->oAction, 4); - packet_read(p, &o->oHeldState, 4); - packet_read(p, &o->oMoveAngleYaw, 4); -} +} \ No newline at end of file diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 4b980d33..229584dd 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -29,8 +29,8 @@ void network_receive_player(struct Packet* p) { packet_read(p, &heldSyncID, 4); if (heldSyncID != NULL) { - assert(syncObjects[heldSyncID] != NULL); - gMarioStates[1].heldObj = syncObjects[heldSyncID]; + assert(syncObjects[heldSyncID].o != NULL); + gMarioStates[1].heldObj = syncObjects[heldSyncID].o; gMarioStates[1].heldObj->heldByPlayerIndex = 1; }