X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fclient%2Fclient.cpp;h=4a48b45afc91eb5179f9a6d038c88b19244f213d;hb=8507332e2d0c54aec4045fb6f0021bdc3bd57750;hp=bd436358b9af5163766121bf07981f7d5fdc60a9;hpb=d2eb51ad9759eeee743b04aee6f1ae69132fc706;p=blank.git diff --git a/src/client/client.cpp b/src/client/client.cpp index bd43635..4a48b45 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -56,7 +56,8 @@ InteractiveState::InteractiveState(MasterState &master, uint32_t player_id) ) , chunk_renderer(*interface.GetPlayer().chunks) , skeletons() -, update_timer(16) { +, update_timer(16) +, player_hist() { TextureIndex tex_index; master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index); chunk_renderer.LoadTextures(master.GetEnv().loader, tex_index); @@ -111,7 +112,7 @@ void InteractiveState::Update(int dt) { Entity &player = *interface.GetPlayer().entity; if (update_timer.Hit()) { - master.GetClient().SendPlayerUpdate(player); + PushPlayerUpdate(player); } glm::mat4 trans = player.Transform(player.ChunkCoords()); @@ -122,6 +123,37 @@ void InteractiveState::Update(int dt) { master.GetEnv().audio.Orientation(dir, up); } +void InteractiveState::PushPlayerUpdate(const Entity &player) { + std::uint16_t packet = master.GetClient().SendPlayerUpdate(player); + if (player_hist.size() < 16) { + player_hist.emplace_back(player.GetState(), update_timer.Elapsed(), packet); + } else { + auto entry = player_hist.begin(); + entry->state = player.GetState(); + entry->timestamp = update_timer.Elapsed(); + entry->packet = packet; + player_hist.splice(player_hist.end(), player_hist, entry); + } +} + +void InteractiveState::MergePlayerCorrection(uint16_t seq, const EntityState &corrected_state) { + if (player_hist.empty()) return; + + auto entry = player_hist.begin(); + auto end = player_hist.end(); + + // drop anything older than the fix + while (entry != end) { + int pack_diff = int16_t(seq) - int16_t(entry->packet); + if (pack_diff < 0) { + entry = player_hist.erase(entry); + } else { + break; + } + } + if (entry == end) return; +} + void InteractiveState::Render(Viewport &viewport) { Entity &player = *interface.GetPlayer().entity; viewport.WorldPosition(player.Transform(player.ChunkCoords())); @@ -212,7 +244,7 @@ void MasterState::On(const Packet::Join &pack) { pack.ReadPlayerID(player_id); state.reset(new InteractiveState(*this, player_id)); - pack.ReadPlayer(*state->GetInterface().GetPlayer().entity); + pack.ReadPlayerState(state->GetInterface().GetPlayer().entity->GetState()); env.state.PopAfter(this); env.state.Push(state.get()); @@ -293,7 +325,7 @@ void MasterState::On(const Packet::EntityUpdate &pack) { } if (world_iter->ID() == entity_id) { if (UpdateEntity(entity_id, pack.Seq())) { - pack.ReadEntity(*world_iter, i); + pack.ReadEntityState(world_iter->GetState(), i); } } } @@ -322,5 +354,18 @@ void MasterState::ClearEntity(uint32_t entity_id) { update_status.erase(entity_id); } +void MasterState::On(const Packet::PlayerCorrection &pack) { + if (!state) { + cout << "got player correction without a player :S" << endl; + Quit(); + return; + } + uint16_t pack_seq; + EntityState corrected_state; + pack.ReadPacketSeq(pack_seq); + pack.ReadPlayerState(corrected_state); + state->MergePlayerCorrection(pack_seq, corrected_state); +} + } }