mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 13:35:12 +00:00
Synchronized bowling balls
Added flag to keep randomization for sync objects
This commit is contained in:
parent
199bd07bb3
commit
2a0a3df34f
6 changed files with 48 additions and 7 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include "game/object_list_processor.h"
|
#include "game/object_list_processor.h"
|
||||||
#include "graph_node.h"
|
#include "graph_node.h"
|
||||||
#include "surface_collision.h"
|
#include "surface_collision.h"
|
||||||
|
#include "pc/network/network.h"
|
||||||
|
|
||||||
// Macros for retrieving arguments from behavior scripts.
|
// Macros for retrieving arguments from behavior scripts.
|
||||||
#define BHV_CMD_GET_1ST_U8(index) (u8)((gCurBhvCommand[index] >> 24) & 0xFF) // unused
|
#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.
|
// 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
|
// 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;
|
u16 temp1, temp2;
|
||||||
|
|
||||||
|
|
|
@ -180,41 +180,69 @@ void bhv_generic_bowling_ball_spawner_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void bhv_generic_bowling_ball_spawner_loop(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;
|
struct Object *bowlingBall;
|
||||||
|
|
||||||
if (o->oTimer == 256)
|
if (o->oTimer == 256)
|
||||||
o->oTimer = 0;
|
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)
|
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;
|
return;
|
||||||
|
|
||||||
if ((o->oTimer & o->oBBallSpawnerPeriodMinus1) == 0) /* Modulus */
|
if ((o->oTimer & o->oBBallSpawnerPeriodMinus1) == 0) /* Modulus */
|
||||||
{
|
{
|
||||||
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, o->oBBallSpawnerMaxSpawnDist)) {
|
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, o->oBBallSpawnerMaxSpawnDist)) {
|
||||||
if ((s32)(random_float() * o->oBBallSpawnerSpawnOdds) == 0) {
|
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 = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
|
||||||
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
|
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) {
|
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 *bowlingBall;
|
||||||
|
struct Object* player = nearest_player_to_object(o);
|
||||||
|
|
||||||
if (o->oTimer == 256)
|
if (o->oTimer == 256)
|
||||||
o->oTimer = 0;
|
o->oTimer = 0;
|
||||||
|
|
||||||
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 800)
|
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;
|
return;
|
||||||
|
|
||||||
if ((o->oTimer % 64) == 0) {
|
if ((o->oTimer % 64) == 0) {
|
||||||
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 12000)) {
|
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 = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
|
||||||
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
|
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->oGravity = 12.0f;
|
||||||
o->oFriction = 1.0f;
|
o->oFriction = 1.0f;
|
||||||
o->oBuoyancy = 2.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) {
|
void bhv_bob_pit_bowling_ball_loop(void) {
|
||||||
|
|
|
@ -46,7 +46,7 @@ void checkerboard_plat_act_rotate(s32 a0, s16 a1) {
|
||||||
void bhv_checkerboard_platform_init(void) {
|
void bhv_checkerboard_platform_init(void) {
|
||||||
o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte;
|
o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte;
|
||||||
network_init_object(o, 1000.0f);
|
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) {
|
void bhv_checkerboard_platform_loop(void) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ void bhv_water_bomb_spawner_update(void) {
|
||||||
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||||
network_init_object_field(o, &o->oWaterBombSpawnerBombActive);
|
network_init_object_field(o, &o->oWaterBombSpawnerBombActive);
|
||||||
network_init_object_field(o, &o->oWaterBombSpawnerTimeToSpawn);
|
network_init_object_field(o, &o->oWaterBombSpawnerTimeToSpawn);
|
||||||
|
network_object_settings(o, FALSE, 0, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 latDistToMario = 9999;
|
f32 latDistToMario = 9999;
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct SyncObject {
|
||||||
u16 onEventId;
|
u16 onEventId;
|
||||||
u8 extraFieldCount;
|
u8 extraFieldCount;
|
||||||
bool fullObjectSync;
|
bool fullObjectSync;
|
||||||
|
bool keepRandomSeed;
|
||||||
float maxUpdateRate;
|
float maxUpdateRate;
|
||||||
void* extraFields[MAX_SYNC_OBJECT_FIELDS];
|
void* extraFields[MAX_SYNC_OBJECT_FIELDS];
|
||||||
};
|
};
|
||||||
|
@ -55,7 +56,7 @@ extern struct SyncObject syncObjects[];
|
||||||
|
|
||||||
void network_init(enum NetworkType networkType);
|
void network_init(enum NetworkType networkType);
|
||||||
void network_init_object(struct Object *object, float maxSyncDistance);
|
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_send(struct Packet* p);
|
||||||
void network_update(void);
|
void network_update(void);
|
||||||
void network_shutdown(void);
|
void network_shutdown(void);
|
||||||
|
|
|
@ -27,15 +27,17 @@ void network_init_object(struct Object *o, float maxSyncDistance) {
|
||||||
so->behavior = o->behavior;
|
so->behavior = o->behavior;
|
||||||
so->onEventId = 0;
|
so->onEventId = 0;
|
||||||
so->fullObjectSync = false;
|
so->fullObjectSync = false;
|
||||||
|
so->keepRandomSeed = false;
|
||||||
so->maxUpdateRate = 0;
|
so->maxUpdateRate = 0;
|
||||||
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS);
|
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);
|
assert(o->oSyncID != 0);
|
||||||
struct SyncObject* so = &syncObjects[o->oSyncID];
|
struct SyncObject* so = &syncObjects[o->oSyncID];
|
||||||
so->fullObjectSync = fullObjectSync;
|
so->fullObjectSync = fullObjectSync;
|
||||||
so->maxUpdateRate = maxUpdateRate;
|
so->maxUpdateRate = maxUpdateRate;
|
||||||
|
so->keepRandomSeed = keepRandomSeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_init_object_field(struct Object *o, void* field) {
|
void network_init_object_field(struct Object *o, void* field) {
|
||||||
|
|
Loading…
Reference in a new issue