From f40d09cb8f712e87691af4912f3630d92d692779 Mon Sep 17 00:00:00 2001 From: untodesu Date: Thu, 11 Dec 2025 15:14:26 +0500 Subject: Shuffle stuff around - Use the new and improved hierarchy I figured out when making Prospero chat - Re-add NSIS scripts, again from Prospero - Update most build and utility scripts with their most recent versions --- src/game/server/world/unloader.cc | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/game/server/world/unloader.cc (limited to 'src/game/server/world/unloader.cc') diff --git a/src/game/server/world/unloader.cc b/src/game/server/world/unloader.cc new file mode 100644 index 0000000..4a3f4e1 --- /dev/null +++ b/src/game/server/world/unloader.cc @@ -0,0 +1,78 @@ +#include "server/pch.hh" + +#include "server/world/unloader.hh" + +#include "core/config/number.hh" + +#include "shared/entity/player.hh" +#include "shared/entity/transform.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/chunk_aabb.hh" +#include "shared/world/dimension.hh" + +#include "server/world/inhabited.hh" +#include "server/world/universe.hh" + +#include "server/game.hh" +#include "server/globals.hh" + +static void on_chunk_update(const world::ChunkUpdateEvent& event) +{ + event.dimension->chunks.emplace_or_replace(event.chunk->get_entity()); +} + +static void on_voxel_set(const world::VoxelSetEvent& event) +{ + event.dimension->chunks.emplace_or_replace(event.chunk->get_entity()); +} + +void world::unloader::init(void) +{ + globals::dispatcher.sink().connect<&on_chunk_update>(); + globals::dispatcher.sink().connect<&on_voxel_set>(); +} + +void world::unloader::init_late(void) +{ +} + +void world::unloader::fixed_update_late(Dimension* dimension) +{ + auto group = dimension->entities.group(entt::get); + auto boxes = std::vector(); + + for(const auto [entity, transform] : group.each()) { + ChunkAABB aabb; + aabb.min = transform.chunk - static_cast(server_game::view_distance.get_value()); + aabb.max = transform.chunk + static_cast(server_game::view_distance.get_value()); + boxes.push_back(aabb); + } + + auto view = dimension->chunks.view(); + auto chunk_in_view = false; + + for(const auto [entity, chunk] : view.each()) { + chunk_in_view = false; + + for(const auto& aabb : boxes) { + if(aabb.contains(chunk.cpos)) { + chunk_in_view = true; + break; + } + } + + if(chunk_in_view) { + // The chunk is within view box of at least + // a single player; we shouldn't unload it now + continue; + } + + if(dimension->chunks.any_of(entity)) { + // Only store inhabited chunks on disk + world::universe::save_chunk(dimension, chunk.cpos); + } + + dimension->remove_chunk(entity); + } +} -- cgit