/* * 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 TRANSPORTMGR_H #define TRANSPORTMGR_H #include "ObjectGuid.h" #include "Optional.h" #include "Position.h" #include #include #include struct GameObjectTemplate; struct TaxiPathNodeEntry; struct TransportAnimationEntry; struct TransportRotationEntry; struct TransportTemplate; class Transport; class Map; namespace Movement { template class Spline; } using TransportSpline = Movement::Spline; enum class TransportMovementState : uint8 { Moving, WaitingOnPauseWaypoint }; // Represents a segment within path leg between stops struct TransportPathSegment { uint32 SegmentEndArrivalTimestamp = 0; uint32 Delay = 0; double DistanceFromLegStartAtEnd = 0.0; }; struct TransportPathEvent { uint32 Timestamp = 0; uint32 EventId = 0; }; // Represents a contignuous part of transport path (without map changes or teleports) struct TransportPathLeg { TransportPathLeg(); ~TransportPathLeg(); TransportPathLeg(TransportPathLeg const&) = delete; TransportPathLeg(TransportPathLeg&&) noexcept; TransportPathLeg& operator=(TransportPathLeg const&) = delete; TransportPathLeg& operator=(TransportPathLeg&&) noexcept; uint32 MapId = 0; std::unique_ptr Spline; uint32 StartTimestamp = 0; uint32 Duration = 0; std::vector Segments; }; struct TransportTemplate { TransportTemplate(); ~TransportTemplate(); TransportTemplate(TransportTemplate const&) = delete; TransportTemplate(TransportTemplate&&) noexcept; TransportTemplate& operator=(TransportTemplate const&) = delete; TransportTemplate& operator=(TransportTemplate&&) noexcept; uint32 TotalPathTime = 0; double Speed = 0.0; double AccelerationRate = 0.0; double AccelerationTime = 0.0; double AccelerationDistance = 0.0; std::vector PathLegs; std::vector Events; Optional ComputePosition(uint32 time, TransportMovementState* moveState, size_t* legIndex) const; TransportPathLeg const* GetLegForTime(uint32 time) const; uint32 GetNextPauseWaypointTimestamp(uint32 time) const; double CalculateDistanceMoved(double timePassedInSegment, double segmentDuration, bool isFirstSegment, bool isLastSegment) const; std::set MapIds; }; struct TransportAnimation { TransportAnimation(); ~TransportAnimation(); TransportAnimation(TransportAnimation const&) = delete; TransportAnimation(TransportAnimation&&) noexcept; TransportAnimation& operator=(TransportAnimation const&) = delete; TransportAnimation& operator=(TransportAnimation&&) noexcept; std::map Path; std::map Rotations; uint32 TotalTime = 0; TransportAnimationEntry const* GetPrevAnimNode(uint32 time) const; TransportRotationEntry const* GetPrevAnimRotation(uint32 time) const; TransportAnimationEntry const* GetNextAnimNode(uint32 time) const; TransportRotationEntry const* GetNextAnimRotation(uint32 time) const; }; struct TransportSpawn { ObjectGuid::LowType SpawnId = UI64LIT(0); uint32 TransportGameObjectId = 0; // entry in respective _template table uint8 PhaseUseFlags = 0; uint32 PhaseId = 0; uint32 PhaseGroup = 0; }; class TC_GAME_API TransportMgr { public: TransportMgr(TransportMgr const&) = delete; TransportMgr(TransportMgr&&) = delete; TransportMgr& operator=(TransportMgr const&) = delete; TransportMgr& operator=(TransportMgr&&) = delete; static TransportMgr* instance(); void Unload(); void LoadTransportTemplates(); void LoadTransportAnimationAndRotation(); void LoadTransportSpawns(); // Creates a transport using given GameObject template entry Transport* CreateTransport(uint32 entry, Map* map, ObjectGuid::LowType guid = 0, uint8 phaseUseFlags = 0, uint32 phaseId = 0, uint32 phaseGroupId = 0); // creates all transports for map void CreateTransportsForMap(Map* map); TransportTemplate const* GetTransportTemplate(uint32 entry) const; TransportAnimation const* GetTransportAnimInfo(uint32 entry) const; TransportSpawn const* GetTransportSpawn(ObjectGuid::LowType spawnId) const; private: TransportMgr(); ~TransportMgr(); // Generates and precaches a path for transport to avoid generation each time transport instance is created void GeneratePath(GameObjectTemplate const* goInfo, TransportTemplate* transport); void AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg, TransportAnimationEntry const* node); void AddPathRotationToTransport(uint32 transportEntry, uint32 timeSeg, TransportRotationEntry const* node); // Container storing transport templates std::unordered_map _transportTemplates; // Container storing transport entries to create for instanced maps std::unordered_map> _transportsByMap; std::map _transportAnimations; std::unordered_map _transportSpawns; }; #define sTransportMgr TransportMgr::instance() #endif // TRANSPORTMGR_H