diff options
author | Treeston <treeston.mmoc@gmail.com> | 2017-06-08 00:25:06 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2017-06-08 00:25:06 +0200 |
commit | f6c849729b27b77228704b595de3adaf24da2c10 (patch) | |
tree | b9f7e1ae9c6db0aa367c353ebd2a3f5dddf860d1 /src/server/game/Maps/Map.cpp | |
parent | 1660bb7d27d6f42b49012a6b57e3c2b2eab20fd3 (diff) |
[3.3.5] Get zone/area IDs from vmap data in the liquid update (#19840)
* Add new method Map::getFullVMapDataForPosition to get area info and liquid info in a single vmap lookup
* Use this lookup in Map:: relocation methods to update m_areaId and m_zoneId fields on WorldObject
* Adjust GetZoneId/GetAreaId on WorldObject to always return these cached fields
* Clean up liquid state handling on Unit and Player
* Hand floor's Z coord up through GetFullTerrainStatusForPosition, use it to update a new field in WorldObject, and use that to feed a new GetFloorZ call on WorldObject.
Closes #16489
Diffstat (limited to 'src/server/game/Maps/Map.cpp')
-rw-r--r-- | src/server/game/Maps/Map.cpp | 125 |
1 files changed, 113 insertions, 12 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index b3eb7fa275d..4bac7b84669 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -993,6 +993,7 @@ void Map::PlayerRelocation(Player* player, float x, float y, float z, float orie AddToGrid(player, new_cell); } + player->UpdatePositionData(); player->UpdateObjectVisibility(false); } @@ -1027,6 +1028,7 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa if (creature->IsVehicle()) creature->GetVehicleKit()->RelocatePassengers(); creature->UpdateObjectVisibility(false); + creature->UpdatePositionData(); RemoveCreatureFromMoveList(creature); } @@ -1057,6 +1059,7 @@ void Map::GameObjectRelocation(GameObject* go, float x, float y, float z, float { go->Relocate(x, y, z, orientation); go->UpdateModelPosition(); + go->UpdatePositionData(); go->UpdateObjectVisibility(false); RemoveGameObjectFromMoveList(go); } @@ -1089,6 +1092,7 @@ void Map::DynamicObjectRelocation(DynamicObject* dynObj, float x, float y, float else { dynObj->Relocate(x, y, z, orientation); + dynObj->UpdatePositionData(); dynObj->UpdateObjectVisibility(false); RemoveDynamicObjectFromMoveList(dynObj); } @@ -1182,6 +1186,7 @@ void Map::MoveAllCreaturesInMoveList() if (c->IsVehicle()) c->GetVehicleKit()->RelocatePassengers(); //CreatureRelocationNotify(c, new_cell, new_cell.cellCoord()); + c->UpdatePositionData(); c->UpdateObjectVisibility(false); } else @@ -1236,6 +1241,7 @@ void Map::MoveAllGameObjectsInMoveList() // update pos go->Relocate(go->_newPosition); go->UpdateModelPosition(); + go->UpdatePositionData(); go->UpdateObjectVisibility(false); } else @@ -1280,6 +1286,7 @@ void Map::MoveAllDynamicObjectsInMoveList() { // update pos dynObj->Relocate(dynObj->_newPosition); + dynObj->UpdatePositionData(); dynObj->UpdateObjectVisibility(false); } else @@ -1500,6 +1507,7 @@ bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly) c->Relocate(resp_x, resp_y, resp_z, resp_o); c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators //CreatureRelocationNotify(c, resp_cell, resp_cell.GetCellCoord()); + c->UpdatePositionData(); c->UpdateObjectVisibility(false); return true; } @@ -1525,6 +1533,7 @@ bool Map::GameObjectRespawnRelocation(GameObject* go, bool diffGridOnly) if (GameObjectCellRelocation(go, resp_cell)) { go->Relocate(resp_x, resp_y, resp_z, resp_o); + go->UpdatePositionData(); go->UpdateObjectVisibility(false); return true; } @@ -2203,7 +2212,7 @@ uint8 GridMap::getTerrainType(float x, float y) const } // Get water state on map -inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) +inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) { // Check water type (if no water return) if (!_liquidType && !_liquidFlags) @@ -2321,7 +2330,7 @@ float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, fl LiquidData liquid_status; - ZLiquidStatus res = getLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status); + ZLiquidStatus res = GetLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status); return res ? liquid_status.level : ground_z; } @@ -2480,11 +2489,6 @@ uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const return areaId; } -uint32 Map::GetAreaId(float x, float y, float z) const -{ - return GetAreaId(x, y, z, nullptr); -} - uint32 Map::GetZoneId(float x, float y, float z) const { uint32 areaId = GetAreaId(x, y, z); @@ -2511,7 +2515,7 @@ 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(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) const { ZLiquidStatus result = LIQUID_MAP_NO_WATER; VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); @@ -2520,7 +2524,7 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp uint32 liquid_type = 0; if (vmgr->GetLiquidLevel(GetId(), 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); + 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 if (liquid_level > ground_level && z > ground_level - 2) { @@ -2578,7 +2582,7 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) { LiquidData map_data; - ZLiquidStatus map_result = gmap->getLiquidStatus(x, y, z, ReqLiquidType, &map_data); + ZLiquidStatus map_result = gmap->GetLiquidStatus(x, y, z, ReqLiquidType, &map_data); // Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER: if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level)) { @@ -2596,6 +2600,103 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp return result; } +void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType) const +{ + VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); + VMAP::AreaAndLiquidData vmapData; + vmgr->getAreaAndLiquidData(GetId(), x, y, z, reqLiquidType, vmapData); + if (vmapData.areaInfo) + data.areaInfo = boost::in_place(vmapData.areaInfo->adtId, vmapData.areaInfo->rootId, vmapData.areaInfo->groupId, vmapData.areaInfo->mogpFlags); + + GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y); + float mapHeight = gmap->getHeight(x, y); + + // area lookup + AreaTableEntry const* areaEntry = nullptr; + if (vmapData.areaInfo && (z + 2.0f <= mapHeight || mapHeight <= vmapData.floorZ)) + if (WMOAreaTableEntry const* wmoEntry = GetWMOAreaTableEntryByTripple(vmapData.areaInfo->rootId, vmapData.areaInfo->adtId, vmapData.areaInfo->groupId)) + areaEntry = sAreaTableStore.LookupEntry(wmoEntry->areaId); + + if (areaEntry) + { + data.floorZ = vmapData.floorZ; + data.areaId = areaEntry->ID; + } + else + { + data.floorZ = mapHeight; + if (gmap) + data.areaId = gmap->getArea(x, y); + else + data.areaId = 0; + + if (!data.areaId) + data.areaId = i_mapEntry->linked_zone; + + if (data.areaId) + areaEntry = sAreaTableStore.LookupEntry(data.areaId); + } + + // liquid processing + data.liquidStatus = LIQUID_MAP_NO_WATER; + if (vmapData.liquidInfo && vmapData.liquidInfo->level > vmapData.floorZ && z + 2.0f > vmapData.floorZ) + { + uint32 liquidType = vmapData.liquidInfo->type; + if (GetId() == 530 && liquidType == 2) // gotta love blizzard hacks + liquidType = 15; + + uint32 liquidFlagType = 0; + if (LiquidTypeEntry const* liquidData = sLiquidTypeStore.LookupEntry(liquidType)) + liquidFlagType = liquidData->Type; + + if (liquidType && liquidType < 21 && areaEntry) + { + uint32 overrideLiquid = areaEntry->LiquidTypeOverride[liquidFlagType]; + if (!overrideLiquid && areaEntry->zone) + { + AreaTableEntry const* zoneEntry = sAreaTableStore.LookupEntry(areaEntry->zone); + if (zoneEntry) + overrideLiquid = zoneEntry->LiquidTypeOverride[liquidFlagType]; + } + + if (LiquidTypeEntry const* overrideData = sLiquidTypeStore.LookupEntry(overrideLiquid)) + { + liquidType = overrideLiquid; + liquidFlagType = overrideData->Type; + } + } + + data.liquidInfo = boost::in_place(); + data.liquidInfo->level = vmapData.liquidInfo->level; + data.liquidInfo->depth_level = vmapData.floorZ; + data.liquidInfo->entry = liquidType; + data.liquidInfo->type_flags = 1 << liquidFlagType; + + float delta = vmapData.liquidInfo->level - z; + if (delta > 2.0f) + data.liquidStatus = LIQUID_MAP_UNDER_WATER; + else if (delta > 0.0f) + data.liquidStatus = LIQUID_MAP_IN_WATER; + else if (delta > -0.1f) + data.liquidStatus = LIQUID_MAP_WATER_WALK; + else + data.liquidStatus = LIQUID_MAP_ABOVE_WATER; + } + // look up liquid data from grid map + if (gmap && (data.liquidStatus == LIQUID_MAP_ABOVE_WATER || data.liquidStatus == LIQUID_MAP_NO_WATER)) + { + LiquidData gridMapLiquid; + ZLiquidStatus gridMapStatus = gmap->GetLiquidStatus(x, y, z, reqLiquidType, &gridMapLiquid); + if (gridMapStatus != LIQUID_MAP_NO_WATER && (gridMapLiquid.level > vmapData.floorZ)) + { + if (GetId() == 530 && gridMapLiquid.entry == 2) + gridMapLiquid.entry = 15; + data.liquidInfo = gridMapLiquid; + data.liquidStatus = gridMapStatus; + } + } +} + float Map::GetWaterLevel(float x, float y) const { if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) @@ -2633,12 +2734,12 @@ bool Map::IsInWater(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(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 { - return (getLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER) != 0; + return (GetLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER) != 0; } bool Map::CheckGridIntegrity(Creature* c, bool moved) const |