aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/PlayerTaxi.cpp8
-rw-r--r--src/server/game/Entities/Taxi/TaxiPathGraph.cpp64
-rw-r--r--src/server/game/Entities/Taxi/TaxiPathGraph.h8
-rw-r--r--src/server/game/Handlers/TaxiHandler.cpp10
-rw-r--r--src/server/game/Server/Packets/TaxiPackets.cpp8
-rw-r--r--src/server/game/Server/Packets/TaxiPackets.h4
6 files changed, 74 insertions, 28 deletions
diff --git a/src/server/game/Entities/Player/PlayerTaxi.cpp b/src/server/game/Entities/Player/PlayerTaxi.cpp
index 7a7f8d8533c..68d34e97c33 100644
--- a/src/server/game/Entities/Player/PlayerTaxi.cpp
+++ b/src/server/game/Entities/Player/PlayerTaxi.cpp
@@ -111,13 +111,13 @@ void PlayerTaxi::AppendTaximaskTo(WorldPackets::Taxi::ShowTaxiNodes& data, bool
{
if (all)
{
- data.CanLandNodes = &sTaxiNodesMask; // all existed nodes
- data.CanUseNodes = &sTaxiNodesMask;
+ data.CanLandNodes = sTaxiNodesMask; // all existed nodes
+ data.CanUseNodes = sTaxiNodesMask;
}
else
{
- data.CanLandNodes = &m_taximask; // known nodes
- data.CanUseNodes = &m_taximask;
+ data.CanLandNodes = m_taximask; // known nodes
+ data.CanUseNodes = m_taximask;
}
}
diff --git a/src/server/game/Entities/Taxi/TaxiPathGraph.cpp b/src/server/game/Entities/Taxi/TaxiPathGraph.cpp
index b60c1780fd3..2614ad0520c 100644
--- a/src/server/game/Entities/Taxi/TaxiPathGraph.cpp
+++ b/src/server/game/Entities/Taxi/TaxiPathGraph.cpp
@@ -21,6 +21,7 @@
#include "DB2Stores.h"
#include "Config.h"
#include "Util.h"
+#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/property_map/transform_value_property_map.hpp>
@@ -32,7 +33,7 @@ TaxiPathGraph& TaxiPathGraph::Instance()
void TaxiPathGraph::Initialize()
{
- if (GetVertexCount() > 0)
+ if (boost::num_vertices(m_graph) > 0)
return;
std::vector<std::pair<edge, EdgeCost>> edges;
@@ -47,7 +48,7 @@ void TaxiPathGraph::Initialize()
}
// create graph
- m_graph = Graph(GetVertexCount());
+ m_graph = Graph(m_nodesByVertex.size());
WeightMap weightmap = boost::get(boost::edge_weight, m_graph);
for (std::size_t j = 0; j < edges.size(); ++j)
@@ -59,21 +60,16 @@ void TaxiPathGraph::Initialize()
uint32 TaxiPathGraph::GetNodeIDFromVertexID(vertex_descriptor vertexID)
{
- if (vertexID < m_vertices.size())
- return m_vertices[vertexID]->ID;
+ if (vertexID < m_nodesByVertex.size())
+ return m_nodesByVertex[vertexID]->ID;
return std::numeric_limits<uint32>::max();
}
TaxiPathGraph::vertex_descriptor TaxiPathGraph::GetVertexIDFromNodeID(TaxiNodesEntry const* node)
{
- return node->CharacterBitNumber;
-}
-
-std::size_t TaxiPathGraph::GetVertexCount()
-{
- //So we can use this function for readability, we define either max defined vertices or already loaded in graph count
- return std::max(boost::num_vertices(m_graph), m_vertices.size());
+ auto itr = m_verticesByNode.find(node->ID);
+ return itr != m_verticesByNode.end() ? itr->second : std::numeric_limits<vertex_descriptor>::max();
}
void GetTaxiMapPosition(DBCPosition3D const& position, int32 mapId, DBCPosition2D* uiMapPosition, int32* uiMapId)
@@ -181,14 +177,50 @@ std::size_t TaxiPathGraph::GetCompleteNodeRoute(TaxiNodesEntry const* from, Taxi
return shortestPath.size();
}
+template<typename T>
+struct DiscoverVertexVisitor : public boost::base_visitor<DiscoverVertexVisitor<T>>
+{
+ using event_filter = boost::on_discover_vertex;
+
+ DiscoverVertexVisitor(T&& func) : _func(std::forward<T>(func)) { }
+
+ template <class Vertex, class Graph>
+ void operator()(Vertex v, Graph& /*g*/)
+ {
+ _func(v);
+ }
+
+private:
+ T _func;
+};
+
+template<typename T>
+inline auto make_discover_vertex_dfs_visitor(T&& t)
+{
+ return boost::make_dfs_visitor(DiscoverVertexVisitor<T>(std::forward<T>(t)));
+}
+
+void TaxiPathGraph::GetReachableNodesMask(TaxiNodesEntry const* from, TaxiMask* mask)
+{
+ boost::vector_property_map<boost::default_color_type> color(boost::num_vertices(m_graph));
+ std::fill(color.storage_begin(), color.storage_end(), boost::white_color);
+ boost::depth_first_visit(m_graph, GetVertexIDFromNodeID(from), make_discover_vertex_dfs_visitor([this, mask](vertex_descriptor vertex)
+ {
+ if (TaxiNodesEntry const* taxiNode = sTaxiNodesStore.LookupEntry(GetNodeIDFromVertexID(vertex)))
+ (*mask)[(taxiNode->ID - 1) / 8] |= 1 << ((taxiNode->ID - 1) % 8);
+ }), color);
+}
+
TaxiPathGraph::vertex_descriptor TaxiPathGraph::CreateVertexFromFromNodeInfoIfNeeded(TaxiNodesEntry const* node)
{
- //Check if we need a new one or if it may be already created
- if (m_vertices.size() <= node->CharacterBitNumber)
- m_vertices.resize(node->CharacterBitNumber + 1);
+ auto itr = m_verticesByNode.find(node->ID);
+ if (itr == m_verticesByNode.end())
+ {
+ itr = m_verticesByNode.emplace(node->ID, m_nodesByVertex.size()).first;
+ m_nodesByVertex.push_back(node);
+ }
- m_vertices[node->CharacterBitNumber] = node;
- return node->CharacterBitNumber;
+ return itr->second;
}
uint32 TaxiPathGraph::EdgeCost::EvaluateDistance(Player const* player) const
diff --git a/src/server/game/Entities/Taxi/TaxiPathGraph.h b/src/server/game/Entities/Taxi/TaxiPathGraph.h
index 5331f12ba49..4f6508e2cfc 100644
--- a/src/server/game/Entities/Taxi/TaxiPathGraph.h
+++ b/src/server/game/Entities/Taxi/TaxiPathGraph.h
@@ -20,7 +20,10 @@
#include "Position.h"
#include "Define.h"
+#include "DBCEnums.h"
#include <boost/graph/adjacency_list.hpp>
+#include <unordered_map>
+#include <vector>
class Player;
struct TaxiNodesEntry;
@@ -32,6 +35,7 @@ public:
void Initialize();
std::size_t GetCompleteNodeRoute(TaxiNodesEntry const* from, TaxiNodesEntry const* to, Player const* player, std::vector<uint32>& shortestPath);
+ void GetReachableNodesMask(TaxiNodesEntry const* from, TaxiMask* mask);
private:
struct EdgeCost
@@ -53,10 +57,10 @@ private:
vertex_descriptor GetVertexIDFromNodeID(TaxiNodesEntry const* node);
uint32 GetNodeIDFromVertexID(vertex_descriptor vertexID);
vertex_descriptor CreateVertexFromFromNodeInfoIfNeeded(TaxiNodesEntry const* node);
- std::size_t GetVertexCount();
Graph m_graph;
- std::vector<TaxiNodesEntry const*> m_vertices;
+ std::vector<TaxiNodesEntry const*> m_nodesByVertex;
+ std::unordered_map<uint32, vertex_descriptor> m_verticesByNode;
TaxiPathGraph(TaxiPathGraph const&) = delete;
TaxiPathGraph& operator=(TaxiPathGraph const&) = delete;
diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp
index 5b08ed6bdb2..dbefda3cd11 100644
--- a/src/server/game/Handlers/TaxiHandler.cpp
+++ b/src/server/game/Handlers/TaxiHandler.cpp
@@ -107,6 +107,16 @@ void WorldSession::SendTaxiMenu(Creature* unit)
GetPlayer()->m_taxi.AppendTaximaskTo(data, lastTaxiCheaterState);
+ TaxiMask reachableNodes;
+ std::fill(reachableNodes.begin(), reachableNodes.end(), 0);
+ sTaxiPathGraph.GetReachableNodesMask(sTaxiNodesStore.LookupEntry(curloc), &reachableNodes);
+
+ for (std::size_t i = 0; i < TaxiMaskSize; ++i)
+ {
+ data.CanLandNodes[i] &= reachableNodes[i];
+ data.CanUseNodes[i] &= reachableNodes[i];
+ }
+
SendPacket(data.Write());
GetPlayer()->SetTaxiCheater(lastTaxiCheaterState);
diff --git a/src/server/game/Server/Packets/TaxiPackets.cpp b/src/server/game/Server/Packets/TaxiPackets.cpp
index 9e8e552f363..a39e37425f7 100644
--- a/src/server/game/Server/Packets/TaxiPackets.cpp
+++ b/src/server/game/Server/Packets/TaxiPackets.cpp
@@ -36,8 +36,8 @@ WorldPacket const* WorldPackets::Taxi::ShowTaxiNodes::Write()
_worldPacket.WriteBit(WindowInfo.is_initialized());
_worldPacket.FlushBits();
- _worldPacket << uint32(CanLandNodes->size());
- _worldPacket << uint32(CanUseNodes->size());
+ _worldPacket << uint32(CanLandNodes.size());
+ _worldPacket << uint32(CanUseNodes.size());
if (WindowInfo.is_initialized())
{
@@ -45,8 +45,8 @@ WorldPacket const* WorldPackets::Taxi::ShowTaxiNodes::Write()
_worldPacket << uint32(WindowInfo->CurrentNode);
}
- _worldPacket.append(CanLandNodes->data(), CanLandNodes->size());
- _worldPacket.append(CanUseNodes->data(), CanUseNodes->size());
+ _worldPacket.append(CanLandNodes.data(), CanLandNodes.size());
+ _worldPacket.append(CanUseNodes.data(), CanUseNodes.size());
return &_worldPacket;
}
diff --git a/src/server/game/Server/Packets/TaxiPackets.h b/src/server/game/Server/Packets/TaxiPackets.h
index 9e10f7bd442..dbf730a8bd9 100644
--- a/src/server/game/Server/Packets/TaxiPackets.h
+++ b/src/server/game/Server/Packets/TaxiPackets.h
@@ -62,8 +62,8 @@ namespace WorldPackets
WorldPacket const* Write() override;
Optional<ShowTaxiNodesWindowInfo> WindowInfo;
- TaxiMask const* CanLandNodes = nullptr; // Nodes known by player
- TaxiMask const* CanUseNodes = nullptr; // Nodes available for use - this can temporarily disable a known node
+ TaxiMask CanLandNodes; // Nodes known by player
+ TaxiMask CanUseNodes; // Nodes available for use - this can temporarily disable a known node
};
class EnableTaxiNode final : public ClientPacket