From dc18ea1973deda9c9b8b584c739db37211db8f40 Mon Sep 17 00:00:00 2001 From: elexis Date: Fri, 16 Feb 2018 18:49:54 +0000 Subject: [PATCH] Implement a DiskPlacer to enable random map scripts chosing all points inside a circle without using a special case of the other placers. Especially useful if the center position doesn't meet the constraint or is outside of the map boundary. Removing the preliminary boundary check from the centered placers seems to come with a too high performance penalty, for instance when creating forests. This was SVN commit r21225. --- .../public/maps/random/belgian_uplands.js | 2 +- .../public/maps/random/caledonian_meadows.js | 2 +- binaries/data/mods/public/maps/random/gear.js | 10 +++--- .../data/mods/public/maps/random/lions_den.js | 4 +-- .../mods/public/maps/random/mediterranean.js | 2 +- .../mods/public/maps/random/ngorongoro.js | 2 +- .../data/mods/public/maps/random/pompeii.js | 2 +- .../data/mods/public/maps/random/red_sea.js | 2 +- .../maps/random/rmgen/placer_centered.js | 32 +++++++++++++++++++ .../maps/random/rmgen/placer_noncentered.js | 8 ++--- .../data/mods/public/maps/random/wild_lake.js | 2 +- 11 files changed, 50 insertions(+), 18 deletions(-) diff --git a/binaries/data/mods/public/maps/random/belgian_uplands.js b/binaries/data/mods/public/maps/random/belgian_uplands.js index 1f4a463cfc..2744055a86 100644 --- a/binaries/data/mods/public/maps/random/belgian_uplands.js +++ b/binaries/data/mods/public/maps/random/belgian_uplands.js @@ -101,7 +101,7 @@ while (true) g_Map.log("Mark valid heightrange for player starting positions"); let tHeightRange = g_Map.createTileClass(); let area = createArea( - new ClumpPlacer(diskArea(fractionToTiles(0.5) - MAP_BORDER_WIDTH), 1, 1, Infinity, mapCenter), + new DiskPlacer(fractionToTiles(0.5) - MAP_BORDER_WIDTH, mapCenter), new TileClassPainter(tHeightRange), new HeightConstraint(lowerHeightLimit, upperHeightLimit)); diff --git a/binaries/data/mods/public/maps/random/caledonian_meadows.js b/binaries/data/mods/public/maps/random/caledonian_meadows.js index 14bd8937fb..dad28b845c 100644 --- a/binaries/data/mods/public/maps/random/caledonian_meadows.js +++ b/binaries/data/mods/public/maps/random/caledonian_meadows.js @@ -297,7 +297,7 @@ Engine.SetProgress(30); g_Map.log("Smoothing player locations"); for (let position of playerPosition) createArea( - new ClumpPlacer(diskArea(35), 1, 1, Infinity, position), + new DiskPlacer(35, position), new SmoothElevationPainter(ELEVATION_SET, g_Map.getHeight(position), 35)); g_Map.log("Creating paths between players"); diff --git a/binaries/data/mods/public/maps/random/gear.js b/binaries/data/mods/public/maps/random/gear.js index b2daf8fe60..aae3bb5076 100644 --- a/binaries/data/mods/public/maps/random/gear.js +++ b/binaries/data/mods/public/maps/random/gear.js @@ -116,7 +116,7 @@ else if (mapSize == 448) g_Map.log("Creating big circular lake"); createArea( - new ClumpPlacer(diskArea(radiusCentralLake), 1, 1, Infinity, mapCenter), + new DiskPlacer(radiusCentralLake, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4)); g_Map.log("Creating rivers between players"); @@ -144,22 +144,22 @@ for (let m = 0; m < numPlayers * split; ++m) g_Map.log("Creating ring of land connecting players"); createArea( - new ClumpPlacer(diskArea(radiusCentralRingLand), 1, 1, Infinity, mapCenter), + new DiskPlacer(radiusCentralRingLand, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightRing, 4)); g_Map.log("Creating inner ring of water"); createArea( - new ClumpPlacer(diskArea(radiusCentralWaterRing), 1, 1, Infinity, mapCenter), + new DiskPlacer(radiusCentralWaterRing, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightShallow, 3)); g_Map.log("Creating central island"); createArea( - new ClumpPlacer(diskArea(radiusCentralIsland), 1, 1, Infinity, mapCenter), + new DiskPlacer(radiusCentralIsland, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightRing, 3)); g_Map.log("Creating hill on the central island"); createArea( - new ClumpPlacer(diskArea(radiusCentralHill), 1, 1, Infinity, mapCenter), + new DiskPlacer(radiusCentralHill, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightHill, 8)); paintTerrainBasedOnHeight(-6, 1, 1, tWater); diff --git a/binaries/data/mods/public/maps/random/lions_den.js b/binaries/data/mods/public/maps/random/lions_den.js index 11e7d7977f..daf2a78934 100644 --- a/binaries/data/mods/public/maps/random/lions_den.js +++ b/binaries/data/mods/public/maps/random/lions_den.js @@ -482,7 +482,7 @@ function createSunkenTerrain() g_Map.log("Creating central valley"); createArea( - new ClumpPlacer(diskArea(fractionToTiles(0.29)), 1, 1, Infinity, mapCenter), + new DiskPlacer(fractionToTiles(0.29), mapCenter), [ new LayeredPainter([g_Terrains.cliff, lower], [3]), new SmoothElevationPainter(ELEVATION_SET, heightValley, 3), @@ -491,7 +491,7 @@ function createSunkenTerrain() g_Map.log("Creating central hill"); createArea( - new ClumpPlacer(diskArea(fractionToTiles(0.21)), 1, 1, Infinity, mapCenter), + new DiskPlacer(fractionToTiles(0.21), mapCenter), [ new LayeredPainter([g_Terrains.cliff, topTerrain], [3]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 3), diff --git a/binaries/data/mods/public/maps/random/mediterranean.js b/binaries/data/mods/public/maps/random/mediterranean.js index 169c9ba3ea..9ee83321d1 100644 --- a/binaries/data/mods/public/maps/random/mediterranean.js +++ b/binaries/data/mods/public/maps/random/mediterranean.js @@ -107,7 +107,7 @@ Engine.SetProgress(30); g_Map.log("Marking land"); createArea( - new ClumpPlacer(diskArea(fractionToTiles(0.5)), 1, 1, Infinity, mapCenter), + new DiskPlacer(fractionToTiles(0.5), mapCenter), new TileClassPainter(g_TileClasses.land), avoidClasses(g_TileClasses.water, 0)); Engine.SetProgress(35); diff --git a/binaries/data/mods/public/maps/random/ngorongoro.js b/binaries/data/mods/public/maps/random/ngorongoro.js index 17227194ad..f72e64999e 100644 --- a/binaries/data/mods/public/maps/random/ngorongoro.js +++ b/binaries/data/mods/public/maps/random/ngorongoro.js @@ -106,7 +106,7 @@ Engine.SetProgress(40); g_Map.log("Marking eden"); createArea( - new ClumpPlacer(diskArea(fractionToTiles(0.14)), 1, 1, Infinity, mapCenter), + new DiskPlacer(fractionToTiles(0.14), mapCenter), new TileClassPainter(g_TileClasses.eden), new HeightConstraint(-Infinity, heightEden)); Engine.SetProgress(45); diff --git a/binaries/data/mods/public/maps/random/pompeii.js b/binaries/data/mods/public/maps/random/pompeii.js index 4aad3bb381..ebaa540e4d 100644 --- a/binaries/data/mods/public/maps/random/pompeii.js +++ b/binaries/data/mods/public/maps/random/pompeii.js @@ -132,7 +132,7 @@ Engine.SetProgress(40); g_Map.log("Marking dock search location"); var areaDockStart = createArea( - new ClumpPlacer(diskArea(fractionToTiles(0.5)) - 10, 1, 1, Infinity, mapCenter), + new DiskPlacer(fractionToTiles(0.5) - 10, mapCenter), undefined, stayClasses(g_TileClasses.land, 6)); diff --git a/binaries/data/mods/public/maps/random/red_sea.js b/binaries/data/mods/public/maps/random/red_sea.js index e291d1dd91..8d016bbc30 100644 --- a/binaries/data/mods/public/maps/random/red_sea.js +++ b/binaries/data/mods/public/maps/random/red_sea.js @@ -88,7 +88,7 @@ Engine.SetProgress(30); g_Map.log("Marking land"); createArea( - new ClumpPlacer(diskArea(fractionToTiles(0.5)), 1, 1, Infinity, mapCenter), + new DiskPlacer(fractionToTiles(0.5), mapCenter), new TileClassPainter(g_TileClasses.land), avoidClasses(g_TileClasses.water, 0)); Engine.SetProgress(35); diff --git a/binaries/data/mods/public/maps/random/rmgen/placer_centered.js b/binaries/data/mods/public/maps/random/rmgen/placer_centered.js index e78469b050..e123ed11b2 100644 --- a/binaries/data/mods/public/maps/random/rmgen/placer_centered.js +++ b/binaries/data/mods/public/maps/random/rmgen/placer_centered.js @@ -3,6 +3,38 @@ * The center can be modified externally using setCenterPosition, typically called by createAreas. */ +/** + * Returns all points on a disk at the given location that meet the constraint. + */ +function DiskPlacer(radius, centerPosition = undefined) +{ + this.radius = radius; + this.centerPosition = undefined; + + if (centerPosition) + this.setCenterPosition(centerPosition); +} + +DiskPlacer.prototype.setCenterPosition = function(position) +{ + this.centerPosition = deepfreeze(position.clone().round()); +}; + +DiskPlacer.prototype.place = function(constraint) +{ + let points = []; + + for (let x = 0; x < g_Map.getSize(); ++x) + for (let y = 0; y < g_Map.getSize(); ++y) + { + let point = new Vector2D(x, y); + if (this.centerPosition.distanceTo(point) <= this.radius && constraint.allows(point)) + points.push(point); + } + + return points; +}; + /** * Generates a roughly circular clump of points. * diff --git a/binaries/data/mods/public/maps/random/rmgen/placer_noncentered.js b/binaries/data/mods/public/maps/random/rmgen/placer_noncentered.js index 7fa8822fd9..39bcae592d 100644 --- a/binaries/data/mods/public/maps/random/rmgen/placer_noncentered.js +++ b/binaries/data/mods/public/maps/random/rmgen/placer_noncentered.js @@ -186,7 +186,7 @@ function RandomPathPlacer(pathStart, pathEnd, pathWidth, offset, blended) this.pathEnd = pathEnd; this.offset = offset; this.blended = blended; - this.clumpPlacer = new ClumpPlacer(diskArea(pathWidth), 1, 1, Infinity); + this.diskPlacer = new DiskPlacer(pathWidth); this.maxPathLength = fractionToTiles(2); } @@ -203,10 +203,10 @@ RandomPathPlacer.prototype.place = function(constraint) -getAngle(this.pathStart.x, this.pathStart.y, this.pathEnd.x, this.pathEnd.y) + -Math.PI / 2 * (randFloat(-1, 1) + (this.blended ? 0.5 : 0)))).round(); - this.clumpPlacer.setCenterPosition(position); + this.diskPlacer.setCenterPosition(position); - for (let point of this.clumpPlacer.place(constraint) || []) - if (points.every(p => p.x != point.x || p.y != point.y)) + for (let point of this.diskPlacer.place(constraint)) + if (points.every(p => !Vector2D.isEqualTo(p, point))) points.push(point); } diff --git a/binaries/data/mods/public/maps/random/wild_lake.js b/binaries/data/mods/public/maps/random/wild_lake.js index 8ff5e63ccd..9329c0b899 100644 --- a/binaries/data/mods/public/maps/random/wild_lake.js +++ b/binaries/data/mods/public/maps/random/wild_lake.js @@ -635,7 +635,7 @@ for (let i = 0; i < resourceSpots.length; ++i) if (radius) createArea( - new ClumpPlacer(diskArea(radius), 1, 1, Infinity, resourceSpots[i]), + new DiskPlacer(radius, resourceSpots[i]), new SmoothElevationPainter(ELEVATION_SET, g_Map.getHeight(resourceSpots[i]), radius / 3)); }