Added ability to sync multiple objects

This commit is contained in:
MysterD 2020-08-02 16:09:32 -07:00
parent 716a924803
commit 3d055255bc
5 changed files with 94 additions and 46 deletions

View File

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

View File

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

View File

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

View File

@ -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++;
}
assert(o->oSyncID < MAX_SYNC_OBJECTS);
syncObjects[o->oSyncID] = o;
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 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 forget_sync_object(struct SyncObject* so) {
so->o = NULL;
so->owned = false;
so->ticksSinceUpdate = -1;
so->syncDeactive = 0;
}
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);
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]);
}
packet_read(p, &o->oPosX, 28);
packet_read(p, &o->oAction, 4);
packet_read(p, &o->oHeldState, 4);
packet_read(p, &o->oMoveAngleYaw, 4);
}

View File

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