diff options
Diffstat (limited to 'src/server/movement/movement.cc')
| -rw-r--r-- | src/server/movement/movement.cc | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/server/movement/movement.cc b/src/server/movement/movement.cc new file mode 100644 index 0000000..0dd3f28 --- /dev/null +++ b/src/server/movement/movement.cc @@ -0,0 +1,98 @@ +#include "server/movement/movement.hh" + +namespace server { +namespace movement { + +// Gets blocks from chunks, returning nullopt if it doesn't exist. +static std::optional<shared::world::block> +maybe_get_block(const shared::math::coords& pos, + server::resources::chunk_map& chunks, + const glm::ivec3& block_pos) noexcept { + + const auto find_it = chunks.find(pos); + if (find_it == std::end(chunks)) { + return std::nullopt; + } + auto& chunk_data = find_it->second; + if (!chunk_data->has_initialised()) { + return std::nullopt; + } + + return chunk_data->get_chunk().get_block(block_pos); +} + +static std::optional<shared::movement::blocks> +maybe_make_blocks(server::client& client, + server::resources::chunk_map& chunks) noexcept { + + shared::movement::blocks blocks; + + const auto xy = shared::movement::get_move_xy(server::state.tickrate, + client.get_player()); + for (int x = -xy.x; x <= xy.x; ++x) { + for (int y = -xy.y; y <= xy.y; ++y) { + for (int z = -xy.x; z <= xy.x; ++z) { + + const glm::ivec3 rel_pos = + glm::ivec3{x, y, z} + + glm::ivec3{client.get_player().get_local_pos()}; + + if (rel_pos.y < 0 || + rel_pos.y >= shared::world::chunk::HEIGHT) { + continue; + } + + const shared::math::coords norm_chunk_pos = + shared::world::chunk::get_normalised_chunk( + client.get_player().get_chunk_pos(), rel_pos.x, + rel_pos.z); + const glm::ivec3 norm_pos = + shared::world::chunk::get_normalised_coords(rel_pos); + + const auto block = + maybe_get_block(norm_chunk_pos, chunks, norm_pos); + if (!block.has_value()) { + return std::nullopt; + } + + const glm::vec3 pos = + glm::vec3{rel_pos} - client.get_player().get_local_pos(); + + const shared::movement::aabb aabb = { + .min = glm::vec3{0.0f, 0.0f, 0.0f} + pos, + .max = glm::vec3{1.0f, 1.0f, 1.0f} + pos}; + blocks.push_back( + shared::movement::block{.block = *block, + .aabb = aabb, + .chunk_pos = norm_chunk_pos, + .pos = norm_pos}); + } + } + } + + return blocks; +} + +void move(client& client, resources::chunk_map& chunks) noexcept { + + if (!client.has_initialised()) { + return; + } + + const auto blocks = maybe_make_blocks(client, chunks); + if (!blocks.has_value()) { + return; + } + + auto& player = client.get_player(); + + const shared::animate result = + shared::movement::move(player, *blocks, state.tickrate); + + player.get_mutable_velocity() = result.get_velocity(); + player.get_mutable_local_pos() = result.get_local_pos(); + player.get_mutable_chunk_pos() = result.get_chunk_pos(); +} + +} // namespace movement +} // namespace server |
