]> git.localhorst.tv Git - blank.git/blobdiff - src/client/net.cpp
unified location handling
[blank.git] / src / client / net.cpp
index 5c06bbe6a0c115f8952fd19c3315a3b7da8cfb59..d7a2661d56c3bc54d09df6140da9a003fed848db 100644 (file)
@@ -4,6 +4,7 @@
 #include "NetworkedInput.hpp"
 
 #include "../app/init.hpp"
+#include "../geometry/distance.hpp"
 #include "../io/WorldSave.hpp"
 #include "../net/Packet.hpp"
 #include "../world/Chunk.hpp"
@@ -61,7 +62,7 @@ int ChunkReceiver::ToLoad() const noexcept {
 void ChunkReceiver::LoadOne() {
        if (!store.HasMissing()) return;
 
-       Chunk::Pos pos = store.NextMissing();
+       ExactLocation::Coarse pos = store.NextMissing();
        Chunk *chunk = store.Allocate(pos);
        if (!chunk) {
                // chunk store corrupted?
@@ -294,8 +295,6 @@ uint16_t Client::SendPlayerUpdate(
        auto pack = Packet::Make<Packet::PlayerUpdate>(client_pack);
        pack.WritePredictedState(prediction);
        pack.WriteMovement(movement);
-       pack.WritePitch(pitch);
-       pack.WriteYaw(yaw);
        pack.WriteActions(actions);
        pack.WriteSlot(slot);
        return conn.Send(client_pack, client_sock);
@@ -306,16 +305,34 @@ uint16_t Client::SendPart() {
        return conn.Send(client_pack, client_sock);
 }
 
+uint16_t Client::SendMessage(
+       uint8_t type,
+       uint32_t ref,
+       const string &msg
+) {
+       auto pack = Packet::Make<Packet::Message>(client_pack);
+       pack.WriteType(type);
+       pack.WriteReferral(ref);
+       pack.WriteMessage(msg);
+       client_pack.len = sizeof(Packet::Header) + Packet::Message::GetSize(msg);
+       return conn.Send(client_pack, client_sock);
+}
 
 NetworkedInput::NetworkedInput(World &world, Player &player, Client &client)
 : PlayerController(world, player)
 , client(client)
 , player_hist()
+, old_movement(0.0f)
+, old_actions(0)
 , actions(0) {
 
 }
 
-void NetworkedInput::Update(int dt) {
+bool NetworkedInput::UpdateImportant() const noexcept {
+       return old_actions != actions || !iszero(old_movement - GetMovement());
+}
+
+void NetworkedInput::Update(Entity &, float dt) {
        Invalidate();
        UpdatePlayer();
 }
@@ -332,14 +349,17 @@ void NetworkedInput::PushPlayerUpdate(int dt) {
                InventorySlot()
        );
        if (player_hist.size() < 16) {
-               player_hist.emplace_back(state, dt, packet);
+               player_hist.emplace_back(state, GetMovement(), dt * 0.001f, packet);
        } else {
                auto entry = player_hist.begin();
                entry->state = state;
-               entry->delta_t = dt;
+               entry->movement = GetMovement();
+               entry->delta_t = dt * 0.001f;
                entry->packet = packet;
                player_hist.splice(player_hist.end(), player_hist, entry);
        }
+       old_movement = GetMovement();
+       old_actions = actions;
 }
 
 void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corrected_state) {
@@ -365,26 +385,22 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr
                }
        }
 
-       EntityState &player_state = GetPlayer().GetEntity().GetState();
+       glm::vec3 restore_movement(GetMovement());
+
+       EntityState player_state = GetPlayer().GetEntity().GetState();
        Entity replay(GetPlayer().GetEntity());
        replay.SetState(corrected_state);
 
        if (entry != end) {
-               entry->state.chunk_pos = replay.GetState().chunk_pos;
-               entry->state.block_pos = replay.GetState().block_pos;
+               entry->state.pos = replay.GetState().pos;
                ++entry;
        }
 
        vector<WorldCollision> col;
        while (entry != end) {
-               replay.Velocity(entry->state.velocity);
-               replay.Update(entry->delta_t);
-               if (GetWorld().Intersection(replay, col)) {
-                       GetWorld().Resolve(replay, col);
-                       col.clear();
-               }
-               entry->state.chunk_pos = replay.GetState().chunk_pos;
-               entry->state.block_pos = replay.GetState().block_pos;
+               SetMovement(entry->movement);
+               GetWorld().Update(replay, entry->delta_t);
+               entry->state.pos = replay.GetState().pos;
                ++entry;
        }
 
@@ -392,6 +408,7 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr
        const float disp_squared = dot(displacement, displacement);
 
        if (disp_squared < 16.0f * numeric_limits<float>::epsilon()) {
+               SetMovement(restore_movement);
                return;
        }
 
@@ -402,14 +419,15 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr
        constexpr float max_disp = 0.0001f; // (1/100)^2
 
        if (disp_squared > warp_thresh) {
-               player_state.chunk_pos = replay.GetState().chunk_pos;
-               player_state.block_pos = replay.GetState().block_pos;
+               player_state.pos = replay.GetState().pos;
        } else if (disp_squared < max_disp) {
-               player_state.block_pos += displacement;
+               player_state.pos.block += displacement;
        } else {
                displacement *= 0.01f / sqrt(disp_squared);
-               player_state.block_pos += displacement;
+               player_state.pos.block += displacement;
        }
+       GetPlayer().GetEntity().SetState(player_state);
+       SetMovement(restore_movement);
 }
 
 void NetworkedInput::StartPrimaryAction() {