diff --git a/src/game/Maps/MapManager.cpp b/src/game/Maps/MapManager.cpp index 010973a6dd1..a1d56e14572 100644 --- a/src/game/Maps/MapManager.cpp +++ b/src/game/Maps/MapManager.cpp @@ -625,19 +625,218 @@ BattleGroundMap* MapManager::CreateBattleGroundMap(uint32 id, uint32 InstanceId, return map; } -bool IsNorthTo(float x, float y, float const* limits, int count /* last case is limits[2*count - 1] */) -{ +// Following defines are part of the instantiated continents feature. +// Polylines should go from east to west; The first Y coordinate must be less than the last Y coordinate. + +static float const topNorthSouthLimit[] = { 2032.048340f, -6927.750000f, + 1634.863403f, -6157.505371f, + 1109.519775f, -5181.036133f, + 1315.204712f, -4096.020508f, + 1073.089233f, -3372.571533f, + 825.833191f, -3125.778809f, + 657.343994f, -2314.813232f, + 424.736145f, -1888.283691f, + 744.395813f, -1647.935425f, + 1424.160645f, -654.948181f, + 1447.065308f, -169.751358f, + 1208.715454f, 189.748703f, + 1596.240356f, 998.616699f, + 1577.923706f, 1293.419922f, + 1458.520264f, 1727.373291f, + 1591.916138f, 3728.139404f}; +static InstantiatedContinentBoundary const topNorthSouthBoundary(MakeBoundary(topNorthSouthLimit, sizeof(topNorthSouthLimit) / (2 * sizeof(float)))); + +static float const ironforgeAreaSouthLimit[] = {-5806.26f, -5864.11f, + -5989.37f, -4312.29f, + -6008.49f, -3590.52f, + -6107.82f, -3345.30f, + -6308.63f, -3049.32f, + -6349.54f, -2533.66f, + -6087.62f, -2190.21f, + -6063.96f, -1411.76f, + -6366.68f, -730.10f, + -7472.04f, -391.88f, + -7491.33f, 3093.74f}; +static InstantiatedContinentBoundary const ironforgeAreaSouthBoundary(MakeBoundary(ironforgeAreaSouthLimit, sizeof(ironforgeAreaSouthLimit) / (2 * sizeof(float)))); + +static float const stormwindAreaNorthLimit[] = {-12863.23f, -4798.42f, + -13006.40f, -1622.80f, + -10908.48f, -1563.87f, + -10670.61f, -1692.51f, + -10049.60f, -1740.40f, + -9810.40f, -1698.41f, + -8725.50f, -1618.45f, + -8739.00f, -501.00f, + -9097.00f, -510.00f, + -9206.00f, -290.00f, + -9094.00f, -147.00f, + -9068.00f, -125.00f, + -9044.00f, 35.00f, + -8638.00f, 169.00f, + -8075.00f, -179.00f, + -8004.25f, 3714.11f}; +static InstantiatedContinentBoundary const stormwindAreaNorthBoundary(MakeBoundary(stormwindAreaNorthLimit, sizeof(stormwindAreaNorthLimit) / (2 * sizeof(float)))); + +static float const stormwindAreaSouthLimit[] = {-7910.859375f, -5855.578125f, + -7949.329590f, -4081.389404f, + -9610.209961f, -3648.369385f, + -9944.026367f, -3205.886963f, + -9861.309570f, -2989.841064f, + -9966.274414f, -2227.197754f, + -10169.600586f, -1801.582031f, + -9887.579102f, -1618.514038f, + -9991.717773f, -1428.793213f, + -9980.967773f, -1128.510498f, + -9877.489258f, -563.304871f, + -9978.146484f, -361.638031f, + -10014.583984f, -161.638519f, + -10148.072266f, 80.056450f, + -10083.828125f, 380.389893f, + -10287.361328f, 760.076477f, + -9946.341797f, 743.102844f, + -9796.953125f, 839.069580f, + -9525.699219f, 910.132568f, + -8725.337891f, 3535.624023f}; +static InstantiatedContinentBoundary const stormwindAreaSouthBoundary(MakeBoundary(stormwindAreaSouthLimit, sizeof(stormwindAreaSouthLimit) / (2 * sizeof(float)))); + +static float const northMiddleLimit[] = {1368.00f, -8530.00f, + 1497.59f, -6376.56f, + 1703.57f, -5510.53f, + 2193.79f, -5484.38f, + 2388.13f, -5124.35f, + 2373.78f, -4019.96f, + 1694.11f, -3615.20f, + 1424.22f, -3365.69f, + 1521.82f, -3047.85f, + 1281.54f, -2689.42f, + 899.68f, -2625.56f, + 788.96f, -2276.02f, + 879.60f, -2110.18f, + 1211.09f, -1135.55f, + 568.86f, -892.28f, + 284.31f, -1105.39f, + -81.29f, -930.89f, + -280.65f, -1008.87f, + -512.57f, -919.49f, + -377.92f, -748.70f, + -358.40f, -587.42f, + -311.38f, 114.43f, + -685.55f, 408.43f, + -747.46f, 647.73f, + -1094.55f, 651.75f, + -1754.85f, 504.55f, + -1808.52f, 436.39f, + -2044.54f, 489.86f, + -2137.00f, 662.00f, + -2286.00f, 769.00f, + -2432.00f, 1338.00f, + -2401.00f, 2365.00f, + -2280.00f, 4054.00f}; +static InstantiatedContinentBoundary const northMiddleBoundary(MakeBoundary(northMiddleLimit, sizeof(northMiddleLimit) / (2 * sizeof(float)))); + +static float const durotarSouthLimit[] = {-2243.00f, -6046.00f, + -1387.00f, -4674.00f, + -1176.00f, -4213.00f, + -790.00f, -4502.00f, + -668.00f, -4539.00f, + -522.00f, -4583.00f, + -397.00f, -4601.00f, + -14.00f, -4551.00f, + -5.00f, -4192.00f, + 16.00f, -4187.00f, + -49.00f, -4089.00f, + -81.00f, -4091.00f, + -173.00f, -4064.00f, + -263.00f, -3836.00f, + -75.00f, -3742.00f, + 737.00f, -3782.00f, + 1184.00f, -3915.00f, + 1564.00f, -3943.00f, + 1762.00f, -3746.00f, + 2225.00f, -3596.00f, + 2755.00f, -3766.00f}; +static InstantiatedContinentBoundary const durotarSouthBoundary(MakeBoundary(durotarSouthLimit, sizeof(durotarSouthLimit) / (2 * sizeof(float)))); + +static float const valleyoftrialsSouthLimit[] = {-521.00f, -4582.00f, + -661.00f, -4541.00f, + -828.00f, -4414.00f, + -932.00f, -4349.00f, + -965.00f, -4290.00f, + -774.00f, -3992.00f, + -324.00f, -3869.00f}; +static InstantiatedContinentBoundary const valleyoftrialsSouthBoundary(MakeBoundary(valleyoftrialsSouthLimit, sizeof(valleyoftrialsSouthLimit) / (2 * sizeof(float)))); + +static float const middleToSouthLimit[] = {- 5437.00f, -5863.00f, + -5459.449707f, -4920.155273f, -5246.920898f, -3339.139893f, -5248.286621f, -3034.536377f, -5102.913574f, -2647.062744f, -4824.16f, -2310.11f, // Tanaris + -4543.093750f, -1882.869385f, -4515.219727f, -1681.356079f, // Thousand Needles + -4365.006836f, -1602.575439f, // the Barrens + -3472.819580f, 182.522476f, // Feralas + -2826.438965f, 403.824738f, -2344.124023f, 1756.164307f, // Mulgore + -2475.933105f, 3199.568359f, -2402.01f, 4255.70f // Desolace +}; +static InstantiatedContinentBoundary const middleToSouthBoundary(MakeBoundary(middleToSouthLimit, sizeof(middleToSouthLimit) / (2 * sizeof(float)))); + +static float const orgrimmarSouthLimit[] = {2219.1562f, -4854.3330f, + 1979.7647f, -4883.4585f, + 1875.8312f, -4788.7187f, + 1716.8065f, -4601.1323f, + 1584.1331f, -4596.8764f, + 1464.7142f, -4545.2875f, + 1407.2349f, -4429.4145f, + 1445.2428f, -4373.9052f, + 1393.3199f, -4196.0625f, + 1436.3106f, -4007.8950f, + 1400.9472f, -4242.2387f, + 1593.9861f, -3975.5413f, + 1654.3671f, -3380.9902f, + 1735.6906f, -3834.2417f, + 1944.4298f, -3855.2583f, + 2132.5076f, -3912.2478f}; +static InstantiatedContinentBoundary const orgrimmarSouthBoundary(MakeBoundary(orgrimmarSouthLimit, sizeof(orgrimmarSouthLimit) / (2 * sizeof(float)))); + +static float const feralasThousandNeedlesSouthLimit[] = {-6495.4995f, -4711.981f, + -6674.9995f, -4515.0019f, + -6769.5717f, -4122.4272f, + -6838.2651f, -3874.2792f, + -6851.1314f, -3659.1179f, + -6624.6845f, -3063.3843f, + -6416.9067f, -2570.1301f, + -5959.8466f, -2287.2634f, + -5947.9135f, -1866.5028f, + -5947.9135f, -820.4881f, + -5876.7114f, -3.5138f, + -5876.7114f, 917.6407f, + -6099.3603f, 1153.2884f, + -6021.8989f, 1638.1809f, + -6091.6176f, 2335.8892f, + -6744.9946f, 2393.4855f, + -6973.8608f, 3077.0281f, + -7068.7241f, 4376.2304f, + -7142.1211f, 4808.4331f}; +static InstantiatedContinentBoundary const feralasThousandNeedlesSouthBoundary(MakeBoundary(feralasThousandNeedlesSouthLimit, sizeof(feralasThousandNeedlesSouthLimit) / (2 * sizeof(float)))); + +bool IsNorthTo(float x, float y, InstantiatedContinentBoundary const& icb) +{ + if (x < icb.minX) + return false; + + if (y < icb.minY || y > icb.maxY) + return false; + + if (x > icb.maxX && y<=icb.points[icb.count * 2 - 1] && y>icb.points[1]) + return true; + int insideCount = 0; - for (int i = 0; i < count - 1; ++i) + for (int i = 0; i < icb.count - 1; ++i) { - if ((limits[2*i + 1] < y && y < limits[2*i + 3]) || (limits[2*i + 1] > y && y > limits[2*i + 3])) + if ((icb.points[2 * i + 1] < y && y < icb.points[2 * i + 3]) || (icb.points[2 * i + 1] > y && y > icb.points[2 * i + 3])) { - float threshold = limits[2*i] + (limits[2*i + 2] - limits[2*i]) * (y - limits[2*i + 1]) / (limits[2*i + 3] - limits[2*i + 1]); + float threshold = icb.points[2 * i] + (icb.points[2 * i + 2] - icb.points[2 * i]) * (y - icb.points[2 * i + 1]) / (icb.points[2 * i + 3] - icb.points[2 * i + 1]); if (x > threshold) ++insideCount; } } - return insideCount % 2 == 1; + return insideCount & 1; } uint32 MapManager::GetContinentInstanceId(uint32 mapId, float x, float y, bool* transitionArea) @@ -651,229 +850,33 @@ uint32 MapManager::GetContinentInstanceId(uint32 mapId, float x, float y, bool* // Y = horizontal axis on wow ... switch (mapId) { - case MAP_EASTERN_KINGDOMS: + case MAP_EASTERN_KINGDOMS: { - static float const topNorthSouthLimit[] = { - 2032.048340f, -6927.750000f, - 1634.863403f, -6157.505371f, - 1109.519775f, -5181.036133f, - 1315.204712f, -4096.020508f, - 1073.089233f, -3372.571533f, - 825.833191f, -3125.778809f, - 657.343994f, -2314.813232f, - 424.736145f, -1888.283691f, - 744.395813f, -1647.935425f, - 1424.160645f, -654.948181f, - 1447.065308f, -169.751358f, - 1208.715454f, 189.748703f, - 1596.240356f, 998.616699f, - 1577.923706f, 1293.419922f, - 1458.520264f, 1727.373291f, - 1591.916138f, 3728.139404f - }; - static float const ironforgeAreaSouthLimit[] = { - -7491.33f, 3093.74f, - -7472.04f, -391.88f, - -6366.68f, -730.10f, - -6063.96f, -1411.76f, - -6087.62f, -2190.21f, - -6349.54f, -2533.66f, - -6308.63f, -3049.32f, - -6107.82f, -3345.30f, - -6008.49f, -3590.52f, - -5989.37f, -4312.29f, - -5806.26f, -5864.11f - }; - static float const stormwindAreaNorthLimit[] = { - -8004.25f, 3714.11f, - -8075.00f, -179.00f, - -8638.00f, 169.00f, - -9044.00f, 35.00f, - -9068.00f, -125.00f, - -9094.00f, -147.00f, - -9206.00f, -290.00f, - -9097.00f, -510.00f, - -8739.00f, -501.00f, - -8725.50f, -1618.45f, - -9810.40f, -1698.41f, - -10049.60f, -1740.40f, - -10670.61f, -1692.51f, - -10908.48f, -1563.87f, - -13006.40f, -1622.80f, - -12863.23f, -4798.42f - }; - static float const stormwindAreaSouthLimit[] = { - -8725.337891f, 3535.624023f, - -9525.699219f, 910.132568f, - -9796.953125f, 839.069580f, - -9946.341797f, 743.102844f, - -10287.361328f, 760.076477f, - -10083.828125f, 380.389893f, - -10148.072266f, 80.056450f, - -10014.583984f, -161.638519f, - -9978.146484f, -361.638031f, - -9877.489258f, -563.304871f, - -9980.967773f, -1128.510498f, - -9991.717773f, -1428.793213f, - -9887.579102f, -1618.514038f, - -10169.600586f, -1801.582031f, - -9966.274414f, -2227.197754f, - -9861.309570f, -2989.841064f, - -9944.026367f, -3205.886963f, - -9610.209961f, -3648.369385f, - -7949.329590f, -4081.389404f, - -7910.859375f, -5855.578125f - }; - if (IsNorthTo(x, y, topNorthSouthLimit, sizeof(topNorthSouthLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, topNorthSouthBoundary)) return MAP0_TOP_NORTH; if (x > -2521) return MAP0_MIDDLE_NORTH; - if (IsNorthTo(x, y, ironforgeAreaSouthLimit, sizeof(ironforgeAreaSouthLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, ironforgeAreaSouthBoundary)) return MAP0_IRONFORGE_AREA; - if (IsNorthTo(x, y, stormwindAreaNorthLimit, sizeof(stormwindAreaNorthLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, stormwindAreaNorthBoundary)) return MAP0_MIDDLE; - if (IsNorthTo(x, y, stormwindAreaSouthLimit, sizeof(stormwindAreaSouthLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, stormwindAreaSouthBoundary)) return MAP0_STORMWIND_AREA; return MAP0_SOUTH; } - case MAP_KALIMDOR: + case MAP_KALIMDOR: { - static float const northMiddleLimit[] = { - -2280.00f, 4054.00f, - -2401.00f, 2365.00f, - -2432.00f, 1338.00f, - -2286.00f, 769.00f, - -2137.00f, 662.00f, - -2044.54f, 489.86f, - -1808.52f, 436.39f, - -1754.85f, 504.55f, - -1094.55f, 651.75f, - -747.46f, 647.73f, - -685.55f, 408.43f, - -311.38f, 114.43f, - -358.40f, -587.42f, - -377.92f, -748.70f, - -512.57f, -919.49f, - -280.65f, -1008.87f, - -81.29f, -930.89f, - 284.31f, -1105.39f, - 568.86f, -892.28f, - 1211.09f, -1135.55f, - 879.60f, -2110.18f, - 788.96f, -2276.02f, - 899.68f, -2625.56f, - 1281.54f, -2689.42f, - 1521.82f, -3047.85f, - 1424.22f, -3365.69f, - 1694.11f, -3615.20f, - 2373.78f, -4019.96f, - 2388.13f, -5124.35f, - 2193.79f, -5484.38f, - 1703.57f, -5510.53f, - 1497.59f, -6376.56f, - 1368.00f, -8530.00f - }; - static float const durotarSouthLimit[] = { - 2755.00f, -3766.00f, - 2225.00f, -3596.00f, - 1762.00f, -3746.00f, - 1564.00f, -3943.00f, - 1184.00f, -3915.00f, - 737.00f, -3782.00f, - -75.00f, -3742.00f, - -263.00f, -3836.00f, - -173.00f, -4064.00f, - -81.00f, -4091.00f, - -49.00f, -4089.00f, - -16.00f, -4187.00f, - -5.00f, -4192.00f, - -14.00f, -4551.00f, - -397.00f, -4601.00f, - -522.00f, -4583.00f, - -668.00f, -4539.00f, - -790.00f, -4502.00f, - -1176.00f, -4213.00f, - -1387.00f, -4674.00f, - -2243.00f, -6046.00f - }; - static float const valleyoftrialsSouthLimit[] = { - -324.00f, -3869.00f, - -774.00f, -3992.00f, - -965.00f, -4290.00f, - -932.00f, -4349.00f, - -828.00f, -4414.00f, - -661.00f, -4541.00f, - -521.00f, -4582.00f - }; - static float const middleToSouthLimit[] = { - -2402.01f, 4255.70f, - -2475.933105f, 3199.568359f, // Desolace - -2344.124023f, 1756.164307f, - -2826.438965f, 403.824738f, // Mulgore - -3472.819580f, 182.522476f, // Feralas - -4365.006836f, -1602.575439f, // the Barrens - -4515.219727f, -1681.356079f, - -4543.093750f, -1882.869385f, // Thousand Needles - -4824.16f, -2310.11f, - -5102.913574f, -2647.062744f, - -5248.286621f, -3034.536377f, - -5246.920898f, -3339.139893f, - -5459.449707f, -4920.155273f, // Tanaris - -5437.00f, -5863.00f - }; - - static float const orgrimmarSouthLimit[] = { - 2132.5076f, -3912.2478f, - 1944.4298f, -3855.2583f, - 1735.6906f, -3834.2417f, - 1654.3671f, -3380.9902f, - 1593.9861f, -3975.5413f, - 1400.9472f, -4242.2387f, - 1436.3106f, -4007.8950f, - 1393.3199f, -4196.0625f, - 1445.2428f, -4373.9052f, - 1407.2349f, -4429.4145f, - 1464.7142f, -4545.2875f, - 1584.1331f, -4596.8764f, - 1716.8065f, -4601.1323f, - 1875.8312f, -4788.7187f, - 1979.7647f, -4883.4585f, - 2219.1562f, -4854.3330f - }; - - static float const feralasThousandNeedlesSouthLimit[] = { - -6495.4995f, -4711.981f, - -6674.9995f, -4515.0019f, - -6769.5717f, -4122.4272f, - -6838.2651f, -3874.2792f, - -6851.1314f, -3659.1179f, - -6624.6845f, -3063.3843f, - -6416.9067f, -2570.1301f, - -5959.8466f, -2287.2634f, - -5947.9135f, -1866.5028f, - -5947.9135f, -820.4881f, - -5876.7114f, -3.5138f, - -5876.7114f, 917.6407f, - -6099.3603f, 1153.2884f, - -6021.8989f, 1638.1809f, - -6091.6176f, 2335.8892f, - -6744.9946f, 2393.4855f, - -6973.8608f, 3077.0281f, - -7068.7241f, 4376.2304f, - -7142.1211f, 4808.4331f - }; - - if (IsNorthTo(x, y, northMiddleLimit, sizeof(northMiddleLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, northMiddleBoundary)) return MAP1_NORTH; - if (IsNorthTo(x, y, orgrimmarSouthLimit, sizeof(orgrimmarSouthLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, orgrimmarSouthBoundary)) return MAP1_ORGRIMMAR; - if (IsNorthTo(x, y, durotarSouthLimit, sizeof(durotarSouthLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, durotarSouthBoundary)) return MAP1_DUROTAR; - if (IsNorthTo(x, y, valleyoftrialsSouthLimit, sizeof(valleyoftrialsSouthLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, valleyoftrialsSouthBoundary)) return MAP1_VALLEY; - if (IsNorthTo(x, y, middleToSouthLimit, sizeof(middleToSouthLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, middleToSouthBoundary)) return MAP1_UPPER_MIDDLE; - if (IsNorthTo(x, y, feralasThousandNeedlesSouthLimit, sizeof(feralasThousandNeedlesSouthLimit) / (2 * sizeof(float)))) + if (IsNorthTo(x, y, feralasThousandNeedlesSouthBoundary)) return MAP1_LOWER_MIDDLE; return MAP1_SOUTH; } diff --git a/src/game/Maps/MapManager.h b/src/game/Maps/MapManager.h index 29302506576..84ba811f486 100644 --- a/src/game/Maps/MapManager.h +++ b/src/game/Maps/MapManager.h @@ -54,6 +54,41 @@ enum MAP1_LAST = 20, }; +struct InstantiatedContinentBoundary +{ + float const* points; + int count; + float minY, maxY; + float minX, maxX; + + InstantiatedContinentBoundary(float const* pts, int c, float minY_, float maxY_, float minX_, float maxX_) : points(pts), count(c), minY(minY_), maxY(maxY_), minX(minX_), maxX(maxX_) {} +}; + +inline InstantiatedContinentBoundary MakeBoundary(float const* pts, int count) +{ + assert(pts[1] < pts[count * 2 - 1] && "Boundary must be defined from west to east (first X < last X)"); + + float minX = pts[0], maxX = pts[0]; + float minY = pts[1], maxY = pts[1]; + + for (int i = 1; i < count; ++i) + { + float x = pts[i * 2]; + float y = pts[i * 2 + 1]; + + if (x < minX) + minX = x; + if (x > maxX) + maxX = x; + if (y < minY) + minY = y; + if (y > maxY) + maxY = y; + } + + return InstantiatedContinentBoundary(pts, count, minY, maxY, minX, maxX); +} + struct MapID { explicit MapID(uint32 id) : nMapId(id), nInstanceId(0) {}