Late-join synchronized chain chomp and exclamation box

This commit is contained in:
MysterD 2021-06-08 01:29:21 -07:00
parent 050d940d53
commit 4be00a2eb1
7 changed files with 44 additions and 7 deletions

View file

@ -528,8 +528,15 @@ void bhv_wooden_post_update(void) {
// chomp
o->oWoodenPostOffsetY = -190.0f;
if (o->parentObj != o) {
play_puzzle_jingle();
o->parentObj->oChainChompReleaseStatus = CHAIN_CHOMP_RELEASED_TRIGGER_CUTSCENE;
if (gNetworkLevelSyncing) {
// force chain chomp cutscene ending
o->parentObj->oAction = CHAIN_CHOMP_ACT_UNLOAD_CHAIN;
o->parentObj->oChainChompReleaseStatus = CHAIN_CHOMP_RELEASED_END_CUTSCENE;
o->parentObj->oChainChompHitGate = TRUE;
} else {
play_puzzle_jingle();
o->parentObj->oChainChompReleaseStatus = CHAIN_CHOMP_RELEASED_TRIGGER_CUTSCENE;
}
o->parentObj = o;
}
}

View file

@ -164,8 +164,10 @@ void exclamation_box_act_4(void) {
void exclamation_box_act_5(void) {
o->oExclamationBoxForce = FALSE;
if (o->oTimer > 300)
if (o->oTimer > 300) {
o->oAction = 2;
forget_ent_reliable_packet(o);
}
}
void exclamation_box_act_6(void) {
o->oExclamationBoxForce = FALSE;

View file

@ -21,8 +21,12 @@ struct NetworkSystem* gNetworkSystem = &gNetworkSystemSocket;
#endif
#define LOADING_LEVEL_THRESHOLD 10
u8 networkLoadingLevel = 0;
#define SYNCING_LEVEL_THRESHOLD 30 * 6
u16 networkLoadingLevel = 0;
bool gNetworkLevelLoaded = false;
bool gNetworkLevelSyncing = true;
clock_t gLastNetworkSend = 0;
struct StringLinkedList gRegisteredMods = { 0 };
@ -85,6 +89,7 @@ void network_on_init_level(void) {
// reset loading timer
networkLoadingLevel = 0;
gNetworkLevelLoaded = false;
gNetworkLevelSyncing = true;
}
void network_on_loaded_level(void) {
@ -193,11 +198,15 @@ void network_receive(u8 localIndex, u8* data, u16 dataLength) {
void network_update(void) {
// check for level loaded event
if (!gNetworkLevelLoaded) {
if (networkLoadingLevel++ >= LOADING_LEVEL_THRESHOLD) {
if (networkLoadingLevel < SYNCING_LEVEL_THRESHOLD) {
networkLoadingLevel++;
if (!gNetworkLevelLoaded && networkLoadingLevel >= LOADING_LEVEL_THRESHOLD) {
gNetworkLevelLoaded = true;
network_on_loaded_level();
}
if (networkLoadingLevel >= SYNCING_LEVEL_THRESHOLD) {
gNetworkLevelSyncing = false;
}
}
// send out update packets

View file

@ -83,6 +83,7 @@ struct ServerSettings {
extern struct NetworkSystem* gNetworkSystem;
extern enum NetworkType gNetworkType;
extern bool gNetworkLevelLoaded;
extern bool gNetworkLevelSyncing;
extern struct SyncObject gSyncObjects[];
extern struct ServerSettings gServerSettings;
extern clock_t gLastNetworkSend;

View file

@ -86,6 +86,7 @@ void network_receive_player(struct Packet* p);
// packet_object.c
struct Packet* get_last_sync_ent_reliable_packet(u8 syncId);
void forget_ent_reliable_packet(struct Object* o);
struct SyncObject* network_init_object(struct Object* object, float maxSyncDistance);
void network_init_object_field(struct Object* o, void* field);
bool network_owns_object(struct Object* o);

View file

@ -182,7 +182,17 @@ void network_send_location_response(u8 destGlobalIndex) {
//LOG_INFO("network_send_location_response() { %d, %d, %d, %d, %d } to: %d", destGlobalIndex, gCurrCourseNum, gCurrActNum, gCurrLevelNum, gCurrAreaIndex, (gNetworkType == NT_SERVER) ? destNp->localIndex : 0);
network_send_to(destGlobalIndex, &p);
network_send_to(destNp->localIndex, &p);
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
struct SyncObject* so = &gSyncObjects[i];
if (so == NULL || so->o == NULL) { continue; }
struct Packet* entPacket = get_last_sync_ent_reliable_packet(i);
if (entPacket->error) { continue; }
struct Packet p2 = { 0 };
packet_duplicate(entPacket, &p2);
network_send_to(destNp->localIndex, &p2);
}
}
void network_receive_location_response(struct Packet* p) {

View file

@ -18,6 +18,13 @@ struct Packet* get_last_sync_ent_reliable_packet(u8 syncId) {
return &sLastSyncEntReliablePacket[syncId];
}
void forget_ent_reliable_packet(struct Object* o) {
u8 syncId = o->oSyncID;
if (gSyncObjects[syncId].o == o) {
sLastSyncEntReliablePacket[syncId].error = true;
}
}
// todo: move this to somewhere more general
static float player_distance(struct MarioState* marioState, struct Object* o) {
if (marioState->marioObj == NULL) { return 0; }