Synchronize late-join coin collection

This commit is contained in:
MysterD 2021-06-08 02:26:35 -07:00
parent 4be00a2eb1
commit 5db1a9e827
9 changed files with 86 additions and 12 deletions

View File

@ -529,3 +529,20 @@ const BehaviorScript* get_behavior_from_id(enum BehaviorId id) {
}
return gBehaviorTable[id];
}
u8 is_behavior_a_coin(const BehaviorScript* behavior) {
return behavior == bhvCoinFormationSpawn
|| behavior == bhvCoinFormation
|| behavior == bhvOneCoin
|| behavior == bhvYellowCoin
|| behavior == bhvTemporaryYellowCoin
|| behavior == bhvThreeCoinsSpawn
|| behavior == bhvTenCoinsSpawn
|| behavior == bhvHiddenBlueCoin
|| behavior == bhvMovingYellowCoin
|| behavior == bhvMovingBlueCoin
|| behavior == bhvBlueCoinSliding
|| behavior == bhvBlueCoinJumping
|| behavior == bhvRedCoin
|| behavior == bhvBowserCourseRedCoinStar;
}

View File

@ -526,5 +526,6 @@ enum BehaviorId {
enum BehaviorId get_id_from_behavior(const BehaviorScript* behavior);
const BehaviorScript* get_behavior_from_id(enum BehaviorId id);
u8 is_behavior_a_coin(const BehaviorScript* behavior);
#endif

View File

@ -406,6 +406,7 @@
#ifndef VERSION_JP
#define /*0x1B0*/ oCoinUnk1B0 OBJECT_FIELD_S32(0x4A)
#endif
#define /*0x110*/ oCoinID OBJECT_FIELD_S16(0x49, 0)
/* Collision Particle */
#define /*0x0F4*/ oCollisionParticleUnkF4 OBJECT_FIELD_F32(0x1B)

View File

@ -838,6 +838,9 @@ u32 interact_coin(struct MarioState *m, UNUSED u32 interactType, struct Object *
}
network_send_collect_coin(o);
if (o->oCoinID > 0) {
coin_collection_remember(o->oCoinID);
}
return FALSE;
}

View File

