Skip to content

Commit

Permalink
[12105] Implement abstract classes for transporter
Browse files Browse the repository at this point in the history
This includes class TransportBase as helper class for transporter
And class TransportInfo has helper class for passengers on a transporter

Signed-off-by: Schmoozerd <schmoozerd@scriptdev2.com>
  • Loading branch information
kid10 authored and Schmoozerd committed Aug 21, 2012
1 parent 5bb227c commit fab94fa
Show file tree
Hide file tree
Showing 7 changed files with 303 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/game/Object.h
Expand Up @@ -77,6 +77,7 @@ typedef UNORDERED_MAP<Player*, UpdateData> 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;
};

Expand Down
161 changes: 161 additions & 0 deletions src/game/TransportSystem.cpp
@@ -0,0 +1,161 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* 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);
}

/*! @} */
122 changes: 122 additions & 0 deletions src/game/TransportSystem.h
@@ -0,0 +1,122 @@
/*
* Copyright (C) 2005-2012 MaNGOS <http://getmangos.com/>
*
* 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
/*! @} */
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "12104"
#define REVISION_NR "12105"
#endif // __REVISION_NR_H__
4 changes: 3 additions & 1 deletion win/VC100/game.vcxproj
Expand Up @@ -481,6 +481,7 @@
<ClCompile Include="..\..\src\game\Spell.cpp" />
<ClCompile Include="..\..\src\game\SpellAuras.cpp" />
<ClCompile Include="..\..\src\game\SQLStorages.cpp" />
<ClCompile Include="..\..\src\game\TransportSystem.cpp" />
<ClCompile Include="..\..\src\game\UnitAuraProcHandler.cpp" />
<ClCompile Include="..\..\src\game\SpellEffects.cpp" />
<ClCompile Include="..\..\src\game\SpellHandler.cpp" />
Expand Down Expand Up @@ -653,6 +654,7 @@
<ClInclude Include="..\..\src\game\Totem.h" />
<ClInclude Include="..\..\src\game\TotemAI.h" />
<ClInclude Include="..\..\src\game\Transports.h" />
<ClInclude Include="..\..\src\game\TransportSystem.h" />
<ClInclude Include="..\..\src\game\Unit.h" />
<ClInclude Include="..\..\src\game\UnitEvents.h" />
<ClInclude Include="..\..\src\game\UpdateData.h" />
Expand Down Expand Up @@ -700,4 +702,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
8 changes: 7 additions & 1 deletion win/VC100/game.vcxproj.filters
Expand Up @@ -541,6 +541,9 @@
<ClCompile Include="..\..\src\game\CreatureLinkingMgr.cpp">
<Filter>World/Handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\game\TransportSystem.cpp">
<Filter>Object</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\game\AccountMgr.h">
Expand Down Expand Up @@ -1027,5 +1030,8 @@
<ClInclude Include="..\..\src\game\CreatureLinkingMgr.h">
<Filter>World/Handlers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\game\TransportSystem.h">
<Filter>Object</Filter>
</ClInclude>
</ItemGroup>
</Project>
</Project>
8 changes: 8 additions & 0 deletions win/VC90/game.vcproj
Expand Up @@ -1014,6 +1014,14 @@
RelativePath="..\..\src\game\Transports.h"
>
</File>
<File
RelativePath="..\..\src\game\TransportSystem.cpp"
>
</File>
<File
RelativePath="..\..\src\game\TransportSystem.h"
>
</File>
<File
RelativePath="..\..\src\game\UnitAuraProcHandler.cpp"
>
Expand Down

9 comments on commit fab94fa

@rsa
Copy link
Contributor

@rsa rsa commented on fab94fa Aug 21, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting rework of recent Shauren implementation of the on-transport moving... Only, I hope you know that it's pretty rough hack, and the transport moving realized is by "submap" moving? As I recall, a description of the mechanics, published in the last 2 years at least 3 times. Although, of course, the implementation of this type of traffic is very complicated...

@Schmoozerd
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

false, false, maybe, depends.

@rsa
Copy link
Contributor

@rsa rsa commented on fab94fa Aug 21, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

o

@Shauren
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The map files for transports exist in game files for one purpose: to display a special loading screen during teleport. These maps have no terrain files for pathfinding (adt, wdt, wmo) - only the GameObject model (.m2) exists, but the map (not transport) is not linked to it in any way.

@rsa
Copy link
Contributor

@rsa rsa commented on fab94fa Aug 21, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Shauren, m2 sufficient for create vmo and LOS/etc calculating (only pathfinding currently impossible). over a year ago i make simple realization of submap moving, works (but without dynamic_vmaps many other problems appears). but in current stage of mangos development no sence in this method...

@Shauren
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rsa, while I agree that my implementation for this movement is not the best out there, I don't see the need for creating such complicated (as you stated in your first comment) thing as submap.

@rsa
Copy link
Contributor

@rsa rsa commented on fab94fa Aug 21, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Shauren, i'm agree - this is challenging, maybe just the way (like yours) is much more effective. But without submaps you can not fully emulate blizz sniffs :) Also, in my opinion, the solution to this problem is very interesting ...

@Schmoozerd
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no submap.

@Shauren
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rsa, actually you do get data like in sniffs on tc, we pay very much attention to that detail. If you believe that it's still not possible, I'll ask which part cannot be done fully blizzlike (which packet, where in that packet)

Please sign in to comment.