mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-12-22 16:30:23 +00:00
Added ability to sync multiple objects
This commit is contained in:
parent
716a924803
commit
3d055255bc
5 changed files with 94 additions and 46 deletions
|
@ -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(),
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue