Synchronized breakable boxes
Added maximum sync distance, special cases for infinite distance and only synchronizing entity deaths. Started mocking out reliable packets for entity deaths.
This commit is contained in:
parent
4452b38848
commit
6d3a90031c
|
@ -125,7 +125,7 @@
|
|||
#define /*0x198*/ oNumLootCoins OBJECT_FIELD_S32(0x44)
|
||||
#define /*0x19C*/ oDrawingDistance OBJECT_FIELD_F32(0x45)
|
||||
#define /*0x1A0*/ oRoom OBJECT_FIELD_S32(0x46)
|
||||
// 0x1A4 is unused, possibly related to 0x1A8 in removed macro purposes.
|
||||
#define /*0x1A4*/ oSyncDeath OBJECT_FIELD_U32(0x47)
|
||||
#define /*0x1A8*/ oUnk1A8 OBJECT_FIELD_U32(0x48)
|
||||
// 0x1AC-0x1B2 (0x48-0x4A) are object specific and defined below the common fields.
|
||||
#define /*0x1B4*/ oWallAngle OBJECT_FIELD_S32(0x4B)
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "spawn_object.h"
|
||||
#include "spawn_sound.h"
|
||||
#include "thread6.h"
|
||||
#include "src/pc/network/network.h"
|
||||
|
||||
#define o gCurrentObject
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ void bhv_bobomb_init(void) {
|
|||
o->oFriction = 0.8;
|
||||
o->oBuoyancy = 1.3;
|
||||
o->oInteractionSubtype = INT_SUBTYPE_KICKABLE;
|
||||
network_init_object(o);
|
||||
network_init_object(o, 4000);
|
||||
}
|
||||
|
||||
void bobomb_spawn_coin(void) {
|
||||
|
|
|
@ -5,7 +5,7 @@ void bhv_breakable_box_loop(void) {
|
|||
cur_obj_set_model(MODEL_BREAKABLE_BOX_SMALL);
|
||||
if (o->oTimer == 0)
|
||||
breakable_box_init();
|
||||
if (cur_obj_was_attacked_or_ground_pounded() != 0) {
|
||||
if (cur_obj_was_attacked_or_ground_pounded() != 0 || o->oSyncDeath) {
|
||||
obj_explode_and_spawn_coins(46.0f, 1);
|
||||
create_sound_spawner(SOUND_GENERAL_BREAK_BOX);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ void bhv_breakable_box_small_init(void) {
|
|||
obj_set_hitbox(o, &sBreakableBoxSmallHitbox);
|
||||
o->oAnimState = 1;
|
||||
o->activeFlags |= ACTIVE_FLAG_UNK9;
|
||||
network_init_object(o, 500);
|
||||
}
|
||||
|
||||
void small_breakable_box_spawn_dust(void) {
|
||||
|
|
|
@ -127,7 +127,7 @@ void bhv_goomba_init(void) {
|
|||
|
||||
o->oGravity = -8.0f / 3.0f * o->oGoombaScale;
|
||||
|
||||
network_init_object(o);
|
||||
network_init_object(o, 4000);
|
||||
network_init_object_field(o, &o->oGoombaTargetYaw);
|
||||
network_init_object_field(o, &o->oGoombaWalkTimer);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ void breakable_box_init(void) {
|
|||
cur_obj_scale(1.5f);
|
||||
break;
|
||||
}
|
||||
network_init_object(o, SYNC_DISTANCE_ONLY_DEATH);
|
||||
network_init_object_field(o, &o->oInteractStatus);
|
||||
}
|
||||
|
||||
void hidden_breakable_box_actions(void) {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <assert.h>
|
||||
#include "../cliopts.h"
|
||||
|
||||
#define SYNC_DISTANCE_ONLY_DEATH -1
|
||||
#define SYNC_DISTANCE_INFINITE 0
|
||||
#define MAX_SYNC_OBJECTS 256
|
||||
#define MAX_SYNC_OBJECT_FIELDS 16
|
||||
#define PACKET_LENGTH 1024
|
||||
|
@ -21,11 +23,14 @@ enum PacketType {
|
|||
struct Packet {
|
||||
int cursor;
|
||||
bool error;
|
||||
bool reliable;
|
||||
u16 seqId;
|
||||
char buffer[PACKET_LENGTH];
|
||||
};
|
||||
|
||||
struct SyncObject {
|
||||
struct Object* o;
|
||||
float maxSyncDistance;
|
||||
bool owned;
|
||||
unsigned int ticksSinceUpdate;
|
||||
unsigned int syncDeactive;
|
||||
|
@ -40,7 +45,7 @@ extern enum NetworkType networkType;
|
|||
extern struct SyncObject syncObjects[];
|
||||
|
||||
void network_init(enum NetworkType networkType);
|
||||
void network_init_object(struct Object *object);
|
||||
void network_init_object(struct Object *object, float maxSyncDistance);
|
||||
void network_send(struct Packet* p);
|
||||
void network_update(void);
|
||||
void network_shutdown(void);
|
||||
|
|
|
@ -6,16 +6,17 @@
|
|||
u32 nextSyncID = 1;
|
||||
struct SyncObject syncObjects[MAX_SYNC_OBJECTS] = { 0 };
|
||||
|
||||
void network_init_object(struct Object *o) {
|
||||
void network_init_object(struct Object *o, float maxSyncDistance) {
|
||||
if (o->oSyncID == 0) {
|
||||
o->oSyncID = nextSyncID++;
|
||||
}
|
||||
assert(o->oSyncID < MAX_SYNC_OBJECTS);
|
||||
struct SyncObject* so = &syncObjects[o->oSyncID];
|
||||
so->o = o;
|
||||
so->maxSyncDistance = maxSyncDistance;
|
||||
so->owned = false;
|
||||
so->ticksSinceUpdate = -1;
|
||||
so->syncDeactive = 0;
|
||||
so->syncDeactive = false;
|
||||
so->extraFieldCount = 0;
|
||||
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS);
|
||||
}
|
||||
|
@ -45,7 +46,11 @@ void network_send_object(struct SyncObject* so) {
|
|||
packet_write(&p, so->extraFields[i], 4);
|
||||
}
|
||||
|
||||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { so->syncDeactive++; }
|
||||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
|
||||
so->syncDeactive = true;
|
||||
p.reliable = true;
|
||||
}
|
||||
|
||||
so->ticksSinceUpdate = 0;
|
||||
network_send(&p);
|
||||
}
|
||||
|
@ -64,6 +69,22 @@ void network_receive_object(struct Packet* p) {
|
|||
struct Object* o = syncObjects[syncId].o;
|
||||
if (o == NULL) { printf("%s failed to receive object!\n", NETWORKTYPESTR); return; }
|
||||
|
||||
// make sure it's active
|
||||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) {
|
||||
return;
|
||||
}
|
||||
|
||||
// sync only death
|
||||
if (so->maxSyncDistance == SYNC_DISTANCE_ONLY_DEATH) {
|
||||
s16 activeFlags;
|
||||
packet_read(p, &activeFlags, 2);
|
||||
if (activeFlags == ACTIVE_FLAG_DEACTIVATED) {
|
||||
so->o->oSyncDeath = 1;
|
||||
so->syncDeactive = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// write object flags
|
||||
packet_read(p, &o->activeFlags, 2);
|
||||
packet_read(p, &o->oPosX, 28);
|
||||
|
@ -80,7 +101,6 @@ void network_receive_object(struct Packet* p) {
|
|||
packet_read(p, so->extraFields[i], 4);
|
||||
}
|
||||
|
||||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { so->syncDeactive++; }
|
||||
}
|
||||
|
||||
float player_distance(struct MarioState* marioState, struct Object* o) {
|
||||
|
@ -104,7 +124,7 @@ void forget_sync_object(struct SyncObject* so) {
|
|||
so->o = NULL;
|
||||
so->owned = false;
|
||||
so->ticksSinceUpdate = -1;
|
||||
so->syncDeactive = 0;
|
||||
so->syncDeactive = false;
|
||||
}
|
||||
|
||||
void network_update_objects(void) {
|
||||
|
@ -113,7 +133,7 @@ void network_update_objects(void) {
|
|||
if (so->o == NULL) { continue; }
|
||||
|
||||
// check for stale sync object
|
||||
if (so->o->oSyncID != i || so->syncDeactive > 10) {
|
||||
if (so->o->oSyncID != i || so->syncDeactive) {
|
||||
forget_sync_object(so);
|
||||
continue;
|
||||
}
|
||||
|
@ -123,7 +143,15 @@ void network_update_objects(void) {
|
|||
if (!should_own_object(so)) { continue; }
|
||||
|
||||
// check update rate
|
||||
int updateRate = player_distance(&gMarioStates[0], so->o) / 50;
|
||||
if (so->maxSyncDistance == SYNC_DISTANCE_ONLY_DEATH) {
|
||||
if (so->o->activeFlags != ACTIVE_FLAG_DEACTIVATED) { continue; }
|
||||
network_send_object(&syncObjects[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
float dist = player_distance(&gMarioStates[0], so->o);
|
||||
if (so->maxSyncDistance != SYNC_DISTANCE_INFINITE && dist > so->maxSyncDistance) { continue; }
|
||||
int updateRate = dist / 50;
|
||||
if (gMarioStates[0].heldObj == so->o) { updateRate = 0; }
|
||||
if (so->ticksSinceUpdate < updateRate) { continue; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue