aboutsummaryrefslogtreecommitdiff
path: root/src/server/world.cc
blob: 6527d6ce7038de872656b91a95a16ec385b51066 (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
#include "server/world.hh"

namespace server {
namespace world {

proto::packet chunk::make_chunk_packet() const noexcept {

    proto::packet ret_packet;

    auto chunk_packet = ret_packet.mutable_chunk_packet();

    auto chunk_pos = chunk_packet->mutable_chunk_pos();
    const shared::math::coords this_chunk_pos = this->get_pos();
    chunk_pos->set_x(this_chunk_pos.x);
    chunk_pos->set_z(this_chunk_pos.z);

    // Since protobuf can store at minimum uint32, we mash four of our
    // uint_8 chunk blocks into a single uint32.
    static_assert(shared::world::chunk::VOLUME % 4 == 0);
    for (unsigned i = 0u; i < shared::world::chunk::VOLUME / 4u; ++i) {
        std::uint32_t packed_blocks = 0u;

        for (unsigned j = 0; j < 4; ++j) {
            const auto block =
                static_cast<std::uint8_t>(this->blocks[i * 4 + j].type);
            packed_blocks |= static_cast<unsigned>(block << j * 8);
        }

        chunk_packet->add_blocks(packed_blocks);
    }

    return ret_packet;
}

static std::optional<shared::world::chunk::block_array>
maybe_get_blocks(const shared::math::coords& coords) {
    const auto chunk = database::maybe_read_chunk(coords);
    if (!chunk.has_value()) {
        return std::nullopt;
    }
    return shared::world::chunk::make_blocks_from_chunk(chunk.value());
}

chunk::chunk(const std::uint64_t& seed,
             const shared::math::coords& coords) noexcept
    : shared::world::chunk(seed, coords, maybe_get_blocks(coords)) {
    this->update();
}

chunk::~chunk() noexcept { this->write(); }

} // namespace world
} // namespace server