diff options
author | Shauren <shauren.trinity@gmail.com> | 2018-02-24 22:35:27 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2018-03-25 19:28:36 +0300 |
commit | bea7faa8f9d48894d836c7205b98e36126734d56 (patch) | |
tree | df32e1a56518cb43445c5e708a6a855917bf6c62 | |
parent | 4798d9ce7abd86be381af086763d8dbc9ed67ef3 (diff) |
Core/Entities: Take terrain swaps into account when calculating LoS/height/area
19 files changed, 113 insertions, 74 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 1ec8586c90f..7d27d573cac 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1622,17 +1622,17 @@ void WorldObject::RemoveFromWorld() uint32 WorldObject::GetZoneId() const { - return GetBaseMap()->GetZoneId(m_positionX, m_positionY, m_positionZ); + return GetBaseMap()->GetZoneId(GetPhaseShift(), m_positionX, m_positionY, m_positionZ); } uint32 WorldObject::GetAreaId() const { - return GetBaseMap()->GetAreaId(m_positionX, m_positionY, m_positionZ); + return GetBaseMap()->GetAreaId(GetPhaseShift(), m_positionX, m_positionY, m_positionZ); } void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const { - GetBaseMap()->GetZoneAndAreaId(zoneid, areaid, m_positionX, m_positionY, m_positionZ); + GetBaseMap()->GetZoneAndAreaId(GetPhaseShift(), zoneid, areaid, m_positionX, m_positionY, m_positionZ); } InstanceScript* WorldObject::GetInstanceScript() @@ -2795,7 +2795,7 @@ float NormalizeZforCollision(WorldObject* obj, float x, float y, float z) return z; } LiquidData liquid_status; - ZLiquidStatus res = obj->GetMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status); + ZLiquidStatus res = obj->GetMap()->getLiquidStatus(obj->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquid_status); if (res && liquid_status.level > helper) // water must be above ground { if (liquid_status.level > z) // z is underwater @@ -2822,7 +2822,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float } destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ()); - bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f); + bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetPhaseShift().GetTerrainMapId(GetMapId(), pos.m_positionX, pos.m_positionY), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f); // collision occured if (col) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d5da4d8e66b..68d5024e959 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5938,7 +5938,7 @@ void Player::CheckAreaExploreAndOutdoor() return; bool isOutdoor; - uint32 areaId = GetBaseMap()->GetAreaId(GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor); + uint32 areaId = GetBaseMap()->GetAreaId(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor); AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId); if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor) @@ -6946,7 +6946,7 @@ uint32 Player::GetZoneIdFromDB(ObjectGuid guid) if (!sMapStore.LookupEntry(map)) return 0; - zone = sMapMgr->GetZoneId(map, posx, posy, posz); + zone = sMapMgr->GetZoneId(PhaseShift(), map, posx, posy, posz); if (zone > 0) { @@ -25293,7 +25293,7 @@ int32 Player::NextGroupUpdateSequenceNumber(GroupCategory category) void Player::UpdateUnderwaterState(Map* m, float x, float y, float z) { LiquidData liquid_status; - ZLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status); + ZLiquidStatus res = m->getLiquidStatus(GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquid_status); if (!res) { m_MirrorTimerFlags &= ~(UNDERWATER_INWATER | UNDERWATER_INLAVA | UNDERWATER_INSLIME | UNDERWARER_INDARKWATER); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 75590a0c44d..1d4814f7c9b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3045,12 +3045,12 @@ bool Unit::isInAccessiblePlaceFor(Creature const* c) const bool Unit::IsInWater() const { - return GetBaseMap()->IsInWater(GetPositionX(), GetPositionY(), GetPositionZ()); + return GetBaseMap()->IsInWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()); } bool Unit::IsUnderWater() const { - return GetBaseMap()->IsUnderWater(GetPositionX(), GetPositionY(), GetPositionZ()); + return GetBaseMap()->IsUnderWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()); } void Unit::UpdateUnderwaterState(Map* m, float x, float y, float z) @@ -3059,7 +3059,7 @@ void Unit::UpdateUnderwaterState(Map* m, float x, float y, float z) return; LiquidData liquid_status; - ZLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status); + ZLiquidStatus res = m->getLiquidStatus(GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquid_status); if (!res) { if (_lastLiquid && _lastLiquid->SpellID) @@ -7580,7 +7580,7 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const mountFlags = areaTable->MountFlags; LiquidData liquid; - ZLiquidStatus liquidStatus = GetMap()->getLiquidStatus(GetPositionX(), GetPositionY(), GetPositionZ(), MAP_ALL_LIQUIDS, &liquid); + ZLiquidStatus liquidStatus = GetMap()->getLiquidStatus(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), MAP_ALL_LIQUIDS, &liquid); isSubmerged = (liquidStatus & LIQUID_MAP_UNDER_WATER) != 0 || HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING); isInWater = (liquidStatus & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 78cd1e7e5b9..737f1952348 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -38,6 +38,7 @@ #include "MotionMaster.h" #include "ObjectAccessor.h" #include "ObjectDefines.h" +#include "PhasingHandler.h" #include "Player.h" #include "PoolMgr.h" #include "QuestDef.h" @@ -1890,8 +1891,9 @@ void ObjectMgr::LoadCreatures() for (auto& difficultyPair : mapDifficultyPair.second) spawnMasks[mapDifficultyPair.first] |= UI64LIT(1) << difficultyPair.first; + PhaseShift phaseShift; - _creatureDataStore.rehash(result->GetRowCount()); + _creatureDataStore.reserve(result->GetRowCount()); do { @@ -2078,7 +2080,8 @@ void ObjectMgr::LoadCreatures() { uint32 zoneId = 0; uint32 areaId = 0; - sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); + PhasingHandler::InitDbVisibleMapId(phaseShift, data.terrainSwapMap); + sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA); @@ -2249,7 +2252,9 @@ void ObjectMgr::LoadGameobjects() for (auto& difficultyPair : mapDifficultyPair.second) spawnMasks[mapDifficultyPair.first] |= UI64LIT(1) << difficultyPair.first; - _gameObjectDataStore.rehash(result->GetRowCount()); + PhaseShift phaseShift; + + _gameObjectDataStore.reserve(result->GetRowCount()); do { @@ -2448,7 +2453,8 @@ void ObjectMgr::LoadGameobjects() { uint32 zoneId = 0; uint32 areaId = 0; - sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); + PhasingHandler::InitDbVisibleMapId(phaseShift, data.terrainSwapMap); + sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA); @@ -6246,7 +6252,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(WorldLocation const& lo uint32 MapId = location.GetMapId(); // search for zone associated closest graveyard - uint32 zoneId = sMapMgr->GetZoneId(MapId, x, y, z); + uint32 zoneId = sMapMgr->GetZoneId(PhaseShift(), MapId, x, y, z); if (!zoneId) { diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 66373496997..3ec04849875 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -374,7 +374,7 @@ void WorldSession::HandleMovementOpcode(OpcodeClient opcode, MovementInfo& movem if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater()) { // now client not include swimming flag in case jumping under water - plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); + plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(plrMover->GetPhaseShift(), movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } uint32 mstime = getMSTime(); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 6ffa688ca08..6ece7791b6e 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2511,14 +2511,14 @@ float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, LiquidData liquid_status; - ZLiquidStatus res = getLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status); + ZLiquidStatus res = getLiquidStatus(phaseShift, x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status); return res ? liquid_status.level : ground_z; } return VMAP_INVALID_HEIGHT_VALUE; } -float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const +float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const { // find raw .map surface under Z coordinates float mapHeight = VMAP_INVALID_HEIGHT_VALUE; @@ -2535,7 +2535,7 @@ float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float { VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); if (vmgr->isHeightCalcEnabled()) - vmapHeight = vmgr->getHeight(GetId(), x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor + vmapHeight = vmgr->getHeight(phaseShift.GetTerrainMapId(GetId(), x, y), x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor } // mapHeight set for any above raw ground Z or <= INVALID_HEIGHT @@ -2592,13 +2592,13 @@ inline bool IsOutdoorWMO(uint32 mogpFlags, int32 /*adtId*/, int32 /*rootId*/, in return outdoor; } -bool Map::IsOutdoors(float x, float y, float z) const +bool Map::IsOutdoors(PhaseShift const& phaseShift, float x, float y, float z) const { uint32 mogpFlags; int32 adtId, rootId, groupId; // no wmo found? -> outside by default - if (!GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId)) + if (!GetAreaInfo(phaseShift, x, y, z, mogpFlags, adtId, rootId, groupId)) return true; AreaTableEntry const* atEntry = nullptr; @@ -2611,11 +2611,11 @@ bool Map::IsOutdoors(float x, float y, float z) const return IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry); } -bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const +bool Map::GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const { float vmap_z = z; VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); - if (vmgr->getAreaInfo(GetId(), x, y, vmap_z, flags, adtId, rootId, groupId)) + if (vmgr->getAreaInfo(phaseShift.GetTerrainMapId(GetId(), x, y), x, y, vmap_z, flags, adtId, rootId, groupId)) { // check if there's terrain between player height and object height if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) @@ -2630,7 +2630,7 @@ bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, in return false; } -uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const +uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, bool *isOutdoors) const { uint32 mogpFlags; int32 adtId, rootId, groupId; @@ -2639,7 +2639,7 @@ uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const bool haveAreaInfo = false; uint32 areaId = 0; - if (GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId)) + if (GetAreaInfo(phaseShift, x, y, z, mogpFlags, adtId, rootId, groupId)) { haveAreaInfo = true; wmoEntry = sDB2Manager.GetWMOAreaTable(rootId, adtId, groupId); @@ -2670,14 +2670,14 @@ uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const return areaId; } -uint32 Map::GetAreaId(float x, float y, float z) const +uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z) const { - return GetAreaId(x, y, z, nullptr); + return GetAreaId(phaseShift, x, y, z, nullptr); } -uint32 Map::GetZoneId(float x, float y, float z) const +uint32 Map::GetZoneId(PhaseShift const& phaseShift, float x, float y, float z) const { - uint32 areaId = GetAreaId(x, y, z); + uint32 areaId = GetAreaId(phaseShift, x, y, z); if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId)) if (area->ParentAreaID) return area->ParentAreaID; @@ -2685,9 +2685,9 @@ uint32 Map::GetZoneId(float x, float y, float z) const return areaId; } -void Map::GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const +void Map::GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, float x, float y, float z) const { - areaid = zoneid = GetAreaId(x, y, z); + areaid = zoneid = GetAreaId(phaseShift, x, y, z); if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaid)) if (area->ParentAreaID) zoneid = area->ParentAreaID; @@ -2701,14 +2701,14 @@ uint8 Map::GetTerrainType(float x, float y) const return 0; } -ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) const +ZLiquidStatus Map::getLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) const { ZLiquidStatus result = LIQUID_MAP_NO_WATER; VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); float liquid_level = INVALID_HEIGHT; float ground_level = INVALID_HEIGHT; uint32 liquid_type = 0; - if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type)) + if (vmgr->GetLiquidLevel(phaseShift.GetTerrainMapId(GetId(), x, y), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type)) { TC_LOG_DEBUG("maps", "getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type); // Check water level and ground level @@ -2727,7 +2727,7 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp if (liquid_type && liquid_type < 21) { - if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(x, y, z))) + if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(phaseShift, x, y, z))) { uint32 overrideLiquid = area->LiquidTypeID[liquidFlagType]; if (!overrideLiquid && area->ParentAreaID) @@ -2796,7 +2796,7 @@ float Map::GetWaterLevel(float x, float y) 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) + return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(phaseShift.GetTerrainMapId(GetId(), x1, x2), x1, y1, z1, x2, y2, z2) && _dynamicTree.isInLineOfSight({ x1, y1, z1 }, { x2, y2, z2 }, phaseShift); } @@ -2816,19 +2816,19 @@ bool Map::getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, floa 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, phaseShift)); + return std::max<float>(GetStaticHeight(phaseShift, x, y, z, vmap, maxSearchDist), _dynamicTree.getHeight(x, y, z, maxSearchDist, phaseShift)); } -bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const +bool Map::IsInWater(PhaseShift const& phaseShift, float x, float y, float pZ, LiquidData* data) const { LiquidData liquid_status; LiquidData* liquid_ptr = data ? data : &liquid_status; - return (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr) & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0; + return (getLiquidStatus(phaseShift, x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr) & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0; } -bool Map::IsUnderWater(float x, float y, float z) const +bool Map::IsUnderWater(PhaseShift const& phaseShift, float x, float y, float z) const { - return (getLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER) != 0; + return (getLiquidStatus(phaseShift, x, y, z, MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER) != 0; } bool Map::CheckGridIntegrity(Creature* c, bool moved) const diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index ee43874fe2c..065efc203ad 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -333,23 +333,23 @@ class TC_GAME_API Map : public GridRefManager<NGridType> // some calls like isInWater should not use vmaps due to processor power // can return INVALID_HEIGHT if under z+2 z coord not found height - float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; + float GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; float GetMinHeight(float x, float y) const; - ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const; + ZLiquidStatus getLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const; - uint32 GetAreaId(float x, float y, float z, bool *isOutdoors) const; - bool GetAreaInfo(float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const; - uint32 GetAreaId(float x, float y, float z) const; - uint32 GetZoneId(float x, float y, float z) const; - void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const; + uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, bool *isOutdoors) const; + bool GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const; + uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z) const; + uint32 GetZoneId(PhaseShift const& phaseShift, float x, float y, float z) const; + void GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, float x, float y, float z) const; - bool IsOutdoors(float x, float y, float z) const; + bool IsOutdoors(PhaseShift const& phaseShift, float x, float y, float z) const; uint8 GetTerrainType(float x, float y) const; float GetWaterLevel(float x, float y) const; - bool IsInWater(float x, float y, float z, LiquidData* data = nullptr) const; - bool IsUnderWater(float x, float y, float z) const; + bool IsInWater(PhaseShift const& phaseShift, float x, float y, float z, LiquidData* data = nullptr) const; + bool IsUnderWater(PhaseShift const& phaseShift, float x, float y, float z) const; void MoveAllCreaturesInMoveList(); void MoveAllGameObjectsInMoveList(); diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 187e70d1bb2..892756db0d4 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -25,6 +25,7 @@ #include "GridStates.h" #include "MapUpdater.h" +class PhaseShift; class Transport; struct TransportCreatureProto; @@ -38,20 +39,20 @@ class TC_GAME_API MapManager Map* CreateMap(uint32 mapId, Player* player, uint32 loginInstanceId=0); Map* FindMap(uint32 mapId, uint32 instanceId) const; - uint32 GetAreaId(uint32 mapid, float x, float y, float z) const + uint32 GetAreaId(PhaseShift const& phaseShift, uint32 mapid, float x, float y, float z) const { Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid); - return m->GetAreaId(x, y, z); + return m->GetAreaId(phaseShift, x, y, z); } - uint32 GetZoneId(uint32 mapid, float x, float y, float z) const + uint32 GetZoneId(PhaseShift const& phaseShift, uint32 mapid, float x, float y, float z) const { Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid); - return m->GetZoneId(x, y, z); + return m->GetZoneId(phaseShift, x, y, z); } - void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z) + void GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z) { Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid); - m->GetZoneAndAreaId(zoneid, areaid, x, y, z); + m->GetZoneAndAreaId(phaseShift, zoneid, areaid, x, y, z); } void Initialize(void); diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 05044c95523..210de91f8b0 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -51,7 +51,7 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T* owner) // Add LOS check for target point Position mypos = owner->GetPosition(); - bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(owner->GetMapId(), + bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(owner->GetPhaseShift().GetTerrainMapId(owner->GetMapId(), mypos.m_positionX, mypos.m_positionY), mypos.m_positionX, mypos.m_positionY, mypos.m_positionZ + 2.0f, diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index f6716a0f4b0..6c9e1cd01d9 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -185,7 +185,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con // Check both start and end points, if they're both in water, then we can *safely* let the creature move for (uint32 i = 0; i < _pathPoints.size(); ++i) { - ZLiquidStatus status = _sourceUnit->GetBaseMap()->getLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL); + ZLiquidStatus status = _sourceUnit->GetBaseMap()->getLiquidStatus(_sourceUnit->GetPhaseShift(), _pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL); // One of the points is not in the water, cancel movement. if (status == LIQUID_MAP_NO_WATER) { @@ -211,7 +211,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con Creature* owner = (Creature*)_sourceUnit; G3D::Vector3 const& p = (distToStartPoly > 7.0f) ? startPos : endPos; - if (_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z)) + if (_sourceUnit->GetBaseMap()->IsUnderWater(_sourceUnit->GetPhaseShift(), p.x, p.y, p.z)) { TC_LOG_DEBUG("maps", "++ BuildPolyPath :: underWater case\n"); if (owner->CanSwim()) @@ -648,7 +648,7 @@ void PathGenerator::UpdateFilter() NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) { LiquidData data; - ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data); + ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->getLiquidStatus(_sourceUnit->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &data); if (liquidStatus == LIQUID_MAP_NO_WATER) return NAV_GROUND; diff --git a/src/server/game/Phasing/PhaseShift.cpp b/src/server/game/Phasing/PhaseShift.cpp index b2885ae15bb..d543ccd1f22 100644 --- a/src/server/game/Phasing/PhaseShift.cpp +++ b/src/server/game/Phasing/PhaseShift.cpp @@ -17,6 +17,8 @@ #include "PhaseShift.h" #include "Containers.h" +#include "GridDefines.h" +#include "VMapFactory.h" bool PhaseShift::AddPhase(uint32 phaseId, PhaseFlags flags, std::vector<Condition*> const* areaConditions, int32 references /*= 1*/) { @@ -145,6 +147,33 @@ bool PhaseShift::CanSee(PhaseShift const& other) const return checkInversePhaseShift(other, *this); } +uint32 PhaseShift::GetTerrainMapId(uint32 realMapId, float x, float y) const +{ + if (VisibleMapIds.empty()) + return realMapId; + + if (VisibleMapIds.size() == 1) + return VisibleMapIds.begin()->first; + + GridCoord gridCoord = Trinity::ComputeGridCoord(x, y); + int32 gx = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.x_coord; + int32 gy = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.y_coord; + + int32 minDistance = std::numeric_limits<int32>::max(); + uint32 terrainMapId; + for (auto itr = VisibleMapIds.begin(); itr != VisibleMapIds.end(); ++itr) + { + int32 dist = VMAP::VMapFactory::createOrGetVMapManager()->GetDistanceToClosestPrimaryTile(itr->first, gx, gy); + if (dist < minDistance) + { + minDistance = dist; + terrainMapId = itr->first; + } + } + + return terrainMapId; +} + void PhaseShift::ModifyPhasesReferences(PhaseContainer::iterator itr, int32 references) { itr->References += references; diff --git a/src/server/game/Phasing/PhaseShift.h b/src/server/game/Phasing/PhaseShift.h index 8755868ae9d..ca38614ed45 100644 --- a/src/server/game/Phasing/PhaseShift.h +++ b/src/server/game/Phasing/PhaseShift.h @@ -101,6 +101,7 @@ public: void ClearPhases(); bool CanSee(PhaseShift const& other) const; + uint32 GetTerrainMapId(uint32 realMapId, float x, float y) const; protected: friend class PhasingHandler; diff --git a/src/server/game/Phasing/PhasingHandler.cpp b/src/server/game/Phasing/PhasingHandler.cpp index 2f0fd7d870e..08ed3f729b0 100644 --- a/src/server/game/Phasing/PhasingHandler.cpp +++ b/src/server/game/Phasing/PhasingHandler.cpp @@ -422,6 +422,7 @@ void PhasingHandler::FillPartyMemberPhase(WorldPackets::Party::PartyMemberPhaseS void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId) { + phaseShift.ClearPhases(); phaseShift.IsDbPhaseShift = true; EnumClassFlag<PhaseShiftFlags> flags = PhaseShiftFlags::None; @@ -449,6 +450,7 @@ void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlag void PhasingHandler::InitDbVisibleMapId(PhaseShift& phaseShift, int32 visibleMapId) { + phaseShift.VisibleMapIds.clear(); if (visibleMapId != -1) phaseShift.AddVisibleMapId(visibleMapId, sObjectMgr->GetTerrainSwapInfo(visibleMapId)); } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 0763be83110..e1dc6d62dfa 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1305,7 +1305,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseShift(), x, y, z, true, 50.0f); float liquidLevel = VMAP_INVALID_HEIGHT_VALUE; LiquidData liquidData; - if (m_caster->GetMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquidData)) + if (m_caster->GetMap()->getLiquidStatus(m_caster->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquidData)) liquidLevel = liquidData.level; if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level @@ -4909,11 +4909,11 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint if (m_caster->GetTypeId() == TYPEID_PLAYER && VMAP::VMapFactory::createOrGetVMapManager()->isLineOfSightCalcEnabled()) { if (m_spellInfo->HasAttribute(SPELL_ATTR0_OUTDOORS_ONLY) && - !m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) + !m_caster->GetMap()->IsOutdoors(m_caster->GetPhaseShift(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) return SPELL_FAILED_ONLY_OUTDOORS; if (m_spellInfo->HasAttribute(SPELL_ATTR0_INDOORS_ONLY) && - m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) + m_caster->GetMap()->IsOutdoors(m_caster->GetPhaseShift(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ())) return SPELL_FAILED_ONLY_INDOORS; } diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 255a0854226..09a31c885b7 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -247,7 +247,7 @@ public: player->SaveRecallPosition(); Map const* map = sMapMgr->CreateBaseMap(mapId); - float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + float z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); player->TeleportTo(mapId, x, y, z, player->GetOrientation()); return true; @@ -369,7 +369,7 @@ public: player->SaveRecallPosition(); Map const* map = sMapMgr->CreateBaseMap(mapId); - z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); player->TeleportTo(mapId, x, y, z, 0.0f); return true; @@ -532,7 +532,7 @@ public: else player->SaveRecallPosition(); - float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + float z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); player->TeleportTo(zoneEntry->ContinentID, x, y, z, player->GetOrientation()); return true; @@ -580,7 +580,7 @@ public: return false; } Map const* map = sMapMgr->CreateBaseMap(mapId); - z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); + z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); } // stop flight if need diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index c75b528521c..9be3ff64559 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -273,7 +273,7 @@ public: if (haveVMap) { - if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) + if (map->IsOutdoors(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) handler->PSendSysMessage(LANG_GPS_POSITION_OUTDOORS); else handler->PSendSysMessage(LANG_GPS_POSITION_INDOORS); @@ -297,7 +297,7 @@ public: zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap, haveMMap); LiquidData liquidStatus; - ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); + ZLiquidStatus status = map->getLiquidStatus(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); if (status) handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index b4185c7c0b3..79113971fe4 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -207,7 +207,7 @@ public: SQLTransaction dummy; Player::SavePositionInDB(WorldLocation(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation), - sMapMgr->GetZoneId(tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy); + sMapMgr->GetZoneId(PhaseShift(), tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy); } return true; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp index 48333ba31c6..1bfd96f0e35 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp @@ -272,7 +272,7 @@ public: Position pos = me->GetRandomNearPosition(10.0f); //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000)) return summon; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp index 05faa7524fd..64c8bb0db1d 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp @@ -309,7 +309,7 @@ public: Position pos = me->GetRandomNearPosition(10.0f); //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); if (Unit* Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT)) if (Unit* temp = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_MEDIVH))) |