/*
* 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 .
*/
#ifndef TRINITYSERVER_MOVEPLINE_H
#define TRINITYSERVER_MOVEPLINE_H
#include "Spline.h"
#include "MoveSplineInitArgs.h"
#include
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 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 spell_effect_extra;
Optional turn;
Optional 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
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 GetAnimation() const { return anim_tier ? anim_tier->AnimTier : Optional{}; }
bool onTransport;
bool splineIsFacingOnly;
std::string ToString() const;
bool HasStarted() const
{
return time_passed > 0;
}
};
}
#endif // TRINITYSERVER_MOVEPLINE_H