#include "map.hpp" #include "chunk.hpp" #include "tile/tile_base.hpp" #include <glm/gtc/integer.hpp> #include <utility> using World::Tile::TileBase; using World::Chunk; using World::Map; constexpr glm::vec<2, int> get_pos_mod(glm::vec<2, int> pos) { return (pos % Map::N + Map::N) % Map::N; } constexpr uint64_t get_chunk_id(glm::vec<2, int> pos) { glm::vec<2, int> pos_mod = get_pos_mod(pos); glm::vec<2, uint32_t> cpos = (pos - pos_mod) / Map::N; return ((uint64_t)cpos.x << 32) | cpos.y; } Chunk* Map::get_or_generate_chunk(glm::vec<2, int> pos) { uint64_t cid = get_chunk_id(pos); auto it = m_chunks.find(cid); if(it == m_chunks.end()) { it = m_chunks.try_emplace(cid, pos - get_pos_mod(pos)).first; } return &it->second; } Chunk* Map::get_chunk(glm::vec<2, int> pos) { uint64_t cid = get_chunk_id(pos); auto it = m_chunks.find(cid); if(it == m_chunks.end()) { return nullptr; } return &it->second; } const Chunk* Map::get_chunk(glm::vec<2, int> pos) const { uint64_t cid = get_chunk_id(pos); auto it = m_chunks.find(cid); if(it == m_chunks.end()) { return nullptr; } return &it->second; } TileBase* Map::get_tile(glm::vec<2, int> pos) { Chunk* c = get_chunk(pos); return c ? c->get(pos) : nullptr; } const TileBase* Map::get_tile(glm::vec<2, int> pos) const { const Chunk* c = get_chunk(pos); return c ? c->get(pos) : nullptr; } TileBase* Map::set_tile(glm::vec<2, int> pos, std::unique_ptr<TileBase> tile) { tile->m_pos = pos; return get_or_generate_chunk(pos)->set(pos, std::move(tile)); } void Map::update() { for(auto& [cid, chunk] : m_chunks) { chunk.update(*this); } } void Map::render(Graphics::Context& ctx) const { for(auto& [cid, chunk] : m_chunks) { chunk.render(ctx); } }