#include "server/movement/movement.hh" namespace server { namespace movement { // Gets blocks from chunks, returning nullopt if it doesn't exist. static std::optional 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 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