From d0fbd68055e3f4a796330cc8acc6c0954b5327ff Mon Sep 17 00:00:00 2001 From: untodesu Date: Thu, 11 Sep 2025 15:48:53 +0500 Subject: Run clang-format across the project --- game/shared/world/chunk.cc | 140 ++++++------- game/shared/world/chunk.hh | 84 ++++---- game/shared/world/chunk_aabb.cc | 108 +++++----- game/shared/world/chunk_aabb.hh | 66 +++--- game/shared/world/dimension.cc | 346 +++++++++++++++---------------- game/shared/world/dimension.hh | 200 +++++++++--------- game/shared/world/feature.cc | 106 +++++----- game/shared/world/feature.hh | 44 ++-- game/shared/world/item_registry.cc | 212 +++++++++---------- game/shared/world/item_registry.hh | 128 ++++++------ game/shared/world/ray_dda.cc | 214 ++++++++++---------- game/shared/world/ray_dda.hh | 82 ++++---- game/shared/world/voxel_registry.cc | 392 ++++++++++++++++++------------------ game/shared/world/voxel_registry.hh | 298 +++++++++++++-------------- game/shared/world/voxel_storage.cc | 96 ++++----- game/shared/world/voxel_storage.hh | 40 ++-- 16 files changed, 1278 insertions(+), 1278 deletions(-) (limited to 'game/shared/world') diff --git a/game/shared/world/chunk.cc b/game/shared/world/chunk.cc index f689fc1..e59b68d 100644 --- a/game/shared/world/chunk.cc +++ b/game/shared/world/chunk.cc @@ -1,70 +1,70 @@ -#include "shared/pch.hh" - -#include "shared/world/chunk.hh" - -#include "shared/coord.hh" - -world::Chunk::Chunk(entt::entity entity, Dimension* dimension) -{ - m_entity = entity; - m_dimension = dimension; - m_voxels.fill(NULL_VOXEL_ID); - m_biome = BIOME_VOID; -} - -voxel_id world::Chunk::get_voxel(const local_pos& lpos) const -{ - return get_voxel(coord::to_index(lpos)); -} - -voxel_id world::Chunk::get_voxel(const std::size_t index) const -{ - if(index >= CHUNK_VOLUME) { - return NULL_VOXEL_ID; - } - else { - return m_voxels[index]; - } -} - -void world::Chunk::set_voxel(voxel_id voxel, const local_pos& lpos) -{ - set_voxel(voxel, coord::to_index(lpos)); -} - -void world::Chunk::set_voxel(voxel_id voxel, const std::size_t index) -{ - if(index < CHUNK_VOLUME) { - m_voxels[index] = voxel; - } -} - -const world::VoxelStorage& world::Chunk::get_voxels(void) const -{ - return m_voxels; -} - -void world::Chunk::set_voxels(const VoxelStorage& voxels) -{ - m_voxels = voxels; -} - -unsigned int world::Chunk::get_biome(void) const -{ - return m_biome; -} - -void world::Chunk::set_biome(unsigned int biome) -{ - m_biome = biome; -} - -entt::entity world::Chunk::get_entity(void) const -{ - return m_entity; -} - -world::Dimension* world::Chunk::get_dimension(void) const -{ - return m_dimension; -} +#include "shared/pch.hh" + +#include "shared/world/chunk.hh" + +#include "shared/coord.hh" + +world::Chunk::Chunk(entt::entity entity, Dimension* dimension) +{ + m_entity = entity; + m_dimension = dimension; + m_voxels.fill(NULL_VOXEL_ID); + m_biome = BIOME_VOID; +} + +voxel_id world::Chunk::get_voxel(const local_pos& lpos) const +{ + return get_voxel(coord::to_index(lpos)); +} + +voxel_id world::Chunk::get_voxel(const std::size_t index) const +{ + if(index >= CHUNK_VOLUME) { + return NULL_VOXEL_ID; + } + else { + return m_voxels[index]; + } +} + +void world::Chunk::set_voxel(voxel_id voxel, const local_pos& lpos) +{ + set_voxel(voxel, coord::to_index(lpos)); +} + +void world::Chunk::set_voxel(voxel_id voxel, const std::size_t index) +{ + if(index < CHUNK_VOLUME) { + m_voxels[index] = voxel; + } +} + +const world::VoxelStorage& world::Chunk::get_voxels(void) const +{ + return m_voxels; +} + +void world::Chunk::set_voxels(const VoxelStorage& voxels) +{ + m_voxels = voxels; +} + +unsigned int world::Chunk::get_biome(void) const +{ + return m_biome; +} + +void world::Chunk::set_biome(unsigned int biome) +{ + m_biome = biome; +} + +entt::entity world::Chunk::get_entity(void) const +{ + return m_entity; +} + +world::Dimension* world::Chunk::get_dimension(void) const +{ + return m_dimension; +} diff --git a/game/shared/world/chunk.hh b/game/shared/world/chunk.hh index 439694c..c5bba12 100644 --- a/game/shared/world/chunk.hh +++ b/game/shared/world/chunk.hh @@ -1,42 +1,42 @@ -#pragma once - -#include "shared/world/voxel_storage.hh" - -#include "shared/types.hh" - -constexpr static unsigned int BIOME_VOID = 0U; - -namespace world -{ -class Dimension; -} // namespace world - -namespace world -{ -class Chunk final { -public: - explicit Chunk(entt::entity entity, Dimension* dimension); - virtual ~Chunk(void) = default; - - voxel_id get_voxel(const local_pos& lpos) const; - voxel_id get_voxel(const std::size_t index) const; - - void set_voxel(voxel_id voxel, const local_pos& lpos); - void set_voxel(voxel_id voxel, const std::size_t index); - - const VoxelStorage& get_voxels(void) const; - void set_voxels(const VoxelStorage& voxels); - - unsigned int get_biome(void) const; - void set_biome(unsigned int biome); - - entt::entity get_entity(void) const; - Dimension* get_dimension(void) const; - -private: - entt::entity m_entity; - Dimension* m_dimension; - VoxelStorage m_voxels; - unsigned int m_biome; -}; -} // namespace world +#pragma once + +#include "shared/world/voxel_storage.hh" + +#include "shared/types.hh" + +constexpr static unsigned int BIOME_VOID = 0U; + +namespace world +{ +class Dimension; +} // namespace world + +namespace world +{ +class Chunk final { +public: + explicit Chunk(entt::entity entity, Dimension* dimension); + virtual ~Chunk(void) = default; + + voxel_id get_voxel(const local_pos& lpos) const; + voxel_id get_voxel(const std::size_t index) const; + + void set_voxel(voxel_id voxel, const local_pos& lpos); + void set_voxel(voxel_id voxel, const std::size_t index); + + const VoxelStorage& get_voxels(void) const; + void set_voxels(const VoxelStorage& voxels); + + unsigned int get_biome(void) const; + void set_biome(unsigned int biome); + + entt::entity get_entity(void) const; + Dimension* get_dimension(void) const; + +private: + entt::entity m_entity; + Dimension* m_dimension; + VoxelStorage m_voxels; + unsigned int m_biome; +}; +} // namespace world diff --git a/game/shared/world/chunk_aabb.cc b/game/shared/world/chunk_aabb.cc index c0e540e..634b230 100644 --- a/game/shared/world/chunk_aabb.cc +++ b/game/shared/world/chunk_aabb.cc @@ -1,54 +1,54 @@ -#include "shared/pch.hh" - -#include "shared/world/chunk_aabb.hh" - -void world::ChunkAABB::set_bounds(const chunk_pos& min, const chunk_pos& max) -{ - this->min = min; - this->max = max; -} - -void world::ChunkAABB::set_offset(const chunk_pos& base, const chunk_pos& size) -{ - this->min = base; - this->max = base + size; -} - -bool world::ChunkAABB::contains(const chunk_pos& point) const -{ - auto result = true; - result = result && (point.x >= min.x) && (point.x <= max.x); - result = result && (point.y >= min.y) && (point.y <= max.y); - result = result && (point.z >= min.z) && (point.z <= max.z); - return result; -} - -bool world::ChunkAABB::intersect(const ChunkAABB& other_box) const -{ - auto result = true; - result = result && (min.x < other_box.max.x) && (max.x > other_box.min.x); - result = result && (min.y < other_box.max.y) && (max.y > other_box.min.y); - result = result && (min.z < other_box.max.z) && (max.z > other_box.min.z); - return result; -} - -world::ChunkAABB world::ChunkAABB::combine_with(const ChunkAABB& other_box) const -{ - ChunkAABB result; - result.set_bounds(min, other_box.max); - return result; -} - -world::ChunkAABB world::ChunkAABB::multiply_with(const ChunkAABB& other_box) const -{ - ChunkAABB result; - result.set_bounds(other_box.min, max); - return result; -} - -world::ChunkAABB world::ChunkAABB::push(const chunk_pos& vector) const -{ - ChunkAABB result; - result.set_bounds(min + vector, max + vector); - return result; -} +#include "shared/pch.hh" + +#include "shared/world/chunk_aabb.hh" + +void world::ChunkAABB::set_bounds(const chunk_pos& min, const chunk_pos& max) +{ + this->min = min; + this->max = max; +} + +void world::ChunkAABB::set_offset(const chunk_pos& base, const chunk_pos& size) +{ + this->min = base; + this->max = base + size; +} + +bool world::ChunkAABB::contains(const chunk_pos& point) const +{ + auto result = true; + result = result && (point.x >= min.x) && (point.x <= max.x); + result = result && (point.y >= min.y) && (point.y <= max.y); + result = result && (point.z >= min.z) && (point.z <= max.z); + return result; +} + +bool world::ChunkAABB::intersect(const ChunkAABB& other_box) const +{ + auto result = true; + result = result && (min.x < other_box.max.x) && (max.x > other_box.min.x); + result = result && (min.y < other_box.max.y) && (max.y > other_box.min.y); + result = result && (min.z < other_box.max.z) && (max.z > other_box.min.z); + return result; +} + +world::ChunkAABB world::ChunkAABB::combine_with(const ChunkAABB& other_box) const +{ + ChunkAABB result; + result.set_bounds(min, other_box.max); + return result; +} + +world::ChunkAABB world::ChunkAABB::multiply_with(const ChunkAABB& other_box) const +{ + ChunkAABB result; + result.set_bounds(other_box.min, max); + return result; +} + +world::ChunkAABB world::ChunkAABB::push(const chunk_pos& vector) const +{ + ChunkAABB result; + result.set_bounds(min + vector, max + vector); + return result; +} diff --git a/game/shared/world/chunk_aabb.hh b/game/shared/world/chunk_aabb.hh index bd4a0c5..a9e0205 100644 --- a/game/shared/world/chunk_aabb.hh +++ b/game/shared/world/chunk_aabb.hh @@ -1,33 +1,33 @@ -#ifndef SHARED_CHUNK_AABB -#define SHARED_CHUNK_AABB 1 -#pragma once - -#include "shared/types.hh" - -namespace world -{ -class ChunkAABB final { -public: - ChunkAABB(void) = default; - virtual ~ChunkAABB(void) = default; - - void set_bounds(const chunk_pos& min, const chunk_pos& max); - void set_offset(const chunk_pos& base, const chunk_pos& size); - - const chunk_pos& get_min(void) const; - const chunk_pos& get_max(void) const; - - bool contains(const chunk_pos& point) const; - bool intersect(const ChunkAABB& other_box) const; - - ChunkAABB combine_with(const ChunkAABB& other_box) const; - ChunkAABB multiply_with(const ChunkAABB& other_box) const; - ChunkAABB push(const chunk_pos& vector) const; - -public: - chunk_pos min; - chunk_pos max; -}; -} // namespace world - -#endif // SHARED_CHUNK_AABB +#ifndef SHARED_CHUNK_AABB +#define SHARED_CHUNK_AABB 1 +#pragma once + +#include "shared/types.hh" + +namespace world +{ +class ChunkAABB final { +public: + ChunkAABB(void) = default; + virtual ~ChunkAABB(void) = default; + + void set_bounds(const chunk_pos& min, const chunk_pos& max); + void set_offset(const chunk_pos& base, const chunk_pos& size); + + const chunk_pos& get_min(void) const; + const chunk_pos& get_max(void) const; + + bool contains(const chunk_pos& point) const; + bool intersect(const ChunkAABB& other_box) const; + + ChunkAABB combine_with(const ChunkAABB& other_box) const; + ChunkAABB multiply_with(const ChunkAABB& other_box) const; + ChunkAABB push(const chunk_pos& vector) const; + +public: + chunk_pos min; + chunk_pos max; +}; +} // namespace world + +#endif // SHARED_CHUNK_AABB diff --git a/game/shared/world/dimension.cc b/game/shared/world/dimension.cc index 2d193fc..dd28449 100644 --- a/game/shared/world/dimension.cc +++ b/game/shared/world/dimension.cc @@ -1,173 +1,173 @@ -#include "shared/pch.hh" - -#include "shared/world/dimension.hh" - -#include "shared/world/chunk.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(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(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(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(chunk->get_entity()); - m_chunkmap.erase(component.cpos); - chunks.destroy(chunk->get_entity()); - } -} - -voxel_id 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); - } - else { - return NULL_VOXEL_ID; - } -} - -voxel_id 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(voxel_id voxel, const voxel_pos& vpos) -{ - auto cpos = coord::to_chunk(vpos); - auto lpos = coord::to_local(vpos); - - if(auto chunk = find_chunk(cpos)) { - chunk->set_voxel(voxel, lpos); - - VoxelSetEvent event; - event.dimension = this; - event.cpos = cpos; - event.lpos = lpos; - event.voxel = voxel; - event.chunk = chunk; - - globals::dispatcher.trigger(event); - - return true; - } - - return false; -} - -bool world::Dimension::set_voxel(voxel_id 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; -} +#include "shared/pch.hh" + +#include "shared/world/dimension.hh" + +#include "shared/world/chunk.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(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(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(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(chunk->get_entity()); + m_chunkmap.erase(component.cpos); + chunks.destroy(chunk->get_entity()); + } +} + +voxel_id 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); + } + else { + return NULL_VOXEL_ID; + } +} + +voxel_id 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(voxel_id voxel, const voxel_pos& vpos) +{ + auto cpos = coord::to_chunk(vpos); + auto lpos = coord::to_local(vpos); + + if(auto chunk = find_chunk(cpos)) { + chunk->set_voxel(voxel, lpos); + + VoxelSetEvent event; + event.dimension = this; + event.cpos = cpos; + event.lpos = lpos; + event.voxel = voxel; + event.chunk = chunk; + + globals::dispatcher.trigger(event); + + return true; + } + + return false; +} + +bool world::Dimension::set_voxel(voxel_id 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; +} diff --git a/game/shared/world/dimension.hh b/game/shared/world/dimension.hh index 8b6691d..bf9bfe1 100644 --- a/game/shared/world/dimension.hh +++ b/game/shared/world/dimension.hh @@ -1,100 +1,100 @@ -#pragma once - -#include "shared/const.hh" -#include "shared/types.hh" - -namespace io -{ -class ConfigMap; -} // namespace io - -namespace world -{ -class Chunk; -class VoxelStorage; -} // namespace world - -namespace world -{ -using dimension_entropy_map = std::array; -using dimension_height_map = std::array; -} // namespace world - -namespace world -{ -class Dimension { -public: - explicit Dimension(std::string_view name, float gravity); - virtual ~Dimension(void); - - std::string_view get_name(void) const; - float get_gravity(void) const; - -public: - Chunk* create_chunk(const chunk_pos& cpos); - Chunk* find_chunk(entt::entity entity) const; - Chunk* find_chunk(const chunk_pos& cpos) const; - - void remove_chunk(entt::entity entity); - void remove_chunk(const chunk_pos& cpos); - void remove_chunk(Chunk* chunk); - -public: - voxel_id get_voxel(const voxel_pos& vpos) const; - voxel_id get_voxel(const chunk_pos& cpos, const local_pos& lpos) const; - - bool set_voxel(voxel_id voxel, const voxel_pos& vpos); - bool set_voxel(voxel_id voxel, const chunk_pos& cpos, const local_pos& lpos); - -public: - virtual void init(io::ConfigMap& config); - virtual void init_late(std::uint64_t global_seed); - virtual bool generate(const chunk_pos& cpos, VoxelStorage& voxels); - -public: - entt::registry chunks; - entt::registry entities; - -private: - std::string m_name; - emhash8::HashMap m_chunkmap; - float m_gravity; -}; -} // namespace world - -namespace world -{ -struct ChunkComponent final { - chunk_pos cpos; - Chunk* chunk; -}; -} // namespace world - -namespace world -{ -struct ChunkCreateEvent final { - Dimension* dimension; - chunk_pos cpos; - Chunk* chunk; -}; - -struct ChunkDestroyEvent final { - Dimension* dimension; - chunk_pos cpos; - Chunk* chunk; -}; - -struct ChunkUpdateEvent final { - Dimension* dimension; - chunk_pos cpos; - Chunk* chunk; -}; - -struct VoxelSetEvent final { - Dimension* dimension; - chunk_pos cpos; - local_pos lpos; - voxel_id voxel; - Chunk* chunk; -}; -} // namespace world +#pragma once + +#include "shared/const.hh" +#include "shared/types.hh" + +namespace io +{ +class ConfigMap; +} // namespace io + +namespace world +{ +class Chunk; +class VoxelStorage; +} // namespace world + +namespace world +{ +using dimension_entropy_map = std::array; +using dimension_height_map = std::array; +} // namespace world + +namespace world +{ +class Dimension { +public: + explicit Dimension(std::string_view name, float gravity); + virtual ~Dimension(void); + + std::string_view get_name(void) const; + float get_gravity(void) const; + +public: + Chunk* create_chunk(const chunk_pos& cpos); + Chunk* find_chunk(entt::entity entity) const; + Chunk* find_chunk(const chunk_pos& cpos) const; + + void remove_chunk(entt::entity entity); + void remove_chunk(const chunk_pos& cpos); + void remove_chunk(Chunk* chunk); + +public: + voxel_id get_voxel(const voxel_pos& vpos) const; + voxel_id get_voxel(const chunk_pos& cpos, const local_pos& lpos) const; + + bool set_voxel(voxel_id voxel, const voxel_pos& vpos); + bool set_voxel(voxel_id voxel, const chunk_pos& cpos, const local_pos& lpos); + +public: + virtual void init(io::ConfigMap& config); + virtual void init_late(std::uint64_t global_seed); + virtual bool generate(const chunk_pos& cpos, VoxelStorage& voxels); + +public: + entt::registry chunks; + entt::registry entities; + +private: + std::string m_name; + emhash8::HashMap m_chunkmap; + float m_gravity; +}; +} // namespace world + +namespace world +{ +struct ChunkComponent final { + chunk_pos cpos; + Chunk* chunk; +}; +} // namespace world + +namespace world +{ +struct ChunkCreateEvent final { + Dimension* dimension; + chunk_pos cpos; + Chunk* chunk; +}; + +struct ChunkDestroyEvent final { + Dimension* dimension; + chunk_pos cpos; + Chunk* chunk; +}; + +struct ChunkUpdateEvent final { + Dimension* dimension; + chunk_pos cpos; + Chunk* chunk; +}; + +struct VoxelSetEvent final { + Dimension* dimension; + chunk_pos cpos; + local_pos lpos; + voxel_id voxel; + Chunk* chunk; +}; +} // namespace world diff --git a/game/shared/world/feature.cc b/game/shared/world/feature.cc index cbdc183..4212043 100644 --- a/game/shared/world/feature.cc +++ b/game/shared/world/feature.cc @@ -1,53 +1,53 @@ -#include "shared/pch.hh" - -#include "shared/world/feature.hh" - -#include "shared/world/chunk.hh" -#include "shared/world/dimension.hh" -#include "shared/world/voxel_storage.hh" - -#include "shared/coord.hh" - -void world::Feature::place(const voxel_pos& vpos, Dimension* dimension) const -{ - for(const auto [rpos, voxel, overwrite] : (*this)) { - auto it_vpos = vpos + rpos; - auto it_cpos = coord::to_chunk(it_vpos); - - if(auto chunk = dimension->create_chunk(it_cpos)) { - auto it_lpos = coord::to_local(it_vpos); - auto it_index = coord::to_index(it_lpos); - - if(chunk->get_voxel(it_index) && !overwrite) { - // There is something in the way - // and the called intentionally requested - // we do not force feature to overwrite voxels - continue; - } - - chunk->set_voxel(voxel, it_index); - } - } -} - -void world::Feature::place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const -{ - for(const auto [rpos, voxel, overwrite] : (*this)) { - auto it_vpos = vpos + rpos; - auto it_cpos = coord::to_chunk(it_vpos); - - if(it_cpos == cpos) { - auto it_lpos = coord::to_local(it_vpos); - auto it_index = coord::to_index(it_lpos); - - if(voxels[it_index] && !overwrite) { - // There is something in the way - // and the called intentionally requested - // we do not force feature to overwrite voxels - continue; - } - - voxels[it_index] = voxel; - } - } -} +#include "shared/pch.hh" + +#include "shared/world/feature.hh" + +#include "shared/world/chunk.hh" +#include "shared/world/dimension.hh" +#include "shared/world/voxel_storage.hh" + +#include "shared/coord.hh" + +void world::Feature::place(const voxel_pos& vpos, Dimension* dimension) const +{ + for(const auto [rpos, voxel, overwrite] : (*this)) { + auto it_vpos = vpos + rpos; + auto it_cpos = coord::to_chunk(it_vpos); + + if(auto chunk = dimension->create_chunk(it_cpos)) { + auto it_lpos = coord::to_local(it_vpos); + auto it_index = coord::to_index(it_lpos); + + if(chunk->get_voxel(it_index) && !overwrite) { + // There is something in the way + // and the called intentionally requested + // we do not force feature to overwrite voxels + continue; + } + + chunk->set_voxel(voxel, it_index); + } + } +} + +void world::Feature::place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const +{ + for(const auto [rpos, voxel, overwrite] : (*this)) { + auto it_vpos = vpos + rpos; + auto it_cpos = coord::to_chunk(it_vpos); + + if(it_cpos == cpos) { + auto it_lpos = coord::to_local(it_vpos); + auto it_index = coord::to_index(it_lpos); + + if(voxels[it_index] && !overwrite) { + // There is something in the way + // and the called intentionally requested + // we do not force feature to overwrite voxels + continue; + } + + voxels[it_index] = voxel; + } + } +} diff --git a/game/shared/world/feature.hh b/game/shared/world/feature.hh index 5008223..20a809b 100644 --- a/game/shared/world/feature.hh +++ b/game/shared/world/feature.hh @@ -1,22 +1,22 @@ -#pragma once - -#include "shared/types.hh" - -namespace world -{ -class Dimension; -class VoxelStorage; -} // namespace world - -namespace world -{ -class Feature final : public std::vector> { -public: - Feature(void) = default; - virtual ~Feature(void) = default; - -public: - void place(const voxel_pos& vpos, Dimension* dimension) const; - void place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const; -}; -} // namespace world +#pragma once + +#include "shared/types.hh" + +namespace world +{ +class Dimension; +class VoxelStorage; +} // namespace world + +namespace world +{ +class Feature final : public std::vector> { +public: + Feature(void) = default; + virtual ~Feature(void) = default; + +public: + void place(const voxel_pos& vpos, Dimension* dimension) const; + void place(const voxel_pos& vpos, const chunk_pos& cpos, VoxelStorage& voxels) const; +}; +} // namespace world diff --git a/game/shared/world/item_registry.cc b/game/shared/world/item_registry.cc index e0d30cc..d1b9ff4 100644 --- a/game/shared/world/item_registry.cc +++ b/game/shared/world/item_registry.cc @@ -1,106 +1,106 @@ -#include "shared/pch.hh" - -#include "shared/world/item_registry.hh" - -#include "core/math/crc64.hh" - -#include "shared/world/voxel_registry.hh" - -std::unordered_map world::item_registry::builders = {}; -std::unordered_map world::item_registry::names = {}; -std::vector> world::item_registry::items = {}; - -world::ItemInfoBuilder::ItemInfoBuilder(std::string_view name) -{ - prototype.name = name; - prototype.texture = std::string(); - prototype.place_voxel = NULL_VOXEL_ID; - prototype.cached_texture = nullptr; -} - -world::ItemInfoBuilder& world::ItemInfoBuilder::set_texture(std::string_view texture) -{ - prototype.texture = texture; - prototype.cached_texture = nullptr; - return *this; -} - -world::ItemInfoBuilder& world::ItemInfoBuilder::set_place_voxel(voxel_id place_voxel) -{ - prototype.place_voxel = place_voxel; - return *this; -} - -item_id world::ItemInfoBuilder::build(void) const -{ - const auto it = world::item_registry::names.find(prototype.name); - - if(it != world::item_registry::names.cend()) { - spdlog::warn("item_registry: cannot build {}: name already present", prototype.name); - return it->second; - } - - auto new_info = std::make_shared(); - new_info->name = prototype.name; - new_info->texture = prototype.texture; - new_info->place_voxel = prototype.place_voxel; - new_info->cached_texture = nullptr; - - world::item_registry::items.push_back(new_info); - world::item_registry::names.insert_or_assign(prototype.name, static_cast(world::item_registry::items.size())); - - return static_cast(world::item_registry::items.size()); -} - -world::ItemInfoBuilder& world::item_registry::construct(std::string_view name) -{ - const auto it = world::item_registry::builders.find(std::string(name)); - - if(it != world::item_registry::builders.cend()) { - return it->second; - } - else { - return world::item_registry::builders.emplace(std::string(name), ItemInfoBuilder(name)).first->second; - } -} - -world::ItemInfo* world::item_registry::find(std::string_view name) -{ - const auto it = world::item_registry::names.find(std::string(name)); - - if(it != world::item_registry::names.cend()) { - return world::item_registry::find(it->second); - } - else { - return nullptr; - } -} - -world::ItemInfo* world::item_registry::find(const item_id item) -{ - if((item != NULL_ITEM_ID) && (item <= world::item_registry::items.size())) { - return world::item_registry::items[item - 1].get(); - } - else { - return nullptr; - } -} - -void world::item_registry::purge(void) -{ - world::item_registry::builders.clear(); - world::item_registry::names.clear(); - world::item_registry::items.clear(); -} - -std::uint64_t world::item_registry::calculate_checksum(void) -{ - std::uint64_t result = 0; - - for(const auto& info : world::item_registry::items) { - result = math::crc64(info->name, result); - result += static_cast(info->place_voxel); - } - - return result; -} +#include "shared/pch.hh" + +#include "shared/world/item_registry.hh" + +#include "core/math/crc64.hh" + +#include "shared/world/voxel_registry.hh" + +std::unordered_map world::item_registry::builders = {}; +std::unordered_map world::item_registry::names = {}; +std::vector> world::item_registry::items = {}; + +world::ItemInfoBuilder::ItemInfoBuilder(std::string_view name) +{ + prototype.name = name; + prototype.texture = std::string(); + prototype.place_voxel = NULL_VOXEL_ID; + prototype.cached_texture = nullptr; +} + +world::ItemInfoBuilder& world::ItemInfoBuilder::set_texture(std::string_view texture) +{ + prototype.texture = texture; + prototype.cached_texture = nullptr; + return *this; +} + +world::ItemInfoBuilder& world::ItemInfoBuilder::set_place_voxel(voxel_id place_voxel) +{ + prototype.place_voxel = place_voxel; + return *this; +} + +item_id world::ItemInfoBuilder::build(void) const +{ + const auto it = world::item_registry::names.find(prototype.name); + + if(it != world::item_registry::names.cend()) { + spdlog::warn("item_registry: cannot build {}: name already present", prototype.name); + return it->second; + } + + auto new_info = std::make_shared(); + new_info->name = prototype.name; + new_info->texture = prototype.texture; + new_info->place_voxel = prototype.place_voxel; + new_info->cached_texture = nullptr; + + world::item_registry::items.push_back(new_info); + world::item_registry::names.insert_or_assign(prototype.name, static_cast(world::item_registry::items.size())); + + return static_cast(world::item_registry::items.size()); +} + +world::ItemInfoBuilder& world::item_registry::construct(std::string_view name) +{ + const auto it = world::item_registry::builders.find(std::string(name)); + + if(it != world::item_registry::builders.cend()) { + return it->second; + } + else { + return world::item_registry::builders.emplace(std::string(name), ItemInfoBuilder(name)).first->second; + } +} + +world::ItemInfo* world::item_registry::find(std::string_view name) +{ + const auto it = world::item_registry::names.find(std::string(name)); + + if(it != world::item_registry::names.cend()) { + return world::item_registry::find(it->second); + } + else { + return nullptr; + } +} + +world::ItemInfo* world::item_registry::find(const item_id item) +{ + if((item != NULL_ITEM_ID) && (item <= world::item_registry::items.size())) { + return world::item_registry::items[item - 1].get(); + } + else { + return nullptr; + } +} + +void world::item_registry::purge(void) +{ + world::item_registry::builders.clear(); + world::item_registry::names.clear(); + world::item_registry::items.clear(); +} + +std::uint64_t world::item_registry::calculate_checksum(void) +{ + std::uint64_t result = 0; + + for(const auto& info : world::item_registry::items) { + result = math::crc64(info->name, result); + result += static_cast(info->place_voxel); + } + + return result; +} diff --git a/game/shared/world/item_registry.hh b/game/shared/world/item_registry.hh index 74bd60a..c3e6cf9 100644 --- a/game/shared/world/item_registry.hh +++ b/game/shared/world/item_registry.hh @@ -1,64 +1,64 @@ -#pragma once - -#include "core/resource/resource.hh" - -#include "shared/types.hh" - -// This resource is only defined client-side and -// resource_ptr should remain set to null -// anywhere else in the shared and server code -struct TextureGUI; - -namespace world -{ -struct ItemInfo final { - std::string name; - std::string texture; - voxel_id place_voxel; - - resource_ptr cached_texture; // Client-side only -}; -} // namespace world - -namespace world -{ -class ItemInfoBuilder final { -public: - explicit ItemInfoBuilder(std::string_view name); - virtual ~ItemInfoBuilder(void) = default; - -public: - ItemInfoBuilder& set_texture(std::string_view texture); - ItemInfoBuilder& set_place_voxel(voxel_id place_voxel); - -public: - item_id build(void) const; - -private: - ItemInfo prototype; -}; -} // namespace world - -namespace world::item_registry -{ -extern std::unordered_map builders; -extern std::unordered_map names; -extern std::vector> items; -} // namespace world::item_registry - -namespace world::item_registry -{ -ItemInfoBuilder& construct(std::string_view name); -ItemInfo* find(std::string_view name); -ItemInfo* find(const item_id item); -} // namespace world::item_registry - -namespace world::item_registry -{ -void purge(void); -} // namespace world::item_registry - -namespace world::item_registry -{ -std::uint64_t calculate_checksum(void); -} // namespace world::item_registry +#pragma once + +#include "core/resource/resource.hh" + +#include "shared/types.hh" + +// This resource is only defined client-side and +// resource_ptr should remain set to null +// anywhere else in the shared and server code +struct TextureGUI; + +namespace world +{ +struct ItemInfo final { + std::string name; + std::string texture; + voxel_id place_voxel; + + resource_ptr cached_texture; // Client-side only +}; +} // namespace world + +namespace world +{ +class ItemInfoBuilder final { +public: + explicit ItemInfoBuilder(std::string_view name); + virtual ~ItemInfoBuilder(void) = default; + +public: + ItemInfoBuilder& set_texture(std::string_view texture); + ItemInfoBuilder& set_place_voxel(voxel_id place_voxel); + +public: + item_id build(void) const; + +private: + ItemInfo prototype; +}; +} // namespace world + +namespace world::item_registry +{ +extern std::unordered_map builders; +extern std::unordered_map names; +extern std::vector> items; +} // namespace world::item_registry + +namespace world::item_registry +{ +ItemInfoBuilder& construct(std::string_view name); +ItemInfo* find(std::string_view name); +ItemInfo* find(const item_id item); +} // namespace world::item_registry + +namespace world::item_registry +{ +void purge(void); +} // namespace world::item_registry + +namespace world::item_registry +{ +std::uint64_t calculate_checksum(void); +} // namespace world::item_registry diff --git a/game/shared/world/ray_dda.cc b/game/shared/world/ray_dda.cc index 9f85e6b..b337e9d 100644 --- a/game/shared/world/ray_dda.cc +++ b/game/shared/world/ray_dda.cc @@ -1,107 +1,107 @@ -#include "shared/pch.hh" - -#include "shared/world/ray_dda.hh" - -#include "shared/world/dimension.hh" - -#include "shared/coord.hh" - -world::RayDDA::RayDDA( - const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction) -{ - reset(dimension, start_chunk, start_fpos, direction); -} - -world::RayDDA::RayDDA( - const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction) -{ - reset(dimension, start_chunk, start_fpos, direction); -} - -void world::RayDDA::reset( - const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction) -{ - this->dimension = dimension; - this->start_chunk = start_chunk; - this->start_fpos = start_fpos; - this->direction = direction; - - this->delta_dist.x = direction.x ? math::abs(1.0f / direction.x) : std::numeric_limits::max(); - this->delta_dist.y = direction.y ? math::abs(1.0f / direction.y) : std::numeric_limits::max(); - this->delta_dist.z = direction.z ? math::abs(1.0f / direction.z) : std::numeric_limits::max(); - - this->distance = 0.0f; - this->vpos = coord::to_voxel(start_chunk, start_fpos); - this->vnormal = voxel_pos(0, 0, 0); - - // Need this for initial direction calculations - auto lpos = coord::to_local(start_fpos); - - if(direction.x < 0.0f) { - this->side_dist.x = this->delta_dist.x * (start_fpos.x - lpos.x); - this->vstep.x = voxel_pos::value_type(-1); - } - else { - this->side_dist.x = this->delta_dist.x * (lpos.x + 1.0f - start_fpos.x); - this->vstep.x = voxel_pos::value_type(+1); - } - - if(direction.y < 0.0f) { - this->side_dist.y = this->delta_dist.y * (start_fpos.y - lpos.y); - this->vstep.y = voxel_pos::value_type(-1); - } - else { - this->side_dist.y = this->delta_dist.y * (lpos.y + 1.0f - start_fpos.y); - this->vstep.y = voxel_pos::value_type(+1); - } - - if(direction.z < 0.0f) { - this->side_dist.z = this->delta_dist.z * (start_fpos.z - lpos.z); - this->vstep.z = voxel_pos::value_type(-1); - } - else { - this->side_dist.z = this->delta_dist.z * (lpos.z + 1.0f - start_fpos.z); - this->vstep.z = voxel_pos::value_type(+1); - } -} - -void world::RayDDA::reset( - const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction) -{ - reset(&dimension, start_chunk, start_fpos, direction); -} - -voxel_id world::RayDDA::step(void) -{ - if(side_dist.x < side_dist.z) { - if(side_dist.x < side_dist.y) { - vnormal = voxel_pos(-vstep.x, 0, 0); - distance = side_dist.x; - side_dist.x += delta_dist.x; - vpos.x += vstep.x; - } - else { - vnormal = voxel_pos(0, -vstep.y, 0); - distance = side_dist.y; - side_dist.y += delta_dist.y; - vpos.y += vstep.y; - } - } - else { - if(side_dist.z < side_dist.y) { - vnormal = voxel_pos(0, 0, -vstep.z); - distance = side_dist.z; - side_dist.z += delta_dist.z; - vpos.z += vstep.z; - } - else { - vnormal = voxel_pos(0, -vstep.y, 0); - distance = side_dist.y; - side_dist.y += delta_dist.y; - vpos.y += vstep.y; - } - } - - // This is slower than I want it to be - return dimension->get_voxel(vpos); -} +#include "shared/pch.hh" + +#include "shared/world/ray_dda.hh" + +#include "shared/world/dimension.hh" + +#include "shared/coord.hh" + +world::RayDDA::RayDDA(const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, + const glm::fvec3& direction) +{ + reset(dimension, start_chunk, start_fpos, direction); +} + +world::RayDDA::RayDDA(const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, + const glm::fvec3& direction) +{ + reset(dimension, start_chunk, start_fpos, direction); +} + +void world::RayDDA::reset(const world::Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, + const glm::fvec3& direction) +{ + this->dimension = dimension; + this->start_chunk = start_chunk; + this->start_fpos = start_fpos; + this->direction = direction; + + this->delta_dist.x = direction.x ? math::abs(1.0f / direction.x) : std::numeric_limits::max(); + this->delta_dist.y = direction.y ? math::abs(1.0f / direction.y) : std::numeric_limits::max(); + this->delta_dist.z = direction.z ? math::abs(1.0f / direction.z) : std::numeric_limits::max(); + + this->distance = 0.0f; + this->vpos = coord::to_voxel(start_chunk, start_fpos); + this->vnormal = voxel_pos(0, 0, 0); + + // Need this for initial direction calculations + auto lpos = coord::to_local(start_fpos); + + if(direction.x < 0.0f) { + this->side_dist.x = this->delta_dist.x * (start_fpos.x - lpos.x); + this->vstep.x = voxel_pos::value_type(-1); + } + else { + this->side_dist.x = this->delta_dist.x * (lpos.x + 1.0f - start_fpos.x); + this->vstep.x = voxel_pos::value_type(+1); + } + + if(direction.y < 0.0f) { + this->side_dist.y = this->delta_dist.y * (start_fpos.y - lpos.y); + this->vstep.y = voxel_pos::value_type(-1); + } + else { + this->side_dist.y = this->delta_dist.y * (lpos.y + 1.0f - start_fpos.y); + this->vstep.y = voxel_pos::value_type(+1); + } + + if(direction.z < 0.0f) { + this->side_dist.z = this->delta_dist.z * (start_fpos.z - lpos.z); + this->vstep.z = voxel_pos::value_type(-1); + } + else { + this->side_dist.z = this->delta_dist.z * (lpos.z + 1.0f - start_fpos.z); + this->vstep.z = voxel_pos::value_type(+1); + } +} + +void world::RayDDA::reset(const world::Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, + const glm::fvec3& direction) +{ + reset(&dimension, start_chunk, start_fpos, direction); +} + +voxel_id world::RayDDA::step(void) +{ + if(side_dist.x < side_dist.z) { + if(side_dist.x < side_dist.y) { + vnormal = voxel_pos(-vstep.x, 0, 0); + distance = side_dist.x; + side_dist.x += delta_dist.x; + vpos.x += vstep.x; + } + else { + vnormal = voxel_pos(0, -vstep.y, 0); + distance = side_dist.y; + side_dist.y += delta_dist.y; + vpos.y += vstep.y; + } + } + else { + if(side_dist.z < side_dist.y) { + vnormal = voxel_pos(0, 0, -vstep.z); + distance = side_dist.z; + side_dist.z += delta_dist.z; + vpos.z += vstep.z; + } + else { + vnormal = voxel_pos(0, -vstep.y, 0); + distance = side_dist.y; + side_dist.y += delta_dist.y; + vpos.y += vstep.y; + } + } + + // This is slower than I want it to be + return dimension->get_voxel(vpos); +} diff --git a/game/shared/world/ray_dda.hh b/game/shared/world/ray_dda.hh index 927c74d..54bd48a 100644 --- a/game/shared/world/ray_dda.hh +++ b/game/shared/world/ray_dda.hh @@ -1,41 +1,41 @@ -#ifndef SHARED_RAY_DDA -#define SHARED_RAY_DDA 1 -#pragma once - -#include "shared/types.hh" - -namespace world -{ -class Dimension; -} // namespace world - -namespace world -{ -class RayDDA final { -public: - RayDDA(void) = default; - explicit RayDDA(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); - explicit RayDDA(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); - - void reset(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); - void reset(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); - - voxel_id step(void); - -public: - const Dimension* dimension; - chunk_pos start_chunk; - glm::fvec3 start_fpos; - glm::fvec3 direction; - - glm::fvec3 delta_dist; - glm::fvec3 side_dist; - voxel_pos vstep; - - double distance; - voxel_pos vnormal; - voxel_pos vpos; -}; -} // namespace world - -#endif // SHARED_RAY_DDA +#ifndef SHARED_RAY_DDA +#define SHARED_RAY_DDA 1 +#pragma once + +#include "shared/types.hh" + +namespace world +{ +class Dimension; +} // namespace world + +namespace world +{ +class RayDDA final { +public: + RayDDA(void) = default; + explicit RayDDA(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); + explicit RayDDA(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); + + void reset(const Dimension* dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); + void reset(const Dimension& dimension, const chunk_pos& start_chunk, const glm::fvec3& start_fpos, const glm::fvec3& direction); + + voxel_id step(void); + +public: + const Dimension* dimension; + chunk_pos start_chunk; + glm::fvec3 start_fpos; + glm::fvec3 direction; + + glm::fvec3 delta_dist; + glm::fvec3 side_dist; + voxel_pos vstep; + + double distance; + voxel_pos vnormal; + voxel_pos vpos; +}; +} // namespace world + +#endif // SHARED_RAY_DDA diff --git a/game/shared/world/voxel_registry.cc b/game/shared/world/voxel_registry.cc index 46737d6..b44845e 100644 --- a/game/shared/world/voxel_registry.cc +++ b/game/shared/world/voxel_registry.cc @@ -1,196 +1,196 @@ -#include "shared/pch.hh" - -#include "shared/world/voxel_registry.hh" - -#include "core/math/crc64.hh" - -std::unordered_map world::voxel_registry::builders = {}; -std::unordered_map world::voxel_registry::names = {}; -std::vector> world::voxel_registry::voxels = {}; - -world::VoxelInfoBuilder::VoxelInfoBuilder(std::string_view name, voxel_type type, bool animated, bool blending) -{ - prototype.name = name; - prototype.type = type; - prototype.animated = animated; - prototype.blending = blending; - - switch(type) { - case voxel_type::CUBE: - prototype.textures.resize(static_cast(voxel_face::CUBE__NR)); - break; - case voxel_type::CROSS: - prototype.textures.resize(static_cast(voxel_face::CROSS__NR)); - break; - case voxel_type::MODEL: - // Custom models should use a different texture - // resource management that is not a voxel atlas - // TODO: actually implement custom models lol - prototype.textures.resize(0); - break; - default: - // Something really bad should happen if we end up here. - // The outside code would static_cast an int to VoxelType - // and possibly fuck a lot of things up to cause this - spdlog::critical("voxel_registry: {}: unknown voxel type {}", name, static_cast(type)); - std::terminate(); - } - - // Physics properties - prototype.touch_type = voxel_touch::SOLID; - prototype.touch_values = glm::fvec3(0.0f, 0.0f, 0.0f); - prototype.surface = voxel_surface::DEFAULT; - - // Things set in future by item_def - prototype.item_pick = NULL_ITEM_ID; -} - -world::VoxelInfoBuilder& world::VoxelInfoBuilder::add_texture_default(std::string_view texture) -{ - default_texture.paths.push_back(std::string(texture)); - return *this; -} - -world::VoxelInfoBuilder& world::VoxelInfoBuilder::add_texture(voxel_face face, std::string_view texture) -{ - const auto index = static_cast(face); - prototype.textures[index].paths.push_back(std::string(texture)); - return *this; -} - -world::VoxelInfoBuilder& world::VoxelInfoBuilder::set_touch(voxel_touch type, const glm::fvec3& values) -{ - prototype.touch_type = type; - prototype.touch_values = values; - return *this; -} - -world::VoxelInfoBuilder& world::VoxelInfoBuilder::set_surface(voxel_surface surface) -{ - prototype.surface = surface; - return *this; -} - -voxel_id world::VoxelInfoBuilder::build(void) const -{ - const auto it = world::voxel_registry::names.find(prototype.name); - - if(it != world::voxel_registry::names.cend()) { - spdlog::warn("voxel_registry: cannot build {}: name already present", prototype.name); - return it->second; - } - - std::size_t state_count; - - switch(prototype.type) { - case voxel_type::CUBE: - case voxel_type::CROSS: - case voxel_type::MODEL: - state_count = 1; - break; - default: - // Something really bad should happen if we end up here. - // The outside code would static_cast an int to VoxelType - // and possibly fuck a lot of things up to cause this - spdlog::critical("voxel_registry: {}: unknown voxel type {}", prototype.name, static_cast(prototype.type)); - std::terminate(); - } - - if((world::voxel_registry::voxels.size() + state_count) >= MAX_VOXEL_ID) { - spdlog::critical("voxel_registry: voxel registry overflow"); - std::terminate(); - } - - auto new_info = std::make_shared(); - new_info->name = prototype.name; - new_info->type = prototype.type; - new_info->animated = prototype.animated; - new_info->blending = prototype.blending; - - new_info->textures.resize(prototype.textures.size()); - - for(std::size_t i = 0; i < prototype.textures.size(); ++i) { - if(prototype.textures[i].paths.empty()) { - new_info->textures[i].paths = default_texture.paths; - new_info->textures[i].cached_offset = SIZE_MAX; - new_info->textures[i].cached_plane = SIZE_MAX; - } - else { - new_info->textures[i].paths = prototype.textures[i].paths; - new_info->textures[i].cached_offset = SIZE_MAX; - new_info->textures[i].cached_plane = SIZE_MAX; - } - } - - // Physics properties - new_info->touch_type = prototype.touch_type; - new_info->touch_values = prototype.touch_values; - new_info->surface = prototype.surface; - - // Things set in future by item_def - new_info->item_pick = prototype.item_pick; - - // Base voxel identifier offset - new_info->base_voxel = world::voxel_registry::voxels.size() + 1; - - for(std::size_t i = 0; i < state_count; ++i) - world::voxel_registry::voxels.push_back(new_info); - world::voxel_registry::names.insert_or_assign(new_info->name, new_info->base_voxel); - - return new_info->base_voxel; -} - -world::VoxelInfoBuilder& world::voxel_registry::construct(std::string_view name, voxel_type type, bool animated, bool blending) -{ - const auto it = world::voxel_registry::builders.find(std::string(name)); - - if(it != world::voxel_registry::builders.cend()) { - return it->second; - } - else { - return world::voxel_registry::builders.emplace(std::string(name), VoxelInfoBuilder(name, type, animated, blending)).first->second; - } -} - -world::VoxelInfo* world::voxel_registry::find(std::string_view name) -{ - const auto it = world::voxel_registry::names.find(std::string(name)); - - if(it != world::voxel_registry::names.cend()) { - return world::voxel_registry::find(it->second); - } - else { - return nullptr; - } -} - -world::VoxelInfo* world::voxel_registry::find(const voxel_id voxel) -{ - if((voxel != NULL_VOXEL_ID) && (voxel <= world::voxel_registry::voxels.size())) { - return world::voxel_registry::voxels[voxel - 1].get(); - } - else { - return nullptr; - } -} - -void world::voxel_registry::purge(void) -{ - world::voxel_registry::builders.clear(); - world::voxel_registry::names.clear(); - world::voxel_registry::voxels.clear(); -} - -std::uint64_t world::voxel_registry::calculate_checksum(void) -{ - std::uint64_t result = 0; - - for(const std::shared_ptr& info : world::voxel_registry::voxels) { - result = math::crc64(info->name, result); - result += static_cast(info->type); - result += static_cast(info->base_voxel); - result += info->blending ? 256 : 1; - } - - return result; -} +#include "shared/pch.hh" + +#include "shared/world/voxel_registry.hh" + +#include "core/math/crc64.hh" + +std::unordered_map world::voxel_registry::builders = {}; +std::unordered_map world::voxel_registry::names = {}; +std::vector> world::voxel_registry::voxels = {}; + +world::VoxelInfoBuilder::VoxelInfoBuilder(std::string_view name, voxel_type type, bool animated, bool blending) +{ + prototype.name = name; + prototype.type = type; + prototype.animated = animated; + prototype.blending = blending; + + switch(type) { + case voxel_type::CUBE: + prototype.textures.resize(static_cast(voxel_face::CUBE__NR)); + break; + case voxel_type::CROSS: + prototype.textures.resize(static_cast(voxel_face::CROSS__NR)); + break; + case voxel_type::MODEL: + // Custom models should use a different texture + // resource management that is not a voxel atlas + // TODO: actually implement custom models lol + prototype.textures.resize(0); + break; + default: + // Something really bad should happen if we end up here. + // The outside code would static_cast an int to VoxelType + // and possibly fuck a lot of things up to cause this + spdlog::critical("voxel_registry: {}: unknown voxel type {}", name, static_cast(type)); + std::terminate(); + } + + // Physics properties + prototype.touch_type = voxel_touch::SOLID; + prototype.touch_values = glm::fvec3(0.0f, 0.0f, 0.0f); + prototype.surface = voxel_surface::DEFAULT; + + // Things set in future by item_def + prototype.item_pick = NULL_ITEM_ID; +} + +world::VoxelInfoBuilder& world::VoxelInfoBuilder::add_texture_default(std::string_view texture) +{ + default_texture.paths.push_back(std::string(texture)); + return *this; +} + +world::VoxelInfoBuilder& world::VoxelInfoBuilder::add_texture(voxel_face face, std::string_view texture) +{ + const auto index = static_cast(face); + prototype.textures[index].paths.push_back(std::string(texture)); + return *this; +} + +world::VoxelInfoBuilder& world::VoxelInfoBuilder::set_touch(voxel_touch type, const glm::fvec3& values) +{ + prototype.touch_type = type; + prototype.touch_values = values; + return *this; +} + +world::VoxelInfoBuilder& world::VoxelInfoBuilder::set_surface(voxel_surface surface) +{ + prototype.surface = surface; + return *this; +} + +voxel_id world::VoxelInfoBuilder::build(void) const +{ + const auto it = world::voxel_registry::names.find(prototype.name); + + if(it != world::voxel_registry::names.cend()) { + spdlog::warn("voxel_registry: cannot build {}: name already present", prototype.name); + return it->second; + } + + std::size_t state_count; + + switch(prototype.type) { + case voxel_type::CUBE: + case voxel_type::CROSS: + case voxel_type::MODEL: + state_count = 1; + break; + default: + // Something really bad should happen if we end up here. + // The outside code would static_cast an int to VoxelType + // and possibly fuck a lot of things up to cause this + spdlog::critical("voxel_registry: {}: unknown voxel type {}", prototype.name, static_cast(prototype.type)); + std::terminate(); + } + + if((world::voxel_registry::voxels.size() + state_count) >= MAX_VOXEL_ID) { + spdlog::critical("voxel_registry: voxel registry overflow"); + std::terminate(); + } + + auto new_info = std::make_shared(); + new_info->name = prototype.name; + new_info->type = prototype.type; + new_info->animated = prototype.animated; + new_info->blending = prototype.blending; + + new_info->textures.resize(prototype.textures.size()); + + for(std::size_t i = 0; i < prototype.textures.size(); ++i) { + if(prototype.textures[i].paths.empty()) { + new_info->textures[i].paths = default_texture.paths; + new_info->textures[i].cached_offset = SIZE_MAX; + new_info->textures[i].cached_plane = SIZE_MAX; + } + else { + new_info->textures[i].paths = prototype.textures[i].paths; + new_info->textures[i].cached_offset = SIZE_MAX; + new_info->textures[i].cached_plane = SIZE_MAX; + } + } + + // Physics properties + new_info->touch_type = prototype.touch_type; + new_info->touch_values = prototype.touch_values; + new_info->surface = prototype.surface; + + // Things set in future by item_def + new_info->item_pick = prototype.item_pick; + + // Base voxel identifier offset + new_info->base_voxel = world::voxel_registry::voxels.size() + 1; + + for(std::size_t i = 0; i < state_count; ++i) + world::voxel_registry::voxels.push_back(new_info); + world::voxel_registry::names.insert_or_assign(new_info->name, new_info->base_voxel); + + return new_info->base_voxel; +} + +world::VoxelInfoBuilder& world::voxel_registry::construct(std::string_view name, voxel_type type, bool animated, bool blending) +{ + const auto it = world::voxel_registry::builders.find(std::string(name)); + + if(it != world::voxel_registry::builders.cend()) { + return it->second; + } + else { + return world::voxel_registry::builders.emplace(std::string(name), VoxelInfoBuilder(name, type, animated, blending)).first->second; + } +} + +world::VoxelInfo* world::voxel_registry::find(std::string_view name) +{ + const auto it = world::voxel_registry::names.find(std::string(name)); + + if(it != world::voxel_registry::names.cend()) { + return world::voxel_registry::find(it->second); + } + else { + return nullptr; + } +} + +world::VoxelInfo* world::voxel_registry::find(const voxel_id voxel) +{ + if((voxel != NULL_VOXEL_ID) && (voxel <= world::voxel_registry::voxels.size())) { + return world::voxel_registry::voxels[voxel - 1].get(); + } + else { + return nullptr; + } +} + +void world::voxel_registry::purge(void) +{ + world::voxel_registry::builders.clear(); + world::voxel_registry::names.clear(); + world::voxel_registry::voxels.clear(); +} + +std::uint64_t world::voxel_registry::calculate_checksum(void) +{ + std::uint64_t result = 0; + + for(const std::shared_ptr& info : world::voxel_registry::voxels) { + result = math::crc64(info->name, result); + result += static_cast(info->type); + result += static_cast(info->base_voxel); + result += info->blending ? 256 : 1; + } + + return result; +} diff --git a/game/shared/world/voxel_registry.hh b/game/shared/world/voxel_registry.hh index 6ab8c97..a75f59f 100644 --- a/game/shared/world/voxel_registry.hh +++ b/game/shared/world/voxel_registry.hh @@ -1,149 +1,149 @@ -#pragma once - -#include "shared/types.hh" - -namespace world -{ -enum class voxel_face : unsigned short { - CUBE_NORTH = 0x0000, - CUBE_SOUTH = 0x0001, - CUBE_EAST = 0x0002, - CUBE_WEST = 0x0003, - CUBE_TOP = 0x0004, - CUBE_BOTTOM = 0x0005, - CUBE__NR = 0x0006, - - CROSS_NESW = 0x0000, - CROSS_NWSE = 0x0001, - CROSS__NR = 0x0002, -}; - -enum class voxel_type : unsigned short { - CUBE = 0x0000, - CROSS = 0x0001, // TODO - MODEL = 0x0002, // TODO -}; - -enum class voxel_facing : unsigned short { - NORTH = 0x0000, - SOUTH = 0x0001, - EAST = 0x0002, - WEST = 0x0003, - UP = 0x0004, - DOWN = 0x0005, - NESW = 0x0006, - NWSE = 0x0007, -}; - -enum class voxel_touch : unsigned short { - SOLID = 0x0000, // The entity is stopped in its tracks - BOUNCE = 0x0001, // The entity bounces back with some energy loss - SINK = 0x0002, // The entity phases/sinks through the voxel - NOTHING = 0xFFFF, -}; - -enum class voxel_surface : unsigned short { - DEFAULT = 0x0000, - STONE = 0x0001, - DIRT = 0x0002, - GLASS = 0x0003, - GRASS = 0x0004, - GRAVEL = 0x0005, - METAL = 0x0006, - SAND = 0x0007, - WOOD = 0x0008, - SLOSH = 0x0009, - COUNT = 0x000A, - UNKNOWN = 0xFFFF, -}; - -using voxel_vis = unsigned short; -constexpr static voxel_vis VIS_NORTH = 1 << static_cast(voxel_facing::NORTH); -constexpr static voxel_vis VIS_SOUTH = 1 << static_cast(voxel_facing::SOUTH); -constexpr static voxel_vis VIS_EAST = 1 << static_cast(voxel_facing::EAST); -constexpr static voxel_vis VIS_WEST = 1 << static_cast(voxel_facing::WEST); -constexpr static voxel_vis VIS_UP = 1 << static_cast(voxel_facing::UP); -constexpr static voxel_vis VIS_DOWN = 1 << static_cast(voxel_facing::DOWN); -} // namespace world - -namespace world -{ -struct VoxelTexture final { - std::vector paths; - std::size_t cached_offset; // client-side only - std::size_t cached_plane; // client-side only -}; - -struct VoxelInfo final { - std::string name; - voxel_type type; - bool animated; - bool blending; - - std::vector textures; - - // Physics properties go here - // TODO: player_move friction modifiers - // that would make the voxel very sticky or - // very slippery to walk on - voxel_touch touch_type; - glm::fvec3 touch_values; - voxel_surface surface; - - // Some voxel types might occupy multiple voxel_id - // values that reference to the exact same VoxelInfo - // structure; the actual numeric state is figured out by - // subtracting base_voxel from the checking voxel_id - voxel_id base_voxel; - - // These will be set by item_registry - // and by default set to NULL_ITEM_ID - item_id item_pick; -}; -} // namespace world - -namespace world -{ -class VoxelInfoBuilder final { -public: - explicit VoxelInfoBuilder(std::string_view name, voxel_type type, bool animated, bool blending); - virtual ~VoxelInfoBuilder(void) = default; - -public: - VoxelInfoBuilder& add_texture_default(std::string_view texture); - VoxelInfoBuilder& add_texture(voxel_face face, std::string_view texture); - VoxelInfoBuilder& set_touch(voxel_touch type, const glm::fvec3& values); - VoxelInfoBuilder& set_surface(voxel_surface surface); - -public: - voxel_id build(void) const; - -private: - VoxelTexture default_texture; - VoxelInfo prototype; -}; -} // namespace world - -namespace world::voxel_registry -{ -extern std::unordered_map builders; -extern std::unordered_map names; -extern std::vector> voxels; -} // namespace world::voxel_registry - -namespace world::voxel_registry -{ -VoxelInfoBuilder& construct(std::string_view name, voxel_type type, bool animated, bool blending); -VoxelInfo* find(std::string_view name); -VoxelInfo* find(const voxel_id voxel); -} // namespace world::voxel_registry - -namespace world::voxel_registry -{ -void purge(void); -} // namespace world::voxel_registry - -namespace world::voxel_registry -{ -std::uint64_t calculate_checksum(void); -} // namespace world::voxel_registry +#pragma once + +#include "shared/types.hh" + +namespace world +{ +enum class voxel_face : unsigned short { + CUBE_NORTH = 0x0000, + CUBE_SOUTH = 0x0001, + CUBE_EAST = 0x0002, + CUBE_WEST = 0x0003, + CUBE_TOP = 0x0004, + CUBE_BOTTOM = 0x0005, + CUBE__NR = 0x0006, + + CROSS_NESW = 0x0000, + CROSS_NWSE = 0x0001, + CROSS__NR = 0x0002, +}; + +enum class voxel_type : unsigned short { + CUBE = 0x0000, + CROSS = 0x0001, // TODO + MODEL = 0x0002, // TODO +}; + +enum class voxel_facing : unsigned short { + NORTH = 0x0000, + SOUTH = 0x0001, + EAST = 0x0002, + WEST = 0x0003, + UP = 0x0004, + DOWN = 0x0005, + NESW = 0x0006, + NWSE = 0x0007, +}; + +enum class voxel_touch : unsigned short { + SOLID = 0x0000, // The entity is stopped in its tracks + BOUNCE = 0x0001, // The entity bounces back with some energy loss + SINK = 0x0002, // The entity phases/sinks through the voxel + NOTHING = 0xFFFF, +}; + +enum class voxel_surface : unsigned short { + DEFAULT = 0x0000, + STONE = 0x0001, + DIRT = 0x0002, + GLASS = 0x0003, + GRASS = 0x0004, + GRAVEL = 0x0005, + METAL = 0x0006, + SAND = 0x0007, + WOOD = 0x0008, + SLOSH = 0x0009, + COUNT = 0x000A, + UNKNOWN = 0xFFFF, +}; + +using voxel_vis = unsigned short; +constexpr static voxel_vis VIS_NORTH = 1 << static_cast(voxel_facing::NORTH); +constexpr static voxel_vis VIS_SOUTH = 1 << static_cast(voxel_facing::SOUTH); +constexpr static voxel_vis VIS_EAST = 1 << static_cast(voxel_facing::EAST); +constexpr static voxel_vis VIS_WEST = 1 << static_cast(voxel_facing::WEST); +constexpr static voxel_vis VIS_UP = 1 << static_cast(voxel_facing::UP); +constexpr static voxel_vis VIS_DOWN = 1 << static_cast(voxel_facing::DOWN); +} // namespace world + +namespace world +{ +struct VoxelTexture final { + std::vector paths; + std::size_t cached_offset; // client-side only + std::size_t cached_plane; // client-side only +}; + +struct VoxelInfo final { + std::string name; + voxel_type type; + bool animated; + bool blending; + + std::vector textures; + + // Physics properties go here + // TODO: player_move friction modifiers + // that would make the voxel very sticky or + // very slippery to walk on + voxel_touch touch_type; + glm::fvec3 touch_values; + voxel_surface surface; + + // Some voxel types might occupy multiple voxel_id + // values that reference to the exact same VoxelInfo + // structure; the actual numeric state is figured out by + // subtracting base_voxel from the checking voxel_id + voxel_id base_voxel; + + // These will be set by item_registry + // and by default set to NULL_ITEM_ID + item_id item_pick; +}; +} // namespace world + +namespace world +{ +class VoxelInfoBuilder final { +public: + explicit VoxelInfoBuilder(std::string_view name, voxel_type type, bool animated, bool blending); + virtual ~VoxelInfoBuilder(void) = default; + +public: + VoxelInfoBuilder& add_texture_default(std::string_view texture); + VoxelInfoBuilder& add_texture(voxel_face face, std::string_view texture); + VoxelInfoBuilder& set_touch(voxel_touch type, const glm::fvec3& values); + VoxelInfoBuilder& set_surface(voxel_surface surface); + +public: + voxel_id build(void) const; + +private: + VoxelTexture default_texture; + VoxelInfo prototype; +}; +} // namespace world + +namespace world::voxel_registry +{ +extern std::unordered_map builders; +extern std::unordered_map names; +extern std::vector> voxels; +} // namespace world::voxel_registry + +namespace world::voxel_registry +{ +VoxelInfoBuilder& construct(std::string_view name, voxel_type type, bool animated, bool blending); +VoxelInfo* find(std::string_view name); +VoxelInfo* find(const voxel_id voxel); +} // namespace world::voxel_registry + +namespace world::voxel_registry +{ +void purge(void); +} // namespace world::voxel_registry + +namespace world::voxel_registry +{ +std::uint64_t calculate_checksum(void); +} // namespace world::voxel_registry diff --git a/game/shared/world/voxel_storage.cc b/game/shared/world/voxel_storage.cc index 68e261c..75013b4 100644 --- a/game/shared/world/voxel_storage.cc +++ b/game/shared/world/voxel_storage.cc @@ -1,48 +1,48 @@ -#include "shared/pch.hh" - -#include "shared/world/voxel_storage.hh" - -#include "core/io/buffer.hh" - -void world::VoxelStorage::serialize(io::WriteBuffer& buffer) const -{ - auto bound = mz_compressBound(sizeof(VoxelStorage)); - auto zdata = std::vector(bound); - - VoxelStorage net_storage; - - for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) { - // Convert voxel indices into network byte order; - // We're going to compress them but we still want - // the order to be consistent across all the platforms - net_storage[i] = ENET_HOST_TO_NET_16(at(i)); - } - - mz_compress(zdata.data(), &bound, reinterpret_cast(net_storage.data()), sizeof(VoxelStorage)); - - buffer.write(bound); - - // Write all the compressed data into the buffer - for(std::size_t i = 0; i < bound; buffer.write(zdata[i++])) { - // empty - } -} - -void world::VoxelStorage::deserialize(io::ReadBuffer& buffer) -{ - auto size = static_cast(sizeof(VoxelStorage)); - auto bound = static_cast(buffer.read()); - auto zdata = std::vector(bound); - - // Read all the compressed data from the buffer - for(std::size_t i = 0; i < bound; zdata[i++] = buffer.read()) { - // empty - } - - mz_uncompress(reinterpret_cast(data()), &size, zdata.data(), bound); - - for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) { - // Convert voxel indices back into the host byte order - at(i) = ENET_NET_TO_HOST_16(at(i)); - } -} +#include "shared/pch.hh" + +#include "shared/world/voxel_storage.hh" + +#include "core/io/buffer.hh" + +void world::VoxelStorage::serialize(io::WriteBuffer& buffer) const +{ + auto bound = mz_compressBound(sizeof(VoxelStorage)); + auto zdata = std::vector(bound); + + VoxelStorage net_storage; + + for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) { + // Convert voxel indices into network byte order; + // We're going to compress them but we still want + // the order to be consistent across all the platforms + net_storage[i] = ENET_HOST_TO_NET_16(at(i)); + } + + mz_compress(zdata.data(), &bound, reinterpret_cast(net_storage.data()), sizeof(VoxelStorage)); + + buffer.write(bound); + + // Write all the compressed data into the buffer + for(std::size_t i = 0; i < bound; buffer.write(zdata[i++])) { + // empty + } +} + +void world::VoxelStorage::deserialize(io::ReadBuffer& buffer) +{ + auto size = static_cast(sizeof(VoxelStorage)); + auto bound = static_cast(buffer.read()); + auto zdata = std::vector(bound); + + // Read all the compressed data from the buffer + for(std::size_t i = 0; i < bound; zdata[i++] = buffer.read()) { + // empty + } + + mz_uncompress(reinterpret_cast(data()), &size, zdata.data(), bound); + + for(std::size_t i = 0; i < CHUNK_VOLUME; ++i) { + // Convert voxel indices back into the host byte order + at(i) = ENET_NET_TO_HOST_16(at(i)); + } +} diff --git a/game/shared/world/voxel_storage.hh b/game/shared/world/voxel_storage.hh index ac7f03d..98e85a3 100644 --- a/game/shared/world/voxel_storage.hh +++ b/game/shared/world/voxel_storage.hh @@ -1,20 +1,20 @@ -#pragma once - -#include "shared/const.hh" -#include "shared/types.hh" - -namespace io -{ -class ReadBuffer; -class WriteBuffer; -} // namespace io - -namespace world -{ -class VoxelStorage final : public std::array { -public: - using std::array::array; - void serialize(io::WriteBuffer& buffer) const; - void deserialize(io::ReadBuffer& buffer); -}; -} // namespace world +#pragma once + +#include "shared/const.hh" +#include "shared/types.hh" + +namespace io +{ +class ReadBuffer; +class WriteBuffer; +} // namespace io + +namespace world +{ +class VoxelStorage final : public std::array { +public: + using std::array::array; + void serialize(io::WriteBuffer& buffer) const; + void deserialize(io::ReadBuffer& buffer); +}; +} // namespace world -- cgit