nuclear-plant-sim/src/world/map.cpp

79 lines
1.7 KiB
C++

#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);
}
}