Synchronized bowling balls

Added flag to keep randomization for sync objects
This commit is contained in:
MysterD 2020-08-07 21:13:07 -07:00
parent 199bd07bb3
commit 2a0a3df34f
6 changed files with 48 additions and 7 deletions

View file

@ -13,6 +13,7 @@
#include "game/object_list_processor.h"
#include "graph_node.h"
#include "surface_collision.h"
#include "pc/network/network.h"
// Macros for retrieving arguments from behavior scripts.
#define BHV_CMD_GET_1ST_U8(index) (u8)((gCurBhvCommand[index] >> 24) & 0xFF) // unused
@ -63,7 +64,12 @@ void force_replicable_seed(u8 always) {
// 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) { force_replicable_seed(FALSE); }
if (gCurrentObject->oSyncID != 0) {
struct SyncObject* so = &syncObjects[gCurrentObject->oSyncID];
if (so->o != NULL && !so->keepRandomSeed) {
force_replicable_seed(FALSE);
}
}
u16 temp1, temp2;

View file

@ -180,41 +180,69 @@ void bhv_generic_bowling_ball_spawner_init(void) {
}
void bhv_generic_bowling_ball_spawner_loop(void) {
if (o->oSyncID == 0) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_object_settings(o, FALSE, 0, TRUE);
}
struct Object *bowlingBall;
if (o->oTimer == 256)
o->oTimer = 0;
struct Object* player = nearest_player_to_object(o);
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 1000)
|| (o->oPosY < gMarioObject->header.gfx.pos[1]))
|| (o->oPosY < player->header.gfx.pos[1]))
return;
if ((o->oTimer & o->oBBallSpawnerPeriodMinus1) == 0) /* Modulus */
{
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, o->oBBallSpawnerMaxSpawnDist)) {
if ((s32)(random_float() * o->oBBallSpawnerSpawnOdds) == 0) {
if (!network_owns_object(o)) {
return;
}
// this branch only runs for one player at a time
bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
// send out the bowlingBall object
struct Object* spawn_objects[] = { bowlingBall };
u32 models[] = { MODEL_BOWLING_BALL };
network_send_spawn_objects(spawn_objects, models, 1);
}
}
}
}
void bhv_thi_bowling_ball_spawner_loop(void) {
if (o->oSyncID == 0) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_object_settings(o, FALSE, 0, TRUE);
}
struct Object *bowlingBall;
struct Object* player = nearest_player_to_object(o);
if (o->oTimer == 256)
o->oTimer = 0;
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 800)
|| (o->oPosY < gMarioObject->header.gfx.pos[1]))
|| (o->oPosY < player->header.gfx.pos[1]))
return;
if ((o->oTimer % 64) == 0) {
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 12000)) {
if ((s32)(random_float() * 1.5) == 0) {
if (network_owns_object(o) && (s32)(random_float() * 1.5) == 0) {
// this branch only runs for one player at a time
bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
// send out the bowlingBall object
struct Object* spawn_objects[] = { bowlingBall };
u32 models[] = { MODEL_BOWLING_BALL };
network_send_spawn_objects(spawn_objects, models, 1);
}
}
}
@ -224,6 +252,9 @@ void bhv_bob_pit_bowling_ball_init(void) {
o->oGravity = 12.0f;
o->oFriction = 1.0f;
o->oBuoyancy = 2.0f;
network_init_object(o, 5000.0f);
network_object_settings(o, FALSE, 5.0f, TRUE);
}
void bhv_bob_pit_bowling_ball_loop(void) {

View file

@ -46,7 +46,7 @@ void checkerboard_plat_act_rotate(s32 a0, s16 a1) {
void bhv_checkerboard_platform_init(void) {
o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte;
network_init_object(o, 1000.0f);
network_object_settings(o, TRUE, 5.0f);
network_object_settings(o, TRUE, 5.0f, TRUE);
}
void bhv_checkerboard_platform_loop(void) {

View file

@ -33,6 +33,7 @@ void bhv_water_bomb_spawner_update(void) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_init_object_field(o, &o->oWaterBombSpawnerBombActive);
network_init_object_field(o, &o->oWaterBombSpawnerTimeToSpawn);
network_object_settings(o, FALSE, 0, TRUE);
}
f32 latDistToMario = 9999;

View file

@ -43,6 +43,7 @@ struct SyncObject {
u16 onEventId;
u8 extraFieldCount;
bool fullObjectSync;
bool keepRandomSeed;
float maxUpdateRate;
void* extraFields[MAX_SYNC_OBJECT_FIELDS];
};
@ -55,7 +56,7 @@ extern struct SyncObject syncObjects[];
void network_init(enum NetworkType networkType);
void network_init_object(struct Object *object, float maxSyncDistance);
void network_object_settings(struct Object *object, bool fullObjectSync, float maxUpdateRate);
void network_object_settings(struct Object *object, bool fullObjectSync, float maxUpdateRate, bool keepRandomSeed);
void network_send(struct Packet* p);
void network_update(void);
void network_shutdown(void);

View file

@ -27,15 +27,17 @@ void network_init_object(struct Object *o, float maxSyncDistance) {
so->behavior = o->behavior;
so->onEventId = 0;
so->fullObjectSync = false;
so->keepRandomSeed = false;
so->maxUpdateRate = 0;
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS);
}
void network_object_settings(struct Object *o, bool fullObjectSync, float maxUpdateRate) {
void network_object_settings(struct Object *o, bool fullObjectSync, float maxUpdateRate, bool keepRandomSeed) {
assert(o->oSyncID != 0);
struct SyncObject* so = &syncObjects[o->oSyncID];
so->fullObjectSync = fullObjectSync;
so->maxUpdateRate = maxUpdateRate;
so->keepRandomSeed = keepRandomSeed;
}
void network_init_object_field(struct Object *o, void* field) {