Synchronize late-join coin collection
This commit is contained in:
parent
4be00a2eb1
commit
5db1a9e827
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue