diff options
Diffstat (limited to 'src/game/Map.cpp')
-rw-r--r-- | src/game/Map.cpp | 340 |
1 files changed, 132 insertions, 208 deletions
diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 53efb35e373..f8e48d3a326 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1746,220 +1746,105 @@ float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const } } -float Map::GetVmapHeight(float x, float y, float z) const +inline bool IsOutdoorWMO(uint32 mogpFlags, int32 adtId, int32 rootId, int32 groupId, WMOAreaTableEntry const* wmoEntry, AreaTableEntry const* atEntry) { - float mapHeight; - - mapHeight = GetHeight(x, y, z, false); - if (fabs(mapHeight - z) < 0.1) - return mapHeight; + bool outdoor = true; - VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); - if (!vmgr->isLineOfSightCalcEnabled()) - return mapHeight; + if(wmoEntry && atEntry) + { + if(atEntry->flags & AREA_FLAG_OUTSIDE) + return true; + if(atEntry->flags & AREA_FLAG_INSIDE) + return false; + } - float vmapHeight = vmgr->getHeight(GetId(), x, y, z + 2.0f, z + 2.0f - mapHeight); - if (vmapHeight > VMAP_INVALID_HEIGHT_VALUE) - return vmapHeight; + outdoor = mogpFlags&0x8; - return mapHeight; + if(wmoEntry) + { + if(wmoEntry->Flags & 4) + return true; + if((wmoEntry->Flags & 2)!=0) + outdoor = false; + } + return outdoor; } -uint16 Map::GetAreaFlag(float x, float y, float z) const +bool Map::IsOutdoors(float x, float y, float z) const { - uint16 areaflag; - if (GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y)) - areaflag = gmap->getArea(x, y); - // this used while not all *.map files generated (instances) - else - areaflag = GetAreaFlagByMapId(GetId()); - - //FIXME: some hacks for areas above or underground for ground area - // required for area specific spells/etc, until map/vmap data - // not provided correct areaflag with this hacks - switch(areaflag) - { - case 2817: // Argent Tournament Grounds (Icecrown) - if (x < 8445.0f && x > 8390.0f && y > 640.0f && y < 689.0f && 548.0f < z && z < 562.0f) - areaflag = 2875; // Sunreaver Pavilion (Icecrown) - else if (x > 8587.0f && x < 8629.0f && y > 646.0f && y < 686.0f && 548.0f < z && z < 562.0f) - areaflag = 2879; // Silver Covenant Pavilion (Icecrown) - break; - case 2227: // The Foot Steppes (Storm Peaks) - case 2207: // Sifreldar Village (Storm Peaks) - if (6924.0f < x && x < 6980.0f && -1520.0f < y && y < -1432.0f && 838.0f < z && z < 843.0f) - areaflag = 2213; // The Forlorn Mine (Storm Peaks) - break; - case 2209: // Brunnhildar Village (Storm Peaks) - if (6885.0f < x && x < 6938.0f && -1200.0f < y && y < -1138.0f && 801.0f < z && z < 809.0f) - areaflag = 2213; // The Forlorn Mine (Storm Peaks) - break; - case 166: // Storm Peaks - if (6812.0f < x && x < 7048.0f && -1463.0f < y && y < -1200.0f && 807.0f < z && z < 843.0f) - areaflag = 2213; // The Forlorn Mine (Storm Peaks) - break; - case 446: // (Stonelaton Mountains) - case 944: // Boulderslide Ravine (Stonelaton Mountains) - if (-128.0f < x && x < 35.0f && 221.0f < y && y < 456.0f && 87.0f < z && z < 130.0f) - areaflag = 1019; // Boulderslide Cavern (Stonelaton Mountains) - break; - case 272: // Palemane Rock (Mulgore) - if (-2466.0f < x && x < -2295.0f && 366.0f < y && y < 530.0f && 40.0f < z && z < 70.0f) - areaflag = 668; // Palemane Rock (Mulgore) - break; - case 65535: // Multipe places. - if (-128.0f < x && x < 35.0f && 221.0f < y && y < 456.0f && 87.0f < z && z < 130.0f) - areaflag = 1019; // Boulderslide Cavern (Stonelaton Mountains) - else if (-2466.0f < x && x < -2295.0f && 366.0f < y && y < 530.0f && 40.0f < z && z < 70.0f) - areaflag = 668; // Palemane Rock (Mulgore) - break; - // Acherus: The Ebon Hold (Plaguelands: The Scarlet Enclave) - case 1984: // Plaguelands: The Scarlet Enclave - case 2076: // Death's Breach (Plaguelands: The Scarlet Enclave) - case 2745: // The Noxious Pass (Plaguelands: The Scarlet Enclave) - if (z > 350.0f) areaflag = 2048; break; - // Acherus: The Ebon Hold (Eastern Plaguelands) - case 856: // The Noxious Glade (Eastern Plaguelands) - case 2456: // Death's Breach (Eastern Plaguelands) - if (z > 350.0f) areaflag = 1950; break; - // Dalaran - case 2492: // Forlorn Woods (Crystalsong Forest) - case 2371: // Valley of Echoes (Icecrown Glacier) - if (x > 5568.0f && x < 6022.0f && y > 374.0f && y < 918.0f && z > 563.0f) - { - areaflag = 2153; - if (y - 1.41f * x + 7649.55f > 0) // Violet Hold - { - if (y < 595.0f) - areaflag = 2540; - } - else if (y + 2.91 * x - 17522.57f < 0) // Krasus landing - areaflag = 2531; - } - break; - // The Violet Citadel (Dalaran) or Dalaran - case 2484: // The Twilight Rivulet (Crystalsong Forest) - case 1593: // Crystalsong Forest - // Dalaran - if (x > 5568.0f && x < 6116.0f && y > 282.0f && y < 918.0f && z > 563.0f) - { - // The Violet Citadel (Dalaran), fast check - if (x > 5721.1f && x < 5884.66f && y > 764.4f && y < 948.0f) - { - // The Violet Citadel (Dalaran) - if ((x-5803.0f)*(x-5803.0f)+(y-846.18f)*(y-846.18f) < 6690.0f) - { - areaflag = 2696; - break; - } - } + uint32 mogpFlags; + int32 adtId, rootId, groupId; - // The Eventide (Dalaran), fast check against diagonal box with lower limit - if (z > 635.0f && x+y < 6375.0f && x+y > 6295.0f && x-y < 5106.0f && x-y > 4972.0f) - { - areaflag = 2543; - break; - } + // no wmo found? -> outside by default + if(!GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId)) + return true; - // The Violet Hold (Dalaran), fast check - if (x < 5791.0f && y > 404.0f && y < 595.0f) - { - areaflag = 2540; - break; - } + AreaTableEntry const* atEntry = 0; + WMOAreaTableEntry const* wmoEntry= GetWMOAreaTableEntryByTripple(rootId, adtId, groupId); + if(wmoEntry) + { + DEBUG_LOG("Got WMOAreaTableEntry! flag %u, areaid %u", wmoEntry->Flags, wmoEntry->areaId); + atEntry = GetAreaEntryByAreaID(wmoEntry->areaId); + } + return IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry); +} - // Dalaran - areaflag = 2153; - } - break; - // Vargoth's Retreat (Dalaran) or The Violet Citadel (Dalaran) or Dalaran - case 2504: // Violet Stand (Crystalsong Forest) - // Dalaran - if (x > 5568.0f && x < 6116.0f && y > 282.0f && y < 982.0f && z > 563.0f) - { - // The Violet Citadel (Dalaran), fast check - if (x > 5721.1f && x < 5884.66f && y > 764.4f && y < 948.0f) - { - // Vargoth's Retreat (Dalaran), nice slow circle with upper limit - if (z < 898.0f && (x-5765.0f)*(x-5765.0f)+(y-862.4f)*(y-862.4f) < 262.0f) - { - areaflag = 2748; - break; - } +bool Map::GetAreaInfo(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)) + { + // check if there's terrain between player height and object height + if(GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y)) + { + float _mapheight = gmap->getHeight(x,y); + // z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice... + if(z + 2.0f > _mapheight && _mapheight > vmap_z) + return false; + } + return true; + } + return false; +} - // The Violet Citadel (Dalaran) - if ((x-5803.0f)*(x-5803.0f)+(y-846.18f)*(y-846.18f) < 6690.0f) - { - areaflag = 2696; - break; - } - } +uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const +{ + uint32 mogpFlags; + int32 adtId, rootId, groupId; + WMOAreaTableEntry const* wmoEntry = 0; + AreaTableEntry const* atEntry = 0; + bool haveAreaInfo = false; - // Dalaran - areaflag = 2153; - } - break; - // Maw of Neltharion (cave) - case 164: // Dragonblight - case 1797: // Obsidian Dragonshrine (Dragonblight) - if (x > 4364.0f && x < 4632.0f && y > 1545.0f && y < 1886.0f && z < 200.0f) areaflag = 1853; break; - // Undercity (sewers enter and path) - case 179: // Tirisfal Glades - if (x > 1595.0f && x < 1699.0f && y > 535.0f && y < 643.5f && z < 30.5f) areaflag = 685; break; - // Undercity (Royal Quarter) - case 210: // Silverpine Forest - case 316: // The Shining Strand (Silverpine Forest) - case 438: // Lordamere Lake (Silverpine Forest) - if (x > 1237.0f && x < 1401.0f && y > 284.0f && y < 440.0f && z < -40.0f) areaflag = 685; break; - // Undercity (cave and ground zone, part of royal quarter) - case 607: // Ruins of Lordaeron (Tirisfal Glades) - // ground and near to ground (by city walls) - if (z > 0.0f) - { - if (x > 1510.0f && x < 1839.0f && y > 29.77f && y < 433.0f) areaflag = 685; - } - // more wide underground, part of royal quarter - else - { - if (x > 1299.0f && x < 1839.0f && y > 10.0f && y < 440.0f) areaflag = 685; - } - break; - // The Makers' Perch (ground) and Makers' Overlook (ground and cave) - case 1335: // Sholazar Basin - // The Makers' Perch ground (fast box) - if (x > 6100.0f && x < 6250.0f && y > 5650.0f && y < 5800.0f) - { - // nice slow circle - if ((x-6183.0f)*(x-6183.0f)+(y-5717.0f)*(y-5717.0f) < 2500.0f) - areaflag = 2189; - } - // Makers' Overlook (ground and cave) - else if (x > 5634.48f && x < 5774.53f && y < 3475.0f && z > 300.0f) - { - if (y > 3380.26f || (y > 3265.0f && z < 360.0f)) - areaflag = 2187; - } - break; - // The Makers' Perch (underground) - case 2147: // The Stormwright's Shelf (Sholazar Basin) - if (x > 6199.0f && x < 6283.0f && y > 5705.0f && y < 5817.0f && z < 38.0f) areaflag = 2189; break; - // Makers' Overlook (deep cave) - case 267: // Icecrown - if (x > 5684.0f && x < 5798.0f && y > 3035.0f && y < 3367.0f && z < 358.0f) areaflag = 2187; break; - // Wyrmrest Temple (Dragonblight) - case 1814: // Path of the Titans (Dragonblight) - case 1897: // The Dragon Wastes (Dragonblight) - // fast box - if (x > 3400.0f && x < 3700.0f && y > 130.0f && y < 420.0f) - { - // nice slow circle - if ((x-3546.87f)*(x-3546.87f)+(y-272.71f)*(y-272.71f) < 19600.0f) areaflag = 1791; - } - break; + if (GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId)) + { + haveAreaInfo = true; + if (wmoEntry = GetWMOAreaTableEntryByTripple(rootId, adtId, groupId)) + atEntry = GetAreaEntryByAreaID(wmoEntry->areaId); + } + + uint16 areaflag; + + if (atEntry) + areaflag = atEntry->exploreFlag; + else + { + if (GridMap *gmap = const_cast<Map*>(this)->GetGrid(x, y)) + areaflag = gmap->getArea(x, y); + // this used while not all *.map files generated (instances) + else + areaflag = GetAreaFlagByMapId(i_mapEntry->MapID); } + if (isOutdoors) + { + if (haveAreaInfo) + *isOutdoors = IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry); + else + *isOutdoors = true; + } return areaflag; -} + } uint8 Map::GetTerrainType(float x, float y) const { @@ -1971,10 +1856,51 @@ uint8 Map::GetTerrainType(float x, float y) const ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data) const { - if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) - return gmap->getLiquidStatus(x, y, z, ReqLiquidType, data); - else - return LIQUID_MAP_NO_WATER; + ZLiquidStatus result = LIQUID_MAP_NO_WATER; + VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); + float liquid_level, ground_level = INVALID_HEIGHT; + uint32 liquid_type; + if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type)) + { + sLog.outDebug("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) + { + // All ok in water -> store data + if (data) + { + data->type = liquid_type; + data->level = liquid_level; + data->depth_level = ground_level; + } + + // For speed check as int values + int delta = int((liquid_level - z) * 10); + + // Get position delta + if (delta > 20) // Under water + return LIQUID_MAP_UNDER_WATER; + if (delta > 0 ) // In water + return LIQUID_MAP_IN_WATER; + if (delta > -1) // Walk on water + return LIQUID_MAP_WATER_WALK; + result = LIQUID_MAP_ABOVE_WATER; + } + } + + if(GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y)) + { + LiquidData 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)) + { + if (data) + *data = map_data; + return map_result; + } + } + return result; } float Map::GetWaterLevel(float x, float y) const @@ -2013,17 +1939,15 @@ void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 area zoneid = entry ? ((entry->zone != 0) ? entry->zone : entry->ID) : 0; } -bool Map::IsInWater(float x, float y, float pZ, float min_depth) const +bool Map::IsInWater(float x, float y, float pZ, LiquidData *data) const { // Check surface in x, y point for liquid if (const_cast<Map*>(this)->GetGrid(x, y)) { LiquidData liquid_status; - if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, &liquid_status)) - { - if (liquid_status.level - liquid_status.depth_level > min_depth) + LiquidData *liquid_ptr = data ? data : &liquid_status; + if (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr)) return true; - } } return false; } |