diff --git a/deps/dragonnet b/deps/dragonnet index 8bcc4ba..164e1ed 160000 --- a/deps/dragonnet +++ b/deps/dragonnet @@ -1 +1 @@ -Subproject commit 8bcc4ba04baea8f4d1f86524e58bd81d4df67bf6 +Subproject commit 164e1ed7f93e1889c36b549a995e93fc0992c888 diff --git a/deps/dragontype b/deps/dragontype index 61292ea..18ae77e 160000 --- a/deps/dragontype +++ b/deps/dragontype @@ -1 +1 @@ -Subproject commit 61292ea8a973ba03f93ebf4acde705071e15ccaf +Subproject commit 18ae77e35da46f97f3b06562a4a892ebdeeb9750 diff --git a/src/client/client.c b/src/client/client.c index 04364af..63d3c59 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -45,6 +45,7 @@ static void on_ToClientBlock(unused DragonnetPeer *peer, ToClientBlock *pkt) MapBlock *block = map_get_block(client_map.map, pkt->pos, true); map_deserialize_block(block, pkt->data); + ((MapBlockExtraData *) block->extra)->all_air = (pkt->data.siz == 0); client_map_block_received(block); } diff --git a/src/client/client_map.c b/src/client/client_map.c index f617341..43252dd 100644 --- a/src/client/client_map.c +++ b/src/client/client_map.c @@ -133,6 +133,7 @@ static void on_create_block(MapBlock *block) extra->queue = false; extra->last_synced = 0; extra->obj = NULL; + extra->all_air = false; } // callback for deleting a block @@ -236,9 +237,17 @@ void client_map_schedule_update_block_mesh(MapBlock *block) pthread_mutex_lock(&block->mtx); MapBlockExtraData *extra = block->extra; + if (! extra->queue) { - extra->queue = true; - queue_enqueue(client_map.queue, block); + if (extra->all_air) { + if (extra->obj) { + extra->obj->remove = true; + extra->obj = NULL; + } + } else { + extra->queue = true; + queue_enqueue(client_map.queue, block); + } } pthread_mutex_unlock(&block->mtx); } diff --git a/src/client/client_map.h b/src/client/client_map.h index f340a9a..b49f199 100644 --- a/src/client/client_map.h +++ b/src/client/client_map.h @@ -20,6 +20,7 @@ typedef struct bool queue; // whether the block is in meshgen queue u64 last_synced; // keep track of when a block was synced the last time (used to detect when a block got out of and then back into range) Object *obj; // mesh object, generated by blockmesh file + bool all_air; // no thoughts brain empty } MapBlockExtraData; extern struct ClientMap diff --git a/src/map.c b/src/map.c index a9a83be..8c75756 100644 --- a/src/map.c +++ b/src/map.c @@ -145,6 +145,18 @@ void map_free_block(MapBlock *block) Blob map_serialize_block(MapBlock *block) { + bool all_air = true; + + ITERATE_MAPBLOCK { + if (block->data[x][y][z].type != NODE_AIR) { + all_air = false; + break; + } + } + + if (all_air) + return (Blob) {0, NULL}; + SerializedMapBlock block_data; ITERATE_MAPBLOCK { @@ -174,6 +186,13 @@ Blob map_serialize_block(MapBlock *block) bool map_deserialize_block(MapBlock *block, Blob buffer) { + if (buffer.siz == 0) { + ITERATE_MAPBLOCK + block->data[x][y][z] = map_node_create(NODE_AIR, (Blob) {0, NULL}); + + return true; + } + // it's important to copy Blobs that have been malloc'd before reading from them // because reading from a Blob modifies its data and size pointer, // but does not free anything