@ -2,6 +2,8 @@
#include "network.h"
#include "object_fields.h"
#include "object_constants.h"
#include "game/object_list_processor.h"
#include "behavior_table.h"
#include "socket/socket.h"
#ifdef DISCORD_SDK
#include "discord/discord.h"
@ -98,6 +100,15 @@ void network_on_loaded_level(void) {
gSyncObjects[i].staticLevelSpawn = true;
}
// give all coins an ID
u8 coinId = 0;
for (int i = 0; i < OBJECT_POOL_CAPACITY; i++) {
struct Object* o = &gObjectPool[i];
if (o->activeFlags & ACTIVE_FLAG_DEACTIVATED) { continue; }
if (!is_behavior_a_coin(o->behavior)) { continue; }
o->oCoinID = ++coinId;
}
// check for level change
struct NetworkPlayer* np = gNetworkPlayerLocal;
if (np != NULL) {

View File

@ -173,6 +173,8 @@ void network_send_level_area_valid(u8 toGlobalIndex);
void network_receive_level_area_valid(struct Packet* p);
// packet_location_request.c
void coin_collection_remember(u8 coinId);
void coin_collection_clear(void);
void static_spawn_removal_remember(u8 syncId);
void static_spawn_removal_clear(void);
void network_send_location_request(void);

View File

@ -34,7 +34,7 @@ void network_send_level_area(void) {
np->currAreaIndex = gCurrAreaIndex;
np->currAreaSyncValid = false;
LOG_INFO("set currAreaSyncValid to false");
//LOG_INFO("set currAreaSyncValid to false");
}
//LOG_INFO("tx location: [%d, %d, %d, %d]", gCurrCourseNum, gCurrActNum, gCurrLevelNum, gCurrAreaIndex);
@ -118,7 +118,7 @@ static void network_receive_level_area_valid_server(struct Packet* p) {
return;
}
np->currAreaSyncValid = true;
LOG_INFO("set global %d's currAreaSyncValid to true", np->globalIndex);
//LOG_INFO("set global %d's currAreaSyncValid to true", np->globalIndex);
}
static void network_receive_level_area_valid_client(struct Packet* p) {
@ -135,7 +135,7 @@ static void network_receive_level_area_valid_client(struct Packet* p) {
gNetworkPlayerLocal->currAreaSyncValid = true;
network_send_level_area_valid_client();
LOG_INFO("set currAreaSyncValid to true (3)");
//LOG_INFO("set currAreaSyncValid to true (3)");
}
void network_receive_level_area_valid(struct Packet* p) {

View File

@ -1,6 +1,10 @@
#include <stdio.h>
#include "../network.h"
#include "menu/custom_menu_system.h"
#include "game/interaction.h"
#include "game/object_list_processor.h"
#include "object_constants.h"
#include "object_fields.h"
//#define DISABLE_MODULE_LOG 1
#include "pc/debuglog.h"
@ -10,6 +14,19 @@ extern s16 gCurrCourseNum, gCurrActNum, gCurrLevelNum, gCurrAreaIndex;
u8 sStaticSpawnRemoval[MAX_STATIC_SPAWN_REMOVAL] = { 0 };
u8 sStaticSpawnRemovalIndex = 0;
#define MAX_COIN_COLLECTION 128
u8 sCoinCollection[MAX_STATIC_SPAWN_REMOVAL] = { 0 };
u8 sCoinCollectionIndex = 0;
void coin_collection_remember(u8 coinId) {
sCoinCollection[sCoinCollectionIndex++] = coinId;
if (sStaticSpawnRemovalIndex >= MAX_COIN_COLLECTION) { sStaticSpawnRemovalIndex = MAX_COIN_COLLECTION - 1; }
}
void coin_collection_clear(void) {
sCoinCollectionIndex = 0;
}
void static_spawn_removal_remember(u8 syncId) {
sStaticSpawnRemoval[sStaticSpawnRemovalIndex++] = syncId;
if (sStaticSpawnRemovalIndex == 0) { sStaticSpawnRemovalIndex = MAX_STATIC_SPAWN_REMOVAL - 1; }
@ -40,7 +57,7 @@ void network_send_location_request(void) {
struct NetworkPlayer* np = get_network_player_from_valid_location(gCurrCourseNum, gCurrActNum, gCurrLevelNum, gCurrAreaIndex);
if (np == NULL) {
gNetworkPlayerLocal->currAreaSyncValid = true;
LOG_INFO("set currAreaSyncValid to true (1)");
//LOG_INFO("set currAreaSyncValid to true (1)");
return;
}
//LOG_INFO("network_send_location_request()");
@ -81,7 +98,7 @@ void network_receive_location_request(struct Packet* p) {
np->currLevelNum = levelNum;
np->currAreaIndex = areaIndex;
np->currAreaSyncValid = false;
LOG_INFO("set global %d's currAreaSyncValid to false", np->globalIndex);
//LOG_INFO("set global %d's currAreaSyncValid to false", np->globalIndex);
//LOG_INFO("network_receive_location_request() { %d, %d, %d, %d }", courseNum, actNum, levelNum, areaIndex);
@ -180,6 +197,11 @@ void network_send_location_response(u8 destGlobalIndex) {
packet_write(&p, &sStaticSpawnRemoval[i], sizeof(u8));
}
packet_write(&p, &sCoinCollectionIndex, sizeof(u8));
for (int i = 0; i < sCoinCollectionIndex; i++) {
packet_write(&p, &sCoinCollection[i], sizeof(u8));
}
//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(destNp->localIndex, &p);
@ -202,20 +224,17 @@ void network_receive_location_response(struct Packet* p) {
packet_read(p, &levelNum, sizeof(s16));
packet_read(p, &areaIndex, sizeof(s16));
// TODO: read entities here!
//LOG_INFO("network_receive_location_response() { %d, %d, %d, %d, %d }", destGlobalIndex, courseNum, actNum, levelNum, areaIndex);
if (courseNum != gCurrCourseNum || actNum != gCurrActNum || levelNum != gCurrLevelNum || areaIndex != gCurrAreaIndex) {
LOG_ERROR("Receiving 'location response' with the wrong location!");
return;
}
// TODO: apply entities!
if (gNetworkType == NT_SERVER) {
/*if (gNetworkType == NT_SERVER) {
struct NetworkPlayer* srcNp = &gNetworkPlayers[p->localIndex];
LOG_INFO("sending location response from global %d to global %d", srcNp->globalIndex, gNetworkPlayerLocal->globalIndex);
}
}*/
if (gNetworkPlayerLocal->currAreaSyncValid) {
LOG_ERROR("Receiving 'location response' when our location is already valid!");
@ -228,6 +247,7 @@ void network_receive_location_response(struct Packet* p) {
u8 staticSpawnRemovals;
static_spawn_removal_clear();
// read static spawn removals
packet_read(p, &staticSpawnRemovals, sizeof(u8));
for (int i = 0; i < staticSpawnRemovals; i++) {
u8 syncId;
@ -236,15 +256,33 @@ void network_receive_location_response(struct Packet* p) {
if (so != NULL) {
if (so->o != NULL) {
obj_mark_for_deletion(so->o);
LOG_INFO("marking for deletion: %d", syncId);
}
network_forget_sync_object(so);
}
}
// read coin collections
packet_read(p, &sCoinCollectionIndex, sizeof(u8));
for (int i = 0; i < sCoinCollectionIndex; i++) {
packet_read(p, &sCoinCollection[i], sizeof(u8));
}
// collect the coins
for (int i = 0; i < OBJECT_POOL_CAPACITY; i++) {
struct Object* o = &gObjectPool[i];
if (o->activeFlags & ACTIVE_FLAG_DEACTIVATED) { continue; }
if (!is_behavior_a_coin(o->behavior)) { continue; }
for (int j = 0; j < sCoinCollectionIndex; j++) {
if (o->oCoinID == sCoinCollection[j]) {
o->oInteractStatus = INT_STATUS_INTERACTED;
}
}
}
gMarioStates[0].numCoins = numCoins;
gNetworkPlayerLocal->currAreaSyncValid = true;
LOG_INFO("set currAreaSyncValid to true (2)");
//LOG_INFO("set currAreaSyncValid to true (2)");
if (gNetworkType != NT_SERVER) {
network_send_level_area_valid(0);
}

View File

@ -138,6 +138,7 @@ void network_clear_sync_objects(void) {
}
nextSyncID = 1;
static_spawn_removal_clear();
coin_collection_clear();
}
void network_set_sync_id(struct Object* o) {