Synchronized goombas, synced randomness, added extra fields to object packets

This commit is contained in:
MysterD 2020-08-02 18:21:43 -07:00
parent de9eab364f
commit 9b5b5acf19
9 changed files with 101 additions and 12 deletions

View File

@ -556,6 +556,7 @@
#define /*0x104*/ oGoombaBlinkTimer OBJECT_FIELD_S32(0x1F)
#define /*0x108*/ oGoombaTurningAwayFromWall OBJECT_FIELD_S32(0x20)
#define /*0x10C*/ oGoombaRelativeSpeed OBJECT_FIELD_F32(0x21)
#define /*0x110*/ oGoombaJumpCooldown OBJECT_FIELD_U32(0x22)
/* Haunted Chair */
#define /*0x0F4*/ oHauntedChairUnkF4 OBJECT_FIELD_S32(0x1B)

View File

@ -90,9 +90,9 @@ static const LevelScript script_func_local_4[] = {
OBJECT(/*model*/ MODEL_BUTTERFLY, /*pos*/ -1204, 326, 3296, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvButterfly),
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),
OBJECT(/*model*/ MODEL_BLACK_BOBOMB, /*pos*/ -528, 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*/ -528, 260, 3264, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvGoombaTripletSpawner),
RETURN(),
};

View File

@ -1,5 +1,5 @@
set -e
make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1
./build/us_pc/sm64.us.f3dex2e.exe --server --configfile sm64config_server.txt &
#./build/us_pc/sm64.us.f3dex2e.exe --client --configfile sm64config_client.txt &
winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'run --client --configfile sm64config_client.txt' -ex 'quit'
./build/us_pc/sm64.us.f3dex2e.exe --client --configfile sm64config_client.txt &
#winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'run --client --configfile sm64config_client.txt' -ex 'quit'

View File

