aboutsummaryrefslogtreecommitdiff
path: root/src/server/movement/movement.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/movement/movement.cc')
-rw-r--r--src/server/movement/movement.cc98
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