From e0bdaa1229512cf55193281d3ef6e2bdf69e2751 Mon Sep 17 00:00:00 2001 From: MysterD Date: Sat, 26 Sep 2020 15:13:46 -0700 Subject: [PATCH] Fade remote players into level/area, drop player packets when in different area --- src/game/level_update.c | 10 ++++++++++ src/game/mario.c | 17 +++++++++++++---- src/game/obj_behaviors.c | 6 +++++- src/pc/network/network_player.c | 3 +++ src/pc/network/network_player.h | 3 +++ src/pc/network/packets/packet_player.c | 18 ++++++++++++++++++ 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/game/level_update.c b/src/game/level_update.c index cfc953ca5..e34dd78f7 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -1155,6 +1155,11 @@ void level_set_transition(s16 length, void (*updateFunction)(s16 *)) { * Play the transition and then return to normal play mode. */ s32 play_mode_change_area(void) { + // fade out all players + for (int i = 0; i < MAX_PLAYERS; i++) { + gNetworkPlayers[i].fadeOpacity = 0; + } + //! This maybe was supposed to be sTransitionTimer == -1? sTransitionUpdate // is never set to -1. if (sTransitionUpdate == (void (*)(s16 *)) - 1) { @@ -1180,6 +1185,11 @@ s32 play_mode_change_area(void) { * Play the transition and then return to normal play mode. */ s32 play_mode_change_level(void) { + // fade out all players + for (int i = 0; i < MAX_PLAYERS; i++) { + gNetworkPlayers[i].fadeOpacity = 0; + } + if (sTransitionUpdate != NULL) { sTransitionUpdate(&sTransitionTimer); } diff --git a/src/game/mario.c b/src/game/mario.c index cb269c2ec..21c24098b 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1751,7 +1751,9 @@ void mario_update_hitbox_and_cap_model(struct MarioState *m) { m->marioObj->hitboxHeight = 160.0f; } - if ((m->flags & MARIO_TELEPORTING) && (m->fadeWarpOpacity != 0xFF)) { + struct NetworkPlayer* np = &gNetworkPlayers[gMarioState->playerIndex]; + u8 teleportFade = (m->flags & MARIO_TELEPORTING) || (np->type != NPT_LOCAL && np->connected && np->fadeOpacity < 32); + if (teleportFade && (m->fadeWarpOpacity != 0xFF)) { bodyState->modelState &= ~0xFF; bodyState->modelState |= (0x100 | m->fadeWarpOpacity); } @@ -1833,13 +1835,20 @@ static u8 prevent_hang(u32 hangPreventionActions[], u8* hangPreventionIndex) { */ s32 execute_mario_action(UNUSED struct Object *o) { s32 inLoop = TRUE; - // hide unconnected players - if (gNetworkPlayers[gMarioState->playerIndex].type != NPT_LOCAL) { - if (!gNetworkPlayers[gMarioState->playerIndex].connected) { + // hide inactive players + struct NetworkPlayer* np = &gNetworkPlayers[gMarioState->playerIndex]; + if (np->type != NPT_LOCAL) { + if (!np->connected || np->currLevelNum != gCurrLevelNum || np->currAreaIndex != gCurrAreaIndex) { gMarioState->marioObj->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; gMarioState->marioObj->oIntangibleTimer = -1; return 0; } + if (np->fadeOpacity < 32) { + if (!(gMarioState->flags & MARIO_TELEPORTING)) { + np->fadeOpacity += 2; + gMarioState->fadeWarpOpacity = np->fadeOpacity << 3; + } + } } /** diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index 5fba9ba73..6574f6415 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -513,7 +513,11 @@ s32 is_point_within_radius_of_mario(f32 x, f32 y, f32 z, s32 dist) { u8 is_player_active(struct MarioState* m) { if (m->action == ACT_BUBBLED) { return FALSE; } - if (gNetworkPlayers[m->playerIndex].type != NPT_LOCAL && !gNetworkPlayers[m->playerIndex].connected) { return FALSE; } + struct NetworkPlayer* np = &gNetworkPlayers[m->playerIndex]; + if (np->type != NPT_LOCAL) { + if (!np->connected) { return FALSE; } + if (np->currLevelNum != gCurrLevelNum || np->currAreaIndex != gCurrAreaIndex) { return FALSE; } + } return TRUE; } diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index 3866a716c..effd03d63 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -83,6 +83,9 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) { struct NetworkPlayer* np = &gNetworkPlayers[i]; if (np->connected) { continue; } np->connected = true; + np->currLevelNum = -1; + np->currAreaIndex = -1; + np->fadeOpacity = 0; np->localIndex = i; np->globalIndex = (gNetworkType == NT_SERVER) ? i : globalIndex; np->type = type; diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h index 22e599396..5842c657d 100644 --- a/src/pc/network/network_player.h +++ b/src/pc/network/network_player.h @@ -22,6 +22,9 @@ struct NetworkPlayer { u8 localIndex; u8 globalIndex; clock_t lastReceived; + s16 currLevelNum; + s16 currAreaIndex; + u8 fadeOpacity; }; extern struct NetworkPlayer gNetworkPlayers[]; diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 411fe45bb..752f95bec 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -5,6 +5,7 @@ #include "sm64.h" #include "game/interaction.h" #include "game/mario.h" +#include "game/area.h" #include "audio/external.h" #define SET_BIT(val, num) ((((u8)(val)) & 0x01) << (num)); @@ -48,6 +49,9 @@ struct PacketPlayerData { u8 customFlags; u32 heldSyncID; u32 heldBySyncID; + + s16 currLevelNum; + s16 currAreaIndex; }; static void read_packet_data(struct PacketPlayerData* data, struct MarioState* m) { @@ -91,6 +95,9 @@ static void read_packet_data(struct PacketPlayerData* data, struct MarioState* m data->customFlags = customFlags; data->heldSyncID = heldSyncID; data->heldBySyncID = heldBySyncID; + + data->currLevelNum = gCurrLevelNum; + data->currAreaIndex = gCurrAreaIndex; } static void write_packet_data(struct PacketPlayerData* data, struct MarioState* m, @@ -164,6 +171,17 @@ void network_receive_player(struct Packet* p) { return; } + // check player level/area + u8 levelAreaMismatch = TRUE; + if (p->localIndex != UNKNOWN_LOCAL_INDEX) { + struct NetworkPlayer* np = &gNetworkPlayers[p->localIndex]; + np->currLevelNum = data.currLevelNum; + np->currAreaIndex = data.currAreaIndex; + levelAreaMismatch = (data.currLevelNum != gCurrLevelNum || data.currAreaIndex != gCurrAreaIndex); + if (levelAreaMismatch) { np->fadeOpacity = 0; } + } + if (levelAreaMismatch) { return; } + // apply data from packet to mario state u32 heldSyncID = 0; u32 heldBySyncID = 0;