diff --git a/src/game/Object.h b/src/game/Object.h index 6a740c6ce..03bd8d9c7 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -78,6 +78,7 @@ typedef UNORDERED_MAP UpdateDataMapType; struct Position { Position() : x(0.0f), y(0.0f), z(0.0f), o(0.0f) {} + Position(float _x, float _y, float _z, float _o) : x(_x), y(_y), z(_z), o(_o) {} float x, y, z, o; }; diff --git a/src/game/TransportSystem.cpp b/src/game/TransportSystem.cpp new file mode 100644 index 000000000..53d410956 --- /dev/null +++ b/src/game/TransportSystem.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2005-2012 MaNGOS + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @addtogroup TransportSystem + * @{ + * + * @file TransportSystem.cpp + * This file contains the code needed for MaNGOS to provide abstract support for transported entities + * Currently implemented + * - Calculating between local and global coords + * + */ + +#include "TransportSystem.h" +#include "Unit.h" +#include "Vehicle.h" +#include "MapManager.h" + +/* **************************************** TransportBase ****************************************/ + +TransportBase::TransportBase(WorldObject* owner) : + m_owner(owner), + m_lastPosition(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation()), + m_sinO(sin(m_lastPosition.o)), + m_cosO(cos(m_lastPosition.o)), + m_updatePositionsTimer(500) +{ + MANGOS_ASSERT(m_owner); +} + +TransportBase::~TransportBase() +{ + MANGOS_ASSERT(m_passengers.size() == 0); +} + +// Update every now and then (after some change of transporter's position) +// This is used to calculate global positions (which don't have to be exact, they are only required for some server-side calculations +void TransportBase::Update(uint32 diff) +{ + if (m_updatePositionsTimer < diff) + { + if (fabs(m_owner->GetPositionX() - m_lastPosition.x) + + fabs(m_owner->GetPositionY() - m_lastPosition.y) + + fabs(m_owner->GetPositionZ() - m_lastPosition.z) > 1.0f || + MapManager::NormalizeOrientation(m_owner->GetOrientation() - m_lastPosition.o) > 0.01f) + UpdateGlobalPositions(); + + m_updatePositionsTimer = 500; + } + else + m_updatePositionsTimer -= diff; +} + +// Update the global positions of all passengers +void TransportBase::UpdateGlobalPositions() +{ + Position pos(m_owner->GetPositionX(), m_owner->GetPositionY(), + m_owner->GetPositionZ(), m_owner->GetOrientation()); + + // Calculate new direction multipliers + if (MapManager::NormalizeOrientation(pos.o - m_lastPosition.o) > 0.01f) + { + m_sinO = sin(pos.o); + m_cosO = cos(pos.o); + } + + // Update global positions + for (PassengerMap::const_iterator itr = m_passengers.begin(); itr != m_passengers.end(); ++itr) + UpdateGlobalPositionOf(itr->first, itr->second->GetLocalPositionX(), itr->second->GetLocalPositionY(), + itr->second->GetLocalPositionZ(), itr->second->GetLocalOrientation()); + + m_lastPosition = pos; +} + +// Update the global position of a passenger +void TransportBase::UpdateGlobalPositionOf(WorldObject* passenger, float lx, float ly, float lz, float lo) const +{ + float gx, gy, gz, go; + CalculateGlobalPositionOf(lx, ly, lz, lo, gx, gy, gz, go); + + if (passenger->GetTypeId() == TYPEID_PLAYER || passenger->GetTypeId() == TYPEID_UNIT) + { + if (passenger->GetTypeId() == TYPEID_PLAYER) + { + m_owner->GetMap()->PlayerRelocation((Player*)passenger, gx, gy, gz, go); + } + else + m_owner->GetMap()->CreatureRelocation((Creature*)passenger, gx, gy, gz, go); + + //// If passenger is vehicle + //if (((Unit*)passenger)->IsVehicle()) + // ((Unit*)passenger)->GetVehicleInfo()->UpdateGlobalPositions(); + } + // ToDo: Add gameobject relocation + // ToDo: Add passenger relocation for MO transports +} + +// This rotates the vector (lx, ly) by transporter->orientation +void TransportBase::RotateLocalPosition(float lx, float ly, float& rx, float& ry) const +{ + rx = lx * m_cosO - ly * m_sinO; + ry = lx * m_sinO + ly * m_cosO; +} + +// This rotates the vector (rx, ry) by -transporter->orientation +void TransportBase::NormalizeRotatedPosition(float rx, float ry, float& lx, float& ly) const +{ + lx = rx * -m_cosO - ry * -m_sinO; + ly = rx * -m_sinO + ry * -m_cosO; +} + +// Calculate a global position of local positions based on this transporter +void TransportBase::CalculateGlobalPositionOf(float lx, float ly, float lz, float lo, float& gx, float& gy, float& gz, float& go) const +{ + RotateLocalPosition(lx, ly, gx, gy); + gx += m_owner->GetPositionX(); + gy += m_owner->GetPositionY(); + + gz = lz + m_owner->GetPositionZ(); + go = MapManager::NormalizeOrientation(lo + m_owner->GetOrientation()); +} + +/* **************************************** TransportInfo ****************************************/ + +TransportInfo::TransportInfo(WorldObject* owner, TransportBase* transport, float lx, float ly, float lz, float lo, uint8 seat) : + m_owner(owner), + m_transport(transport), + m_localPosition(lx, ly, lz, lo), + m_seat(seat) +{ + MANGOS_ASSERT(owner && m_transport); +} + +void TransportInfo::SetLocalPosition(float lx, float ly, float lz, float lo) +{ + m_localPosition.x = lx; + m_localPosition.y = ly; + m_localPosition.z = lz; + m_localPosition.o = lo; + + // Update global position + m_transport->UpdateGlobalPositionOf(m_owner, lx, ly, lz, lo); +} + +/*! @} */ diff --git a/src/game/TransportSystem.h b/src/game/TransportSystem.h new file mode 100644 index 000000000..f0b4e1a04 --- /dev/null +++ b/src/game/TransportSystem.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2005-2012 MaNGOS + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @addtogroup TransportSystem to provide abstract support for transported entities + * The Transport System in MaNGOS consists of these files: + * - TransportSystem.h to provide the basic classes TransportBase and TransportInfo + * - TransportSystem.cpp which implements these classes + * - Vehicle.h as a vehicle is a transporter it will inherit itr transporter-information from TransportBase + * - Transports.h to implement the MOTransporter (subclas of gameobject) - Remains TODO + * as well of + * - impacts to various files + * + * @{ + * + * @file TransportSystem.h + * This file contains the headers for base clases needed for MaNGOS to handle passengers on transports + * + */ + +#ifndef _TRANSPORT_SYSTEM_H +#define _TRANSPORT_SYSTEM_H + +#include "Common.h" +#include "Object.h" + +class TransportInfo; + +typedef UNORDERED_MAP < WorldObject* /*passenger*/, TransportInfo* /*passengerInfo*/ > PassengerMap; + +/** + * A class to provide basic support for each transporter. This includes + * - Storing a list of passengers + * - Providing helper for calculating between local and global coordinates + */ + +class TransportBase +{ + public: + explicit TransportBase(WorldObject* owner); + ~TransportBase(); + + void Update(uint32 diff); + void UpdateGlobalPositions(); + void UpdateGlobalPositionOf(WorldObject* passenger, float lx, float ly, float lz, float lo) const; + + WorldObject* GetOwner() const { return m_owner; } + + // Helper functions to calculate positions + void RotateLocalPosition(float lx, float ly, float& rx, float& ry) const; + void NormalizeRotatedPosition(float rx, float ry, float& lx, float& ly) const; + + void CalculateGlobalPositionOf(float lx, float ly, float lz, float lo, float& gx, float& gy, float& gz, float& go) const; + + protected: + WorldObject* m_owner; ///< The transporting unit + PassengerMap m_passengers; ///< List of passengers and their transport-information + + // Helpers to speedup position calculations + Position m_lastPosition; + float m_sinO, m_cosO; + uint32 m_updatePositionsTimer; ///< Timer that is used to trigger updates for global coordinate calculations +}; + +/** + * A class to provide basic information for each transported passenger. This includes + * - local positions + * - Accessors to get the transporter + */ + +class TransportInfo +{ + public: + explicit TransportInfo(WorldObject* owner, TransportBase* transport, float lx, float ly, float lz, float lo, uint8 seat); + + void SetLocalPosition(float lx, float ly, float lz, float lo); + + // Accessors + WorldObject* GetTransport() const { return m_transport->GetOwner(); } + ObjectGuid GetTransportGuid() const { return m_transport->GetOwner()->GetObjectGuid(); } + + // Required for chain-updating (passenger on transporter on transporter) + bool IsOnVehicle() const { return m_transport->GetOwner()->GetTypeId() == TYPEID_PLAYER || m_transport->GetOwner()->GetTypeId() == TYPEID_UNIT; } + + // Get local position and seat + uint8 GetTransportSeat() const { return m_seat; } + float GetLocalOrientation() const { return m_localPosition.o; } + float GetLocalPositionX() const { return m_localPosition.x; } + float GetLocalPositionY() const { return m_localPosition.y; } + float GetLocalPositionZ() const { return m_localPosition.z; } + void GetLocalPosition(float& lx, float& ly, float& lz, float& lo) const + { + lx = m_localPosition.x; + ly = m_localPosition.y; + lz = m_localPosition.z; + lo = m_localPosition.o; + } + + private: + WorldObject* m_owner; ///< Passenger + TransportBase* m_transport; ///< Transporter + Position m_localPosition; + uint8 m_seat; +}; + +#endif +/*! @} */ diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a6f9913ad..ce288e37b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "0145" + #define REVISION_NR "12105" #endif // __REVISION_NR_H__ diff --git a/win/VC100/game.vcxproj b/win/VC100/game.vcxproj index 2f8c82d9f..432369dfa 100644 --- a/win/VC100/game.vcxproj +++ b/win/VC100/game.vcxproj @@ -483,6 +483,7 @@ + @@ -659,6 +660,7 @@ + @@ -706,4 +708,4 @@ - \ No newline at end of file + diff --git a/win/VC100/game.vcxproj.filters b/win/VC100/game.vcxproj.filters index 950dd245b..51290a5e0 100644 --- a/win/VC100/game.vcxproj.filters +++ b/win/VC100/game.vcxproj.filters @@ -496,9 +496,6 @@ Object - - Server - World/Handlers @@ -544,8 +541,8 @@ World/Handlers - - Server + + Object @@ -1006,9 +1003,6 @@ vmaps - - Movement - Movement @@ -1036,14 +1030,8 @@ World/Handlers - - Server - - - Server - - - Server + + Object - \ No newline at end of file + diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index ebb839971..dae9d4bc8 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -1014,6 +1014,14 @@ RelativePath="..\..\src\game\Transports.h" > + + + +