aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/Common.h1
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp2
-rw-r--r--src/server/game/DataStores/DB2Structure.h11
-rw-r--r--src/server/game/DataStores/DBCStructure.h5
-rw-r--r--src/server/game/Entities/Player/Player.cpp33
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp1
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp10
-rw-r--r--src/server/game/Handlers/TaxiHandler.cpp64
-rw-r--r--src/server/game/Maps/TransportMgr.cpp8
-rw-r--r--src/server/game/Maps/TransportMgr.h2
-rw-r--r--src/server/game/Movement/MotionMaster.cpp3
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp109
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h38
-rw-r--r--src/server/game/Movement/Waypoints/Path.h98
15 files changed, 158 insertions, 229 deletions
diff --git a/src/common/Common.h b/src/common/Common.h
index e83340bdd84..58bb006166a 100644
--- a/src/common/Common.h
+++ b/src/common/Common.h
@@ -39,6 +39,7 @@
#include <sstream>
#include <algorithm>
#include <memory>
+#include <vector>
#include <boost/optional.hpp>
#include <boost/utility/in_place_factory.hpp>
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index ae26119986c..68658586239 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -443,7 +443,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
// fill data
for (TaxiPathNodeEntry const* entry : sTaxiPathNodeStore)
- sTaxiPathNodesByPath[entry->PathID].set(entry->NodeIndex, entry);
+ sTaxiPathNodesByPath[entry->PathID][entry->NodeIndex] = entry;
// Initialize global taxinodes mask
// include existed nodes that have at least single not spell base (scripted) path
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index f2f8bec2b68..9c898ea0101 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -20,7 +20,6 @@
#include "Common.h"
#include "DBCEnums.h"
-#include "Path.h"
#include "Util.h"
#pragma pack(push, 1)
@@ -1358,15 +1357,7 @@ struct TaxiPathBySourceAndDestination
typedef std::map<uint32, TaxiPathBySourceAndDestination> TaxiPathSetForSource;
typedef std::map<uint32, TaxiPathSetForSource> TaxiPathSetBySource;
-struct TaxiPathNodePtr
-{
- TaxiPathNodePtr() : i_ptr(NULL) { }
- TaxiPathNodePtr(TaxiPathNodeEntry const* ptr) : i_ptr(ptr) { }
- TaxiPathNodeEntry const* i_ptr;
- operator TaxiPathNodeEntry const& () const { return *i_ptr; }
-};
-
-typedef Path<TaxiPathNodePtr, TaxiPathNodeEntry const> TaxiPathNodeList;
+typedef std::vector<TaxiPathNodeEntry const*> TaxiPathNodeList;
typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath;
#define TaxiMaskSize 217
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index dc53a316ee7..b2a2704307e 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -21,13 +21,8 @@
#include "Common.h"
#include "DBCEnums.h"
-#include "Path.h"
#include "Util.h"
-#include <map>
-#include <set>
-#include <vector>
-
// Structures using to access raw DBC data and required packing to portability
#pragma pack(push, 1)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index b00b18f2f4f..9689144ebc9 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -21038,6 +21038,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
// fill destinations path tail
uint32 sourcepath = 0;
uint32 totalcost = 0;
+ uint32 firstcost = 0;
uint32 prevnode = sourcenode;
uint32 lastnode = 0;
@@ -21056,6 +21057,8 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
}
totalcost += cost;
+ if (i == 1)
+ firstcost = cost;
if (prevnode == sourcenode)
sourcepath = path;
@@ -21094,8 +21097,6 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
}
//Checks and preparations done, DO FLIGHT
- ModifyMoney(-int64(totalcost));
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1);
// prevent stealth flight
@@ -21106,11 +21107,15 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
TaxiNodesEntry const* lastPathNode = sTaxiNodesStore.LookupEntry(nodes[nodes.size()-1]);
ASSERT(lastPathNode);
m_taxi.ClearTaxiDestinations();
+ ModifyMoney(-int64(totalcost));
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
TeleportTo(lastPathNode->MapID, lastPathNode->Pos.X, lastPathNode->Pos.Y, lastPathNode->Pos.Z, GetOrientation());
return false;
}
else
{
+ ModifyMoney(-int64(firstcost));
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, firstcost);
GetSession()->SendActivateTaxiReply(ERR_TAXIOK);
GetSession()->SendDoFlight(mount_display_id, sourcepath);
}
@@ -21161,30 +21166,30 @@ void Player::ContinueTaxiFlight()
float distPrev = MAP_SIZE*MAP_SIZE;
float distNext =
- (nodeList[0].Loc.X-GetPositionX())*(nodeList[0].Loc.X-GetPositionX())+
- (nodeList[0].Loc.Y-GetPositionY())*(nodeList[0].Loc.Y-GetPositionY())+
- (nodeList[0].Loc.Z-GetPositionZ())*(nodeList[0].Loc.Z-GetPositionZ());
+ (nodeList[0]->Loc.X - GetPositionX())*(nodeList[0]->Loc.X - GetPositionX()) +
+ (nodeList[0]->Loc.Y - GetPositionY())*(nodeList[0]->Loc.Y - GetPositionY()) +
+ (nodeList[0]->Loc.Z - GetPositionZ())*(nodeList[0]->Loc.Z - GetPositionZ());
for (uint32 i = 1; i < nodeList.size(); ++i)
{
- TaxiPathNodeEntry const& node = nodeList[i];
- TaxiPathNodeEntry const& prevNode = nodeList[i-1];
+ TaxiPathNodeEntry const* node = nodeList[i];
+ TaxiPathNodeEntry const* prevNode = nodeList[i-1];
// skip nodes at another map
- if (node.MapID != GetMapId())
+ if (node->MapID != GetMapId())
continue;
distPrev = distNext;
distNext =
- (node.Loc.X-GetPositionX())*(node.Loc.X-GetPositionX())+
- (node.Loc.Y-GetPositionY())*(node.Loc.Y-GetPositionY())+
- (node.Loc.Z-GetPositionZ())*(node.Loc.Z-GetPositionZ());
+ (node->Loc.X - GetPositionX()) * (node->Loc.X - GetPositionX()) +
+ (node->Loc.Y - GetPositionY()) * (node->Loc.Y - GetPositionY()) +
+ (node->Loc.Z - GetPositionZ()) * (node->Loc.Z - GetPositionZ());
float distNodes =
- (node.Loc.X-prevNode.Loc.X)*(node.Loc.X-prevNode.Loc.X)+
- (node.Loc.Y-prevNode.Loc.Y)*(node.Loc.Y-prevNode.Loc.Y)+
- (node.Loc.Z-prevNode.Loc.Z)*(node.Loc.Z-prevNode.Loc.Z);
+ (node->Loc.X - prevNode->Loc.X) * (node->Loc.X - prevNode->Loc.X) +
+ (node->Loc.Y - prevNode->Loc.Y) * (node->Loc.Y - prevNode->Loc.Y) +
+ (node->Loc.Z - prevNode->Loc.Z) * (node->Loc.Z - prevNode->Loc.Z);
if (distNext + distPrev < distNodes)
{
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index d4973e0f332..559f1f28570 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1129,6 +1129,8 @@ class PlayerTaxi
m_TaxiDestinations.pop_front();
return GetTaxiDestination();
}
+
+ std::deque<uint32> const& GetPath() const { return m_TaxiDestinations; }
bool empty() const { return m_TaxiDestinations.empty(); }
friend std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi);
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 0be9a205e5b..e6b3067cc2a 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -20,7 +20,6 @@
#include "Transport.h"
#include "MapManager.h"
#include "ObjectMgr.h"
-#include "Path.h"
#include "ScriptMgr.h"
#include "DBCStores.h"
#include "GameObjectAI.h"
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 7f014e22efb..5352112caca 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -4875,13 +4875,13 @@ void ObjectMgr::LoadEventScripts()
{
for (size_t node_idx = 0; node_idx < sTaxiPathNodesByPath[path_idx].size(); ++node_idx)
{
- TaxiPathNodeEntry const& node = sTaxiPathNodesByPath[path_idx][node_idx];
+ TaxiPathNodeEntry const* node = sTaxiPathNodesByPath[path_idx][node_idx];
- if (node.ArrivalEventID)
- evt_scripts.insert(node.ArrivalEventID);
+ if (node->ArrivalEventID)
+ evt_scripts.insert(node->ArrivalEventID);
- if (node.DepartureEventID)
- evt_scripts.insert(node.DepartureEventID);
+ if (node->DepartureEventID)
+ evt_scripts.insert(node->DepartureEventID);
}
}
diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp
index 20a8ba70f76..1669bc306d6 100644
--- a/src/server/game/Handlers/TaxiHandler.cpp
+++ b/src/server/game/Handlers/TaxiHandler.cpp
@@ -24,7 +24,6 @@
#include "Log.h"
#include "ObjectMgr.h"
#include "Player.h"
-#include "Path.h"
#include "WaypointMovementGenerator.h"
void WorldSession::HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvData)
@@ -198,7 +197,7 @@ void WorldSession::HandleActivateTaxiExpressOpcode (WorldPacket& recvData)
void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData)
{
- recvData.read_skip<uint32>(); // unk
+ recvData.read_skip<uint32>(); // spline id
MovementInfo movementInfo; // used only for proper packet read
_player->ValidateMovementInfo(&movementInfo);
@@ -209,59 +208,32 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData)
// we need process only (1)
uint32 curDest = GetPlayer()->m_taxi.GetTaxiDestination();
- if (!curDest)
- return;
-
- TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
-
- // far teleport case
- if (curDestNode && curDestNode->MapID != GetPlayer()->GetMapId())
+ if (curDest)
{
- if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
- {
- // short preparations to continue flight
- FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top());
-
- flight->SetCurrentNodeAfterTeleport();
- TaxiPathNodeEntry const& node = flight->GetPath()[flight->GetCurrentNode()];
- flight->SkipCurrentNode();
+ TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
- GetPlayer()->TeleportTo(curDestNode->MapID, node.Loc.X, node.Loc.Y, node.Loc.Z, GetPlayer()->GetOrientation());
- }
- return;
- }
-
- uint32 destinationnode = GetPlayer()->m_taxi.NextTaxiDestination();
- if (destinationnode > 0) // if more destinations to go
- {
- // current source node for next destination
- uint32 sourcenode = GetPlayer()->m_taxi.GetTaxiSource();
-
- // Add to taximask middle hubs in taxicheat mode (to prevent having player with disabled taxicheat and not having back flight path)
- if (GetPlayer()->isTaxiCheater())
+ // far teleport case
+ if (curDestNode && curDestNode->MapID != GetPlayer()->GetMapId())
{
- if (GetPlayer()->m_taxi.SetTaximaskNode(sourcenode))
+ if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
{
- WorldPacket data(SMSG_NEW_TAXI_PATH, 0);
- _player->GetSession()->SendPacket(&data);
- }
- }
+ // short preparations to continue flight
+ FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top());
- TC_LOG_DEBUG("network", "WORLD: Taxi has to go from %u to %u", sourcenode, destinationnode);
+ flight->SetCurrentNodeAfterTeleport();
+ TaxiPathNodeEntry const* node = flight->GetPath()[flight->GetCurrentNode()];
+ flight->SkipCurrentNode();
- uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetPlayer()->GetTeam());
-
- uint32 path, cost;
- sObjectMgr->GetTaxiPath(sourcenode, destinationnode, path, cost);
+ GetPlayer()->TeleportTo(curDestNode->MapID, node->Loc.X, node->Loc.Y, node->Loc.Z, GetPlayer()->GetOrientation());
+ }
+ }
- if (path && mountDisplayId)
- SendDoFlight(mountDisplayId, path, 1); // skip start fly node
- else
- GetPlayer()->m_taxi.ClearTaxiDestinations(); // clear problematic path and next
return;
}
- else
- GetPlayer()->m_taxi.ClearTaxiDestinations(); // not destinations, clear source node
+
+ // at this point only 1 node is expected (final destination)
+ if (GetPlayer()->m_taxi.GetPath().size() != 1)
+ return;
GetPlayer()->CleanupAfterTaxiFlight();
GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ());
diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp
index 8c7442a8ae5..86c4fb73108 100644
--- a/src/server/game/Maps/TransportMgr.cpp
+++ b/src/server/game/Maps/TransportMgr.cpp
@@ -114,7 +114,7 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl
Movement::PointsArray splinePath, allPoints;
bool mapChange = false;
for (size_t i = 0; i < path.size(); ++i)
- allPoints.push_back(G3D::Vector3(path[i].Loc.X, path[i].Loc.Y, path[i].Loc.Z));
+ allPoints.push_back(G3D::Vector3(path[i]->Loc.X, path[i]->Loc.Y, path[i]->Loc.Z));
// Add extra points to allow derivative calculations for all path nodes
allPoints.insert(allPoints.begin(), allPoints.front().lerp(allPoints[1], -0.2f));
@@ -130,8 +130,8 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl
{
if (!mapChange)
{
- TaxiPathNodeEntry const& node_i = path[i];
- if (i != path.size() - 1 && (node_i.Flags & 1 || node_i.MapID != path[i + 1].MapID))
+ TaxiPathNodeEntry const* node_i = path[i];
+ if (i != path.size() - 1 && (node_i->Flags & 1 || node_i->MapID != path[i + 1]->MapID))
{
keyFrames.back().Teleport = true;
mapChange = true;
@@ -144,7 +144,7 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl
k.InitialOrientation = Position::NormalizeOrientation(std::atan2(h.y, h.x) + float(M_PI));
keyFrames.push_back(k);
- splinePath.push_back(G3D::Vector3(node_i.Loc.X, node_i.Loc.Y, node_i.Loc.Z));
+ splinePath.push_back(G3D::Vector3(node_i->Loc.X, node_i->Loc.Y, node_i->Loc.Z));
transport->mapsUsed.insert(k.Node->MapID);
}
}
diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h
index 61d08908b78..5e032dbd71f 100644
--- a/src/server/game/Maps/TransportMgr.h
+++ b/src/server/game/Maps/TransportMgr.h
@@ -39,7 +39,7 @@ typedef std::unordered_map<uint32, std::set<uint32> > TransportInstanceMap;
struct KeyFrame
{
- explicit KeyFrame(TaxiPathNodeEntry const& _node) : Index(0), Node(&_node), InitialOrientation(0.0f),
+ explicit KeyFrame(TaxiPathNodeEntry const* node) : Index(0), Node(node), InitialOrientation(0.0f),
DistSinceStop(-1.0f), DistUntilStop(-1.0f), DistFromPrev(-1.0f), TimeFrom(0.0f), TimeTo(0.0f),
Teleport(false), ArriveTime(0), DepartureTime(0), Spline(NULL), NextDistFromPrev(0.0f), NextArriveTime(0)
{
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 0a4deebbbfc..50ff839e23c 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -534,7 +534,8 @@ void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
if (path < sTaxiPathNodesByPath.size())
{
TC_LOG_DEBUG("misc", "%s taxi to (Path %u node %u)", _owner->GetName().c_str(), path, pathnode);
- FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(sTaxiPathNodesByPath[path], pathnode);
+ FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(pathnode);
+ mgen->LoadPath(_owner->ToPlayer());
Mutate(mgen, MOTION_SLOT_CONTROLLED);
}
else
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index 46ccd8638da..a0858b35c17 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -245,17 +245,62 @@ bool WaypointMovementGenerator<Creature>::GetResetPos(Creature*, float& x, float
uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const
{
- if (i_currentNode >= i_path->size())
- return i_path->size();
+ if (i_currentNode >= i_path.size())
+ return i_path.size();
- uint32 curMapId = (*i_path)[i_currentNode].MapID;
- for (uint32 i = i_currentNode; i < i_path->size(); ++i)
- {
- if ((*i_path)[i].MapID != curMapId)
+ uint32 curMapId = i_path[i_currentNode]->MapID;
+ for (uint32 i = i_currentNode; i < i_path.size(); ++i)
+ if (i_path[i]->MapID != curMapId)
return i;
- }
- return i_path->size();
+ return i_path.size();
+}
+
+#define SKIP_SPLINE_POINT_DISTANCE_SQ (40.0f * 40.0f)
+
+bool IsNodeIncludedInShortenedPath(TaxiPathNodeEntry const* p1, TaxiPathNodeEntry const* p2)
+{
+ return p1->MapID != p2->MapID || std::pow(p1->Loc.X - p2->Loc.X, 2) + std::pow(p1->Loc.Y - p2->Loc.Y, 2) > SKIP_SPLINE_POINT_DISTANCE_SQ;
+}
+
+void FlightPathMovementGenerator::LoadPath(Player* player)
+{
+ _pointsForPathSwitch.clear();
+ std::deque<uint32> const& taxi = player->m_taxi.GetPath();
+ for (uint32 src = 0, dst = 1; dst < taxi.size(); src = dst++)
+ {
+ uint32 path, cost;
+ sObjectMgr->GetTaxiPath(taxi[src], taxi[dst], path, cost);
+ if (path > sTaxiPathNodesByPath.size())
+ return;
+
+ TaxiPathNodeList const& nodes = sTaxiPathNodesByPath[path];
+ if (!nodes.empty())
+ {
+ TaxiPathNodeEntry const* start = nodes[0];
+ TaxiPathNodeEntry const* end = nodes[nodes.size() - 1];
+ bool passedPreviousSegmentProximityCheck = false;
+ for (uint32 i = 0; i < nodes.size(); ++i)
+ {
+ if (passedPreviousSegmentProximityCheck || !src || i_path.empty() || IsNodeIncludedInShortenedPath(i_path[i_path.size() - 1], nodes[i]))
+ {
+ if ((!src || (IsNodeIncludedInShortenedPath(start, nodes[i]) && i >= 2)) &&
+ (dst == taxi.size() - 1 || (IsNodeIncludedInShortenedPath(end, nodes[i]) && i < nodes.size() - 1)))
+ {
+ passedPreviousSegmentProximityCheck = true;
+ i_path.push_back(nodes[i]);
+ }
+ }
+ else
+ {
+ i_path.pop_back();
+ --_pointsForPathSwitch.back().PathIndex;
+ }
+ }
+ }
+
+ _pointsForPathSwitch.push_back({ uint32(i_path.size() - 1), int32(cost) });
+ }
}
void FlightPathMovementGenerator::DoInitialize(Player* player)
@@ -296,7 +341,7 @@ void FlightPathMovementGenerator::DoReset(Player* player)
uint32 end = GetPathAtMapEnd();
for (uint32 i = GetCurrentNode(); i != end; ++i)
{
- G3D::Vector3 vertice((*i_path)[i].Loc.X, (*i_path)[i].Loc.Y, (*i_path)[i].Loc.Z);
+ G3D::Vector3 vertice(i_path[i]->Loc.X, i_path[i]->Loc.Y, i_path[i]->Loc.Z);
init.Path().push_back(vertice);
}
init.SetFirstPointId(GetCurrentNode());
@@ -316,9 +361,21 @@ bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/)
bool departureEvent = true;
do
{
- DoEventIfAny(player, (*i_path)[i_currentNode], departureEvent);
+ DoEventIfAny(player, i_path[i_currentNode], departureEvent);
+ while (!_pointsForPathSwitch.empty() && _pointsForPathSwitch.front().PathIndex <= i_currentNode)
+ {
+ _pointsForPathSwitch.pop_front();
+ player->m_taxi.NextTaxiDestination();
+ if (!_pointsForPathSwitch.empty())
+ {
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, _pointsForPathSwitch.front().Cost);
+ player->ModifyMoney(-_pointsForPathSwitch.front().Cost);
+ }
+ }
+
if (pointId == i_currentNode)
break;
+
if (i_currentNode == _preloadTargetNode)
PreloadEndGrid();
i_currentNode += (uint32)departureEvent;
@@ -327,18 +384,18 @@ bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/)
while (true);
}
- return i_currentNode < (i_path->size()-1);
+ return i_currentNode < (i_path.size() - 1);
}
void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
{
- if (i_path->empty())
+ if (i_path.empty() || i_currentNode >= i_path.size())
return;
- uint32 map0 = (*i_path)[0].MapID;
- for (size_t i = 1; i < i_path->size(); ++i)
+ uint32 map0 = i_path[i_currentNode]->MapID;
+ for (size_t i = i_currentNode + 1; i < i_path.size(); ++i)
{
- if ((*i_path)[i].MapID != map0)
+ if (i_path[i]->MapID != map0)
{
i_currentNode = i;
return;
@@ -346,19 +403,21 @@ void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
}
}
-void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry const& node, bool departure)
+void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry const* node, bool departure)
{
- if (uint32 eventid = departure ? node.DepartureEventID : node.ArrivalEventID)
+ if (uint32 eventid = departure ? node->DepartureEventID : node->ArrivalEventID)
{
- TC_LOG_DEBUG("maps.script", "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.NodeIndex, node.PathID, player->GetName().c_str());
+ TC_LOG_DEBUG("maps.script", "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node->NodeIndex, node->PathID, player->GetName().c_str());
player->GetMap()->ScriptsStart(sEventScripts, eventid, player, player);
}
}
bool FlightPathMovementGenerator::GetResetPos(Player*, float& x, float& y, float& z)
{
- const TaxiPathNodeEntry& node = (*i_path)[i_currentNode];
- x = node.Loc.X; y = node.Loc.Y; z = node.Loc.Z;
+ TaxiPathNodeEntry const* node = i_path[i_currentNode];
+ x = node->Loc.X;
+ y = node->Loc.Y;
+ z = node->Loc.Z;
return true;
}
@@ -366,11 +425,11 @@ void FlightPathMovementGenerator::InitEndGridInfo()
{
/*! Storage to preload flightmaster grid at end of flight. For multi-stop flights, this will
be reinitialized for each flightmaster at the end of each spline (or stop) in the flight. */
- uint32 nodeCount = (*i_path).size(); //! Number of nodes in path.
- _endMapId = (*i_path)[nodeCount - 1].MapID; //! MapId of last node
+ uint32 nodeCount = i_path.size(); //! Number of nodes in path.
+ _endMapId = i_path[nodeCount - 1]->MapID; //! MapId of last node
_preloadTargetNode = nodeCount - 3;
- _endGridX = (*i_path)[nodeCount - 1].Loc.X;
- _endGridY = (*i_path)[nodeCount - 1].Loc.Y;
+ _endGridX = i_path[nodeCount - 1]->Loc.X;
+ _endGridY = i_path[nodeCount - 1]->Loc.Y;
}
void FlightPathMovementGenerator::PreloadEndGrid()
@@ -381,7 +440,7 @@ void FlightPathMovementGenerator::PreloadEndGrid()
// Load the grid
if (endMap)
{
- TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path->size()-1));
+ TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path.size() - 1));
endMap->LoadGrid(_endGridX, _endGridY);
}
else
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
index eb8533159a9..caf76b5ea19 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
@@ -27,13 +27,8 @@
#include "MovementGenerator.h"
#include "WaypointManager.h"
-#include "Path.h"
-
#include "Player.h"
-#include <vector>
-#include <set>
-
#define FLIGHT_TRAVEL_UPDATE 100
#define STOP_TIME_FOR_PLAYER 3 * MINUTE * IN_MILLISECONDS // 3 Minutes
#define TIMEDIFF_NEXT_WP 250
@@ -42,11 +37,9 @@ template<class T, class P>
class PathMovementBase
{
public:
- PathMovementBase() : i_path(NULL), i_currentNode(0) { }
+ PathMovementBase() : i_path(), i_currentNode(0) { }
virtual ~PathMovementBase() { };
- // template pattern, not defined .. override required
- void LoadPath(T &);
uint32 GetCurrentNode() const { return i_currentNode; }
protected:
@@ -110,30 +103,30 @@ class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium< Crea
* and hence generates ground and activities for the player.
*/
class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, FlightPathMovementGenerator >,
- public PathMovementBase<Player, TaxiPathNodeList const*>
+ public PathMovementBase<Player, TaxiPathNodeList>
{
public:
- explicit FlightPathMovementGenerator(TaxiPathNodeList const& pathnodes, uint32 startNode = 0)
+ explicit FlightPathMovementGenerator(uint32 startNode = 0)
{
- i_path = &pathnodes;
i_currentNode = startNode;
_endGridX = 0.0f;
_endGridY = 0.0f;
_endMapId = 0;
_preloadTargetNode = 0;
}
+ void LoadPath(Player* player);
void DoInitialize(Player*);
void DoReset(Player*);
void DoFinalize(Player*);
bool DoUpdate(Player*, uint32);
MovementGeneratorType GetMovementGeneratorType() const override { return FLIGHT_MOTION_TYPE; }
- TaxiPathNodeList const& GetPath() { return *i_path; }
+ TaxiPathNodeList const& GetPath() { return i_path; }
uint32 GetPathAtMapEnd() const;
- bool HasArrived() const { return (i_currentNode >= i_path->size()); }
+ bool HasArrived() const { return (i_currentNode >= i_path.size()); }
void SetCurrentNodeAfterTeleport();
void SkipCurrentNode() { ++i_currentNode; }
- void DoEventIfAny(Player* player, TaxiPathNodeEntry const& node, bool departure);
+ void DoEventIfAny(Player* player, TaxiPathNodeEntry const* node, bool departure);
bool GetResetPos(Player*, float& x, float& y, float& z);
@@ -141,9 +134,18 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig
void PreloadEndGrid();
private:
- float _endGridX; //! X coord of last node location
- float _endGridY; //! Y coord of last node location
- uint32 _endMapId; //! map Id of last node location
- uint32 _preloadTargetNode; //! node index where preloading starts
+
+ float _endGridX; //! X coord of last node location
+ float _endGridY; //! Y coord of last node location
+ uint32 _endMapId; //! map Id of last node location
+ uint32 _preloadTargetNode; //! node index where preloading starts
+
+ struct TaxiNodeChangeInfo
+ {
+ uint32 PathIndex;
+ int32 Cost;
+ };
+
+ std::deque<TaxiNodeChangeInfo> _pointsForPathSwitch; //! node indexes and costs where TaxiPath changes
};
#endif
diff --git a/src/server/game/Movement/Waypoints/Path.h b/src/server/game/Movement/Waypoints/Path.h
deleted file mode 100644
index 844089cf393..00000000000
--- a/src/server/game/Movement/Waypoints/Path.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITYCORE_PATH_H
-#define TRINITYCORE_PATH_H
-
-#include "Common.h"
-#include <deque>
-
-struct PathNode
-{
- PathNode(): x(0.0f), y(0.0f), z(0.0f) { }
- PathNode(float _x, float _y, float _z): x(_x), y(_y), z(_z) { }
- float x, y, z;
-};
-
-template<typename PathElem, typename PathNode = PathElem>
-class Path
-{
- public:
- size_t size() const { return i_nodes.size(); }
- bool empty() const { return i_nodes.empty(); }
- void resize(unsigned int sz) { i_nodes.resize(sz); }
- void clear() { i_nodes.clear(); }
- void erase(uint32 idx) { i_nodes.erase(i_nodes.begin() + idx); }
- void crop(unsigned int start, unsigned int end)
- {
- while (start && !i_nodes.empty())
- {
- i_nodes.pop_front();
- --start;
- }
-
- while (end && !i_nodes.empty())
- {
- i_nodes.pop_back();
- --end;
- }
- }
-
- float GetTotalLength(uint32 start, uint32 end) const
- {
- float len = 0.0f;
- for (uint32 idx = start + 1; idx < end; ++idx)
- {
- PathNode const& node = i_nodes[idx];
- PathNode const& prev = i_nodes[idx - 1];
- float xd = node.x - prev.x;
- float yd = node.y - prev.y;
- float zd = node.z - prev.z;
- len += std::sqrt(xd*xd + yd*yd + zd*zd);
- }
- return len;
- }
-
- float GetTotalLength() const { return GetTotalLength(0, size()); }
-
- float GetPassedLength(uint32 curnode, float x, float y, float z) const
- {
- float len = GetTotalLength(0, curnode);
-
- if (curnode > 0)
- {
- PathNode const& node = i_nodes[curnode - 1];
- float xd = x - node.x;
- float yd = y - node.y;
- float zd = z - node.z;
- len += std::sqrt(xd*xd + yd*yd + zd*zd);
- }
-
- return len;
- }
-
- PathNode& operator[](size_t idx) { return i_nodes[idx]; }
- PathNode const& operator[](size_t idx) const { return i_nodes[idx]; }
-
- void set(size_t idx, PathElem elem) { i_nodes[idx] = elem; }
-
- protected:
- std::deque<PathElem> i_nodes;
-};
-
-#endif