Ticket #4152: heightmapFix2016-12-6.patch
File heightmapFix2016-12-6.patch, 3.7 KB (added by , 7 years ago) |
---|
-
binaries/data/mods/public/maps/random/heightmap/heightmap.js
105 105 * @param {integer} [minDistance=30] - How many tile widths the entities to place have to be away from each other, start locations and the map border 106 106 * @param {array} [heightmap=g_Map.height] - The reliefmap the entities should be distributed on 107 107 * @param {array} [entityList=[g_Gaia.stoneLarge, g_Gaia.metalLarge]] - Entity/actor strings to be placed with placeObject() 108 * @param {integer} [playerID=0] - Index of the player the entities should be placed for. Gaia is 0. 108 109 * @param {integer} [maxTries=1000] - How often random player distributions are rolled to be compared 109 110 * @param {boolean} [isCircular=g_MapSettings.CircularMap] - If the map is circular or rectangular 111 * @return {array} [placements] Array of points where entities were placed 110 112 */ 111 function distributeEntitiesByHeight(heightRange, avoidPoints, minDistance = 30, entityList = [g_Gaia.stoneLarge, g_Gaia.metalLarge], maxTries = 1000, heightmap = g_Map.height, isCircular = g_MapSettings.CircularMap)113 function distributeEntitiesByHeight(heightRange, avoidPoints, minDistance = 30, entityList = [g_Gaia.stoneLarge, g_Gaia.metalLarge], playerID = 0, maxTries = 1000, heightmap = g_Map.height, isCircular = g_MapSettings.CircularMap) 112 114 { 113 let placements = deepcopy(avoidPoints); 114 let validTiles = []; 115 let validPoints = []; 115 116 let r = 0.5 * (heightmap.length - 1); // Map center x/y as well as radius 116 117 for (let x = minDistance; x < heightmap.length - minDistance; ++x) 118 { 117 119 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 }); 120 { 121 if (heightmap[x][y] < heightRange.min || heightmap[x][y] > heightRange.max) 122 continue; // Out of height range 123 if (isCircular && r - getDistance(x + 0.5, y + 0.5, r, r) < minDistance) 124 continue; // Too close to map border 125 // Avoid avoidPoints by minDistance, else add to validPoints 126 if (avoidPoints.every(ap => getDistance(x + 0.5, y + 0.5, ap.x, ap.y) > minDistance)) 127 validPoints.push({ "x": x + 0.5, "y": y + 0.5 }); 128 } 129 } 121 130 131 let placements = []; 132 if (!validPoints.length) 133 { 134 log("No placement points found for the given arguments: " + new Error().stack); 135 return placements; 136 } 137 122 138 for (let tries = 0; tries < maxTries; ++tries) 123 139 { 124 let tile = validTiles[randInt(validTiles.length)]; 125 let isValid = true; 126 for (let p = 0; p < placements.length; ++p) 140 141 let checkPointIndex = randInt(validPoints.length); 142 let checkPoint = validPoints[checkPointIndex]; 143 if (placements.every(p => getDistance(p.x, p.y, checkPoint.x, checkPoint.y) > minDistance)) 127 144 { 128 if (getDistance(placements[p].x, placements[p].y, tile.x, tile.y) < minDistance) 129 { 130 isValid = false; 131 break; 132 } 145 placeObject(checkPoint.x, checkPoint.y, entityList[randInt(entityList.length)], playerID, randFloat(0, 2*PI)); 146 placements.push(checkPoint); 133 147 } 134 if (isValid) 135 { 136 placeObject(tile.x, tile.y, entityList[randInt(entityList.length)], 0, randFloat(0, 2*PI)); 137 placements.push(tile); 138 } 148 149 validPoints.splice(checkPointIndex); 150 if (!validPoints.length) 151 break; // No more valid points left 139 152 } 153 154 if (!placements.length) 155 log("Nothing was placed: " + new Error().stack); 156 157 return placements; 140 158 } 141 159 142 160 /**