Index: binaries/data/mods/public/maps/random/fjords.js =================================================================== --- /dev/null +++ binaries/data/mods/public/maps/random/fjords.js @@ -0,0 +1,298 @@ +Engine.LoadLibrary("rmgen"); +Engine.LoadLibrary("rmgen-common"); +Engine.LoadLibrary("rmgen2"); +Engine.LoadLibrary("rmbiome"); + +setSelectedBiome(); + +const heightLand = -4; + +let placedBases = false; + +Engine.SetProgress(10); + +while (!placedBases) +{ + var g_Map = new RandomMap(heightLand, g_Terrains.mainTerrain); + const mapCenter = g_Map.getCenter(); + const mapSize = g_Map.getSize(); + + initTileClasses(["bluffsPassage", "nomadArea"]); + createArea( + new MapBoundsPlacer(), + new TileClassPainter(g_TileClasses.map)); + + addElements([ + { + "func": addBluffsWithoutEntities, + "baseHeight": heightLand, + "avoid": [g_TileClasses.bluffIgnore, 0, g_TileClasses.bluff, 20], + "sizes": ["big"], + "mixes": ["similar"], + "amounts": ["normal"] + } + ]); + + // define the shore + paintTerrainBasedOnHeight(-2, 0, Elevation_IncludeMin_IncludeMax, [g_Terrains.shoreBlend, g_Terrains.shore]); + paintTileClassBasedOnHeight(-2, 0, Elevation_IncludeMin_IncludeMax, g_TileClasses.water); + + // define the deep water and make it deeper + const waterDepthPainter = new SmoothElevationPainter(ELEVATION_MODIFY, -10, 5, 3); + const waterHeight = new HeightPlacer(Elevation_IncludeMin_IncludeMax, -20, -1); + const waterArea = new Area(waterHeight.place(new NullConstraint())); + waterDepthPainter.paint(waterArea); + paintTerrainBasedOnHeight(-20, -1, Elevation_IncludeMin_IncludeMax, g_Terrains.water); + paintTileClassBasedOnHeight(-20, -1, Elevation_IncludeMin_IncludeMax, g_TileClasses.water); + + const playerIDs = shuffleArray(sortAllPlayers()); + + if (!isNomad()) + { + const playerPositions = playerPlacementRandom(playerIDs, new StayInTileClassConstraint(g_TileClasses.bluff, 20)); + if (playerPositions !== undefined && playerPositions[1].length == getNumPlayers()) + placedBases = true; + else + { + g_Map.log("couldn't place player bases, retrying..."); + continue; + } + + for(let i = 0; i < playerPositions[1].length; ++i) + { + const cityTexture = new ClumpPlacer( + Math.floor(diskArea(defaultPlayerBaseRadius() / 2)), + 0.5, + 0.1, + Infinity, + playerPositions[1][i], + new LayeredPainter([g_Terrains.mainTerrain, g_Terrains.tier1Terrain], [1])); + + cityTexture.place(avoidClasses(g_TileClasses.water, 5)); + + placePlayerBase({ + "playerID": playerIDs[i], + "playerPosition": playerPositions[1][i], + "PlayerTileClass": g_TileClasses.player, + "BaseResourceClass": g_TileClasses.baseResource, + "baseResourceConstraint": new AndConstraint([stayClasses(g_TileClasses.bluff, 12), avoidClasses(g_TileClasses.water, 7)]), + "Walls": false, + "CityPatch": { + "outerTerrain": g_Terrains.roadWild, + "innerTerrain": g_Terrains.road, + "painters": [ + new TileClassPainter(g_TileClasses.player) + ] + }, + "Chicken": { + "template": g_Gaia.chicken + }, + "Berries": { + "template": g_Gaia.fruitBush + }, + "Mines": { + "types": [ + { "template": g_Gaia.metalLarge }, + { "template": g_Gaia.stoneLarge } + ] + }, + "Trees": { + "template": g_Gaia.tree1, + "count": currentBiome() == "generic/savanna" ? 5 : 15 + }, + "Decoratives": { + "template": g_Decoratives.grassShort + } + }); + } + } + { + placedBases = true; + } +} +Engine.SetProgress(50); + +addElements([ + { + "func": addLayeredPatches, + "avoid": [ + g_TileClasses.bluffsPassage, 10, + g_TileClasses.dirt, 5, + g_TileClasses.forest, 2, + g_TileClasses.player, 15, + g_TileClasses.water, 8, + ], + "stay": [g_TileClasses.bluff, 8], + "sizes": ["normal"], + "mixes": ["unique"], + "amounts": ["tons"] + }, + { + "func": addDecoration, + "avoid": [ + g_TileClasses.bluffsPassage, 10, + g_TileClasses.forest, 2, + g_TileClasses.player, 15, + g_TileClasses.water, 8, + ], + "stay": [g_TileClasses.bluff, 8], + "sizes": ["normal"], + "mixes": ["unique"], + "amounts": ["normal"] + }, + { + "func": addHills, + "avoid": [ + g_TileClasses.hill, 10, + g_TileClasses.player, 20, + g_TileClasses.water, 4 + ], + "stay": [g_TileClasses.bluff, 15], + "sizes": ["tiny"], + "mixes": ["normal"], + "amounts": ["tons"] + }, +]); +Engine.SetProgress(60); + +addElements(shuffleArray([ + { + "func": addMetal, + "avoid": [ + g_TileClasses.bluffsPassage, 8, + g_TileClasses.berries, 8, + g_TileClasses.forest, 4, + g_TileClasses.player, 20, + g_TileClasses.rock, 8, + g_TileClasses.metal, 12, + g_TileClasses.water, 8 + ], + "stay": [g_TileClasses.bluff, 8], + "sizes": ["normal"], + "mixes": ["similar"], + "amounts": ["tons"] + }, + { + "func": addStone, + "avoid": [ + g_TileClasses.bluffsPassage, 8, + g_TileClasses.berries, 8, + g_TileClasses.forest, 4, + g_TileClasses.player, 20, + g_TileClasses.rock, 12, + g_TileClasses.metal, 8, + g_TileClasses.water, 8 + ], + "stay": [g_TileClasses.bluff, 8], + "sizes": ["normal"], + "mixes": ["similar"], + "amounts": ["normal"] + }, + { + "func": addForests, + "avoid": [ + g_TileClasses.bluffsPassage, 8, + g_TileClasses.forest, 8, + g_TileClasses.metal, 4, + g_TileClasses.player, 20, + g_TileClasses.rock, 4, + g_TileClasses.water, 8 + ], + "stay": [g_TileClasses.bluff, 8], + "sizes": ["normal"], + "mixes": ["normal"], + "amounts": ["many"] + }, +])); +Engine.SetProgress(70); + +addElements(shuffleArray([ + { + "func": addBerries, + "avoid": [ + g_TileClasses.berries, 12, + g_TileClasses.bluffsPassage, 8, + g_TileClasses.forest, 4, + g_TileClasses.metal, 8, + g_TileClasses.player, 8, + g_TileClasses.rock, 8, + g_TileClasses.water, 8 + ], + "stay": [g_TileClasses.bluff, 8], + "sizes": ["normal"], + "mixes": ["similar"], + "amounts": ["normal"] + }, + { + "func": addAnimals, + "avoid": [ + g_TileClasses.animals, 12, + g_TileClasses.bluffsPassage, 8, + g_TileClasses.forest, 4, + g_TileClasses.metal, 8, + g_TileClasses.player, 8, + g_TileClasses.rock, 8, + g_TileClasses.water, 8 + ], + "stay": [g_TileClasses.bluff, 8], + "sizes": ["small"], + "mixes": ["similar"], + "amounts": ["normal"] + }, + { + "func": addStragglerTrees, + "avoid": [ + g_TileClasses.berries, 4, + g_TileClasses.bluffsPassage, 8, + g_TileClasses.forest, 4, + g_TileClasses.metal, 4, + g_TileClasses.player, 15, + g_TileClasses.rock, 4, + g_TileClasses.water, 8 + ], + "stay": [g_TileClasses.bluff, 8], + "sizes": ["huge"], + "mixes": ["similar"], + "amounts": ["tons"] + } +])); + +Engine.SetProgress(80); + +addElements([ + { + "func": addFish, + "avoid": [ + g_TileClasses.fish, 12, + g_TileClasses.bluff, 8 + ], + "stay": [g_TileClasses.water, 8], + "sizes": ["normal"], + "mixes": ["normal"], + "amounts": ["tons"] + } +]); + +Engine.SetProgress(90); + +if (isNomad()) +{ + createArea( + new DiskPlacer(mapSize / 2 - scaleByMapSize(15, 35), mapCenter), + new TileClassPainter(g_TileClasses.nomadArea)); + + placePlayersNomad( + g_TileClasses.player, + [ + stayClasses(g_TileClasses.nomadArea, 0, g_TileClasses.bluff, 15), + avoidClasses( + g_TileClasses.forest, 1, + g_TileClasses.metal, 4, + g_TileClasses.rock, 4, + g_TileClasses.mountain, 4, + g_TileClasses.animals, 2) + ]); +} + +g_Map.ExportMap(); + Index: binaries/data/mods/public/maps/random/fjords.json =================================================================== --- /dev/null +++ binaries/data/mods/public/maps/random/fjords.json @@ -0,0 +1,13 @@ +{ + "settings" : { + "Name" : "Fjords", + "Script" : "fjords.js", + "Description" : "Towering cliffs overlook deep water below. Navigate carefully through the narrow waterways as you island hop looking for comfort or combat.", + "Preview" : "fjords.png", + "Keywords": ["naval"], + "SupportedBiomes": "generic/", + "CircularMap" : true, + "TeamPlacements": ["randomGroup"] + } +} + Index: binaries/data/mods/public/maps/random/rmgen2/gaia.js =================================================================== --- binaries/data/mods/public/maps/random/rmgen2/gaia.js +++ binaries/data/mods/public/maps/random/rmgen2/gaia.js @@ -86,100 +86,7 @@ { g_Map.log("Creating bluffs"); - let elevation = 30; - - // Percent of the length of the bluff determining the entrance area - let margin = 0.08; - - let constrastTerrain = g_Terrains.tier2Terrain; - - if (currentBiome() == "generic/india") - constrastTerrain = g_Terrains.dirt; - - if (currentBiome() == "generic/autumn") - constrastTerrain = g_Terrains.tier3Terrain; - - for (let i = 0; i < fill * 15; ++i) - { - let bluffDeviation = getRandomDeviation(size, deviation); - - // Pick a random bluff location and shape - let areasBluff = createAreas( - new ChainPlacer(5 * bluffDeviation, 7 * bluffDeviation, 100 * bluffDeviation, 0.5), - undefined, - constraint, - 1); - - if (!areasBluff.length || !areasBluff[0].getPoints().length) - continue; - - // Get a random starting position for the baseline and the endline - let angle = randIntInclusive(0, 3); - let opposingAngle = (angle + 2) % 4; - - // Find the edges of the bluff - let baseLine; - let endLine; - - // If we can't access the bluff, try different angles - let retries = 0; - let bluffPassable = false; - while (!bluffPassable && retries++ < 4) - { - baseLine = findClearLine(areasBluff[0], angle); - endLine = findClearLine(areasBluff[0], opposingAngle); - bluffPassable = isBluffPassable(areasBluff[0], baseLine, endLine); - - angle = (angle + 1) % 4; - opposingAngle = (angle + 2) % 4; - } - - if (!bluffPassable) - continue; - - // Paint bluff texture and elevation - createArea( - new MapBoundsPlacer(), - [ - new LayeredPainter([g_Terrains.mainTerrain, constrastTerrain], [5]), - new SmoothElevationPainter(ELEVATION_MODIFY, elevation * bluffDeviation, 2), - new TileClassPainter(g_TileClasses.bluff) - ], - new StayAreasConstraint(areasBluff)); - - let slopeLength = (1 - margin) * Vector2D.average([baseLine.start, baseLine.end]).distanceTo(Vector2D.average([endLine.start, endLine.end])); - - // Adjust the height of each point in the bluff - for (let point of areasBluff[0].getPoints()) - { - let dist = Math.abs(distanceOfPointFromLine(baseLine.start, baseLine.end, point)); - g_Map.setHeight(point, Math.max(g_Map.getHeight(point) * (1 - dist / slopeLength) - 2, baseHeight)); - } - - // Flatten all points adjacent to but not on the bluff - createArea( - new MapBoundsPlacer(), - [ - new SmoothingPainter(1, 1, 1), - new TerrainPainter(g_Terrains.mainTerrain) - ], - new AdjacentToAreaConstraint(areasBluff)); - - // Paint cliffs - createArea( - new MapBoundsPlacer(), - new TerrainPainter(g_Terrains.cliff), - [ - new StayAreasConstraint(areasBluff), - new SlopeConstraint(2, Infinity) - ]); - - // Performance improvement - createArea( - new MapBoundsPlacer(), - new TileClassPainter(g_TileClasses.bluffIgnore), - new NearTileClassConstraint(g_TileClasses.bluff, 8)); - } + addBluffsWithoutEntities(constraint, size, deviation, fill, baseHeight); addElements([ { @@ -352,6 +259,116 @@ ])); } +/** + * Create bluffs, i.e. a slope hill reachable from ground level. + * + * @param {Array} constraint - where to place them + * @param {number} size - size of the bluffs (1.2 would be 120% of normal) + * @param {number} deviation - degree of deviation from the defined size (0.2 would be 20% plus/minus) + * @param {number} fill - size of map to fill (1.5 would be 150% of normal) + * @param {number} baseHeight - elevation of the floor, making the bluff reachable + */ +function addBluffsWithoutEntities(constraint, size, deviation, fill, baseHeight) +{ + g_Map.log("Creating plain bluffs"); + + let elevation = 30; + + // Percent of the length of the bluff determining the entrance area + let margin = 0.08; + + let constrastTerrain = g_Terrains.tier2Terrain; + + if (currentBiome() == "generic/india") + constrastTerrain = g_Terrains.dirt; + + if (currentBiome() == "generic/autumn") + constrastTerrain = g_Terrains.tier3Terrain; + + for (let i = 0; i < fill * 15; ++i) + { + let bluffDeviation = getRandomDeviation(size, deviation); + + // Pick a random bluff location and shape + let areasBluff = createAreas( + new ChainPlacer(5 * bluffDeviation, 7 * bluffDeviation, 100 * bluffDeviation, 0.5), + undefined, + constraint, + 1); + + if (!areasBluff.length || !areasBluff[0].getPoints().length) + continue; + + // Get a random starting position for the baseline and the endline + let angle = randIntInclusive(0, 3); + let opposingAngle = (angle + 2) % 4; + + // Find the edges of the bluff + let baseLine; + let endLine; + + // If we can't access the bluff, try different angles + let retries = 0; + let bluffPassable = false; + while (!bluffPassable && retries++ < 4) + { + baseLine = findClearLine(areasBluff[0], angle); + endLine = findClearLine(areasBluff[0], opposingAngle); + bluffPassable = isBluffPassable(areasBluff[0], baseLine, endLine); + + angle = (angle + 1) % 4; + opposingAngle = (angle + 2) % 4; + } + + if (!bluffPassable) + continue; + + // Paint bluff texture and elevation + createArea( + new MapBoundsPlacer(), + [ + new LayeredPainter([g_Terrains.mainTerrain, constrastTerrain], [5]), + new SmoothElevationPainter(ELEVATION_MODIFY, elevation * bluffDeviation, 2), + new TileClassPainter(g_TileClasses.bluff) + ], + new StayAreasConstraint(areasBluff)); + + let slopeLength = (1 - margin) * Vector2D.average([baseLine.start, baseLine.end]).distanceTo(Vector2D.average([endLine.start, endLine.end])); + + // Adjust the height of each point in the bluff + for (let point of areasBluff[0].getPoints()) + { + let dist = Math.abs(distanceOfPointFromLine(baseLine.start, baseLine.end, point)); + g_Map.setHeight(point, Math.max(g_Map.getHeight(point) * (1 - dist / slopeLength) - 2, baseHeight)); + } + + // Flatten all points adjacent to but not on the bluff + createArea( + new MapBoundsPlacer(), + [ + new SmoothingPainter(1, 1, 1), + new TerrainPainter(g_Terrains.mainTerrain) + ], + new AdjacentToAreaConstraint(areasBluff)); + + // Paint cliffs + createArea( + new MapBoundsPlacer(), + new TerrainPainter(g_Terrains.cliff), + [ + new StayAreasConstraint(areasBluff), + new SlopeConstraint(2, Infinity) + ]); + + // Performance improvement + createArea( + new MapBoundsPlacer(), + new TileClassPainter(g_TileClasses.bluffIgnore), + new NearTileClassConstraint(g_TileClasses.bluff, 8)); + } + +} + /** * Add grass, rocks and bushes. */