Ticket #4152: heightmapFix2016-11-26.patch
File heightmapFix2016-11-26.patch, 3.5 KB (added by , 7 years ago) |
---|
-
binaries/data/mods/public/maps/random/heightmap/heightmap.js
107 107 * @param {array} [entityList=[g_Gaia.stoneLarge, g_Gaia.metalLarge]] - Entity/actor strings to be placed with placeObject() 108 108 * @param {integer} [maxTries=1000] - How often random player distributions are rolled to be compared 109 109 * @param {boolean} [isCircular=g_MapSettings.CircularMap] - If the map is circular or rectangular 110 * @return {array} [placements] Array of points where entities where placed 110 111 */ 111 112 function distributeEntitiesByHeight(heightRange, avoidPoints, minDistance = 30, entityList = [g_Gaia.stoneLarge, g_Gaia.metalLarge], maxTries = 1000, heightmap = g_Map.height, isCircular = g_MapSettings.CircularMap) 112 113 { 113 let placements = deepcopy(avoidPoints); 114 let validTiles = []; 114 let validPoints = []; 115 115 let r = 0.5 * (heightmap.length - 1); // Map center x/y as well as radius 116 116 for (let x = minDistance; x < heightmap.length - minDistance; ++x) 117 { 117 118 for (let y = minDistance; y < heightmap[0].length - minDistance; ++y) 118 if (heightmap[x][y] > heightRange.min && heightmap[x][y] < heightRange.max) // Has the right height 119 if (!isCircular || r - getDistance(x, y, r, r) >= minDistance) // Is far enough away from map border 120 validTiles.push({ "x": x, "y": y }); 119 { 120 if (heightmap[x][y] >= heightRange.min && heightmap[x][y] <= heightRange.max) // Has the right height (accept equality for height range edges) 121 { 122 if (!isCircular || r - getDistance(x + 0.5, y + 0.5, r, r) >= minDistance) // Center of tile is far enough away from map border 123 { 124 // Avoid avoidPoints by minDistance 125 let isValid = true; 126 for (let i = 0; i < avoidPoints.length; ++i) 127 { 128 if (getDistance(x + 0.5, y + 0.5, avoidPoints[i].x, avoidPoints[i].y) < minDistance) 129 { 130 isValid = false; 131 break; 132 } 133 } 134 if (isValid) 135 validPoints.push({ "x": x + 0.5, "y": y + 0.5 }); // Maybe better to randomize 0.5 -> randFloat() and adjust checks 136 } 137 } 138 } 139 } 121 140 141 let placements = []; 142 if (!validPoints.length) // Early return if no valid poins found 143 { 144 log("No placement points found for the given arguments: " + new Error().stack); 145 return placements; 146 } 147 122 148 for (let tries = 0; tries < maxTries; ++tries) 123 149 { 124 let tile = validTiles[randInt(validTiles.length)]; 150 151 let checkPointIndex = randInt(validPoints.length); 152 let checkPoint = validPoints[checkPointIndex]; 125 153 let isValid = true; 126 154 for (let p = 0; p < placements.length; ++p) 127 155 { 128 if (getDistance(placements[p].x, placements[p].y, tile.x, tile.y) < minDistance)156 if (getDistance(placements[p].x, placements[p].y, checkPoint.x, checkPoint.y) < minDistance) 129 157 { 130 158 isValid = false; 131 159 break; … … 133 161 } 134 162 if (isValid) 135 163 { 136 placeObject( tile.x, tile.y, entityList[randInt(entityList.length)], 0, randFloat(0, 2*PI));137 placements.push( tile);164 placeObject(checkPoint.x, checkPoint.y, entityList[randInt(entityList.length)], 0, randFloat(0, 2*PI)); 165 placements.push(checkPoint); 138 166 } 167 168 validPoints.splice(checkPointIndex); 169 if (!validPoints.length) // No more valid points left 170 break; 139 171 } 172 173 if (!placements.length) 174 log("Nothing was placed: " + new Error().stack); 175 176 return placements; 140 177 } 141 178 142 179 /**