From 716a924803e62f9197de6ebb1804348e47a42b5b Mon Sep 17 00:00:00 2001 From: MysterD Date: Sun, 2 Aug 2020 14:18:34 -0700 Subject: [PATCH] Synchronized held objects, made respawners keep their sync ID --- build-windows-visual-studio/sm64ex.vcxproj | 12 +++--- .../sm64ex.vcxproj.filters | 8 +++- network.sh | 4 +- src/game/behaviors/bobomb.inc.c | 10 ++--- src/game/behaviors/breakable_box_small.inc.c | 4 +- src/game/behaviors/corkbox.inc.c | 4 +- src/game/behaviors/snowman.inc.c | 2 +- src/game/behaviors/yoshi.inc.c | 2 +- src/game/mario_actions_object.c | 2 +- src/game/obj_behaviors.h | 2 +- src/pc/network/network.h | 3 ++ src/pc/network/packets/packet_object.c | 38 +++++++++++-------- src/pc/network/packets/packet_player.c | 15 ++++++++ 13 files changed, 71 insertions(+), 35 deletions(-) diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj index eb32f1ae9..e9ca08084 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj +++ b/build-windows-visual-studio/sm64ex.vcxproj @@ -1,4 +1,4 @@ - + @@ -22,7 +22,7 @@ 16.0 {8ADFCAB9-E7D6-4588-86B5-A128DA4F811D} sm64ex - 10.0 + 10.0.18362.0 @@ -41,7 +41,7 @@ Application true - v142 + v141 Unicode @@ -74,7 +74,7 @@ true - ..\include;..\src;$(IncludePath) + ..\include;..\src;.\;..\;$(IncludePath) false @@ -3944,6 +3944,9 @@ + + + @@ -3979,7 +3982,6 @@ - diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters index 16d1ef8b6..480602b4d 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj.filters +++ b/build-windows-visual-studio/sm64ex.vcxproj.filters @@ -14943,7 +14943,13 @@ Source Files\src\pc\network - + + Source Files\src\pc\network\packets + + + Source Files\src\pc\network\packets + + Source Files\src\pc\network\packets diff --git a/network.sh b/network.sh index cb5dac172..0dbb36fc9 100644 --- a/network.sh +++ b/network.sh @@ -1,5 +1,5 @@ set -e make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 ./build/us_pc/sm64.us.f3dex2e.exe --server --configfile sm64config_server.txt & -./build/us_pc/sm64.us.f3dex2e.exe --client --configfile sm64config_client.txt & -#winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'b act_jump_kick' -ex 'run --client --configfile sm64config_client.txt' -ex 'quit' +#./build/us_pc/sm64.us.f3dex2e.exe --client --configfile sm64config_client.txt & +winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'run --client --configfile sm64config_client.txt' -ex 'quit' diff --git a/src/game/behaviors/bobomb.inc.c b/src/game/behaviors/bobomb.inc.c index 75466020d..5c032c9d5 100644 --- a/src/game/behaviors/bobomb.inc.c +++ b/src/game/behaviors/bobomb.inc.c @@ -37,7 +37,7 @@ void bobomb_act_explode(void) { explosion->oGraphYOffset += 100.0f; bobomb_spawn_coin(); - create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000); + create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID); o->activeFlags = ACTIVE_FLAG_DEACTIVATED; } } @@ -128,12 +128,12 @@ void generic_bobomb_free_loop(void) { case BOBOMB_ACT_LAVA_DEATH: if (obj_lava_death() == 1) - create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000); + create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID); break; case BOBOMB_ACT_DEATH_PLANE_DEATH: o->activeFlags = ACTIVE_FLAG_DEACTIVATED; - create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000); + create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID); break; } @@ -155,12 +155,12 @@ void stationary_bobomb_free_loop(void) { case BOBOMB_ACT_LAVA_DEATH: if (obj_lava_death() == 1) - create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000); + create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID); break; case BOBOMB_ACT_DEATH_PLANE_DEATH: o->activeFlags = ACTIVE_FLAG_DEACTIVATED; - create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000); + create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000, o->oSyncID); break; } diff --git a/src/game/behaviors/breakable_box_small.inc.c b/src/game/behaviors/breakable_box_small.inc.c index bb9a4eddc..3acf2d567 100644 --- a/src/game/behaviors/breakable_box_small.inc.c +++ b/src/game/behaviors/breakable_box_small.inc.c @@ -65,7 +65,7 @@ void breakable_box_small_released_loop(void) { // Despawn, and create a corkbox respawner if (o->oBreakableBoxSmallFramesSinceReleased > 900) { - create_respawner(MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall, 3000); + create_respawner(MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall, 3000, o->oSyncID); o->activeFlags = ACTIVE_FLAG_DEACTIVATED; } } @@ -82,7 +82,7 @@ void breakable_box_small_idle_loop(void) { case 101: o->activeFlags = ACTIVE_FLAG_DEACTIVATED; - create_respawner(MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall, 3000); + create_respawner(MODEL_BREAKABLE_BOX_SMALL, bhvBreakableBoxSmall, 3000, o->oSyncID); break; } diff --git a/src/game/behaviors/corkbox.inc.c b/src/game/behaviors/corkbox.inc.c index e9316513c..c1b9ad323 100644 --- a/src/game/behaviors/corkbox.inc.c +++ b/src/game/behaviors/corkbox.inc.c @@ -44,15 +44,17 @@ void bhv_respawner_loop(void) { if (!is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, o->oRespawnerMinSpawnDist)) { spawnedObject = spawn_object(o, o->oRespawnerModelToRespawn, o->oRespawnerBehaviorToRespawn); spawnedObject->oBehParams = o->oBehParams; + spawnedObject->oSyncID = o->oSyncID; o->activeFlags = ACTIVE_FLAG_DEACTIVATED; } } -void create_respawner(s32 model, const BehaviorScript *behToSpawn, s32 minSpawnDist) { +void create_respawner(s32 model, const BehaviorScript *behToSpawn, s32 minSpawnDist, u32 syncID) { struct Object *respawner = spawn_object_abs_with_rot(o, 0, MODEL_NONE, bhvRespawner, o->oHomeX, o->oHomeY, o->oHomeZ, 0, 0, 0); respawner->oBehParams = o->oBehParams; respawner->oRespawnerModelToRespawn = model; respawner->oRespawnerMinSpawnDist = minSpawnDist; respawner->oRespawnerBehaviorToRespawn = behToSpawn; + respawner->oSyncID = syncID; } diff --git a/src/game/behaviors/snowman.inc.c b/src/game/behaviors/snowman.inc.c index cec85f6b5..640438520 100644 --- a/src/game/behaviors/snowman.inc.c +++ b/src/game/behaviors/snowman.inc.c @@ -96,7 +96,7 @@ void snowmans_bottom_act_2(void) { } if (o->oTimer == 200) { - create_respawner(MODEL_CCM_SNOWMAN_BASE, bhvSnowmansBottom, 3000); + create_respawner(MODEL_CCM_SNOWMAN_BASE, bhvSnowmansBottom, 3000, o->oSyncID); o->activeFlags = ACTIVE_FLAG_DEACTIVATED; } } diff --git a/src/game/behaviors/yoshi.inc.c b/src/game/behaviors/yoshi.inc.c index 136a2bda0..b60d2df9a 100644 --- a/src/game/behaviors/yoshi.inc.c +++ b/src/game/behaviors/yoshi.inc.c @@ -34,7 +34,7 @@ void yoshi_walk_loop(void) { o->oAction = YOSHI_ACT_TALK; if (o->oPosY < 2100.0f) { - create_respawner(MODEL_YOSHI, bhvYoshi, 3000); + create_respawner(MODEL_YOSHI, bhvYoshi, 3000, o->oSyncID); o->activeFlags = ACTIVE_FLAG_DEACTIVATED; } } diff --git a/src/game/mario_actions_object.c b/src/game/mario_actions_object.c index ff2e03aab..5f2789992 100644 --- a/src/game/mario_actions_object.c +++ b/src/game/mario_actions_object.c @@ -193,7 +193,7 @@ s32 act_picking_up(struct MarioState *m) { } } - if (m->actionState == 1) { + if (m->actionState == 1 && m->heldObj != NULL) { if (m->heldObj->oInteractionSubtype & INT_SUBTYPE_GRABS_MARIO) { m->marioBodyState->grabPos = GRAB_POS_HEAVY_OBJ; set_mario_animation(m, MARIO_ANIM_GRAB_HEAVY_OBJECT); diff --git a/src/game/obj_behaviors.h b/src/game/obj_behaviors.h index 02a0567fd..5a2b11680 100644 --- a/src/game/obj_behaviors.h +++ b/src/game/obj_behaviors.h @@ -87,7 +87,7 @@ void bhv_bobomb_bully_death_smoke_init(void); void bhv_bobomb_explosion_bubble_init(void); void bhv_bobomb_explosion_bubble_loop(void); void bhv_respawner_loop(void); -void create_respawner(s32 arg0, const BehaviorScript *behToSpawn, s32 minSpawnDist); +void create_respawner(s32 arg0, const BehaviorScript *behToSpawn, s32 minSpawnDist, u32 syncID); void bhv_small_bully_init(void); void bhv_big_bully_init(void); void bully_check_mario_collision(void); diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 72a98539e..4ecc951d0 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -2,13 +2,16 @@ #define NETWORK_H #include +#include #include "../cliopts.h" +#define MAX_SYNC_OBJECTS 256 #define PACKET_LENGTH 1024 #define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server") extern struct MarioState gMarioStates[]; extern enum NetworkType networkType; +extern struct Object* syncObjects[]; enum PacketType { PACKET_PLAYER, diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c index 70bb17322..8d3255be4 100644 --- a/src/pc/network/packets/packet_object.c +++ b/src/pc/network/packets/packet_object.c @@ -4,28 +4,33 @@ #include "object_constants.h" u32 nextSyncID = 1; -struct Object* syncObject = NULL; +struct Object* syncObjects[MAX_SYNC_OBJECTS] = { 0 }; -float player_distance(struct MarioState* marioState, struct Object* obj) { +float player_distance(struct MarioState* marioState, struct Object* o) { if (marioState->marioObj == NULL) { return 0; } - f32 mx = marioState->marioObj->header.gfx.pos[0] - obj->oPosX; - f32 my = marioState->marioObj->header.gfx.pos[1] - obj->oPosY; - f32 mz = marioState->marioObj->header.gfx.pos[2] - obj->oPosZ; + f32 mx = marioState->marioObj->header.gfx.pos[0] - o->oPosX; + f32 my = marioState->marioObj->header.gfx.pos[1] - o->oPosY; + f32 mz = marioState->marioObj->header.gfx.pos[2] - o->oPosZ; mx *= mx; my *= my; mz *= mz; return sqrt(mx + my + mz); } -void network_init_object(struct Object *object) { - object->oSyncID = nextSyncID++; - syncObject = object; +void network_init_object(struct Object *o) { + if (o->oSyncID == 0) { + o->oSyncID = nextSyncID++; + } + assert(o->oSyncID < MAX_SYNC_OBJECTS); + syncObjects[o->oSyncID] = o; } void network_send_object(struct Object* o) { - o = syncObject; + int expectedID = 1; + o = syncObjects[expectedID]; if (o == NULL) { return; } - if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { return; } + //if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { return; } + if (o->oSyncID != expectedID) { return; } if (player_distance(&gMarioStates[0], o) > player_distance(&gMarioStates[1], o)) { return; } struct Packet p; @@ -40,11 +45,14 @@ void network_send_object(struct Object* o) { } void network_receive_object(struct Packet* p) { - if (syncObject == NULL) { return; } u32 syncId; packet_read(p, &syncId, 4); - packet_read(p, &syncObject->oPosX, 28); - packet_read(p, &syncObject->oAction, 4); - packet_read(p, &syncObject->oHeldState, 4); - packet_read(p, &syncObject->oMoveAngleYaw, 4); + assert(syncId < MAX_SYNC_OBJECTS); + struct Object* o = syncObjects[syncId]; + assert(o != NULL); + + packet_read(p, &o->oPosX, 28); + packet_read(p, &o->oAction, 4); + packet_read(p, &o->oHeldState, 4); + packet_read(p, &o->oMoveAngleYaw, 4); } diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 795eed86a..4b980d338 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -1,23 +1,38 @@ #include #include "../network.h" +#include "object_fields.h" +#include "object_constants.h" void network_send_player(void) { if (gMarioStates[0].marioObj == NULL) { return; } + u32 heldSyncID = (gMarioStates[0].heldObj != NULL) + ? gMarioStates[0].heldObj->oSyncID + : NULL; + struct Packet p; packet_init(&p, PACKET_PLAYER); packet_write(&p, &gMarioStates[0], 96); packet_write(&p, gMarioStates[0].controller, 20); packet_write(&p, gMarioStates[0].marioObj->rawData.asU32, 320); + packet_write(&p, &heldSyncID, 4); network_send(&p); } void network_receive_player(struct Packet* p) { if (gMarioStates[1].marioObj == NULL) { return; } int oldActionState = gMarioStates[1].actionState; + u32 heldSyncID = NULL; packet_read(p, &gMarioStates[1], 96); packet_read(p, gMarioStates[1].controller, 20); packet_read(p, &gMarioStates[1].marioObj->rawData.asU32, 320); + packet_read(p, &heldSyncID, 4); + + if (heldSyncID != NULL) { + assert(syncObjects[heldSyncID] != NULL); + gMarioStates[1].heldObj = syncObjects[heldSyncID]; + gMarioStates[1].heldObj->heldByPlayerIndex = 1; + } // restore action state, needed for jump kicking gMarioStates[1].actionState = oldActionState;