aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Maps
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2018-01-28 11:37:20 +0100
committerShauren <shauren.trinity@gmail.com>2018-03-25 19:28:36 +0300
commit91be2332e249147ce3169c46a7da77f0f8c2211d (patch)
treeeab9e0ab76ae523f7a843fe1c2300eba17f53af2 /src/server/game/Maps
parent1e62b53c66829dc9820117e17bfb44cb2652f814 (diff)
Core/Entities: Phasing rewrite
* Optimized phase visibility checking * Handle all phase flags Closes #16758 Closes #21119
Diffstat (limited to 'src/server/game/Maps')
-rw-r--r--src/server/game/Maps/Map.cpp87
-rw-r--r--src/server/game/Maps/Map.h11
-rw-r--r--src/server/game/Maps/TransportMgr.cpp56
-rw-r--r--src/server/game/Maps/TransportMgr.h2
4 files changed, 107 insertions, 49 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index ceb50e2e985..6ffa688ca08 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -41,6 +41,7 @@
#include "ObjectGridLoader.h"
#include "ObjectMgr.h"
#include "Pet.h"
+#include "PhasingHandler.h"
#include "ScriptMgr.h"
#include "Transport.h"
#include "Vehicle.h"
@@ -568,7 +569,7 @@ bool Map::AddPlayerToMap(Player* player, bool initPlayer /*= true*/)
player->m_clientGUIDs.clear();
player->UpdateObjectVisibility(false);
- player->SendUpdatePhasing();
+ PhasingHandler::SendToPlayer(player);
if (player->IsAlive())
ConvertCorpseToBones(player->GetGUID());
@@ -631,8 +632,6 @@ bool Map::AddToMap(T* obj)
if (obj->isActiveObject())
AddToActive(obj);
- obj->RebuildTerrainSwaps();
-
//something, such as vehicle, needs to be update immediately
//also, trigger needs to cast spell, if not update, cannot see visual
obj->UpdateObjectVisibilityOnCreate();
@@ -665,6 +664,7 @@ bool Map::AddToMap(Transport* obj)
{
UpdateData data(GetId());
obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
+ itr->GetSource()->m_visibleTransports.insert(obj->GetGUID());
WorldPacket packet;
data.BuildPacket(&packet);
itr->GetSource()->SendDirectMessage(&packet);
@@ -969,8 +969,13 @@ void Map::RemoveFromMap(Transport* obj, bool remove)
WorldPacket packet;
data.BuildPacket(&packet);
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
if (itr->GetSource()->GetTransport() != obj)
+ {
itr->GetSource()->SendDirectMessage(&packet);
+ itr->GetSource()->m_visibleTransports.erase(obj->GetGUID());
+ }
+ }
}
if (_transportsUpdateIter != _transports.end())
@@ -2495,12 +2500,12 @@ inline GridMap* Map::GetGrid(float x, float y)
return GridMaps[gx][gy];
}
-float Map::GetWaterOrGroundLevel(std::set<uint32> const& phases, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const
+float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const
{
if (const_cast<Map*>(this)->GetGrid(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
- float ground_z = GetHeight(phases, x, y, z, true, 50.0f);
+ float ground_z = GetHeight(phaseShift, x, y, z, true, 50.0f);
if (ground)
*ground = ground_z;
@@ -2789,19 +2794,19 @@ float Map::GetWaterLevel(float x, float y) const
return 0;
}
-bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, std::set<uint32> const& phases) const
+bool Map::isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2) const
{
return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2)
- && _dynamicTree.isInLineOfSight({ x1, y1, z1 }, { x2, y2, z2 }, phases);
+ && _dynamicTree.isInLineOfSight({ x1, y1, z1 }, { x2, y2, z2 }, phaseShift);
}
-bool Map::getObjectHitPos(std::set<uint32> const& phases, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
+bool Map::getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
{
G3D::Vector3 startPos(x1, y1, z1);
G3D::Vector3 dstPos(x2, y2, z2);
G3D::Vector3 resultPos;
- bool result = _dynamicTree.getObjectHitPos(phases, startPos, dstPos, resultPos, modifyDist);
+ bool result = _dynamicTree.getObjectHitPos(startPos, dstPos, resultPos, modifyDist, phaseShift);
rx = resultPos.x;
ry = resultPos.y;
@@ -2809,9 +2814,9 @@ bool Map::getObjectHitPos(std::set<uint32> const& phases, float x1, float y1, fl
return result;
}
-float Map::GetHeight(std::set<uint32> const& phases, float x, float y, float z, bool vmap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const
+float Map::GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const
{
- return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), _dynamicTree.getHeight(x, y, z, maxSearchDist, phases));
+ return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), _dynamicTree.getHeight(x, y, z, maxSearchDist, phaseShift));
}
bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const
@@ -2858,6 +2863,7 @@ void Map::SendInitSelf(Player* player)
if (Transport* transport = player->GetTransport())
{
transport->BuildCreateUpdateBlockForPlayer(&data, player);
+ player->m_visibleTransports.insert(transport->GetGUID());
}
// build data for self presence in world at own client (one time for map)
@@ -2865,9 +2871,9 @@ void Map::SendInitSelf(Player* player)
// build other passengers at transport also (they always visible and marked as visible and will not send at visibility update at add to map
if (Transport* transport = player->GetTransport())
- for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
- if (player != (*itr) && player->HaveAtClient(*itr))
- (*itr)->BuildCreateUpdateBlockForPlayer(&data, player);
+ for (WorldObject* passenger : transport->GetPassengers())
+ if (player != passenger && player->HaveAtClient(passenger))
+ passenger->BuildCreateUpdateBlockForPlayer(&data, player);
WorldPacket packet;
data.BuildPacket(&packet);
@@ -2878,9 +2884,14 @@ void Map::SendInitTransports(Player* player)
{
// Hack to send out transports
UpdateData transData(player->GetMapId());
- for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
- if (*i != player->GetTransport() && player->IsInPhase(*i))
- (*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
+ for (Transport* transport : _transports)
+ {
+ if (transport != player->GetTransport() && player->IsInPhase(transport))
+ {
+ transport->BuildCreateUpdateBlockForPlayer(&transData, player);
+ player->m_visibleTransports.insert(transport->GetGUID());
+ }
+ }
WorldPacket packet;
transData.BuildPacket(&packet);
@@ -2891,28 +2902,40 @@ void Map::SendRemoveTransports(Player* player)
{
// Hack to send out transports
UpdateData transData(player->GetMapId());
- for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
- if (*i != player->GetTransport())
- (*i)->BuildOutOfRangeUpdateBlock(&transData);
+ for (Transport* transport : _transports)
+ {
+ if (transport != player->GetTransport())
+ {
+ transport->BuildOutOfRangeUpdateBlock(&transData);
+ player->m_visibleTransports.erase(transport->GetGUID());
+ }
+ }
WorldPacket packet;
transData.BuildPacket(&packet);
player->GetSession()->SendPacket(&packet);
}
-void Map::SendUpdateTransportVisibility(Player* player, std::set<uint32> const& previousPhases)
+void Map::SendUpdateTransportVisibility(Player* player)
{
// Hack to send out transports
UpdateData transData(player->GetMapId());
- for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
+ for (Transport* transport : _transports)
{
- if (*i == player->GetTransport())
- continue;
-
- if (player->IsInPhase(*i) && !Trinity::Containers::Intersects(previousPhases.begin(), previousPhases.end(), (*i)->GetPhases().begin(), (*i)->GetPhases().end()))
- (*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
- else if (!player->IsInPhase(*i))
- (*i)->BuildOutOfRangeUpdateBlock(&transData);
+ auto transportItr = player->m_visibleTransports.find(transport->GetGUID());
+ if (player->IsInPhase(transport))
+ {
+ if (transportItr == player->m_visibleTransports.end())
+ {
+ transport->BuildCreateUpdateBlockForPlayer(&transData, player);
+ player->m_visibleTransports.insert(transport->GetGUID());
+ }
+ }
+ else if (transportItr != player->m_visibleTransports.end())
+ {
+ transport->BuildOutOfRangeUpdateBlock(&transData);
+ player->m_visibleTransports.erase(transportItr);
+ }
}
WorldPacket packet;
@@ -4030,8 +4053,8 @@ void Map::LoadCorpseData()
continue;
}
- for (auto phaseId : phases[guid])
- corpse->SetInPhase(phaseId, false, true);
+ for (uint32 phaseId : phases[guid])
+ PhasingHandler::AddPhase(corpse, phaseId, false);
AddCorpse(corpse);
@@ -4111,7 +4134,7 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*=
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, corpse->GetUInt32Value(CORPSE_FIELD_FLAGS) | CORPSE_FLAG_BONES);
- bones->CopyPhaseFrom(corpse);
+ PhasingHandler::InheritPhaseShift(bones, corpse);
AddCorpse(bones);
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 03f5f1bb6e6..ee43874fe2c 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -48,6 +48,7 @@ class InstanceScript;
class InstanceScenario;
class MapInstanced;
class Object;
+class PhaseShift;
class Player;
class TempSummon;
class Unit;
@@ -487,14 +488,14 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
BattlegroundMap* ToBattlegroundMap() { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap*>(this); else return NULL; }
BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap const*>(this); return NULL; }
- float GetWaterOrGroundLevel(std::set<uint32> const& phases, float x, float y, float z, float* ground = nullptr, bool swim = false) const;
- float GetHeight(std::set<uint32> const& phases, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
- bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, std::set<uint32> const& phases) const;
+ float GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground = nullptr, bool swim = false) const;
+ float GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
+ bool isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2) const;
void Balance() { _dynamicTree.balance(); }
void RemoveGameObjectModel(const GameObjectModel& model) { _dynamicTree.remove(model); }
void InsertGameObjectModel(const GameObjectModel& model) { _dynamicTree.insert(model); }
bool ContainsGameObjectModel(const GameObjectModel& model) const { return _dynamicTree.contains(model);}
- bool getObjectHitPos(std::set<uint32> const& phases, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
+ bool getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
virtual ObjectGuid::LowType GetOwnerGuildId(uint32 /*team*/ = TEAM_OTHER) const { return UI64LIT(0); }
/*
@@ -537,7 +538,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
void SendInitTransports(Player* player);
void SendRemoveTransports(Player* player);
- void SendUpdateTransportVisibility(Player* player, std::set<uint32> const& previousPhases);
+ void SendUpdateTransportVisibility(Player* player);
void SendZoneDynamicInfo(uint32 zoneId, Player* player) const;
void SendZoneWeather(uint32 zoneId, Player* player) const;
void SendZoneWeather(ZoneDynamicInfo const& zoneDynamicInfo, Player* player) const;
diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp
index 9980a72dfb8..8435b86ecae 100644
--- a/src/server/game/Maps/TransportMgr.cpp
+++ b/src/server/game/Maps/TransportMgr.cpp
@@ -23,6 +23,7 @@
#include "MoveSplineInitArgs.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
+#include "PhasingHandler.h"
#include "Spline.h"
#include "Transport.h"
@@ -364,7 +365,7 @@ void TransportMgr::AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg,
animNode.Path[timeSeg] = node;
}
-Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= NULL*/, uint32 phaseid /*= 0*/, uint32 phasegroup /*= 0*/)
+Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= nullptr*/, uint8 phaseUseFlags /*= 0*/, uint32 phaseId /*= 0*/, uint32 phaseGroupId /*= 0*/)
{
// instance case, execute GetGameObjectEntry hook
if (map)
@@ -404,12 +405,7 @@ Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid
return NULL;
}
- if (phaseid)
- trans->SetInPhase(phaseid, false, true);
-
- if (phasegroup)
- for (auto ph : sDB2Manager.GetPhasesForGroup(phasegroup))
- trans->SetInPhase(ph, false, true);
+ PhasingHandler::InitDbPhaseShift(trans->GetPhaseShift(), phaseUseFlags, phaseId, phaseGroupId);
if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId))
{
@@ -439,7 +435,7 @@ void TransportMgr::SpawnContinentTransports()
uint32 oldMSTime = getMSTime();
- QueryResult result = WorldDatabase.Query("SELECT guid, entry, phaseid, phasegroup FROM transports");
+ QueryResult result = WorldDatabase.Query("SELECT guid, entry, phaseUseFlags, phaseid, phasegroup FROM transports");
uint32 count = 0;
if (result)
@@ -449,12 +445,50 @@ void TransportMgr::SpawnContinentTransports()
Field* fields = result->Fetch();
ObjectGuid::LowType guid = fields[0].GetUInt64();
uint32 entry = fields[1].GetUInt32();
- uint32 phaseid = fields[2].GetUInt32();
- uint32 phasegroup = fields[3].GetUInt32();
+ uint8 phaseUseFlags = fields[2].GetUInt8();
+ uint32 phaseId = fields[3].GetUInt32();
+ uint32 phaseGroupId = fields[4].GetUInt32();
+
+ if (phaseUseFlags & ~PHASE_USE_FLAGS_ALL)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) with unknown `phaseUseFlags` set, removed unknown value.", guid, entry);
+ phaseUseFlags &= PHASE_USE_FLAGS_ALL;
+ }
+
+ if (phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE && phaseUseFlags & PHASE_USE_FLAGS_INVERSE)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
+ " removing PHASE_USE_FLAGS_INVERSE.", guid, entry);
+ phaseUseFlags &= ~PHASE_USE_FLAGS_INVERSE;
+ }
+
+ if (phaseGroupId && phaseId)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, entry);
+ phaseGroupId = 0;
+ }
+
+ if (phaseId)
+ {
+ if (!sPhaseStore.LookupEntry(phaseId))
+ {
+ TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) with `phaseid` %u does not exist, set to 0", guid, entry, phaseId);
+ phaseId = 0;
+ }
+ }
+
+ if (phaseGroupId)
+ {
+ if (!sDB2Manager.GetPhasesForGroup(phaseGroupId))
+ {
+ TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) with `phaseGroup` %u does not exist, set to 0", guid, entry, phaseGroupId);
+ phaseGroupId = 0;
+ }
+ }
if (TransportTemplate const* tInfo = GetTransportTemplate(entry))
if (!tInfo->inInstance)
- if (CreateTransport(entry, guid, nullptr, phaseid, phasegroup))
+ if (CreateTransport(entry, guid, nullptr, phaseUseFlags, phaseId, phaseGroupId))
++count;
} while (result->NextRow());
diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h
index 902052200aa..aca00038205 100644
--- a/src/server/game/Maps/TransportMgr.h
+++ b/src/server/game/Maps/TransportMgr.h
@@ -114,7 +114,7 @@ class TC_GAME_API TransportMgr
void LoadTransportAnimationAndRotation();
// Creates a transport using given GameObject template entry
- Transport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = UI64LIT(0), Map* map = nullptr, uint32 phaseid = 0, uint32 phasegroup = 0);
+ Transport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = UI64LIT(0), Map* map = nullptr, uint8 phaseUseFlags = 0, uint32 phaseId = 0, uint32 phaseGroupId = 0);
// Spawns all continent transports, used at core startup
void SpawnContinentTransports();