aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Movement/Spline/MoveSpline.h
blob: 683198160d7018df3b7dbed51714c7749515630e (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef TRINITYSERVER_MOVEPLINE_H
#define TRINITYSERVER_MOVEPLINE_H

#include "Spline.h"
#include "MoveSplineInitArgs.h"
#include <G3D/Vector3.h>

enum class AnimTier : uint8;

namespace WorldPackets
{
    namespace Movement
    {
        class CommonMovement;
        class MonsterMove;
    }
}

namespace Movement
{
    struct Location : public Vector3
    {
        Location() : orientation(0) { }
        Location(float x, float y, float z, float o) : Vector3(x, y, z), orientation(o) { }
        Location(Vector3 const& v) : Vector3(v), orientation(0) { }
        Location(Vector3 const& v, float o) : Vector3(v), orientation(o) { }

        float orientation;
    };

    // MoveSpline represents smooth catmullrom or linear curve and point that moves belong it
    // curve can be cyclic - in this case movement will be cyclic
    // point can have vertical acceleration motion component (used in fall, parabolic movement)
    class TC_GAME_API MoveSpline
    {
        friend class WorldPackets::Movement::CommonMovement;
        friend class WorldPackets::Movement::MonsterMove;

    public:
        typedef Spline<int32> MySpline;

        enum UpdateResult
        {
            Result_None         = 0x01,
            Result_Arrived      = 0x02,
            Result_NextCycle    = 0x04,
            Result_NextSegment  = 0x08
        };

    protected:
        MySpline        spline;

        FacingInfo      facing;

        uint32          m_Id;

        MoveSplineFlag  splineflags;

        int32           time_passed;
        // currently duration mods are unused, but its _currently_
        //float           duration_mod;
        //float           duration_mod_next;
        float           vertical_acceleration;
        float           initialOrientation;
        int32           effect_start_time;
        int32           point_Idx;
        int32           point_Idx_offset;
        float           velocity;
        Optional<SpellEffectExtraData> spell_effect_extra;
        Optional<TurnData> turn;
        Optional<AnimTierTransition> anim_tier;

        void init_spline(MoveSplineInitArgs const& args);

    protected:
        MySpline::ControlArray const& getPath() const { return spline.getPoints(); }
        Location computePosition(int32 time_point, int32 point_index) const;
        void computeParabolicElevation(int32 time_point, float& el) const;
        void computeFallElevation(int32 time_point, float& el) const;

        UpdateResult _updateState(int32& ms_time_diff);
        void reinit_spline_for_next_cycle();
        int32 next_timestamp() const { return spline.length(point_Idx + 1); }
        int32 segment_time_elapsed() const { return next_timestamp() - time_passed; }

    public:
        int32 timeRemaining() const { return Duration() - time_passed; }
        int32 timePassed() const { return time_passed; }
        int32 Duration() const { return spline.length(); }
        MySpline const& _Spline() const { return spline; }
        int32 _currentSplineIdx() const { return point_Idx; }
        float Velocity() const { return velocity; }
        void _Finalize();
        void _Interrupt() { splineflags.Done = true; }

    public:
        void Initialize(MoveSplineInitArgs const&);
        bool Initialized() const { return !spline.empty(); }

        MoveSpline();

        template<class UpdateHandler>
        void updateState(int32 difftime, UpdateHandler& handler)
        {
            ASSERT(Initialized());
            do
                handler(_updateState(difftime));
            while (difftime > 0);
        }

        void updateState(int32 difftime)
        {
            ASSERT(Initialized());
            do _updateState(difftime);
            while (difftime > 0);
        }

        Location ComputePosition() const;
        Location ComputePosition(int32 time_offset) const;

        uint32 GetId() const { return m_Id; }
        bool Finalized() const { return splineflags.Done; }
        bool isCyclic() const { return splineflags.Cyclic; }
        bool isFalling() const { return splineflags.Falling; }
        bool isTurning() const { return splineflags.Turning; }
        Vector3 const& FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3::zero(); }
        Vector3 const& CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx + 1) : Vector3::zero(); }
        int32 currentPathIdx() const;

        Optional<AnimTier> GetAnimation() const { return anim_tier ? anim_tier->AnimTier : Optional<AnimTier>{}; }

        bool onTransport;
        bool splineIsFacingOnly;
        std::string ToString() const;
        bool HasStarted() const
        {
            return time_passed > 0;
        }
    };
}
#endif // TRINITYSERVER_MOVEPLINE_H