diff options
-rw-r--r-- | src/server/game/Entities/Player/PlayerTaxi.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Entities/Taxi/TaxiPathGraph.cpp | 64 | ||||
-rw-r--r-- | src/server/game/Entities/Taxi/TaxiPathGraph.h | 8 | ||||
-rw-r--r-- | src/server/game/Handlers/TaxiHandler.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Server/Packets/TaxiPackets.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Server/Packets/TaxiPackets.h | 4 |
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 |