#include "NetworkedInput.hpp"
#include "../app/init.hpp"
+#include "../io/WorldSave.hpp"
#include "../net/Packet.hpp"
#include "../world/Chunk.hpp"
#include "../world/ChunkStore.hpp"
#include "../world/Player.hpp"
+#include "../world/World.hpp"
#include <iostream>
#include <zlib.h>
namespace client {
-ChunkReceiver::ChunkReceiver(ChunkStore &store)
+ChunkReceiver::ChunkReceiver(ChunkStore &store, const WorldSave &save)
: store(store)
+, save(save)
, transmissions()
, timer(5000) {
timer.Start();
}
}
}
+ LoadN(10);
+ StoreN(10);
}
+int ChunkReceiver::ToLoad() const noexcept {
+ return store.EstimateMissing();
+}
+
+void ChunkReceiver::LoadOne() {
+ if (!store.HasMissing()) return;
+
+ Chunk::Pos pos = store.NextMissing();
+ Chunk *chunk = store.Allocate(pos);
+ if (!chunk) {
+ // chunk store corrupted?
+ return;
+ }
+
+ if (save.Exists(pos)) {
+ save.Read(*chunk);
+ }
+}
+
+void ChunkReceiver::LoadN(size_t n) {
+ size_t end = min(n, size_t(ToLoad()));
+ for (size_t i = 0; i < end && store.HasMissing(); ++i) {
+ LoadOne();
+ }
+}
+
+void ChunkReceiver::StoreN(size_t n) {
+ size_t saved = 0;
+ for (Chunk &chunk : store) {
+ if (chunk.ShouldUpdateSave()) {
+ save.Write(chunk);
+ ++saved;
+ if (saved >= n) {
+ break;
+ }
+ }
+ }
+}
+
+
void ChunkReceiver::Handle(const Packet::ChunkBegin &pack) {
uint32_t id;
pack.ReadTransmissionId(id);
const glm::vec3 &movement,
float pitch,
float yaw,
- std::uint8_t actions,
- std::uint8_t slot
+ uint8_t actions,
+ uint8_t slot
) {
auto pack = Packet::Make<Packet::PlayerUpdate>(client_pack);
pack.WritePredictedState(prediction);
void NetworkedInput::PushPlayerUpdate(int dt) {
const EntityState &state = GetPlayer().GetEntity().GetState();
- std::uint16_t packet = client.SendPlayerUpdate(
+ uint16_t packet = client.SendPlayerUpdate(
state,
GetMovement(),
GetPitch(),
}
}
- EntityState replay_state(corrected_state);
EntityState &player_state = GetPlayer().GetEntity().GetState();
+ Entity replay(GetPlayer().GetEntity());
+ replay.SetState(corrected_state);
if (entry != end) {
- entry->state.chunk_pos = replay_state.chunk_pos;
- entry->state.block_pos = replay_state.block_pos;
+ entry->state.chunk_pos = replay.GetState().chunk_pos;
+ entry->state.block_pos = replay.GetState().block_pos;
++entry;
}
+ vector<WorldCollision> col;
while (entry != end) {
- replay_state.velocity = entry->state.velocity;
- replay_state.Update(entry->delta_t);
- entry->state.chunk_pos = replay_state.chunk_pos;
- entry->state.block_pos = replay_state.block_pos;
+ 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;
++entry;
}
- glm::vec3 displacement(replay_state.Diff(player_state));
+ glm::vec3 displacement(replay.GetState().Diff(player_state));
const float disp_squared = dot(displacement, displacement);
if (disp_squared < 16.0f * numeric_limits<float>::epsilon()) {
constexpr float max_disp = 0.0001f; // (1/100)^2
if (disp_squared > warp_thresh) {
- player_state.chunk_pos = replay_state.chunk_pos;
- player_state.block_pos = replay_state.block_pos;
+ player_state.chunk_pos = replay.GetState().chunk_pos;
+ player_state.block_pos = replay.GetState().block_pos;
} else if (disp_squared < max_disp) {
player_state.block_pos += displacement;
} else {