From 443fc1a73fea31036c30ebf5917ca80b209db1df Mon Sep 17 00:00:00 2001 From: MysterD Date: Mon, 31 Aug 2020 23:49:51 -0700 Subject: [PATCH] Synchronize cannons as soon as they are unlocked --- dx11.sh | 1 + src/game/behaviors/cannon_door.inc.c | 22 ++++++++++++------ src/pc/network/packets/packet_spawn_objects.c | 23 +++++++++++++++---- 3 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 dx11.sh diff --git a/dx11.sh b/dx11.sh new file mode 100644 index 00000000..dc73fab2 --- /dev/null +++ b/dx11.sh @@ -0,0 +1 @@ +make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 RENDER_API=D3D11 && winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here' \ No newline at end of file diff --git a/src/game/behaviors/cannon_door.inc.c b/src/game/behaviors/cannon_door.inc.c index cb710322..8fa3a21c 100644 --- a/src/game/behaviors/cannon_door.inc.c +++ b/src/game/behaviors/cannon_door.inc.c @@ -4,13 +4,21 @@ void bhv_cannon_closed_init(void) { struct Object *cannon; if (save_file_is_cannon_unlocked() == 1) { - // If the cannon is open, spawn a cannon and despawn the object. - cannon = spawn_object(o, MODEL_CANNON_BASE, bhvCannon); - cannon->oBehParams2ndByte = o->oBehParams2ndByte; - cannon->oPosX = o->oHomeX; - cannon->oPosY = o->oHomeY; - cannon->oPosZ = o->oHomeZ; - + if (!networkLevelLoaded || networkType == NT_SERVER) { + // If the cannon is open, spawn a cannon and despawn the object. + cannon = spawn_object(o, MODEL_CANNON_BASE, bhvCannon); + cannon->parentObj = cannon; + cannon->oBehParams2ndByte = o->oBehParams2ndByte; + cannon->oPosX = o->oHomeX; + cannon->oPosY = o->oHomeY; + cannon->oPosZ = o->oHomeZ; + if (networkLevelLoaded) { + network_set_sync_id(cannon); + struct Object* spawn_objects[] = { cannon }; + u32 models[] = { MODEL_CANNON_BASE }; + network_send_spawn_objects(spawn_objects, models, 1); + } + } o->oAction = CANNON_TRAP_DOOR_ACT_OPEN; o->activeFlags = ACTIVE_FLAG_DEACTIVATED; } diff --git a/src/pc/network/packets/packet_spawn_objects.c b/src/pc/network/packets/packet_spawn_objects.c index df85d5ec..70207e1f 100644 --- a/src/pc/network/packets/packet_spawn_objects.c +++ b/src/pc/network/packets/packet_spawn_objects.c @@ -26,12 +26,15 @@ struct SpawnObjectData { static u8 generate_parent_id(struct Object* objects[], u8 onIndex) { struct Object* o = objects[onIndex]; + // special case if the parent is itself + if (o->parentObj == o) { return (u8)-1; } + if (onIndex == 0) { assert(o->parentObj->oSyncID != 0); return (u8)o->parentObj->oSyncID; } - for (u8 i = (onIndex - 1); i >= 0; i--) { + for (u8 i = onIndex; i >= 0; i--) { if (o->parentObj == objects[i]) { return i; } } @@ -95,15 +98,25 @@ void network_receive_spawn_objects(struct Packet* p) { packet_read(p, &data.activeFlags, sizeof(s16)); packet_read(p, &data.rawData, sizeof(s32) * 80); - struct Object* parentObj = (i == 0) - ? syncObjects[data.parentId].o - : spawned[data.parentId]; - if (parentObj == NULL) { continue; } + struct Object* parentObj = NULL; + if (data.parentId == (u8)-1) { + // this object is it's own parent, set it to a known object temporarily + parentObj = gMarioStates[0].marioObj; + } else { + // this object has a known parent + parentObj = (i == 0) + ? syncObjects[data.parentId].o + : spawned[data.parentId]; + if (parentObj == NULL) { continue; } + } void* behavior = get_behavior_from_id(data.behaviorId); struct Object* o = spawn_object(parentObj, data.model, behavior); memcpy(o->rawData.asU32, data.rawData, sizeof(u32) * 80); + // correct the temporary parent with the object itself + if (data.parentId == (u8)-1) { o->parentObj = o; } + // they've allocated one of their reserved sync objects if (o->oSyncID != 0 && syncObjects[o->oSyncID].reserved == reserveId) { syncObjects[o->oSyncID].o = o;