aboutsummaryrefslogtreecommitdiff
path: root/src/client/entity/animate.hh
blob: 79016ea3e30f76e04ab72159d77a1eb0301608b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef CLIENT_ENTITY_ANIMATE_HH_
#define CLIENT_ENTITY_ANIMATE_HH_

#include <algorithm>
#include <chrono>
#include <cmath>
#include <ranges>
#include <utility>
#include <vector>

#include <boost/circular_buffer.hpp>

#include "client/entity/entity.hh"
#include "client/movement/movement.hh"
#include "client/settings.hh"
#include "client/state/state.hh"
#include "shared/entity/animate.hh"
#include "shared/entity/entity.hh"
#include "shared/movement/movement.hh"
#include "shared/net/proto.hh"
#include "shared/shared.hh"

namespace client {

class animate : virtual public shared::animate, virtual public client::entity {
protected:
    struct animate_update {
        shared::tick_t tick_sequence; // tick or sequence, if LP then sequence.
        shared::animate animate;
        bool from_server;
    };

    // We have 1 second of potential player interpolation to use here when we
    // initialise this with the server's tickrate.
    boost::circular_buffer<animate_update> updates{state::tickrate};
    shared::tick_t latest_sequence = 0;

private:
    float get_target_ticks_back() noexcept;

public:
    animate(shared::player&& p) noexcept
        : shared::entity(p), shared::animate(p), client::entity(p) {}

    animate(const proto::animate& proto) noexcept
        : shared::entity(proto.entity()), shared::animate(proto),
          client::entity(proto.entity()) {}

public:
    // Call when localplayer gets tick to update state timers.
    void update_time_factor(const shared::tick_t& sequence,
                            const shared::tick_t& tick) noexcept;

    virtual void notify(const shared::animate& animate,
                        const shared::tick_t& tick_sequence,
                        const bool from_server) noexcept;

    shared::tick_t& get_mutable_latest_sequence() noexcept {
        return this->latest_sequence;
    }
    shared::tick_t get_latest_sequence() const noexcept {
        return this->latest_sequence;
    }
    // An animate may be interpolated, however it's the moveable class that is
    // required for extrapolation and other prediction.
    void interpolate() noexcept;
};

} // namespace client

#endif