mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-01-03 14:11:10 +00:00
Synchronized goombas, synced randomness, added extra fields to object packets
This commit is contained in:
parent
de9eab364f
commit
9b5b5acf19
9 changed files with 101 additions and 12 deletions
|
@ -556,6 +556,7 @@
|
||||||
#define /*0x104*/ oGoombaBlinkTimer OBJECT_FIELD_S32(0x1F)
|
#define /*0x104*/ oGoombaBlinkTimer OBJECT_FIELD_S32(0x1F)
|
||||||
#define /*0x108*/ oGoombaTurningAwayFromWall OBJECT_FIELD_S32(0x20)
|
#define /*0x108*/ oGoombaTurningAwayFromWall OBJECT_FIELD_S32(0x20)
|
||||||
#define /*0x10C*/ oGoombaRelativeSpeed OBJECT_FIELD_F32(0x21)
|
#define /*0x10C*/ oGoombaRelativeSpeed OBJECT_FIELD_F32(0x21)
|
||||||
|
#define /*0x110*/ oGoombaJumpCooldown OBJECT_FIELD_U32(0x22)
|
||||||
|
|
||||||
/* Haunted Chair */
|
/* Haunted Chair */
|
||||||
#define /*0x0F4*/ oHauntedChairUnkF4 OBJECT_FIELD_S32(0x1B)
|
#define /*0x0F4*/ oHauntedChairUnkF4 OBJECT_FIELD_S32(0x1B)
|
||||||
|
|
|
@ -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_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),
|
OBJECT(/*model*/ MODEL_YOSHI, /*pos*/ 0, 3174, -5625, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvYoshi),
|
||||||
// TESTING BELOW
|
// 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*/ -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_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_NONE, /*pos*/ -528, 260, 3264, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvGoombaTripletSpawner),
|
||||||
RETURN(),
|
RETURN(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
set -e
|
set -e
|
||||||
make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1
|
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 --server --configfile sm64config_server.txt &
|
||||||
#./build/us_pc/sm64.us.f3dex2e.exe --client --configfile sm64config_client.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'
|
#winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'run --client --configfile sm64config_client.txt' -ex 'quit'
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#define BHV_CMD_GET_ADDR_OF_CMD(index) (uintptr_t)(&gCurBhvCommand[index])
|
#define BHV_CMD_GET_ADDR_OF_CMD(index) (uintptr_t)(&gCurBhvCommand[index])
|
||||||
|
|
||||||
static u16 gRandomSeed16;
|
static u16 gRandomSeed16;
|
||||||
|
static u16 gSyncRandom;
|
||||||
|
|
||||||
// Unused function that directly jumps to a behavior command and resets the object's stack index.
|
// Unused function that directly jumps to a behavior command and resets the object's stack index.
|
||||||
static void goto_behavior_unused(const BehaviorScript *bhvAddr) {
|
static void goto_behavior_unused(const BehaviorScript *bhvAddr) {
|
||||||
|
@ -36,8 +37,53 @@ static void goto_behavior_unused(const BehaviorScript *bhvAddr) {
|
||||||
gCurrentObject->bhvStackIndex = 0;
|
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.
|
// Generate a pseudorandom integer from 0 to 65535 from the random seed, and update the seed.
|
||||||
u16 random_u16(void) {
|
u16 random_u16(void) {
|
||||||
|
// override this function for synchronized entities
|
||||||
|
if (gCurrentObject->oSyncID != 0) { return random_sync_u16(); }
|
||||||
|
|
||||||
u16 temp1, temp2;
|
u16 temp1, temp2;
|
||||||
|
|
||||||
if (gRandomSeed16 == 22026) {
|
if (gRandomSeed16 == 22026) {
|
||||||
|
|
|
@ -126,6 +126,10 @@ void bhv_goomba_init(void) {
|
||||||
o->oDamageOrCoinValue = sGoombaProperties[o->oGoombaSize].damage;
|
o->oDamageOrCoinValue = sGoombaProperties[o->oGoombaSize].damage;
|
||||||
|
|
||||||
o->oGravity = -8.0f / 3.0f * o->oGoombaScale;
|
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->oAction = GOOMBA_ACT_JUMP;
|
||||||
o->oForwardVel = 0.0f;
|
o->oForwardVel = 0.0f;
|
||||||
o->oVelY = 50.0f / 3.0f * o->oGoombaScale;
|
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) {
|
if (o->oGoombaWalkTimer != 0) {
|
||||||
o->oGoombaWalkTimer -= 1;
|
o->oGoombaWalkTimer -= 1;
|
||||||
} else {
|
} else {
|
||||||
if (random_u16() & 3) {
|
if (random_u16() & 3 || o->oGoombaJumpCooldown > 0) {
|
||||||
o->oGoombaTargetYaw = obj_random_fixed_turn(0x2000);
|
o->oGoombaTargetYaw = obj_random_fixed_turn(0x2000);
|
||||||
o->oGoombaWalkTimer = random_linear_offset(100, 100);
|
o->oGoombaWalkTimer = random_linear_offset(100, 100);
|
||||||
} else {
|
} else {
|
||||||
|
@ -219,6 +224,10 @@ static void goomba_act_walk(void) {
|
||||||
|
|
||||||
cur_obj_rotate_yaw_toward(o->oGoombaTargetYaw, 0x200);
|
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) {
|
void bhv_goomba_update(void) {
|
||||||
// PARTIAL_UPDATE
|
// PARTIAL_UPDATE
|
||||||
|
random_sync_reset();
|
||||||
|
|
||||||
f32 animSpeed;
|
f32 animSpeed;
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ void network_send(struct Packet* p) {
|
||||||
void network_update(void) {
|
void network_update(void) {
|
||||||
if (networkType == NT_NONE) { return; }
|
if (networkType == NT_NONE) { return; }
|
||||||
|
|
||||||
network_send_player();
|
network_update_player();
|
||||||
network_update_objects();
|
network_update_objects();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../cliopts.h"
|
#include "../cliopts.h"
|
||||||
|
|
||||||
#define MAX_SYNC_OBJECTS 256
|
#define MAX_SYNC_OBJECTS 256
|
||||||
|
#define MAX_SYNC_OBJECT_FIELDS 16
|
||||||
#define PACKET_LENGTH 1024
|
#define PACKET_LENGTH 1024
|
||||||
#define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server")
|
#define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server")
|
||||||
|
|
||||||
|
@ -25,6 +26,8 @@ struct SyncObject {
|
||||||
bool owned;
|
bool owned;
|
||||||
unsigned int ticksSinceUpdate;
|
unsigned int ticksSinceUpdate;
|
||||||
unsigned int syncDeactive;
|
unsigned int syncDeactive;
|
||||||
|
u8 extraFieldCount;
|
||||||
|
void* extraFields[MAX_SYNC_OBJECT_FIELDS];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct MarioState gMarioStates[];
|
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);
|
void packet_read(struct Packet* packet, void* data, int length);
|
||||||
|
|
||||||
// packet headers
|
// packet headers
|
||||||
void network_send_player(void);
|
void network_update_player(void);
|
||||||
void network_receive_player(struct Packet* p);
|
void network_receive_player(struct Packet* p);
|
||||||
|
|
||||||
void network_update_objects(void);
|
void network_update_objects(void);
|
||||||
|
|
|
@ -11,10 +11,20 @@ void network_init_object(struct Object *o) {
|
||||||
o->oSyncID = nextSyncID++;
|
o->oSyncID = nextSyncID++;
|
||||||
}
|
}
|
||||||
assert(o->oSyncID < MAX_SYNC_OBJECTS);
|
assert(o->oSyncID < MAX_SYNC_OBJECTS);
|
||||||
syncObjects[o->oSyncID].o = o;
|
struct SyncObject* so = &syncObjects[o->oSyncID];
|
||||||
syncObjects[o->oSyncID].owned = false;
|
so->o = o;
|
||||||
syncObjects[o->oSyncID].ticksSinceUpdate = -1;
|
so->owned = false;
|
||||||
syncObjects[o->oSyncID].syncDeactive = 0;
|
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) {
|
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->oHeldState, 4);
|
||||||
packet_write(&p, &o->oMoveAngleYaw, 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++; }
|
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { so->syncDeactive++; }
|
||||||
so->ticksSinceUpdate = 0;
|
so->ticksSinceUpdate = 0;
|
||||||
network_send(&p);
|
network_send(&p);
|
||||||
|
@ -55,6 +71,15 @@ void network_receive_object(struct Packet* p) {
|
||||||
packet_read(p, &o->oHeldState, 4);
|
packet_read(p, &o->oHeldState, 4);
|
||||||
packet_read(p, &o->oMoveAngleYaw, 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++; }
|
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { so->syncDeactive++; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,3 +37,7 @@ void network_receive_player(struct Packet* p) {
|
||||||
// restore action state, needed for jump kicking
|
// restore action state, needed for jump kicking
|
||||||
gMarioStates[1].actionState = oldActionState;
|
gMarioStates[1].actionState = oldActionState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void network_update_player(void) {
|
||||||
|
network_send_player();
|
||||||
|
}
|
Loading…
Reference in a new issue