1
0
forked from mirrors/0ad

Remove distributeEntitiesByHeight / derivateEntitiesByHeight from 7471a0db63 / 49194819f6.

Fix collisions of mines with trees and berries on Schwarzwald.

It can't achieve anything that a createArea or createObjectGroups call
with a HeightConstraint (6278f75a1f) or HeightPlacer (49194819f6,
24f02d97eb) can't achieve too,
while it can't perform many crucial tasks like testing for arbitrary
Constraints, using custom shapes determined by a Placer or limiting the
amount of entities,
thus the unconventional code is redundant, refs #4805, #3764.

This was SVN commit r20864.
This commit is contained in:
elexis
2018-01-13 22:42:14 +00:00
parent d2e1af5270
commit b180ad3e5d
2 changed files with 17 additions and 68 deletions
@@ -98,67 +98,6 @@ function getStartLocationsByHeightmap(heightRange, maxTries = 1000, minDistToBor
return finalStartLoc;
}
/**
* Meant to place e.g. resource spots within a height range
*
* @param {array} heightRange - The height range in which to place the entities (An associative array with keys "min" and "max" each containing a float)
* @param {array} avoidPoints - An array of 2D points (arrays of length 2), points that will be avoided in the given minDistance e.g. start locations
* @param {number} minDistance - How many tile widths the entities to place have to be away from each other, start locations and the map border
* @param {array} entityList - Entity/actor strings to be placed with placeObject()
* @param {array} [heightmap=g_Map.height] - The reliefmap the entities should be distributed on
* @param {number} [playerID=0] - Index of the player the entities should be placed for. Gaia is 0.
* @param {number} [maxTries=1000] - How often random player distributions are rolled to be compared
* @param {boolean} [isCircular=g_MapSettings.CircularMap] - If the map is circular or rectangular
* @return {array} [placements] Array of points where entities were placed
*/
function distributeEntitiesByHeight(heightRange, avoidPoints, minDistance, entityList,
playerID = 0, maxTries = 1000, heightmap = g_Map.height, isCircular = g_MapSettings.CircularMap)
{
let validPoints = [];
let r = 0.5 * (heightmap.length - 1); // Map center x/y as well as radius
for (let x = minDistance; x < heightmap.length - minDistance; ++x)
{
for (let y = minDistance; y < heightmap[0].length - minDistance; ++y)
{
if (heightmap[x][y] < heightRange.min || heightmap[x][y] > heightRange.max)
continue; // Out of height range
let checkpoint = { "x" : x + 0.5, "y" : y + 0.5 };
if (isCircular && r - Math.euclidDistance2D(checkpoint.x, checkpoint.y, r, r) < minDistance)
continue; // Too close to map border
// Avoid points by minDistance, else add to validPoints
if (avoidPoints.every(ap => Math.euclidDistance2D(checkpoint.x, checkpoint.y, ap.x, ap.y) > minDistance))
validPoints.push(checkpoint);
}
}
let placements = [];
if (!validPoints.length)
{
log("No placement points found for the given arguments (entityList=" + uneval(entityList) + "):\n" + new Error().stack);
return placements;
}
for (let tries = 0; tries < maxTries; ++tries)
{
let checkPointIndex = randIntExclusive(0, validPoints.length);
let checkPoint = validPoints[checkPointIndex];
if (placements.every(p => Math.euclidDistance2D(p.x, p.y, checkPoint.x, checkPoint.y) > minDistance))
{
placeObject(checkPoint.x, checkPoint.y, pickRandom(entityList), playerID, randFloat(0, 2 * Math.PI));
placements.push(checkPoint);
}
validPoints.splice(checkPointIndex);
if (!validPoints.length)
break; // No more valid points left
}
if (!placements.length)
log("Nothing was placed:\n" + new Error().stack);
return placements;
}
/**
* Sets a given heightmap to entirely random values within a given range
* @param {float} [minHeight=MIN_HEIGHT] - Lower limit of the random height to be rolled
@@ -25,6 +25,8 @@ var clPlayer = createTileClass();
var clPath = createTileClass();
var clForest = createTileClass();
var clWater = createTileClass();
var clMetal = createTileClass();
var clRock = createTileClass();
var clFood = createTileClass();
var clBaseResource = createTileClass();
var clOpen = createTileClass();
@@ -209,9 +211,19 @@ placePlayerBases({
}
});
// Add further stone and metal mines
distributeEntitiesByHeight({ 'min': heighLimits[3], 'max': ((heighLimits[4] + heighLimits[3]) / 2) }, startLocations, 40, [templateStoneMine, templateMetalMine]);
distributeEntitiesByHeight({ 'min': ((heighLimits[5] + heighLimits[6]) / 2), 'max': heighLimits[7] }, startLocations, 40, [templateStoneMine, templateMetalMine]);
log("Creating mines...");
for (let [minHeight, maxHeight] of [[heighLimits[3], (heighLimits[4] + heighLimits[3]) / 2], [(heighLimits[5] + heighLimits[6]) / 2, heighLimits[7]]])
for (let [template, tileClass] of [[templateStoneMine, clRock], [templateMetalMine, clMetal]])
createObjectGroups(
new SimpleGroup([new SimpleObject(template, 1, 1, 0, 4)], true, tileClass),
0,
[
new HeightConstraint(minHeight, maxHeight),
avoidClasses(clForest, 4, clPlayer, 20, clMetal, 40, clRock, 40)
],
scaleByMapSize(2, 8),
100,
false);
Engine.SetProgress(50);
@@ -362,7 +374,6 @@ Engine.SetProgress(90);
log("Planting trees...");
for (var x = 0; x < mapSize; x++)
{
for (var z = 0;z < mapSize;z++)
{
if (!g_Map.validT(x, z))
@@ -390,10 +401,9 @@ for (var x = 0; x < mapSize; x++)
paintClass(clForest)
],
border ?
avoidClasses(clPath, 1, clOpen, 2, clWater, 3) :
avoidClasses(clPath, 2, clOpen, 3, clWater, 4));
avoidClasses(clPath, 1, clOpen, 2, clWater, 3, clMetal, 4, clRock, 4) :
avoidClasses(clPath, 2, clOpen, 3, clWater, 4, clMetal, 4, clRock, 4));
}
}
Engine.SetProgress(100);