@ -29,6 +29,7 @@
#define BHV_CMD_GET_ADDR_OF_CMD(index) (uintptr_t)(&gCurBhvCommand[index])
static u16 gRandomSeed16;
static u16 gSyncRandom;
// Unused function that directly jumps to a behavior command and resets the object's stack index.
static void goto_behavior_unused(const BehaviorScript *bhvAddr) {
@ -36,8 +37,53 @@ static void goto_behavior_unused(const BehaviorScript *bhvAddr) {
gCurrentObject->bhvStackIndex = 0;
}
void random_sync_reset(void) {
// seed the sync'd random seed with enough synchronzied information to be "unique enough"
gSyncRandom = (u16)gCurrentObject->oPosX
^ (u16)gCurrentObject->oPosY
^ (u16)gCurrentObject->oPosZ
^ (u16)gCurrentObject->oVelX
^ (u16)gCurrentObject->oVelY
^ (u16)gCurrentObject->oVelZ
^ (u16)gCurrentObject->oAction;
}
// Generate a pseudorandom integer from 0 to 65535 from the synchronized seed, and update the seed.
u16 random_sync_u16(void) {
u16 temp1, temp2;
if (gSyncRandom == 22026) {
gSyncRandom = 0;
}
temp1 = (gSyncRandom & 0x00FF) << 8;
temp1 = temp1 ^ gSyncRandom;
gSyncRandom = ((temp1 & 0x00FF) << 8) + ((temp1 & 0xFF00) >> 8);
temp1 = ((temp1 & 0x00FF) << 1) ^ gSyncRandom;
temp2 = (temp1 >> 1) ^ 0xFF80;
if ((temp1 & 1) == 0) {
if (temp2 == 43605) {
gSyncRandom = 0;
}
else {
gSyncRandom = temp2 ^ 0x1FF4;
}
}
else {
gSyncRandom = temp2 ^ 0x8180;
}
return gSyncRandom;
}
// Generate a pseudorandom integer from 0 to 65535 from the random seed, and update the seed.
u16 random_u16(void) {
// override this function for synchronized entities
if (gCurrentObject->oSyncID != 0) { return random_sync_u16(); }
u16 temp1, temp2;
if (gRandomSeed16 == 22026) {

View File

@ -126,6 +126,10 @@ void bhv_goomba_init(void) {
o->oDamageOrCoinValue = sGoombaProperties[o->oGoombaSize].damage;
o->oGravity = -8.0f / 3.0f * o->oGoombaScale;
network_init_object(o);
network_init_object_field(o, &o->oGoombaTargetYaw);
network_init_object_field(o, &o->oGoombaWalkTimer);
}
/**
@ -136,6 +140,7 @@ static void goomba_begin_jump(void) {
o->oAction = GOOMBA_ACT_JUMP;
o->oForwardVel = 0.0f;
o->oVelY = 50.0f / 3.0f * o->oGoombaScale;
o->oGoombaJumpCooldown = 10;
}
/**
@ -206,7 +211,7 @@ static void goomba_act_walk(void) {
if (o->oGoombaWalkTimer != 0) {
o->oGoombaWalkTimer -= 1;
} else {
if (random_u16() & 3) {
if (random_u16() & 3 || o->oGoombaJumpCooldown > 0) {
o->oGoombaTargetYaw = obj_random_fixed_turn(0x2000);
o->oGoombaWalkTimer = random_linear_offset(100, 100);
} else {
@ -219,6 +224,10 @@ static void goomba_act_walk(void) {
cur_obj_rotate_yaw_toward(o->oGoombaTargetYaw, 0x200);
}
if (o->oGoombaJumpCooldown > 0) {
o->oGoombaJumpCooldown--;
}
}
/**
@ -276,6 +285,7 @@ void huge_goomba_weakly_attacked(void) {
*/
void bhv_goomba_update(void) {
// PARTIAL_UPDATE
random_sync_reset();
f32 animSpeed;

View File

@ -76,7 +76,7 @@ void network_send(struct Packet* p) {
void network_update(void) {
if (networkType == NT_NONE) { return; }
network_send_player();
network_update_player();
network_update_objects();
do {

View File

@ -6,6 +6,7 @@
#include "../cliopts.h"
#define MAX_SYNC_OBJECTS 256
#define MAX_SYNC_OBJECT_FIELDS 16
#define PACKET_LENGTH 1024
#define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server")
@ -25,6 +26,8 @@ struct SyncObject {
bool owned;
unsigned int ticksSinceUpdate;
unsigned int syncDeactive;
u8 extraFieldCount;
void* extraFields[MAX_SYNC_OBJECT_FIELDS];
};
extern struct MarioState gMarioStates[];
@ -43,7 +46,7 @@ void packet_write(struct Packet* packet, void* data, int length);
void packet_read(struct Packet* packet, void* data, int length);
// packet headers
void network_send_player(void);
void network_update_player(void);
void network_receive_player(struct Packet* p);
void network_update_objects(void);

View File

@ -11,10 +11,20 @@ void network_init_object(struct Object *o) {
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;
struct SyncObject* so = &syncObjects[o->oSyncID];
so->o = o;
so->owned = false;
so->ticksSinceUpdate = -1;
so->syncDeactive = 0;
so->extraFieldCount = 0;
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS);
}
void network_init_object_field(struct Object *o, void* field) {
assert(o->oSyncID != 0);
struct SyncObject* so = &syncObjects[o->oSyncID];
int index = so->extraFieldCount++;
so->extraFields[index] = field;
}
void network_send_object(struct SyncObject* so) {
@ -29,6 +39,12 @@ void network_send_object(struct SyncObject* so) {
packet_write(&p, &o->oHeldState, 4);
packet_write(&p, &o->oMoveAngleYaw, 4);
packet_write(&p, &so->extraFieldCount, 1);
for (int i = 0; i < so->extraFieldCount; i++) {
assert(so->extraFields[i] != NULL);
packet_write(&p, so->extraFields[i], 4);
}
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { so->syncDeactive++; }
so->ticksSinceUpdate = 0;
network_send(&p);
@ -55,6 +71,15 @@ void network_receive_object(struct Packet* p) {
packet_read(p, &o->oHeldState, 4);
packet_read(p, &o->oMoveAngleYaw, 4);
// write extra fields
u8 extraFields = 0;
packet_read(p, &extraFields, 1);
assert(extraFields == so->extraFieldCount);
for (int i = 0; i < extraFields; i++) {
assert(so->extraFields[i] != NULL);
packet_read(p, so->extraFields[i], 4);
}
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { so->syncDeactive++; }
}

View File

@ -37,3 +37,7 @@ void network_receive_player(struct Packet* p) {
// restore action state, needed for jump kicking
gMarioStates[1].actionState = oldActionState;
}
void network_update_player(void) {
network_send_player();
}