aboutsummaryrefslogtreecommitdiff
path: root/src/shared/world/chunk.hh
blob: 8e724a375d373735068aaa53b3f4230afa2b2499 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#ifndef SHARED_WORLD_CHUNK_HH_
#define SHARED_WORLD_CHUNK_HH_

#include <algorithm>
#include <array>
#include <exception>
#include <functional>
#include <istream>
#include <memory>
#include <random>
#include <type_traits>
#include <vector>

#include <boost/functional/hash.hpp>
#include <glm/glm.hpp>

#include "shared/math/math.hh"
#include "shared/net/proto.hh"
#include "shared/shared.hh"
#include "shared/world/block.hh"

namespace shared {
namespace world {

class chunk {
public:
    static constexpr int WIDTH = 16;
    static constexpr int HEIGHT = 256;
    static constexpr int VOLUME = WIDTH * WIDTH * HEIGHT;

    // Stuff for unordered_map.
    static std::size_t hash(const shared::math::coords& c) noexcept {
        std::size_t seed = 0;
        boost::hash_combine(seed, boost::hash_value(c.x));
        boost::hash_combine(seed, boost::hash_value(c.z));
        return seed;
    }
    static std::size_t equal(const shared::math::coords& a,
                             const shared::math::coords& b) noexcept {
        return a == b;
    }
    enum class biome { desert, islands, ocean, plains, forest, tundra, alpine };

    using block_array_t = std::array<block, VOLUME>;
    using blocks_t = std::unique_ptr<block_array_t>;
    using biome_array_t = std::array<std::array<enum biome, WIDTH>, WIDTH>;
    using biomes_t = std::unique_ptr<biome_array_t>;

protected:
    shared::math::coords pos;
    blocks_t blocks; // Use get_block for 3d index access.

    // Simple 2d array of enums where each column maps to the dominant biome
    // at that x, z location. Call get_biome_str for string.
    biomes_t biomes;

public:
    static bool is_outside_chunk(const glm::ivec3& v) noexcept;

    static shared::math::coords
    get_normalised_chunk(const shared::math::coords& coords, const int x,
                         const int z) noexcept;

    static std::pair<unsigned short, unsigned short>
    get_normalised_coords(const int x, const int z) noexcept;

    static glm::ivec3 get_normalised_coords(const glm::ivec3& c) noexcept;

public:
    chunk(const std::uint64_t& seed,
          const shared::math::coords& coords) noexcept;
    chunk(const std::uint64_t& seed, const proto::chunk& chunk) noexcept;
    virtual ~chunk() noexcept {};

protected:
    void pack(proto::chunk* const proto) const noexcept;

public:
    block& get_block(const glm::ivec3& v) noexcept;
    const block& get_block(const glm::ivec3& v) const noexcept;
    const shared::math::coords& get_pos() const noexcept { return this->pos; }

    const char* get_biome(const int x, const int z) const noexcept;
};

} // namespace world
} // namespace shared

#endif