-#include "ChunkRequester.hpp"
#include "InitialState.hpp"
#include "InteractiveState.hpp"
#include "MasterState.hpp"
#include "../app/Environment.hpp"
#include "../app/init.hpp"
#include "../app/TextureIndex.hpp"
-#include "../model/CompositeModel.hpp"
+#include "../model/Model.hpp"
#include "../io/WorldSave.hpp"
#include "../world/ChunkIndex.hpp"
#include "../world/ChunkStore.hpp"
namespace blank {
namespace client {
-ChunkRequester::ChunkRequester(
- ChunkStore &store,
- const WorldSave &save
-) noexcept
-: store(store)
-, save(save) {
-
-}
-
-void ChunkRequester::Update(int dt) {
- // check if there's chunks waiting to be loaded
- LoadN(10);
-
- // store a few chunks as well
- constexpr int max_save = 10;
- int saved = 0;
- for (Chunk &chunk : store) {
- if (chunk.ShouldUpdateSave()) {
- save.Write(chunk);
- ++saved;
- if (saved >= max_save) {
- break;
- }
- }
- }
-}
-
-int ChunkRequester::ToLoad() const noexcept {
- return store.EstimateMissing();
-}
-
-void ChunkRequester::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);
- // TODO: request chunk from server with cache tag
- } else {
- // TODO: request chunk from server
- }
-}
-
-void ChunkRequester::LoadN(std::size_t n) {
- std::size_t end = std::min(n, std::size_t(ToLoad()));
- for (std::size_t i = 0; i < end && store.HasMissing(); ++i) {
- LoadOne();
- }
-}
-
-
InitialState::InitialState(MasterState &master)
: master(master)
, message() {
, manip(master.GetEnv(), player.GetEntity())
, input(world, player, master.GetClient())
, interface(master.GetConfig(), master.GetEnv().keymap, input, *this)
-// TODO: looks like chunk requester and receiver can and should be merged
-, chunk_requester(world.Chunks(), save)
-, chunk_receiver(world.Chunks())
+, chunk_receiver(world.Chunks(), save)
, chunk_renderer(player.GetChunks())
, skeletons()
, loop_timer(16)
}
TextureIndex tex_index;
master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index);
- interface.SetInventorySlots(block_types.Size() - 1);
+ interface.SetInventorySlots(block_types.size() - 1);
chunk_renderer.LoadTextures(master.GetEnv().loader, tex_index);
chunk_renderer.FogDensity(master.GetWorldConf().fog_density);
skeletons.Load();
loop_timer.Start();
+ if (save.Exists(player)) {
+ save.Read(player);
+ }
}
void InteractiveState::OnEnter() {
interface.Handle(event.wheel);
break;
case SDL_QUIT:
- master.Quit();
+ Exit();
break;
default:
break;
loop_timer.Update(dt);
master.Update(dt);
chunk_receiver.Update(dt);
- chunk_requester.Update(dt);
hud.Update(dt);
int world_dt = 0;
Block block;
pack.ReadIndex(index, i);
pack.ReadBlock(block, i);
- if (index < Chunk::size && block.type < block_types.Size()) {
+ if (index < Chunk::size && block.type < block_types.size()) {
manip.SetBlock(*chunk, index, block);
}
}
}
void InteractiveState::Exit() {
+ save.Write(player);
master.Quit();
}
void MasterState::OnTimeout() {
if (client.GetConnection().Closed()) {
- // TODO: push disconnected message
- cout << "connection timed out" << endl;
Quit();
+ env.ShowMessage("connection timed out");
}
}
}
void MasterState::On(const Packet::Part &pack) {
+ Quit();
if (state) {
// kicked
- cout << "kicked by server" << endl;
+ env.ShowMessage("kicked by server");
} else {
// join refused
- cout << "login refused by server" << endl;
+ env.ShowMessage("login refused by server");
}
- Quit();
}
void MasterState::On(const Packet::SpawnEntity &pack) {
if (!state) {
cout << "got entity spawn before world was created" << endl;
- Quit();
return;
}
uint32_t entity_id;
pack.ReadEntity(entity);
uint32_t skel_id;
pack.ReadSkeletonID(skel_id);
- CompositeModel *skel = state->GetSkeletons().ByID(skel_id);
+ Model *skel = state->GetSkeletons().ByID(skel_id);
if (skel) {
skel->Instantiate(entity.GetModel());
}
void MasterState::On(const Packet::DespawnEntity &pack) {
if (!state) {
cout << "got entity despawn before world was created" << endl;
- Quit();
return;
}
uint32_t entity_id;
void MasterState::On(const Packet::EntityUpdate &pack) {
if (!state) {
cout << "got entity update before world was created" << endl;
- Quit();
return;
}
void MasterState::On(const Packet::PlayerCorrection &pack) {
if (!state) {
cout << "got player correction without a player :S" << endl;
- Quit();
return;
}
uint16_t pack_seq;