From dd8de27014e269dcaf2228caf2ef1beeddd2e31e Mon Sep 17 00:00:00 2001 From: MysterD Date: Mon, 5 Oct 2020 22:05:05 -0700 Subject: [PATCH] Snap players on top of synchronized platforms --- src/engine/surface_collision.c | 6 ++ src/game/object_list_processor.c | 2 +- src/game/object_list_processor.h | 1 + src/pc/controller/controller_keyboard_debug.c | 2 +- src/pc/network/packets/packet_player.c | 62 ++++++++++++++----- 5 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c index ee54327d..f85a2329 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -420,6 +420,12 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32 surfaceNode = surfaceNode->next; interpolate = gInterpolatingSurfaces && surf->modifiedTimestamp == gGlobalTimer; + if (gCheckingSurfaceCollisionsForObject != NULL) { + if (surf->object != gCheckingSurfaceCollisionsForObject) { + continue; + } + } + x1 = surf->vertex1[0]; z1 = surf->vertex1[2]; x2 = surf->vertex2[0]; diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index 6b3b0afd..d0bb984c 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -144,7 +144,7 @@ s32 gNumStaticSurfaces; */ struct MemoryPool *gObjectMemoryPool; - +struct Object* gCheckingSurfaceCollisionsForObject = NULL; s16 gCheckingSurfaceCollisionsForCamera; s16 gFindFloorIncludeSurfaceIntangible; s16 *gEnvironmentRegions; diff --git a/src/game/object_list_processor.h b/src/game/object_list_processor.h index b23bd8ad..d222928e 100644 --- a/src/game/object_list_processor.h +++ b/src/game/object_list_processor.h @@ -103,6 +103,7 @@ extern s32 gNumStaticSurfaces; extern struct MemoryPool *gObjectMemoryPool; +extern struct Object* gCheckingSurfaceCollisionsForObject; extern s16 gCheckingSurfaceCollisionsForCamera; extern s16 gFindFloorIncludeSurfaceIntangible; extern s16 *gEnvironmentRegions; diff --git a/src/pc/controller/controller_keyboard_debug.c b/src/pc/controller/controller_keyboard_debug.c index 80edf1ec..d124bddb 100644 --- a/src/pc/controller/controller_keyboard_debug.c +++ b/src/pc/controller/controller_keyboard_debug.c @@ -7,7 +7,7 @@ #ifdef DEBUG -static u8 warpToLevel = LEVEL_DDD; +static u8 warpToLevel = LEVEL_BITFS; #define SCANCODE_0 0x0B #define SCANCODE_1 0x02 diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 2a2ced44..f4129f16 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -7,6 +7,8 @@ #include "game/mario.h" #include "game/area.h" #include "audio/external.h" +#include "engine/surface_collision.h" +#include "game/object_list_processor.h" #pragma pack(1) struct PacketPlayerData { @@ -44,20 +46,22 @@ struct PacketPlayerData { s16 currentRoom; u8 customFlags; - u32 heldSyncID; - u32 heldBySyncID; - u32 interactSyncID; - u32 usedSyncID; + u8 heldSyncID; + u8 heldBySyncID; + u8 interactSyncID; + u8 usedSyncID; + u8 platformSyncID; s16 currLevelNum; s16 currAreaIndex; }; static void read_packet_data(struct PacketPlayerData* data, struct MarioState* m) { - u32 heldSyncID = (m->heldObj != NULL) ? m->heldObj->oSyncID : 0; - u32 heldBySyncID = (m->heldByObj != NULL) ? m->heldByObj->oSyncID : 0; - u32 interactSyncID = (m->interactObj != NULL) ? m->interactObj->oSyncID : 0; - u32 usedSyncID = (m->usedObj != NULL) ? m->usedObj->oSyncID : 0; + u8 heldSyncID = (m->heldObj != NULL) ? m->heldObj->oSyncID : 0; + u8 heldBySyncID = (m->heldByObj != NULL) ? m->heldByObj->oSyncID : 0; + u8 interactSyncID = (m->interactObj != NULL) ? m->interactObj->oSyncID : 0; + u8 usedSyncID = (m->usedObj != NULL) ? m->usedObj->oSyncID : 0; + u8 platformSyncID = (m->marioObj->platform != NULL) ? m->marioObj->platform->oSyncID : 0; u8 customFlags = SET_BIT((m->freeze > 0), 0); @@ -99,14 +103,15 @@ static void read_packet_data(struct PacketPlayerData* data, struct MarioState* m data->heldBySyncID = heldBySyncID; data->interactSyncID = interactSyncID; data->usedSyncID = usedSyncID; + data->platformSyncID = platformSyncID; data->currLevelNum = gCurrLevelNum; data->currAreaIndex = gCurrAreaIndex; } static void write_packet_data(struct PacketPlayerData* data, struct MarioState* m, - u8* customFlags, u32* heldSyncID, u32* heldBySyncID, - u32* interactSyncID, u32* usedSyncID) { + u8* customFlags, u8* heldSyncID, u8* heldBySyncID, + u8* interactSyncID, u8* usedSyncID, u8* platformSyncID) { memcpy(m->marioObj->rawData.asU32, data->rawData, sizeof(u32) * 80); m->marioObj->header.gfx.node.flags = data->nodeFlags; *m->controller = data->controller; @@ -145,6 +150,7 @@ static void write_packet_data(struct PacketPlayerData* data, struct MarioState* *heldBySyncID = data->heldBySyncID; *interactSyncID = data->interactSyncID; *usedSyncID = data->usedSyncID; + *platformSyncID = data->platformSyncID; } void network_send_player(void) { @@ -190,14 +196,16 @@ void network_receive_player(struct Packet* p) { if (levelAreaMismatch) { return; } // apply data from packet to mario state - u32 heldSyncID = 0; - u32 heldBySyncID = 0; - u32 interactSyncID = 0; - u32 usedSyncID = 0; - u8 customFlags = 0; + u8 heldSyncID = 0; + u8 heldBySyncID = 0; + u8 interactSyncID = 0; + u8 usedSyncID = 0; + u8 platformSyncID = 0; + u8 customFlags = 0; write_packet_data(&data, m, &customFlags, &heldSyncID, &heldBySyncID, - &interactSyncID, &usedSyncID); + &interactSyncID, &usedSyncID, + &platformSyncID); // read custom flags m->freeze = GET_BIT(customFlags, 0); @@ -244,6 +252,28 @@ void network_receive_player(struct Packet* p) { m->usedObj = gSyncObjects[usedSyncID].o; } + // place on top of platform + if (platformSyncID != 0 && gSyncObjects[platformSyncID].o != NULL) { + struct Surface* floor = NULL; + // search up to 500 units for the platform + f32 maxDifference = 500; + m->pos[1] += maxDifference; + + // find the platform + gCheckingSurfaceCollisionsForObject = gSyncObjects[platformSyncID].o; + f32 height = find_floor(m->pos[0], m->pos[1], m->pos[2], &floor); + gCheckingSurfaceCollisionsForObject = NULL; + + f32 difference = ABS((m->pos[1] - maxDifference) - height); + if (floor != NULL && difference <= maxDifference) { + // place on top of platform + m->pos[1] = height; + } else { + // search failed, reset position + m->pos[1] -= maxDifference; + } + } + // jump kicking: restore action state, otherwise it won't play if (m->action == ACT_JUMP_KICK) { m->actionState = oldData.actionState;