diff options
| author | untodesu <kirill@untode.su> | 2025-12-11 15:14:26 +0500 |
|---|---|---|
| committer | untodesu <kirill@untode.su> | 2025-12-11 15:14:26 +0500 |
| commit | f40d09cb8f712e87691af4912f3630d92d692779 (patch) | |
| tree | 7ac3a4168ff722689372fd489c6f94d0a2546e8f /src/game/shared/world/dimension.cc | |
| parent | 8bcbd2729388edc63c82d77d314b583af1447c49 (diff) | |
| download | voxelius-f40d09cb8f712e87691af4912f3630d92d692779.tar.bz2 voxelius-f40d09cb8f712e87691af4912f3630d92d692779.zip | |
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
Diffstat (limited to 'src/game/shared/world/dimension.cc')
| -rw-r--r-- | src/game/shared/world/dimension.cc | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/src/game/shared/world/dimension.cc b/src/game/shared/world/dimension.cc new file mode 100644 index 0000000..0088753 --- /dev/null +++ b/src/game/shared/world/dimension.cc @@ -0,0 +1,187 @@ +#include "shared/pch.hh" + +#include "shared/world/dimension.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/voxel_registry.hh" + +#include "shared/coord.hh" +#include "shared/globals.hh" + +world::Dimension::Dimension(std::string_view name, float gravity) +{ + m_name = name; + m_gravity = gravity; +} + +world::Dimension::~Dimension(void) +{ + for(const auto it : m_chunkmap) + delete it.second; + entities.clear(); + chunks.clear(); +} + +std::string_view world::Dimension::get_name(void) const +{ + return m_name; +} + +float world::Dimension::get_gravity(void) const +{ + return m_gravity; +} + +world::Chunk* world::Dimension::create_chunk(const chunk_pos& cpos) +{ + auto it = m_chunkmap.find(cpos); + + if(it != m_chunkmap.cend()) { + // Chunk already exists + return it->second; + } + + auto entity = chunks.create(); + auto chunk = new Chunk(entity, this); + + auto& component = chunks.emplace<ChunkComponent>(entity); + component.chunk = chunk; + component.cpos = cpos; + + ChunkCreateEvent event; + event.dimension = this; + event.chunk = chunk; + event.cpos = cpos; + + globals::dispatcher.trigger(event); + + return m_chunkmap.insert_or_assign(cpos, std::move(chunk)).first->second; +} + +world::Chunk* world::Dimension::find_chunk(entt::entity entity) const +{ + if(chunks.valid(entity)) { + return chunks.get<ChunkComponent>(entity).chunk; + } + else { + return nullptr; + } +} + +world::Chunk* world::Dimension::find_chunk(const chunk_pos& cpos) const +{ + auto it = m_chunkmap.find(cpos); + + if(it != m_chunkmap.cend()) { + return it->second; + } + else { + return nullptr; + } +} + +void world::Dimension::remove_chunk(entt::entity entity) +{ + if(chunks.valid(entity)) { + auto& component = chunks.get<ChunkComponent>(entity); + m_chunkmap.erase(component.cpos); + chunks.destroy(entity); + } +} + +void world::Dimension::remove_chunk(const chunk_pos& cpos) +{ + auto it = m_chunkmap.find(cpos); + + if(it != m_chunkmap.cend()) { + chunks.destroy(it->second->get_entity()); + m_chunkmap.erase(it); + } +} + +void world::Dimension::remove_chunk(Chunk* chunk) +{ + if(chunk) { + const auto& component = chunks.get<ChunkComponent>(chunk->get_entity()); + m_chunkmap.erase(component.cpos); + chunks.destroy(chunk->get_entity()); + } +} + +const world::Voxel* world::Dimension::get_voxel(const voxel_pos& vpos) const +{ + auto cpos = coord::to_chunk(vpos); + auto lpos = coord::to_local(vpos); + + if(auto chunk = find_chunk(cpos)) { + return chunk->get_voxel(lpos); + } + + return nullptr; +} + +const world::Voxel* world::Dimension::get_voxel(const chunk_pos& cpos, const local_pos& lpos) const +{ + // This allows accessing get_voxel with negative + // local coordinates that usually would result in an + // out-of-range values; this is useful for per-voxel update logic + return get_voxel(coord::to_voxel(cpos, lpos)); +} + +bool world::Dimension::set_voxel(const Voxel* voxel, const voxel_pos& vpos) +{ + auto cpos = coord::to_chunk(vpos); + auto lpos = coord::to_local(vpos); + + if(auto chunk = find_chunk(cpos)) { + if(auto old_voxel = chunk->get_voxel(lpos)) { + if(old_voxel != voxel) { + // Notify the old voxel that it is + // being replaced with a different voxel + old_voxel->on_remove(this, vpos); + } + } + + chunk->set_voxel(voxel, lpos); + + if(voxel) { + // If we're not placing air, notify the + // new voxel that it has been placed + voxel->on_place(this, vpos); + } + + VoxelSetEvent event; + event.dimension = this; + event.voxel = voxel; + event.cpos = cpos; + event.lpos = lpos; + event.chunk = chunk; + + globals::dispatcher.trigger(event); + + return true; + } + + return false; +} + +bool world::Dimension::set_voxel(const Voxel* voxel, const chunk_pos& cpos, const local_pos& lpos) +{ + // This allows accessing set_voxel with negative + // local coordinates that usually would result in an + // out-of-range values; this is useful for per-voxel update logic + return set_voxel(voxel, coord::to_voxel(cpos, lpos)); +} + +void world::Dimension::init(io::ConfigMap& config) +{ +} + +void world::Dimension::init_late(std::uint64_t global_seed) +{ +} + +bool world::Dimension::generate(const chunk_pos& cpos, VoxelStorage& voxels) +{ + return false; +} |
