aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Movement
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Movement')
-rw-r--r--src/server/game/Movement/MotionMaster.cpp3
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp111
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h36
-rw-r--r--src/server/game/Movement/Waypoints/Path.h100
4 files changed, 107 insertions, 143 deletions
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index b69322f5720..2bcb4aeb3b3 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -563,7 +563,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 f91fc1985d5..8c61c96dfdc 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -245,17 +245,64 @@ 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->LocX - p2->LocX, 2) + std::pow(p1->LocY - p2->LocY, 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)
+ {
+ sMapMgr->CreateMap(nodes[i]->MapID, player)->SummonCreature(1, { nodes[i]->LocX, nodes[i]->LocY, nodes[i]->LocZ, 0.0f })->SetLevel(i ? i : 1);
+
+ 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 +343,7 @@ void FlightPathMovementGenerator::DoReset(Player* player)
uint32 end = GetPathAtMapEnd();
for (uint32 i = GetCurrentNode(); i != end; ++i)
{
- G3D::Vector3 vertice((*i_path)[i].LocX, (*i_path)[i].LocY, (*i_path)[i].LocZ);
+ G3D::Vector3 vertice(i_path[i]->LocX, i_path[i]->LocY, i_path[i]->LocZ);
init.Path().push_back(vertice);
}
init.SetFirstPointId(GetCurrentNode());
@@ -313,9 +360,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;
@@ -324,18 +383,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;
@@ -343,19 +402,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.LocX; y = node.LocY; z = node.LocZ;
+ TaxiPathNodeEntry const* node = i_path[i_currentNode];
+ x = node->LocX;
+ y = node->LocY;
+ z = node->LocZ;
return true;
}
@@ -363,11 +424,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].LocX;
- _endGridY = (*i_path)[nodeCount - 1].LocY;
+ _endGridX = i_path[nodeCount - 1]->LocX;
+ _endGridY = i_path[nodeCount - 1]->LocY;
}
void FlightPathMovementGenerator::PreloadEndGrid()
@@ -378,7 +439,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..6cddd68ec1c 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
@@ -45,8 +40,6 @@ class PathMovementBase
PathMovementBase() : i_path(NULL), 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 bb8abc37eb3..00000000000
--- a/src/server/game/Movement/Waypoints/Path.h
+++ /dev/null
@@ -1,100 +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;
-};
-
-typedef Path<PathNode> SimplePath;
-
-#endif