+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;
+}
+