Index: binaries/data/mods/public/maps/random/harbor.js =================================================================== --- binaries/data/mods/public/maps/random/harbor.js +++ binaries/data/mods/public/maps/random/harbor.js @@ -1,6 +1,5 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmgen-common"); -Engine.LoadLibrary("rmgen2"); Engine.LoadLibrary("rmbiome"); setSelectedBiome(); @@ -11,400 +10,230 @@ var g_Map = new RandomMap(heightLand, g_Terrains.mainTerrain); -initTileClasses(); - -setFogFactor(0.04); - -createArea( - new MapBoundsPlacer(), - new TileClassPainter(g_TileClasses.land)); - +var mapSize = g_Map.getSize(); +var mapCenter = g_Map.getCenter(); +var startAngle = randomAngle(); +var numPlayers = getNumPlayers(); + +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clStone = g_Map.createTileClass(); +var clFish = g_Map.createTileClass(); +var clHuntables = g_Map.createTileClass(); +var clBerries = g_Map.createTileClass(); +var clHills = g_Map.createTileClass(); +var clSpines = g_Map.createTileClass(); +var clLake = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); + +var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35), startAngle); + +placePlayerBases({ + "PlayerPlacement": [playerIDs, playerPosition], + "PlayerTileClass": clPlayer, + "BaseResourceClass": clBaseResource, + "CityPatch": { + "outerTerrain": g_Terrains.roadWild, + "innerTerrain": g_Terrains.road + }, + "Chicken": { + }, + "Berries": { + "template": g_Gaia.fruitBush + }, + "Mines": { + "types": [ + { "template": g_Gaia.metalLarge }, + { "template": g_Gaia.stoneLarge } + ] + }, + "Trees": { + "template": g_Gaia.tree1, + "count": 5 + }, + "Decoratives": { + "template": g_Decoratives.grassShort + } +}); Engine.SetProgress(10); -const mapSize = g_Map.getSize(); -const mapCenter = g_Map.getCenter(); - -const startAngle = randomAngle(); -const [playerIDs, playerPosition] = createBasesByPattern("radial", fractionToTiles(0.38), fractionToTiles(0.05), startAngle); -Engine.SetProgress(20); - -addCenterLake(); -Engine.SetProgress(30); +g_Map.log("Creating spines"); +var numSpines = ((numPlayers <= 3 || mapSize >= 320) && numPlayers <= 4 ? 2 : 1) * numPlayers; +var [spineSize, spineTapering, heightOffsetSpine] = mapSize <= 192 ? [0.02, -0.1, 20] : [0.5, -1.4, 35]; -if (mapSize >= 192) +for (let i = 0; i < numSpines; ++i) { - addHarbors(); - Engine.SetProgress(40); -} - -addSpines(); -Engine.SetProgress(50); - -addElements([ - { - "func": addFish, - "avoid": [ - g_TileClasses.fish, 12, - g_TileClasses.hill, 8, - g_TileClasses.mountain, 8, - g_TileClasses.player, 8, - g_TileClasses.spine, 4 - ], - "stay": [g_TileClasses.water, 7], - "sizes": g_AllSizes, - "mixes": g_AllMixes, - "amounts": ["many"] - } -]); - -addElements(shuffleArray([ - { - "func": addHills, - "avoid": [ - g_TileClasses.bluff, 5, - g_TileClasses.hill, 15, - g_TileClasses.mountain, 2, - g_TileClasses.plateau, 5, - g_TileClasses.player, 20, - g_TileClasses.spine, 5, - g_TileClasses.valley, 2, - g_TileClasses.water, 2 - ], - "sizes": ["tiny", "small"], - "mixes": g_AllMixes, - "amounts": g_AllAmounts - }, - { - "func": addMountains, - "avoid": [ - g_TileClasses.bluff, 20, - g_TileClasses.mountain, 25, - g_TileClasses.plateau, 20, - g_TileClasses.player, 20, - g_TileClasses.spine, 20, - g_TileClasses.valley, 10, - g_TileClasses.water, 15 - ], - "sizes": ["small"], - "mixes": g_AllMixes, - "amounts": g_AllAmounts - }, - { - "func": addPlateaus, - "avoid": [ - g_TileClasses.bluff, 20, - g_TileClasses.mountain, 25, - g_TileClasses.plateau, 20, - g_TileClasses.player, 40, - g_TileClasses.spine, 20, - g_TileClasses.valley, 10, - g_TileClasses.water, 15 - ], - "sizes": ["small"], - "mixes": g_AllMixes, - "amounts": g_AllAmounts - }, - { - "func": addBluffs, - "baseHeight": heightLand, - "avoid": [ - g_TileClasses.bluff, 20, - g_TileClasses.mountain, 25, - g_TileClasses.plateau, 20, - g_TileClasses.player, 40, - g_TileClasses.spine, 20, - g_TileClasses.valley, 10, - g_TileClasses.water, 15 + let tang = startAngle + (i + 0.5) * 2 * Math.PI / numSpines; + let start = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.1), 0).rotate(-tang)); + let end = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.4), 0).rotate(-tang)); + createArea( + new PathPlacer(start, end, scaleByMapSize(14, spineSize), 0.6, 0.1, 0.4, spineTapering), + [ + new LayeredPainter([g_Terrains.cliff, g_Terrains.tier2Terrain], [3]), + new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetSpine, 3), + new TileClassPainter(clSpines) ], - "sizes": ["normal"], - "mixes": g_AllMixes, - "amounts": g_AllAmounts - } -])); -Engine.SetProgress(60); + avoidClasses(clPlayer, 5, clSpines, 4)); +} -addElements(shuffleArray([ - { - "func": addMetal, - "avoid": [ - g_TileClasses.berries, 5, - g_TileClasses.bluff, 5, - g_TileClasses.forest, 3, - g_TileClasses.mountain, 2, - g_TileClasses.plateau, 2, - g_TileClasses.player, 30, - g_TileClasses.rock, 10, - g_TileClasses.spine, 5, - g_TileClasses.metal, 20, - g_TileClasses.water, 3 - ], - "sizes": ["normal"], - "mixes": ["same"], - "amounts": ["normal", "many"] - }, - { - "func": addStone, - "avoid": [ - g_TileClasses.berries, 5, - g_TileClasses.bluff, 5, - g_TileClasses.forest, 3, - g_TileClasses.mountain, 2, - g_TileClasses.plateau, 2, - g_TileClasses.player, 30, - g_TileClasses.rock, 20, - g_TileClasses.spine, 5, - g_TileClasses.metal, 10, - g_TileClasses.water, 3 - ], - "sizes": ["normal"], - "mixes": ["same"], - "amounts": ["normal", "many"] - }, - { - "func": addForests, - "avoid": [ - g_TileClasses.berries, 5, - g_TileClasses.bluff, 5, - g_TileClasses.forest, 8, - g_TileClasses.metal, 3, - g_TileClasses.mountain, 5, - g_TileClasses.plateau, 5, - g_TileClasses.player, 20, - g_TileClasses.rock, 3, - g_TileClasses.spine, 5, - g_TileClasses.water, 2 - ], - "sizes": ["normal"], - "mixes": ["similar"], - "amounts": ["many"] - } -])); +g_Map.log("Creating the lake"); +createArea( + new ChainPlacer( + 2, + Math.floor(scaleByMapSize(2, 12)), + Math.floor(scaleByMapSize(100, 400)), + Infinity, + mapCenter, + 0, + [Math.floor(fractionToTiles(0.2))]), + [ + new LayeredPainter([g_Terrains.shore, g_Terrains.water], [1]), + new SmoothElevationPainter(ELEVATION_SET, heightOffsetHarbor, 3), + new TileClassPainter(clLake) + ], + avoidClasses(clSpines, 0)); +Engine.SetProgress(20); +g_Map.log("Creating the central dip"); +var deepWater = createArea(new DiskPlacer(scaleByMapSize(15, 45), mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 3)); +Engine.SetProgress(25); + +g_Map.log("Create hills"); +createHills( + [g_Terrains.mainTerrain, g_Terrains.cliff, g_Terrains.hill], + avoidClasses(clPlayer, 20, clHills, 15, clLake, 2), + clHills, + scaleByMapSize(3, 15)); + +var [forestTrees, stragglerTrees] = currentBiome() == "generic/savanna" || currentBiome() == "generic/desert" ? getTreeCounts(100, 500, 0.4) : getTreeCounts(100, 1000, 0.4); +var pForest1 = [g_Terrains.forestFloor2 + TERRAIN_SEPARATOR + g_Gaia.tree1, g_Terrains.forestFloor2 + TERRAIN_SEPARATOR + g_Gaia.tree2, g_Terrains.forestFloor2]; +var pForest2 = [g_Terrains.forestFloor1 + TERRAIN_SEPARATOR + g_Gaia.tree4, g_Terrains.forestFloor1 + TERRAIN_SEPARATOR + g_Gaia.tree5, g_Terrains.forestFloor1]; + +createForests( + [g_Terrains.dirt, g_Terrains.forestFloor1, g_Terrains.forestFloor2, pForest1, pForest2], + avoidClasses(clBerries, 5, clForest, 8, clMetal, 3, clStone, 3, clSpines, 5, clLake, 2, clPlayer, 12, clHills, 5), + clForest, + forestTrees); + +createStragglerTrees( + [g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree3, g_Gaia.tree4], + avoidClasses(clForest, 8, clPlayer, 12, clMetal, 6, clStone, 6, clBerries, 5, clSpines, 5, clLake, 2, clHills, 5), + clForest, + stragglerTrees); +Engine.SetProgress(40); + +g_Map.log("Creating stone mines"); +createObjectGroups( + new SimpleGroup( + [ + new SimpleObject(g_Gaia.stoneSmall, 0, 2, 0, 4, 0, 2 * Math.PI, 1), + new SimpleObject(g_Gaia.stoneLarge, 1, 1, 0, 4, 0, 2 * Math.PI, 4) + ], true, clStone), + 0, + avoidClasses(clForest, 8, clPlayer, 15, clBerries, 2, clHuntables, 4, clSpines, 5, clLake, 5, clMetal, 10, clStone, 10, clHills, 5), + scaleByMapSize(2, 8), + 50); + +g_Map.log("Creating small stone quarries"); +createObjectGroups( + new SimpleGroup([new SimpleObject(g_Gaia.stoneSmall, 2, 5, 1, 3, 0, 2 * Math.PI, 1)], true, clStone), + 0, + avoidClasses(clForest, 8, clPlayer, 15, clBerries, 2, clHuntables, 4, clSpines, 5, clLake, 5, clMetal, 10, clStone, 10, clHills, 5), + scaleByMapSize(2, 8), + 50); + +g_Map.log("Creating metal mines"); +createObjectGroups( + new SimpleGroup( + [ + new SimpleObject(g_Gaia.metalSmall, 0, 2, 0, 4, 0, 2 * Math.PI, 1), + new SimpleObject(g_Gaia.metalLarge, 1, 1, 0, 4, 0, 2 * Math.PI, 4) + ], true, clMetal), + 0, + avoidClasses(clForest, 8, clPlayer, 15, clBerries, 2, clHuntables, 4, clSpines, 5, clLake, 5, clMetal, 10, clStone, 10, clHills, 5), + scaleByMapSize(2, 8), + 50); + +g_Map.log("Creating small metal quarries"); +createObjectGroups( + new SimpleGroup([new SimpleObject(g_Gaia.metalSmall, 2, 5, 1, 3, 0, 2 * Math.PI, 1)], true, clMetal), + 0, + avoidClasses(clForest, 8, clPlayer, 15, clBerries, 2, clHuntables, 4, clSpines, 5, clLake, 5, clMetal, 10, clStone, 10, clHills, 5), + scaleByMapSize(2, 8), + 50); Engine.SetProgress(70); -addElements(shuffleArray([ - { - "func": addBerries, - "avoid": [ - g_TileClasses.berries, 30, - g_TileClasses.bluff, 5, - g_TileClasses.forest, 5, - g_TileClasses.metal, 10, - g_TileClasses.mountain, 2, - g_TileClasses.plateau, 2, - g_TileClasses.player, 20, - g_TileClasses.rock, 10, - g_TileClasses.spine, 2, - g_TileClasses.water, 3 - ], - "sizes": g_AllSizes, - "mixes": g_AllMixes, - "amounts": g_AllAmounts - }, - { - "func": addAnimals, - "avoid": [ - g_TileClasses.animals, 20, - g_TileClasses.bluff, 5, - g_TileClasses.forest, 2, - g_TileClasses.metal, 2, - g_TileClasses.mountain, 1, - g_TileClasses.plateau, 2, - g_TileClasses.player, 20, - g_TileClasses.rock, 2, - g_TileClasses.spine, 2, - g_TileClasses.water, 3 - ], - "sizes": g_AllSizes, - "mixes": g_AllMixes, - "amounts": g_AllAmounts - }, - { - "func": addStragglerTrees, - "avoid": [ - g_TileClasses.berries, 5, - g_TileClasses.bluff, 5, - g_TileClasses.forest, 7, - g_TileClasses.metal, 2, - g_TileClasses.mountain, 1, - g_TileClasses.plateau, 2, - g_TileClasses.player, 12, - g_TileClasses.rock, 2, - g_TileClasses.spine, 2, - g_TileClasses.water, 5 - ], - "sizes": g_AllSizes, - "mixes": g_AllMixes, - "amounts": g_AllAmounts - } -])); - +g_Map.log("Creating berry bushes"); +createObjectGroups( + new SimpleGroup([new SimpleObject(g_Gaia.fruitBush, 3, 7, 1, 3)], true, clBerries), + 0, + avoidClasses(clForest, 8, clPlayer, 15, clBerries, 2, clHuntables, 4, clSpines, 5, clLake, 5, clMetal, 10, clStone, 10, clHills, 5), + scaleByMapSize(5, 15)); +Engine.SetProgress(75); + +g_Map.log("Creating patches"); +for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) + createAreas( + new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), + new LayeredPainter([g_Terrains.tier1Terrain, g_Terrains.mainTerrain], [1]), + avoidClasses(clSpines, 0, clForest, 0, clPlayer, 5, clLake, 10, clHills, 5), + scaleByMapSize(50, 90)); Engine.SetProgress(80); -addElements([ - { - "func": addLayeredPatches, - "avoid": [ - g_TileClasses.bluff, 2, - g_TileClasses.dirt, 5, - g_TileClasses.forest, 2, - g_TileClasses.mountain, 2, - g_TileClasses.plateau, 2, - g_TileClasses.player, 12, - g_TileClasses.spine, 5, - g_TileClasses.water, 3 - ], - "sizes": ["normal"], - "mixes": ["normal"], - "amounts": ["normal"] - }, - { - "func": addDecoration, - "avoid": [ - g_TileClasses.bluff, 2, - g_TileClasses.forest, 2, - g_TileClasses.mountain, 2, - g_TileClasses.plateau, 2, - g_TileClasses.player, 12, - g_TileClasses.spine, 5, - g_TileClasses.water, 3 - ], - "sizes": ["normal"], - "mixes": ["normal"], - "amounts": ["normal"] - } -]); - +g_Map.log("Creating huntable animals"); +var huntCount = currentBiome() == "generic/savanna" ? scaleByMapSize(7, 15) : scaleByMapSize(5, 10); // Simulate addAnimals() behavior from rmgen2 +createObjectGroups( + new SimpleGroup([new SimpleObject(g_Gaia.mainHuntableAnimal, 5, 7, 0, 4)], true, clHuntables), + 0, + avoidClasses(clForest, 0, clPlayer, 20, clHills, 1, clMetal, 4, clStone, 4, clHuntables, 20, clSpines, 3, clLake, 2), + huntCount); + +createObjectGroups( + new SimpleGroup([new SimpleObject(g_Gaia.secondaryHuntableAnimal, 2, 3, 0, 2)], true, clHuntables), + 0, + avoidClasses(clForest, 0, clPlayer, 20, clHills, 1, clMetal, 4, clStone, 4, clHuntables, 20, clSpines, 3, clLake, 2), + huntCount); + +g_Map.log("Creating fish"); +createObjectGroups( + new SimpleGroup([new SimpleObject(g_Gaia.fish, 2, 4, 0, 2)], true, clFish), + 0, + [ + avoidClasses(clSpines, 3), + stayClasses(clLake, 0) + ], + scaleByMapSize(20, 50)); + +// Create more fish out of the "harbors" +createObjectGroupsByAreas( + new SimpleGroup([new SimpleObject(g_Gaia.fish, 2, 4, 0, 2), true, clFish]), + 0, + avoidClasses(clFish, 1), + scaleByMapSize(10, 20), + [deepWater]); Engine.SetProgress(90); -placePlayersNomad( - g_TileClasses.player, - avoidClasses( - g_TileClasses.bluff, 4, - g_TileClasses.water, 4, - g_TileClasses.spine, 4, - g_TileClasses.plateau, 4, - g_TileClasses.forest, 1, - g_TileClasses.metal, 4, - g_TileClasses.rock, 4, - g_TileClasses.mountain, 4, - g_TileClasses.animals, 2)); +g_Map.log("Creating decorations"); +createObjectGroups( + new SimpleGroup([new SimpleObject("actor|props/special/eyecandy/skeleton.xml", 1, 2, 0, 2)], true), + 0, + stayClasses(clSpines, 1)); + +createObjectGroups( + new SimpleGroup([new SimpleObject(g_Decoratives.grassShort, 3, 6, 0, 2), new SimpleObject(g_Decoratives.grass, 3, 6, 0, 2)], true), + 0, + avoidClasses(clLake, 3, clSpines, 2)); + +createObjectGroups( + new SimpleGroup([new SimpleObject(g_Decoratives.rockLarge, 3, 6, 0, 2), new SimpleObject(g_Decoratives.rockMedium, 3, 6, 0, 2)], true), + 0, + avoidClasses(clLake, 3, clSpines, 2)); + +if (currentBiome() == "generic/desert") + createObjectGroups( + new SimpleGroup([new SimpleObject("actor|props/special/eyecandy/well_1_c.xml", 0, 1, 0, 2)], true), + 0, + avoidClasses(clPlayer, 15, clForest, 5, clHills, 5, clSpines, 5, clLake, 20)); g_Map.ExportMap(); - -function addCenterLake() -{ - createArea( - new ChainPlacer( - 2, - Math.floor(scaleByMapSize(2, 12)), - Math.floor(scaleByMapSize(35, 160)), - Infinity, - mapCenter, - 0, - [Math.floor(fractionToTiles(0.2))]), - [ - new LayeredPainter([g_Terrains.shore, g_Terrains.water], [1]), - new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 10), - new TileClassPainter(g_TileClasses.water) - ], - avoidClasses(g_TileClasses.player, 20)); - - let fDist = 50; - if (mapSize <= 192) - fDist = 20; -} - -function addHarbors() -{ - for (let position of playerPosition) - { - let harborPosition = Vector2D.add(position, Vector2D.sub(mapCenter, position).div(2.5).round()); - createArea( - new ClumpPlacer(1200, 0.5, 0.5, Infinity, harborPosition), - [ - new LayeredPainter([g_Terrains.shore, g_Terrains.water], [2]), - new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHarbor, 3), - new TileClassPainter(g_TileClasses.water) - ], - avoidClasses( - g_TileClasses.player, 15, - g_TileClasses.hill, 1 - ) - ); - } -} - -function addSpines() -{ - let smallSpines = mapSize <= 192; - let spineSize = smallSpines ? 0.02 : 0.5; - let spineTapering = smallSpines ?-0.1 : -1.4; - let heightOffsetSpine = smallSpines ? 20 : 35; - - let numPlayers = getNumPlayers(); - let spineTile = g_Terrains.dirt; - - if (currentBiome() == "generic/snowy") - spineTile = g_Terrains.tier1Terrain; - - if (currentBiome() == "generic/alpine" || currentBiome() == "generic/savanna") - spineTile = g_Terrains.tier2Terrain; - - if (currentBiome() == "generic/autumn") - spineTile = g_Terrains.tier4Terrain; - - let split = 1; - if (numPlayers <= 3 || mapSize >= 320 && numPlayers <= 4) - split = 2; - - for (let i = 0; i < numPlayers * split; ++i) - { - let tang = startAngle + (i + 0.5) * 2 * Math.PI / (numPlayers * split); - let start = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.12), 0).rotate(-tang)); - let end = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.4), 0).rotate(-tang)); - - createArea( - new PathPlacer(start, end, scaleByMapSize(14, spineSize), 0.6, 0.1, 0.4, spineTapering), - [ - new LayeredPainter([g_Terrains.cliff, spineTile], [3]), - new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetSpine, 3), - new TileClassPainter(g_TileClasses.spine) - ], - avoidClasses(g_TileClasses.player, 5) - ); - } - - addElements([ - { - "func": addDecoration, - "avoid": [ - g_TileClasses.bluff, 2, - g_TileClasses.forest, 2, - g_TileClasses.mountain, 2, - g_TileClasses.player, 12, - g_TileClasses.water, 3 - ], - "stay": [g_TileClasses.spine, 5], - "sizes": ["normal"], - "mixes": ["normal"], - "amounts": ["normal"] - } - ]); - - addElements([ - { - "func": addProps, - "avoid": [ - g_TileClasses.forest, 2, - g_TileClasses.player, 2, - g_TileClasses.prop, 20, - g_TileClasses.water, 3 - ], - "stay": [g_TileClasses.spine, 8], - "sizes": ["normal"], - "mixes": ["normal"], - "amounts": ["scarce"] - } - ]); -}