/* * 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