Index: ps/trunk/binaries/data/mods/public/maps/random/english_channel.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/english_channel.js (revision 20409) +++ ps/trunk/binaries/data/mods/public/maps/random/english_channel.js (revision 20410) @@ -1,378 +1,378 @@ RMS.LoadLibrary("rmgen"); const tGrass = ["temp_grass", "temp_grass", "temp_grass_d"]; const tGrassDForest = "temp_plants_bog"; const tGrassA = "temp_grass_plants"; const tGrassB = "temp_plants_bog"; const tGrassC = "temp_mud_a"; const tHill = ["temp_highlands", "temp_grass_long_b"]; const tCliff = ["temp_cliff_a", "temp_cliff_b"]; const tRoad = "temp_road"; const tRoadWild = "temp_road_overgrown"; const tGrassPatchBlend = "temp_grass_long_b"; const tGrassPatch = ["temp_grass_d", "temp_grass_clovers"]; const tShore = "temp_dirt_gravel"; const tWater = "temp_dirt_gravel_b"; const oBeech = "gaia/flora_tree_euro_beech"; const oPoplar = "gaia/flora_tree_poplar"; const oApple = "gaia/flora_tree_apple"; const oOak = "gaia/flora_tree_oak"; const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; const oFish = "gaia/fauna_fish"; const oGoat = "gaia/fauna_goat"; const oBoar = "gaia/fauna_boar"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oStoneSmall = "gaia/geology_stone_temperate"; const oMetalLarge = "gaia/geology_metal_temperate_slabs"; const aGrass = "actor|props/flora/grass_soft_large_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aRockLarge = "actor|geology/stone_granite_large.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aBushMedium = "actor|props/flora/bush_medit_me_lush.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm_lush.xml"; const aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; const aLillies = "actor|props/flora/water_lillies.xml"; const pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oBeech, tGrassDForest]; InitMap(); const numPlayers = getNumPlayers(); var clPlayer = createTileClass(); var clHill = createTileClass(); var clForest = createTileClass(); var clWater = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clShallow = createTileClass(); var playerIDs = primeSortAllPlayers(); var playerPos = placePlayersRiver(); var playerX = []; var playerZ = []; for (var i = 0; i < numPlayers; i++) { playerZ[i] = 0.2 + 0.6*(i%2); playerX[i] = playerPos[i]; } for (var i = 0; i < numPlayers; i++) { var id = playerIDs[i]; log("Creating base for player " + id + "..."); var radius = scaleByMapSize(15,25); var cliffRadius = 2; var elevation = 20; // get the x and z in tiles var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // Setting tile class addCivicCenterAreaToClass(ix, iz, clPlayer); // create the city patch var cityRadius = radius/3; var placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); var painter = new LayeredPainter([tRoadWild, tRoad], [1]); createArea(placer, [painter, paintClass(clPlayer)], null); placeCivDefaultEntities(fx, fz, id); placeDefaultChicken(fx, fz, clBaseResource); // create berry bushes var bbAngle = randFloat(0, TWO_PI); var bbDist = 12; var bbX = round(fx + bbDist * cos(bbAngle)); var bbZ = round(fz + bbDist * sin(bbAngle)); var group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,5, 0,3)], true, clBaseResource, bbX, bbZ ); createObjectGroup(group, 0); // create metal mine var mAngle = bbAngle; while(abs(mAngle - bbAngle) < PI/3) mAngle = randFloat(0, TWO_PI); var mDist = 12; var mX = round(fx + mDist * cos(mAngle)); var mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oMetalLarge, 1,1, 0,0)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); // create stone mines mAngle += randFloat(PI/8, PI/4); mX = round(fx + mDist * cos(mAngle)); mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oStoneLarge, 1,1, 0,2)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); // create starting trees var num = 2; var tAngle = randFloat(-PI/3, 4*PI/3); var tDist = randFloat(11, 13); var tX = round(fx + tDist * cos(tAngle)); var tZ = round(fz + tDist * sin(tAngle)); group = new SimpleGroup( [new SimpleObject(oOak, num, num, 0,5)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); placeDefaultDecoratives(fx, fz, aGrassShort, clBaseResource, radius); } RMS.SetProgress(10); paintRiver({ "horizontal": true, "parallel": false, "position": 0.5, "width": 0.25, "fadeDist": 0.01, "deviation": 0, "waterHeight": -4, "landHeight": 3, "meanderShort": 20, "meanderLong": 0, "waterFunc": (ix, iz, height) => { placeTerrain(ix, iz, height < -1.5 ? tWater : tShore); }, "landFunc": (ix, iz, shoreDist1, shoreDist2) => { setHeight(ix, iz, 3.1); } }); RMS.SetProgress(20); log("Creating tributaries..."); for (let i = 0; i <= randIntInclusive(8, scaleByMapSize(12, 20)); ++i) { var cLocation = randFloat(0.05, 0.95); var sign = randBool() ? 1 : -1; var tang = sign * PI * randFloat(0.2, 0.8); var cDistance = sign * 0.05; let someRadius = scaleByMapSize(10, 20); let point = getTIPIADBON( [fractionToTiles(cLocation), fractionToTiles(0.5 + cDistance)], [fractionToTiles(cLocation), fractionToTiles(0.5 - cDistance)], [-6, -1.5], 0.5, 4, 0.01); if (!point) continue; if (!createArea( new PathPlacer( Math.floor(point[0]), Math.floor(point[1]), Math.floor(fractionToTiles(0.5 + 0.49 * Math.cos(tang))), Math.floor(fractionToTiles(0.5 + 0.49 * Math.sin(tang))), someRadius, 0.4, 3 * scaleByMapSize(1, 4), 0.1, 0.05), [ new SmoothElevationPainter(ELEVATION_SET, -4, 4), paintClass(clWater) ], avoidClasses(clPlayer, 8, clWater, 3, clShallow, 2))) continue; log("Creating small puddles at the map border to ensure players being separated..."); createArea( new ClumpPlacer( Math.floor(Math.PI * Math.pow(someRadius / 2, 2)), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49 * Math.cos(tang)), fractionToTiles(0.5 + 0.49 * Math.sin(tang))), new SmoothElevationPainter(ELEVATION_SET, -3, 3), avoidClasses(clPlayer, 23)); } log("Creating shallows in tributaries..."); for (let z of [0.25, 0.75]) - passageMaker( + createShallowsPassage( Math.round(fractionToTiles(0.2)), Math.round(fractionToTiles(z)), Math.round(fractionToTiles(0.8)), Math.round(fractionToTiles(z)), scaleByMapSize(4, 8), -2, -2, 2, clShallow, undefined, -4); paintTerrainBasedOnHeight(-5, 1, 1, tWater); paintTerrainBasedOnHeight(1, 3, 1, tShore); paintTileClassBasedOnHeight(-6, 0.5, 1, clWater); RMS.SetProgress(25); createBumps(avoidClasses(clWater, 5, clPlayer, 20)); RMS.SetProgress(30); createHills([tCliff, tCliff, tHill], avoidClasses(clPlayer, 20, clHill, 15, clWater, 5), clHill, scaleByMapSize(1, 4) * numPlayers); RMS.SetProgress(50); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tGrass, tGrassDForest, tGrassDForest, pForestD, pForestD], avoidClasses(clPlayer, 20, clForest, 17, clHill, 0, clWater, 6), clForest, forestTrees); RMS.SetProgress(70); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tGrass,tGrassA], tGrassB, [tGrassB,tGrassC]], [1,1], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], [tGrassPatchBlend, tGrassPatch], [1], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45), clDirt); RMS.SetProgress(80); log("Creating stone mines..."); createMines( [ [new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], [new SimpleObject(oStoneSmall, 2,5, 1,3)] ], avoidClasses(clWater, 2, clForest, 1, clPlayer, 20, clRock, 10, clHill, 2), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 2, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 2), clMetal ); RMS.SetProgress(85); createDecoration ( [[new SimpleObject(aRockMedium, 1,3, 0,1)], [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)], [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)], [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), scaleByMapSize(13, 200), scaleByMapSize(13, 200), scaleByMapSize(13, 200) ], avoidClasses(clWater, 1, clForest, 0, clPlayer, 0, clHill, 0) ); // create water decoration in the shallow parts createDecoration ( [[new SimpleObject(aReeds, 1,3, 0,1)], [new SimpleObject(aLillies, 1,2, 0,1)] ], [ scaleByMapSize(800, 12800), scaleByMapSize(800, 12800) ], stayClasses(clShallow, 0) ); createFood ( [ [new SimpleObject(oDeer, 5,7, 0,4)], [new SimpleObject(oGoat, 2,3, 0,2)], [new SimpleObject(oBoar, 2,3, 0,2)] ], [ 3 * numPlayers, 3 * numPlayers, 3 * numPlayers ], avoidClasses(clWater, 1, clForest, 0, clPlayer, 20, clHill, 0, clFood, 15) ); createFood ( [ [new SimpleObject(oBerryBush, 5,7, 0,4)] ], [ randIntInclusive(1, 4) * numPlayers + 2 ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10) ); createFood ( [ [new SimpleObject(oFish, 2,3, 0,2)] ], [scaleByMapSize(3, 25) * numPlayers], [avoidClasses(clFood, 6), stayClasses(clWater, 4)] ); createStragglerTrees( [oBeech, oPoplar, oApple], avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 8, clMetal, 6, clRock, 6), clForest, stragglerTrees); setSkySet("cirrus"); setWaterColor(0.114, 0.192, 0.463); setWaterTint(0.255, 0.361, 0.651); setWaterWaviness(3.0); setWaterType("ocean"); setWaterMurkiness(0.83); setFogThickness(0.35); setFogFactor(0.55); setPPEffect("hdr"); setPPSaturation(0.62); setPPContrast(0.62); setPPBloom(0.37); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/lorraine_plain.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/lorraine_plain.js (revision 20409) +++ ps/trunk/binaries/data/mods/public/maps/random/lorraine_plain.js (revision 20410) @@ -1,415 +1,415 @@ RMS.LoadLibrary("rmgen"); const tGrass = ["temp_grass", "temp_grass", "temp_grass_d"]; const tGrassPForest = "temp_plants_bog"; const tGrassDForest = "temp_plants_bog"; const tGrassA = "temp_grass_plants"; const tGrassB = "temp_plants_bog"; const tGrassC = "temp_mud_a"; const tRoad = "temp_road"; const tRoadWild = "temp_road_overgrown"; const tGrassPatchBlend = "temp_grass_long_b"; const tGrassPatch = ["temp_grass_d", "temp_grass_clovers"]; const tShore = "temp_plants_bog"; const tWater = "temp_mud_a"; const oBeech = "gaia/flora_tree_euro_beech"; const oOak = "gaia/flora_tree_oak"; const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; const oRabbit = "gaia/fauna_rabbit"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oStoneSmall = "gaia/geology_stone_temperate"; const oMetalLarge = "gaia/geology_metal_temperate_slabs"; const aGrass = "actor|props/flora/grass_soft_small_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aRockLarge = "actor|geology/stone_granite_med.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; const aLillies = "actor|props/flora/water_lillies.xml"; const aBushMedium = "actor|props/flora/bush_medit_me.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; const pForestB = [tGrassDForest + TERRAIN_SEPARATOR + oBeech, tGrassDForest]; const pForestO = [tGrassPForest + TERRAIN_SEPARATOR + oOak, tGrassPForest]; const pForestR = [tGrassDForest + TERRAIN_SEPARATOR + oBeech, tGrassDForest, tGrassDForest + TERRAIN_SEPARATOR + oOak, tGrassDForest, tGrassDForest, tGrassDForest]; InitMap(); const numPlayers = getNumPlayers(); var clPlayer = createTileClass(); var clHill = createTileClass(); var clForest = createTileClass(); var clWater = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clShallow = createTileClass(); var playerIDs = primeSortAllPlayers(); var playerPos = placePlayersRiver(); var waterHeight = -4; var playerX = []; var playerZ = []; for (var i = 0; i < numPlayers; i++) { playerZ[i] = 0.25 + 0.5*(i%2); playerX[i] = playerPos[i]; } for (var i = 0; i < numPlayers; i++) { var id = playerIDs[i]; log("Creating base for player " + id + "..."); // scale radius of player area by map size var radius = scaleByMapSize(15,25); // get the x and z in tiles var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // calculate size based on the radius var size = PI * radius * radius / 4; // create the player area var placer = new ClumpPlacer(size, 0.9, 0.5, 10, ix, iz); createArea(placer, paintClass(clPlayer), null); // create the city patch var cityRadius = 10; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); var painter = new LayeredPainter([tRoadWild, tRoad], [3]); createArea(placer, painter, null); placeCivDefaultEntities(fx, fz, id, { 'iberWall': 'towers' }); placeDefaultChicken(fx, fz, clBaseResource); // create berry bushes var bbAngle = randFloat(0, TWO_PI); var bbDist = 12; var bbX = round(fx + bbDist * cos(bbAngle)); var bbZ = round(fz + bbDist * sin(bbAngle)); var group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,5, 0,3)], true, clBaseResource, bbX, bbZ ); createObjectGroup(group, 0); // create metal mine var mAngle = bbAngle; while(abs(mAngle - bbAngle) < PI/3) { mAngle = randFloat(0, TWO_PI); } var mDist = 11; var mX = round(fx + mDist * cos(mAngle)); var mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oMetalLarge, 1,1, 0,0), new SimpleObject(aGrass, 2,4, 0,2)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); // create stone mines mAngle += randFloat(PI/8, PI/4); mX = round(fx + mDist * cos(mAngle)); mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oStoneLarge, 1,1, 0,2), new SimpleObject(aGrass, 2,4, 0,2)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); // create starting trees var num = 3; var tAngle = randFloat(-PI/3, 4*PI/3); var tDist = randFloat(11, 13); var tX = round(fx + tDist * cos(tAngle)); var tZ = round(fz + tDist * sin(tAngle)); group = new SimpleGroup( [new SimpleObject(oOak, num, num, 0,5)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); } log("Creating the main river..."); var river1 = [1, fractionToTiles(0.5)]; var river2 = [fractionToTiles(0.99), fractionToTiles(0.5)]; createArea( new PathPlacer(...river1, ...river2, scaleByMapSize(10, 20), 0.5, 3 * scaleByMapSize(1, 4), 0.1, 0.01), new SmoothElevationPainter(ELEVATION_SET, waterHeight, 4), avoidClasses(clPlayer, 4)); log("Creating small puddles at the map border to ensure players being separated..."); for (let [fx, fz] of [river1, river2]) createArea( new ClumpPlacer(Math.floor(diskArea(scaleByMapSize(5, 10))), 0.95, 0.6, 10, fx, fz), new SmoothElevationPainter(ELEVATION_SET, waterHeight, 2), avoidClasses(clPlayer, 8)); log("Creating the shallows of the main river..."); for (let i = 0; i <= randIntInclusive(3, scaleByMapSize(4, 6)); ++i) { let cLocation = Math.floor(fractionToTiles(randFloat(0.15, 0.85))); - passageMaker( + createShallowsPassage( cLocation, Math.floor(fractionToTiles(0.35)), cLocation, Math.floor(fractionToTiles(0.65)), scaleByMapSize(4, 8), -2, -2, 2, clShallow, undefined, waterHeight); } log("Creating tributaries..."); var riverWidth = scaleByMapSize(10, 20); for (let i = 0; i <= randIntInclusive(8, scaleByMapSize(12, 20)); ++i) { log("Determining tributary destination..."); let cLocation = randFloat(0.05, 0.95); let sign = randBool() ? 1 : -1; let tang = sign * PI * randFloat(0.2, 0.8); let cDistance = sign * 0.05; let point = getTIPIADBON( [fractionToTiles(cLocation), fractionToTiles(0.5 + cDistance)], [fractionToTiles(cLocation), fractionToTiles(0.5 - cDistance)], [-6, -1.5], 0.5, 5, 0.01); if (point === undefined) continue; let fx = fractionToTiles(0.5 + 0.49 * Math.cos(tang)); let fz = fractionToTiles(0.5 + 0.49 * Math.sin(tang)); log("Creating tributary river..."); let success = createArea( new PathPlacer( Math.floor(point[0]), Math.floor(point[1]), Math.floor(fx), Math.floor(fz), riverWidth, 0.4, 3 * scaleByMapSize(1, 4), 0.1, 0.05), [ new SmoothElevationPainter(ELEVATION_SET, waterHeight, 4), paintClass(clWater) ], avoidClasses(clPlayer, 3, clWater, 3, clShallow, 2)); if (success === undefined) continue; log("Creating small puddles at the map border to ensure players being separated..."); createArea( new ClumpPlacer(Math.floor(Math.PI * Math.pow(riverWidth, 2) / 4), 0.95, 0.6, 10, fx, fz), new SmoothElevationPainter(ELEVATION_SET, waterHeight, 2), avoidClasses(clPlayer, 3)); } log("Creating shallows to make tributaries passable..."); for (let coord of [0.25, 0.75]) - passageMaker( + createShallowsPassage( Math.floor(fractionToTiles(0.2)), Math.floor(fractionToTiles(coord)), Math.floor(fractionToTiles(0.8)), Math.floor(fractionToTiles(coord)), scaleByMapSize(4, 8), -2, -2, 2, clShallow, undefined, waterHeight); paintTerrainBasedOnHeight(-5, 1, 1, tWater); paintTerrainBasedOnHeight(1, 2, 1, pForestR); paintTileClassBasedOnHeight(-6, 0.5, 1, clWater); RMS.SetProgress(50); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2), avoidClasses(clWater, 2, clPlayer, 15), scaleByMapSize(100, 200) ); RMS.SetProgress(55); var [forestTrees, stragglerTrees] = getTreeCounts(500, 2500, 0.7); createForests( [tGrass, tGrassDForest, tGrassPForest, pForestB, pForestO], avoidClasses(clPlayer, 15, clWater, 3, clForest, 16, clHill, 1), clForest, forestTrees); RMS.SetProgress(70); log("Creating dirt 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([[tGrass,tGrassA], tGrassB, [tGrassB,tGrassC]], [1, 1]), paintClass(clDirt) ], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45) ); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), new LayeredPainter([tGrassPatchBlend, tGrassPatch], [1]), avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45) ); RMS.SetProgress(80); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 1, clPlayer, 15, clRock, 10, clHill, 1)], scaleByMapSize(4,16), 100 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 1, clPlayer, 15, clRock, 10, clHill, 1)], scaleByMapSize(4,16), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 1, clPlayer, 15, clMetal, 10, clRock, 5, clHill, 1)], scaleByMapSize(4,16), 100 ); RMS.SetProgress(86); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(8, 131), 50 ); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 15, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); log("Creating rabbits..."); group = new SimpleGroup( [new SimpleObject(oRabbit, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 15, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 15, clHill, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50 ); createStragglerTrees( [oOak, oBeech], avoidClasses(clWater, 1, clForest, 7, clHill, 1, clPlayer, 5, clMetal, 6, clRock, 6), clForest, stragglerTrees); log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), scaleByMapSize(13, 200) ); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), scaleByMapSize(13, 200) ); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1), scaleByMapSize(13, 200), 50 ); log("Creating shallow flora..."); group = new SimpleGroup( [new SimpleObject(aLillies, 1,2, 0,2), new SimpleObject(aReeds, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, stayClasses(clShallow, 1), 60 * scaleByMapSize(13, 200), 80 ); setSkySet("cirrus"); setWaterColor(0.1,0.212,0.422); setWaterTint(0.3,0.1,0.949); setWaterWaviness(3.0); setWaterType("lake"); setWaterMurkiness(0.80); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/rmgen/gaia_terrain.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/rmgen/gaia_terrain.js (revision 20409) +++ ps/trunk/binaries/data/mods/public/maps/random/rmgen/gaia_terrain.js (revision 20410) @@ -1,95 +1,583 @@ /** * @file These functions are often used to create a landscape, for instance shaping mountains, hills, rivers or grass and dirt patches. */ /** * Bumps add slight, diverse elevation differences to otherwise completely level terrain. */ function createBumps(constraint, count, minSize, maxSize, spread, failFraction = 0, elevation = 2) { log("Creating bumps..."); createAreas( new ChainPlacer( minSize || 1, maxSize || Math.floor(scaleByMapSize(4, 6)), spread || Math.floor(scaleByMapSize(2, 5)), failFraction), new SmoothElevationPainter(ELEVATION_MODIFY, elevation, 2), constraint, count || scaleByMapSize(100, 200)); } /** * Hills are elevated, planar, impassable terrain areas. */ function createHills(terrainset, constraint, tileClass, count, minSize, maxSize, spread, failFraction = 0.5, elevation = 18, elevationSmoothing = 2) { log("Creating hills..."); createAreas( new ChainPlacer( minSize || 1, maxSize || Math.floor(scaleByMapSize(4, 6)), spread || Math.floor(scaleByMapSize(16, 40)), failFraction), [ new LayeredPainter(terrainset, [1, elevationSmoothing]), new SmoothElevationPainter(ELEVATION_SET, elevation, elevationSmoothing), paintClass(tileClass) ], constraint, count || scaleByMapSize(1, 4) * getNumPlayers()); } /** * Mountains are impassable smoothened cones. */ function createMountains(terrain, constraint, tileClass, count, maxHeight, minRadius, maxRadius, numCircles) { log("Creating mountains..."); let mapSize = getMapSize(); for (let i = 0; i < (count || scaleByMapSize(1, 4) * getNumPlayers()); ++i) createMountain( maxHeight !== undefined ? maxHeight : Math.floor(scaleByMapSize(30, 50)), minRadius || Math.floor(scaleByMapSize(3, 4)), maxRadius || Math.floor(scaleByMapSize(6, 12)), numCircles || Math.floor(scaleByMapSize(4, 10)), constraint, randIntExclusive(0, mapSize), randIntExclusive(0, mapSize), terrain, tileClass, 14); } /** + * Create a mountain using a technique very similar to ChainPlacer. + */ +function createMountain(maxHeight, minRadius, maxRadius, numCircles, constraint, x, z, terrain, tileClass, fcc = 0, q = []) +{ + if (constraint instanceof Array) + constraint = new AndConstraint(constraint); + + if (!g_Map.inMapBounds(x, z) || !constraint.allows(x, z)) + return; + + let mapSize = getMapSize(); + let queueEmpty = !q.length; + + let gotRet = []; + for (let i = 0; i < mapSize; ++i) + { + gotRet[i] = []; + for (let j = 0; j < mapSize; ++j) + gotRet[i][j] = -1; + } + + --mapSize; + + minRadius = Math.max(1, Math.min(minRadius, maxRadius)); + + let edges = [[x, z]]; + let circles = []; + + for (let i = 0; i < numCircles; ++i) + { + let badPoint = false; + let [cx, cz] = pickRandom(edges); + + let radius; + if (queueEmpty) + radius = randIntInclusive(minRadius, maxRadius); + else + { + radius = q.pop(); + queueEmpty = !q.length; + } + + let sx = Math.max(0, cx - radius); + let sz = Math.max(0, cz - radius); + let lx = Math.min(cx + radius, mapSize); + let lz = Math.min(cz + radius, mapSize); + + let radius2 = Math.square(radius); + + for (let ix = sx; ix <= lx; ++ix) + { + for (let iz = sz; iz <= lz; ++iz) + { + if (Math.euclidDistance2D(ix, iz, cx, cz) > radius2 || !g_Map.inMapBounds(ix, iz)) + continue; + + if (!constraint.allows(ix, iz)) + { + badPoint = true; + break; + } + + let state = gotRet[ix][iz]; + if (state == -1) + { + gotRet[ix][iz] = -2; + } + else if (state >= 0) + { + let s = edges.splice(state, 1); + gotRet[ix][iz] = -2; + + let edgesLength = edges.length; + for (let k = state; k < edges.length; ++k) + --gotRet[edges[k][0]][edges[k][1]]; + } + } + + if (badPoint) + break; + } + + if (badPoint) + continue; + + circles.push([cx, cz, radius]); + + for (let ix = sx; ix <= lx; ++ix) + for (let iz = sz; iz <= lz; ++iz) + { + if (gotRet[ix][iz] != -2 || + fcc && (x - ix > fcc || ix - x > fcc || z - iz > fcc || iz - z > fcc) || + ix > 0 && gotRet[ix-1][iz] == -1 || + iz > 0 && gotRet[ix][iz-1] == -1 || + ix < mapSize && gotRet[ix+1][iz] == -1 || + iz < mapSize && gotRet[ix][iz+1] == -1) + continue; + + edges.push([ix, iz]); + gotRet[ix][iz] = edges.length - 1; + } + } + + for (let [cx, cz, radius] of circles) + { + let sx = Math.max(0, cx - radius); + let sz = Math.max(0, cz - radius); + let lx = Math.min(cx + radius, mapSize); + let lz = Math.min(cz + radius, mapSize); + + let clumpHeight = radius / maxRadius * maxHeight * randFloat(0.8, 1.2); + + for (let ix = sx; ix <= lx; ++ix) + for (let iz = sz; iz <= lz; ++iz) + { + let distance = Math.euclidDistance2D(ix, iz, cx, cz); + + let newHeight = + randIntInclusive(0, 2) + + Math.round(2/3 * clumpHeight * (Math.sin(Math.PI * 2/3 * (3/4 - distance / radius)) + 0.5)); + + if (distance > radius) + continue; + + if (getHeight(ix, iz) < newHeight) + setHeight(ix, iz, newHeight); + else if (getHeight(ix, iz) >= newHeight && getHeight(ix, iz) < newHeight + 4) + setHeight(ix, iz, newHeight + 4); + + if (terrain !== undefined) + placeTerrain(ix, iz, terrain); + + if (tileClass !== undefined) + addToClass(ix, iz, tileClass); + } + } +} + +/** + * Generates a volcano mountain. Smoke and lava are optional. + * + * @param {number} fx - Horizontal coordinate of the center. + * @param {number} fz - Horizontal coordinate of the center. + * @param {number} tileClass - Painted onto every tile that is occupied by the volcano. + * @param {string} terrainTexture - The texture painted onto the volcano hill. + * @param {array} lavaTextures - Three different textures for the interior, from the outside to the inside. + * @param {boolean} smoke - Whether to place smoke particles. + * @param {number} elevationType - Elevation painter type, ELEVATION_SET = absolute or ELEVATION_MODIFY = relative. + */ +function createVolcano(fx, fz, tileClass, terrainTexture, lavaTextures, smoke, elevationType) +{ + log("Creating volcano"); + + let ix = Math.round(fractionToTiles(fx)); + let iz = Math.round(fractionToTiles(fz)); + + let baseSize = getMapArea() / scaleByMapSize(1, 8); + let coherence = 0.7; + let smoothness = 0.05; + let failFraction = 100; + let steepness = 3; + + let clLava = createTileClass(); + + let layers = [ + { + "clumps": 0.067, + "elevation": 15, + "tileClass": tileClass + }, + { + "clumps": 0.05, + "elevation": 25, + "tileClass": createTileClass() + }, + { + "clumps": 0.02, + "elevation": 45, + "tileClass": createTileClass() + }, + { + "clumps": 0.011, + "elevation": 62, + "tileClass": createTileClass() + }, + { + "clumps": 0.003, + "elevation": 42, + "tileClass": clLava, + "painter": lavaTextures && new LayeredPainter([terrainTexture, ...lavaTextures], [1, 1, 1]), + "steepness": 1 + } + ]; + + for (let i = 0; i < layers.length; ++i) + createArea( + new ClumpPlacer(baseSize * layers[i].clumps, coherence, smoothness, failFraction, ix, iz), + [ + layers[i].painter || new LayeredPainter([terrainTexture, terrainTexture], [3]), + new SmoothElevationPainter(elevationType, layers[i].elevation, layers[i].steepness || steepness), + paintClass(layers[i].tileClass) + ], + i == 0 ? null : stayClasses(layers[i - 1].tileClass, 1)); + + if (smoke) + { + let num = Math.floor(baseSize * 0.002); + createObjectGroup( + new SimpleGroup( + [new SimpleObject("actor|particle/smoke.xml", num, num, 0, 7)], + false, + clLava, + ix, + iz), + 0, + stayClasses(tileClass, 1)); + } +} + +/** * Paint the given terrain texture in the given sizes at random places of the map to diversify monotone land texturing. */ function createPatches(sizes, terrain, constraint, count, tileClass, failFraction = 0.5) { for (let size of sizes) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, failFraction), [ new TerrainPainter(terrain), paintClass(tileClass) ], constraint, count); } /** * Same as createPatches, but each patch consists of a set of textures drawn depending to the distance of the patch border. */ function createLayeredPatches(sizes, terrains, terrainWidths, constraint, count, tileClass, failFraction = 0.5) { for (let size of sizes) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, failFraction), [ new LayeredPainter(terrains, terrainWidths), paintClass(tileClass) ], constraint, count); } + +/** + * Creates a meandering river at the given location and width. + * Optionally calls a function on the affected tiles. + * + * @property horizontal - Whether the river is horizontal or vertical + * @property parallel - Whether the shorelines should be parallel or meander separately. + * @property position - Location of the river. Number between 0 and 1. + * @property width - Size between the two shorelines. Number between 0 and 1. + * @property fadeDist - Size of the shoreline. + * @property deviation - Fuzz effect on the shoreline if greater than 0. + * @property waterHeight - Ground height of the riverbed. + * @proeprty landHeight - Ground height of the end of the shoreline. + * @property meanderShort - Strength of frequent meanders. + * @property meanderLong - Strength of less frequent meanders. + * @property waterFunc - Optional function called on water tiles, providing ix, iz, height. + * @property landFunc - Optional function called on land tiles, providing ix, iz, shoreDist1, shoreDist2. + */ +function paintRiver(args) +{ + log("Creating the river"); + + let theta1 = randFloat(0, 1); + let theta2 = randFloat(0, 1); + + let seed1 = randFloat(2, 3); + let seed2 = randFloat(2, 3); + + let meanderShort = args.meanderShort / scaleByMapSize(35, 160); + let meanderLong = args.meanderLong / scaleByMapSize(35, 100); + + let mapSize = getMapSize(); + + for (let ix = 0; ix < mapSize; ++ix) + for (let iz = 0; iz < mapSize; ++iz) + { + if (args.constraint && !args.constraint.allows(ix, iz)) + continue; + + let x = ix / (mapSize + 1); + let z = iz / (mapSize + 1); + + let coord1 = args.horizontal ? z : x; + let coord2 = args.horizontal ? x : z; + + // River curve at this place + let curve1 = + meanderShort * rndRiver(theta1 + coord2 * mapSize / 128, seed1) + + meanderLong * rndRiver(theta2 + coord2 * mapSize / 256, seed2); + + let curve2 = args.parallel ? curve1 : + meanderShort * rndRiver(theta2 + coord2 * mapSize / 128, seed2) + + meanderLong * rndRiver(theta2 + coord2 * mapSize / 256, seed2); + + // Fuzz the river border + let devCoord1 = coord1 * randFloat(1 - args.deviation, 1 + args.deviation); + let devCoord2 = coord2 * randFloat(1 - args.deviation, 1 + args.deviation); + + let shoreDist1 = -devCoord1 + curve1 + args.position - args.width / 2; + let shoreDist2 = -devCoord1 + curve2 + args.position + args.width / 2; + + if (shoreDist1 < 0 && shoreDist2 > 0) + { + let height = args.waterHeight; + + if (shoreDist1 > -args.fadeDist) + height += (args.landHeight - args.waterHeight) * (1 + shoreDist1 / args.fadeDist); + else if (shoreDist2 < args.fadeDist) + height += (args.landHeight - args.waterHeight) * (1 - shoreDist2 / args.fadeDist); + + setHeight(ix, iz, height); + + if (args.waterFunc) + args.waterFunc(ix, iz, height); + } + else if (args.landFunc) + args.landFunc(ix, iz, shoreDist1, shoreDist2); + } +} + +/** + * Helper function to create a meandering river. + * It works the same as sin or cos function with the difference that it's period is 1 instead of 2 pi. + */ +function rndRiver(f, seed) +{ + let rndRw = seed; + + for (let i = 0; i <= f; ++i) + rndRw = 10 * (rndRw % 1); + + let rndRr = f % 1; + let retVal = (i % 2 ? 1 : -1) * rndRr * (rndRr - 1); + + let rndRe = Math.floor(rndRw) % 5; + if (rndRe == 0) + retVal *= 2.3 * (rndRr - 0.5) * (rndRr - 0.5); + else if (rndRe == 1) + retVal *= 2.6 * (rndRr - 0.3) * (rndRr - 0.7); + else if (rndRe == 2) + retVal *= 22 * (rndRr - 0.2) * (rndRr - 0.3) * (rndRr - 0.3) * (rndRr - 0.8); + else if (rndRe == 3) + retVal *= 180 * (rndRr - 0.2) * (rndRr - 0.2) * (rndRr - 0.4) * (rndRr - 0.6) * (rndRr - 0.6) * (rndRr - 0.8); + else if (rndRe == 4) + retVal *= 2.6 * (rndRr - 0.5) * (rndRr - 0.7); + + return retVal; +} + +/** + * Create shallow water between (x1, z1) and (x2, z2) of tiles below maxHeight. + */ +function createShallowsPassage(x1, z1, x2, z2, width, maxHeight, shallowHeight, smooth, tileClass, terrain, riverHeight) +{ + let a = z1 - z2; + let b = x2 - x1; + + let distance = Math.euclidDistance2D(x1, z1, x2, z2); + let mapSize = getMapSize(); + + for (let ix = 0; ix < mapSize; ++ix) + for (let iz = 0; iz < mapSize; ++iz) + { + let c = a * (ix - x1) + b * (iz - z1); + let my = iz - b * c / Math.square(distance); + let inline = 0; + + let dis; + if (b == 0) + { + dis = Math.abs(ix - x1); + if (iz >= Math.min(z1, z2) && iz <= Math.max(z1, z2)) + inline = 1; + } + else if (my >= Math.min(z1, z2) && my <= Math.max(z1, z2)) + { + dis = Math.abs(c) / distance; + inline = 1; + } + + if (dis > width || !inline || getHeight(ix, iz) > maxHeight) + continue; + + if (dis > width - smooth) + setHeight(ix, iz, ((width - dis) * shallowHeight + riverHeight * (smooth - width + dis)) / smooth); + else if (dis <= width - smooth) + setHeight(ix, iz, shallowHeight); + + if (tileClass !== undefined) + addToClass(ix, iz, tileClass); + + if (terrain !== undefined) + placeTerrain(ix, iz, terrain); + } +} + +/** + * Creates a ramp from (x1, y1) to (x2, y2). + */ +function createRamp(x1, y1, x2, y2, minHeight, maxHeight, width, smoothLevel, mainTerrain, edgeTerrain, tileClass) +{ + let halfWidth = width / 2; + + let x3; + let y3; + + if (y1 == y2) + { + x3 = x2; + y3 = y2 + halfWidth; + } + else + { + x3 = x2 + halfWidth; + y3 = (x1 - x2) / (y1 - y2) * (x2 - x3) + y2; + } + + let minBoundX = Math.max(Math.min(x1, x2) - halfWidth, 0); + let minBoundY = Math.max(Math.min(y1, y2) - halfWidth, 0); + let maxBoundX = Math.min(Math.max(x1, x2) + halfWidth, getMapSize()); + let maxBoundY = Math.min(Math.max(y1, y2) + halfWidth, getMapSize()); + + for (let x = minBoundX; x < maxBoundX; ++x) + for (let y = minBoundY; y < maxBoundY; ++y) + { + let lDist = distanceOfPointFromLine(x3, y3, x2, y2, x, y); + let sDist = distanceOfPointFromLine(x1, y1, x2, y2, x, y); + let rampLength = Math.euclidDistance2D(x1, y1, x2, y2); + + if (lDist > rampLength || sDist > halfWidth) + continue; + + let height = ((rampLength - lDist) * maxHeight + lDist * minHeight) / rampLength; + + if (sDist >= halfWidth - smoothLevel) + { + height = (height - minHeight) * (halfWidth - sDist) / smoothLevel + minHeight; + + if (edgeTerrain) + placeTerrain(x, y, edgeTerrain); + } + else if (mainTerrain) + placeTerrain(x, y, mainTerrain); + + if (tileClass !== undefined) + addToClass(x, y, tileClass); + + if (getHeight(Math.floor(x), Math.floor(y)) < height && height <= maxHeight) + setHeight(x, y, height); + } +} + +/** + * Get The Intended Point In A Direction Based On Height. + * Retrieves the N'th point with a specific height in a line and returns it as a [x, y] array. + * + * @param startPoint - [x, y] array defining the start point + * @param endPoint - [x, y] array defining the ending point + * @param heightRange - [min, max] array defining the range which the height of the intended point can be. includes both "min" and "max" + * @param step - how much tile units per turn should the search go. more value means faster but less accurate + * @param n - how many points to skip before ending the search. skips """n-1 points""". + */ +function getTIPIADBON(startPoint, endPoint, heightRange, step, n) +{ + let X = endPoint[0] - startPoint[0]; + let Y = endPoint[1] - startPoint[1]; + + if (!X && !Y) + { + error("getTIPIADBON startPoint and endPoint are identical! " + new Error().stack); + return undefined; + } + + let M = Math.sqrt(Math.square(X) + step * Math.square(Y)); + let stepX = step * X / M; + let stepY = step * Y / M; + + let y = startPoint[1]; + let checked = 0; + + let mapSize = getMapSize(); + + for (let x = startPoint[0]; true; x += stepX) + { + let ix = Math.floor(x); + let iy = Math.floor(y); + + if (ix < mapSize || iy < mapSize) + { + if (getHeight(ix, iy) <= heightRange[1] && + getHeight(ix, iy) >= heightRange[0]) + ++checked; + + if (checked >= n) + return [x, y]; + } + + y += stepY; + + if (y > endPoint[1] && stepY > 0 || + y < endPoint[1] && stepY < 0 || + x > endPoint[1] && stepX > 0 || + x < endPoint[1] && stepX < 0) + return undefined; + } + + return undefined; +} Index: ps/trunk/binaries/data/mods/public/maps/random/rmgen/misc.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/rmgen/misc.js (revision 20409) +++ ps/trunk/binaries/data/mods/public/maps/random/rmgen/misc.js (revision 20410) @@ -1,773 +1,155 @@ ///////////////////////////////////////////////////////////////////////////////////////// -// passageMaker -// -// Function for creating shallow water between two given points by changing the height of all tiles in -// the path with height less than or equal to "maxheight" to "height" -// -// x1,z1: Starting point of path -// x2,z2: Ending point of path -// width: Width of the shallow -// maxheight: Maximum height that it changes -// height: Height of the shallow -// smooth: smooth elevation in borders -// tileclass: (Optianal) - Adds those tiles to the class given -// terrain: (Optional) - Changes the texture of the elevated land -// -///////////////////////////////////////////////////////////////////////////////////////// - -function passageMaker(x1, z1, x2, z2, width, maxheight, height, smooth, tileclass, terrain, riverheight) -{ - var tchm = TILE_CENTERED_HEIGHT_MAP; - TILE_CENTERED_HEIGHT_MAP = true; - var mapSize = g_Map.size; - for (var ix = 0; ix < mapSize; ix++) - { - for (var iz = 0; iz < mapSize; iz++) - { - var a = z1-z2; - var b = x2-x1; - var c = (z1*(x1-x2))-(x1*(z1-z2)); - var dis = abs(a*ix + b*iz + c)/sqrt(a*a + b*b); - var k = (a*ix + b*iz + c)/(a*a + b*b); - var my = iz-(b*k); - var inline = 0; - if (b == 0) - { - dis = abs(ix-x1); - if ((iz <= Math.max(z1,z2))&&(iz >= Math.min(z1,z2))) - { - inline = 1; - } - } - else - { - if ((my <= Math.max(z1,z2))&&(my >= Math.min(z1,z2))) - { - inline = 1; - } - } - if ((dis <= width)&&(inline)) - { - if(g_Map.getHeight(ix, iz) <= maxheight) - { - if (dis > width - smooth) - { - g_Map.setHeight(ix, iz, ((width - dis)*(height)+(riverheight)*(smooth - width + dis))/(smooth)); - } - else if (dis <= width - smooth) - { - g_Map.setHeight(ix, iz, height); - } - if (tileclass !== undefined) - { - addToClass(ix, iz, tileclass); - } - if (terrain !== undefined) - { - placeTerrain(ix, iz, terrain); - } - } - } - } - } - TILE_CENTERED_HEIGHT_MAP = tchm; -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//rndRiver is a fuction that creates random values useful for making a jagged river. -// -//it works the same as sin or cos function. the only difference is that it's period is 1 instead of 2*pi -//it needs the "seed" parameter to use it to make random curves that don't get broken. -//seed must be created using randFloat(). or else it won't work -// -// f: Input: Same as angle in a sine function -// seed: Random Seed: Best to implement is to use randFloat() -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -function rndRiver(f, seed) -{ - var rndRq = seed; - var rndRw = rndRq; - var rndRe = 0; - var rndRr = f-floor(f); - var rndRa = 0; - for (var rndRx=0; rndRx<=floor(f); rndRx++) - { - rndRw = 10*(rndRw-floor(rndRw)); - } - if (rndRx%2==0) - { - var rndRs = -1; - } - else - { - var rndRs = 1; - } - rndRe = (floor(rndRw))%5; - if (rndRe==0) - { - rndRa = (rndRs)*2.3*(rndRr)*(rndRr-1)*(rndRr-0.5)*(rndRr-0.5); - } - else if (rndRe==1) - { - rndRa = (rndRs)*2.6*(rndRr)*(rndRr-1)*(rndRr-0.3)*(rndRr-0.7); - } - else if (rndRe==2) - { - rndRa = (rndRs)*22*(rndRr)*(rndRr-1)*(rndRr-0.2)*(rndRr-0.3)*(rndRr-0.3)*(rndRr-0.8); - } - else if (rndRe==3) - { - rndRa = (rndRs)*180*(rndRr)*(rndRr-1)*(rndRr-0.2)*(rndRr-0.2)*(rndRr-0.4)*(rndRr-0.6)*(rndRr-0.6)*(rndRr-0.8); - } - else if (rndRe==4) - { - rndRa = (rndRs)*2.6*(rndRr)*(rndRr-1)*(rndRr-0.5)*(rndRr-0.7); - } - return rndRa; -} - -/** - * Creates a meandering river at the given location and width. - * Optionally calls a function on the affected tiles. - * - * @property horizontal - Whether the river is horizontal or vertical - * @property parallel - Whether the shorelines should be parallel or meander separately. - * @property position - Location of the river. Number between 0 and 1. - * @property width - Size between the two shorelines. Number between 0 and 1. - * @property fadeDist - Size of the shoreline. - * @property deviation - Fuzz effect on the shoreline if greater than 0. - * @property waterHeight - Ground height of the riverbed. - * @proeprty landHeight - Ground height of the end of the shoreline. - * @property meanderShort - Strength of frequent meanders. - * @property meanderLong - Strength of less frequent meanders. - * @property waterFunc - Optional function called on water tiles, providing ix, iz, height. - * @property landFunc - Optional function called on land tiles, providing ix, iz, shoreDist1, shoreDist2. - */ -function paintRiver(args) -{ - log("Creating the river"); - - let theta1 = randFloat(0, 1); - let theta2 = randFloat(0, 1); - - let seed1 = randFloat(2, 3); - let seed2 = randFloat(2, 3); - - let meanderShort = args.meanderShort / scaleByMapSize(35, 160); - let meanderLong = args.meanderLong / scaleByMapSize(35, 100); - - let mapSize = g_Map.size; - - for (let ix = 0; ix < mapSize; ++ix) - for (let iz = 0; iz < mapSize; ++iz) - { - if (args.constraint && !args.constraint.allows(ix, iz)) - continue; - - let x = ix / (mapSize + 1.0); - let z = iz / (mapSize + 1.0); - - let coord1 = args.horizontal ? z : x; - let coord2 = args.horizontal ? x : z; - - // River curve at this place - let cu1 = meanderShort * rndRiver(theta1 + coord2 * mapSize / 128, seed1); - let cu2 = meanderShort * rndRiver(theta2 + coord2 * mapSize / 128, seed2); - - cu1 += meanderLong * rndRiver(theta2 + coord2 * mapSize / 256, seed2); - cu2 += meanderLong * rndRiver(theta2 + coord2 * mapSize / 256, seed2); - if (args.parallel) - cu2 = cu1; - - // Fuzz the river border - let devCoord1 = coord1 * randFloat(1 - args.deviation, 1 + args.deviation); - let devCoord2 = coord2 * randFloat(1 - args.deviation, 1 + args.deviation); - - let shoreDist1 = -devCoord1 + cu1 + args.position - args.width / 2; - let shoreDist2 = -devCoord1 + cu2 + args.position + args.width / 2; - - if (shoreDist1 < 0 && shoreDist2 > 0) - { - let height = args.waterHeight; - - if (shoreDist1 > -args.fadeDist) - height += (args.landHeight - args.waterHeight) * (1 + shoreDist1 / args.fadeDist); - else if (shoreDist2 < args.fadeDist) - height += (args.landHeight - args.waterHeight) * (1 - shoreDist2 / args.fadeDist); - - setHeight(ix, iz, height); - - if (args.waterFunc) - args.waterFunc(ix, iz, height); - } - else if (args.landFunc) - args.landFunc(ix, iz, shoreDist1, shoreDist2); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// // createStartingPlayerEntities // // Creates the starting player entities // fx&fz: position of player base // playerid: id of player // civEntities: use getStartingEntities(id-1) fo this one // orientation: orientation of the main base building, default is BUILDING_ORIENTATION // /////////////////////////////////////////////////////////////////////////////////////////// function createStartingPlayerEntities(fx, fz, playerid, civEntities, orientation = BUILDING_ORIENTATION) { var uDist = 6; var uSpace = 2; placeObject(fx, fz, civEntities[0].Template, playerid, orientation); for (var j = 1; j < civEntities.length; ++j) { var uAngle = orientation - PI * (2-j) / 2; var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1); for (var numberofentities = 0; numberofentities < count; numberofentities++) { var ux = fx + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2)); var uz = fz + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2)); placeObject(ux, uz, civEntities[j].Template, playerid, uAngle); } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // placeCivDefaultEntities // // Creates the default starting player entities depending on the players civ // fx&fy: position of player base // playerid: id of player // kwargs: Takes some optional keyword arguments to tweek things // 'iberWall': may be false, 'walls' (default) or 'towers'. Determines the defensive structures Iberians get as civ bonus // 'orientation': angle of the main base building, default is BUILDING_ORIENTATION // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function placeCivDefaultEntities(fx, fz, playerid, kwargs = {}) { // Unpack kwargs var iberWall = 'walls'; if (getMapSize() <= 128) iberWall = false; if ('iberWall' in kwargs) iberWall = kwargs['iberWall']; var orientation = BUILDING_ORIENTATION; if ('orientation' in kwargs) orientation = kwargs['orientation']; // Place default civ starting entities var civ = getCivCode(playerid-1); var civEntities = getStartingEntities(playerid-1); var uDist = 6; var uSpace = 2; placeObject(fx, fz, civEntities[0].Template, playerid, orientation); for (var j = 1; j < civEntities.length; ++j) { var uAngle = orientation - PI * (2-j) / 2; var count = (civEntities[j].Count !== undefined ? civEntities[j].Count : 1); for (var numberofentities = 0; numberofentities < count; numberofentities++) { var ux = fx + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2)); var uz = fz + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2)); placeObject(ux, uz, civEntities[j].Template, playerid, uAngle); } } // Add defensive structiures for Iberians as their civ bonus if (civ == 'iber' && iberWall != false) { if (iberWall == 'towers') placePolygonalWall(fx, fz, 15, ['entry'], 'tower', civ, playerid, orientation, 7); else placeGenericFortress(fx, fz, 20/*radius*/, playerid); } } function placeDefaultChicken(playerX, playerZ, tileClass, constraint = undefined, template = "gaia/fauna_chicken") { for (let j = 0; j < 2; ++j) for (var tries = 0; tries < 10; ++tries) { let aAngle = randFloat(0, TWO_PI); // Roman and ptolemian civic centers have a big footprint! let aDist = 9; let aX = round(playerX + aDist * cos(aAngle)); let aZ = round(playerZ + aDist * sin(aAngle)); let group = new SimpleGroup( [new SimpleObject(template, 5,5, 0,2)], true, tileClass, aX, aZ ); if (createObjectGroup(group, 0, constraint)) break; } } /** * Typically used for placing grass tufts around the civic centers. */ function placeDefaultDecoratives(playerX, playerZ, template, tileclass, radius, constraint = undefined) { for (let i = 0; i < PI * radius * radius / 250; ++i) { let angle = randFloat(0, 2 * PI); let dist = radius - randIntInclusive(5, 11); createObjectGroup( new SimpleGroup( [new SimpleObject(template, 2, 5, 0, 1, -PI/8, PI/8)], false, tileclass, Math.round(playerX + dist * Math.cos(angle)), Math.round(playerZ + dist * Math.sin(angle)) ), 0, constraint); } } function modifyTilesBasedOnHeight(minHeight, maxHeight, mode, func) { for (let qx = 0; qx < g_Map.size; ++qx) for (let qz = 0; qz < g_Map.size; ++qz) { let height = g_Map.getHeight(qx, qz); if (mode == 0 && height > minHeight && height < maxHeight || mode == 1 && height >= minHeight && height < maxHeight || mode == 2 && height > minHeight && height <= maxHeight || mode == 3 && height >= minHeight && height <= maxHeight) func(qx, qz); } } function paintTerrainBasedOnHeight(minHeight, maxHeight, mode, terrain) { modifyTilesBasedOnHeight(minHeight, maxHeight, mode, (qx, qz) => { placeTerrain(qx, qz, terrain); }); } function paintTileClassBasedOnHeight(minHeight, maxHeight, mode, tileclass) { modifyTilesBasedOnHeight(minHeight, maxHeight, mode, (qx, qz) => { addToClass(qx, qz, tileclass); }); } function unPaintTileClassBasedOnHeight(minHeight, maxHeight, mode, tileclass) { modifyTilesBasedOnHeight(minHeight, maxHeight, mode, (qx, qz) => { removeFromClass(qx, qz, tileclass); }); } - -///////////////////////////////////////////////////////////////////////////////////////// -// getTIPIADBON -// -// "get The Intended Point In A Direction Based On Height" -// gets the N'th point with a specific height in a line and returns it as a [x, y] array -// startPoint: [x, y] array defining the start point -// endPoint: [x, y] array defining the ending point -// heightRange: [min, max] array defining the range which the height of the intended point can be. includes both "min" and "max" -// step: how much tile units per turn should the search go. more value means faster but less accurate -// n: how many points to skip before ending the search. skips """n-1 points""". -// -/////////////////////////////////////////////////////////////////////////////////////////// - -function getTIPIADBON(startPoint, endPoint, heightRange, step, n) -{ - var stepX = step*(endPoint[0]-startPoint[0])/(sqrt((endPoint[0]-startPoint[0])*(endPoint[0]-startPoint[0]) + step*(endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); - var stepY = step*(endPoint[1]-startPoint[1])/(sqrt((endPoint[0]-startPoint[0])*(endPoint[0]-startPoint[0]) + step*(endPoint[1]-startPoint[1])*(endPoint[1]-startPoint[1]))); - var y = startPoint[1]; - var checked = 0; - for (var x = startPoint[0]; true; x += stepX) - { - if ((floor(x) < g_Map.size)||(floor(y) < g_Map.size)) - { - if ((g_Map.getHeight(floor(x), floor(y)) <= heightRange[1])&&(g_Map.getHeight(floor(x), floor(y)) >= heightRange[0])) - { - ++checked; - } - if (checked >= n) - { - return [x, y]; - } - } - y += stepY; - if ((y > endPoint[1])&&(stepY>0)) - break; - if ((y < endPoint[1])&&(stepY<0)) - break; - if ((x > endPoint[1])&&(stepX>0)) - break; - if ((x < endPoint[1])&&(stepX<0)) - break; - } - return undefined; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// createRamp -// -// creates a ramp from point (x1, y1) to (x2, y2). -// x1, y1, x2, y2: determine the position of the start and end of the ramp -// minHeight, maxHeight: determine the height levels of the start and end point -// width: determines the width of the ramp -// smoothLevel: determines the smooth level around the edges of the ramp -// mainTerrain: (Optional) determines the terrain texture for the ramp -// edgeTerrain: (Optional) determines the terrain texture for the edges -// tileclass: (Optional) adds the ramp to this tile class -// -/////////////////////////////////////////////////////////////////////////////////////////// - -function createRamp (x1, y1, x2, y2, minHeight, maxHeight, width, smoothLevel, mainTerrain, edgeTerrain, tileclass) -{ - var halfWidth = width / 2; - var mapSize = g_Map.size; - - if (y1 == y2) - { - var x3 = x2; - var y3 = y2 + halfWidth; - } - else - { - var m = (x1 - x2) / (y1 - y2); - var b = y2 + m * x2; - var x3 = x2 + halfWidth; - var y3 = - m * x3 + b; - } - - var minBoundX = (x1 <= x2 ? (x1 > halfWidth ? x1 - halfWidth : 0) : (x2 > halfWidth ? x2 - halfWidth : 0)); - var maxBoundX = (x1 >= x2 ? (x1 < mapSize - halfWidth ? x1 + halfWidth : mapSize) : (x2 < mapSize - halfWidth ? x2 + halfWidth : mapSize)); - var minBoundY = (y1 <= y2 ? (y1 > halfWidth ? y1 - halfWidth : 0) : (y2 > halfWidth ? y2 - halfWidth : 0)); - var maxBoundY = (y1 >= y2 ? (x1 < mapSize - halfWidth ? y1 + halfWidth : mapSize) : (y2 < mapSize - halfWidth ? y2 + halfWidth : mapSize)); - - for (var x = minBoundX; x < maxBoundX; ++x) - { - for (var y = minBoundY; y < maxBoundY; ++y) - { - var lDist = distanceOfPointFromLine(x3, y3, x2, y2, x, y); - var sDist = distanceOfPointFromLine(x1, y1, x2, y2, x, y); - var rampLength = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); - if (lDist <= rampLength && sDist <= halfWidth) - { - var h = ((rampLength - lDist) * maxHeight + lDist * minHeight) / rampLength; - if (sDist >= halfWidth - smoothLevel) - { - h = (h - minHeight) * (halfWidth - sDist) / smoothLevel + minHeight; - if (edgeTerrain !== undefined) - placeTerrain(x, y, edgeTerrain); - } - else - { - if (mainTerrain !== undefined) - placeTerrain(x, y, mainTerrain); - } - if (tileclass !== undefined) - addToClass(x, y, tileclass); - if((g_Map.getHeight(floor(x), floor(y)) < h) && (h <= maxHeight)) - g_Map.setHeight(x, y, h); - } - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// createMountain -// -// creates a mountain using a tecnique very similar to chain placer. -// -/////////////////////////////////////////////////////////////////////////////////////////// - -function createMountain(maxHeight, minRadius, maxRadius, numCircles, constraint, x, z, terrain, tileclass, fcc, q) -{ - fcc = (fcc !== undefined ? fcc : 0); - q = (q !== undefined ? q : []); - - // checking for an array of constraints - if (constraint instanceof Array) - { - var constraintArray = constraint; - constraint = new AndConstraint(constraintArray); - } - - // Preliminary bounds check - if (!g_Map.inMapBounds(x, z) || !constraint.allows(x, z)) - { - return; - } - - var size = getMapSize(); - var queueEmpty = (q.length ? false : true); - - var gotRet = []; - for (var i = 0; i < size; ++i) - { - gotRet[i] = []; - for (var j = 0; j < size; ++j) - gotRet[i][j] = -1; - } - - --size; - - if (minRadius < 1) minRadius = 1; - if (minRadius > maxRadius) minRadius = maxRadius; - - var edges = [[x, z]]; - var circles = []; - - for (var i = 0; i < numCircles; ++i) - { - var badPoint = false; - var [cx, cz] = pickRandom(edges); - - if (queueEmpty) - var radius = randIntInclusive(minRadius, maxRadius); - else - { - var radius = q.pop(); - queueEmpty = (q.length ? false : true); - } - - var sx = cx - radius, lx = cx + radius; - var sz = cz - radius, lz = cz + radius; - - sx = (sx < 0 ? 0 : sx); - sz = (sz < 0 ? 0 : sz); - lx = (lx > size ? size : lx); - lz = (lz > size ? size : lz); - - var radius2 = radius * radius; - var dx, dz, distance2; - - //log (uneval([sx, sz, lx, lz])); - - for (var ix = sx; ix <= lx; ++ix) - { - for (var iz = sz; iz <= lz; ++ iz) - { - dx = ix - cx; - dz = iz - cz; - distance2 = dx * dx + dz * dz; - if (dx * dx + dz * dz <= radius2) - { - if (g_Map.inMapBounds(ix, iz)) - { - if (!constraint.allows(ix, iz)) - { - badPoint = true; - break; - } - - var state = gotRet[ix][iz]; - - if (state == -1) - { - gotRet[ix][iz] = -2; - } - else if (state >= 0) - { - - var s = edges.splice(state, 1); - - gotRet[ix][iz] = -2; - - var edgesLength = edges.length; - for (var k = state; k < edges.length; ++k) - { - --gotRet[edges[k][0]][edges[k][1]]; - } - } - } - } - } - if (badPoint) - break; - } - - if (badPoint) - continue; - else - circles.push([cx, cz, radius]); - - for (var ix = sx; ix <= lx; ++ix) - { - for (var iz = sz; iz <= lz; ++ iz) - { - if (fcc) - if ((x - ix) > fcc || (ix - x) > fcc || (z - iz) > fcc || (iz - z) > fcc) - continue; - - if (gotRet[ix][iz] == -2) - { - if (ix > 0) - { - if (gotRet[ix-1][iz] == -1) - { - edges.push([ix, iz]); - gotRet[ix][iz] = edges.length - 1; - continue; - } - } - if (iz > 0) - { - if (gotRet[ix][iz-1] == -1) - { - edges.push([ix, iz]); - gotRet[ix][iz] = edges.length - 1; - continue; - } - } - if (ix < size) - { - if (gotRet[ix+1][iz] == -1) - { - edges.push([ix, iz]); - gotRet[ix][iz] = edges.length - 1; - continue; - } - } - if (iz < size) - { - if (gotRet[ix][iz+1] == -1) - { - edges.push([ix, iz]); - gotRet[ix][iz] = edges.length - 1; - continue; - } - } - } - } - } - } - - var numFinalCircles = circles.length; - - for (var i = 0; i < numFinalCircles; ++i) - { - var point = circles[i]; - var cx = point[0], cz = point[1], radius = point[2]; - - var sx = cx - radius, lx = cx + radius; - var sz = cz - radius, lz = cz + radius; - - sx = (sx < 0 ? 0 : sx); - sz = (sz < 0 ? 0 : sz); - lx = (lx > size ? size : lx); - lz = (lz > size ? size : lz); - - var radius2 = radius * radius; - var dx, dz, distance2; - - var clumpHeight = radius / maxRadius * maxHeight * randFloat(0.8, 1.2); - - for (var ix = sx; ix <= lx; ++ix) - { - for (var iz = sz; iz <= lz; ++ iz) - { - dx = ix - cx; - dz = iz - cz; - distance2 = dx * dx + dz * dz; - - var newHeight = Math.round((Math.sin(PI * (2 * ((radius - Math.sqrt(distance2)) / radius) / 3 - 1/6)) + 0.5) * 2/3 * clumpHeight) + randIntInclusive(0, 2); - - if (dx * dx + dz * dz <= radius2) - { - if (g_Map.getHeight(ix, iz) < newHeight) - g_Map.setHeight(ix, iz, newHeight); - else if (g_Map.getHeight(ix, iz) >= newHeight && g_Map.getHeight(ix, iz) < newHeight + 4) - g_Map.setHeight(ix, iz, newHeight + 4); - if (terrain !== undefined) - placeTerrain(ix, iz, terrain); - if (tileclass !== undefined) - addToClass(ix, iz, tileclass); - } - } - } - } -} - -/** - * Generates a volcano mountain. Smoke and lava are optional. - * - * @param {number} fx - Horizontal coordinate of the center. - * @param {number} fz - Horizontal coordinate of the center. - * @param {number} tileClass - Painted onto every tile that is occupied by the volcano. - * @param {string} terrainTexture - The texture painted onto the volcano hill. - * @param {array} lavaTextures - Three different textures for the interior, from the outside to the inside. - * @param {boolean} smoke - Whether to place smoke particles. - * @param {number} elevationType - Elevation painter type, ELEVATION_SET = absolute or ELEVATION_MODIFY = relative. - */ -function createVolcano(fx, fz, tileClass, terrainTexture, lavaTextures, smoke, elevationType) -{ - log("Creating volcano"); - - let ix = Math.round(fractionToTiles(fx)); - let iz = Math.round(fractionToTiles(fz)); - - let baseSize = getMapArea() / scaleByMapSize(1, 8); - - let coherence = 0.7; - let smoothness = 0.05; - let failFraction = 100; - let steepness = 3; - - let clLava = createTileClass(); - - let layers = [ - { - "clumps": 0.067, - "elevation": 15, - "tileClass": tileClass - }, - { - "clumps": 0.05, - "elevation": 25, - "tileClass": createTileClass() - }, - { - "clumps": 0.02, - "elevation": 45, - "tileClass": createTileClass() - }, - { - "clumps": 0.011, - "elevation": 62, - "tileClass": createTileClass() - }, - { - "clumps": 0.003, - "elevation": 42, - "tileClass": clLava, - "painter": lavaTextures && new LayeredPainter([terrainTexture, ...lavaTextures], [1, 1, 1]), - "steepness": 1 - } - ]; - - for (let i = 0; i < layers.length; ++i) - createArea( - new ClumpPlacer(baseSize * layers[i].clumps, coherence, smoothness, failFraction, ix, iz), - [ - layers[i].painter || new LayeredPainter([terrainTexture, terrainTexture], [3]), - new SmoothElevationPainter(elevationType, layers[i].elevation, layers[i].steepness || steepness), - paintClass(layers[i].tileClass) - ], - i == 0 ? null : stayClasses(layers[i - 1].tileClass, 1)); - - if (smoke) - { - let num = Math.floor(baseSize * 0.002); - createObjectGroup( - new SimpleGroup( - [new SimpleObject("actor|particle/smoke.xml", num, num, 0, 7)], - false, - clLava, - ix, - iz), - 0, - stayClasses(tileClass, 1)); - } -} Index: ps/trunk/binaries/data/mods/public/maps/random/sahel_watering_holes.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/sahel_watering_holes.js (revision 20409) +++ ps/trunk/binaries/data/mods/public/maps/random/sahel_watering_holes.js (revision 20410) @@ -1,465 +1,465 @@ RMS.LoadLibrary("rmgen"); const tGrass = "savanna_grass_a"; const tForestFloor = "savanna_forestfloor_a"; const tCliff = "savanna_cliff_b"; const tDirtRocksA = "savanna_dirt_rocks_c"; const tDirtRocksB = "savanna_dirt_rocks_a"; const tDirtRocksC = "savanna_dirt_rocks_b"; const tHill = "savanna_cliff_a"; const tRoad = "savanna_tile_a_red"; const tRoadWild = "savanna_tile_a_red"; const tGrassPatch = "savanna_grass_b"; const tShore = "savanna_riparian_bank"; const tWater = "savanna_riparian_wet"; const oBaobab = "gaia/flora_tree_baobab"; const oFig = "gaia/flora_tree_fig"; const oBerryBush = "gaia/flora_bush_berry"; const oWildebeest = "gaia/fauna_wildebeest"; const oFish = "gaia/fauna_fish"; const oGazelle = "gaia/fauna_gazelle"; const oElephant = "gaia/fauna_elephant_african_bush"; const oGiraffe = "gaia/fauna_giraffe"; const oZebra = "gaia/fauna_zebra"; const oStoneLarge = "gaia/geology_stonemine_desert_quarry"; const oStoneSmall = "gaia/geology_stone_savanna_small"; const oMetalLarge = "gaia/geology_metal_savanna_slabs"; const aGrass = "actor|props/flora/grass_savanna.xml"; const aGrassShort = "actor|props/flora/grass_medit_field.xml"; const aRockLarge = "actor|geology/stone_savanna_med.xml"; const aRockMedium = "actor|geology/stone_savanna_med.xml"; const aBushMedium = "actor|props/flora/bush_desert_dry_a.xml"; const aBushSmall = "actor|props/flora/bush_dry_a.xml"; const pForest = [tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor]; InitMap(); const numPlayers = getNumPlayers(); var clPlayer = createTileClass(); var clHill = createTileClass(); var clForest = createTileClass(); var clWater = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clShallows = createTileClass(); var [playerIDs, playerX, playerZ, playerAngle, startAngle] = radialPlayerPlacement(); for (var i = 0; i < numPlayers; i++) { var id = playerIDs[i]; log("Creating base for player " + id + "..."); var radius = scaleByMapSize(15,25); var cliffRadius = 2; var elevation = 20; // get the x and z in tiles var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); addCivicCenterAreaToClass(ix, iz, clPlayer); // create the city patch var cityRadius = radius/3; var placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); var painter = new LayeredPainter([tRoadWild, tRoad], [1]); createArea(placer, painter, null); placeCivDefaultEntities(fx, fz, id); placeDefaultChicken(fx, fz, clBaseResource); // create berry bushes var bbAngle = randFloat(0, TWO_PI); var bbDist = 12; var bbX = round(fx + bbDist * cos(bbAngle)); var bbZ = round(fz + bbDist * sin(bbAngle)); var group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,5, 0,3)], true, clBaseResource, bbX, bbZ ); createObjectGroup(group, 0); // create metal mine var mAngle = bbAngle; while(abs(mAngle - bbAngle) < PI/3) { mAngle = randFloat(0, TWO_PI); } var mDist = 12; var mX = round(fx + mDist * cos(mAngle)); var mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oMetalLarge, 1,1, 0,0)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); // create stone mines mAngle += randFloat(PI/8, PI/4); mX = round(fx + mDist * cos(mAngle)); mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oStoneLarge, 1,1, 0,2)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); // create starting trees var num = 5; var tAngle = randFloat(-PI/3, 4*PI/3); var tDist = randFloat(12, 13); var tX = round(fx + tDist * cos(tAngle)); var tZ = round(fz + tDist * sin(tAngle)); group = new SimpleGroup( [new SimpleObject(oBaobab, num, num, 0,3)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); placeDefaultDecoratives(fx, fz, aGrassShort, clBaseResource, radius); } RMS.SetProgress(20); log ("Creating rivers..."); for (var m = 0; m < numPlayers; m++) { var tang = startAngle + (m + 0.5) * TWO_PI / numPlayers; createArea( new ClumpPlacer( Math.floor(diskArea(scaleByMapSize(10, 50)) / 3), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.15 * Math.cos(tang)), fractionToTiles(0.5 + 0.15 * Math.sin(tang))), [ new SmoothElevationPainter(ELEVATION_SET, -4, 4), paintClass(clWater) ], avoidClasses(clPlayer, 5)); createArea( new PathPlacer( fractionToTiles(0.5 + 0.15 * Math.cos(tang)), fractionToTiles(0.5 + 0.15 * Math.sin(tang)), fractionToTiles(0.5 + 0.49 * Math.cos(tang)), fractionToTiles(0.5 + 0.49 * Math.sin(tang)), scaleByMapSize(10, 50), 0.2, 3 * scaleByMapSize(1, 4), 0.2, 0.05), [ new LayeredPainter([tShore, tWater, tWater], [1, 3]), new SmoothElevationPainter(ELEVATION_SET, -4, 4), paintClass(clWater) ], avoidClasses(clPlayer, 5)); createArea( new ClumpPlacer( Math.floor(diskArea(scaleByMapSize(10, 50)) / 5), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49 * Math.cos(tang)), fractionToTiles(0.5 + 0.49 * Math.sin(tang))), [ new SmoothElevationPainter(ELEVATION_SET, -4, 4), paintClass(clWater) ], avoidClasses(clPlayer, 5)); } for (var i = 0; i < numPlayers; i++) { if (i+1 == numPlayers) { - passageMaker( + createShallowsPassage( round(fractionToTiles(playerX[i])), round(fractionToTiles(playerZ[i])), round(fractionToTiles(playerX[0])), round(fractionToTiles(playerZ[0])), 6, -2, -2, 4, clShallows, undefined, -4); log("Creating animals in shallows..."); var group = new SimpleGroup( [new SimpleObject(oElephant, 2,3, 0,4)], true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[0]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[0]))/2) ); createObjectGroup(group, 0); var group = new SimpleGroup( [new SimpleObject(oWildebeest, 5,6, 0,4)], true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[0]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[0]))/2) ); createObjectGroup(group, 0); } else { - passageMaker( + createShallowsPassage( fractionToTiles(playerX[i]), fractionToTiles(playerZ[i]), fractionToTiles(playerX[i+1]), fractionToTiles(playerZ[i+1]), 6, -2, -2, 4, clShallows, undefined, -4); log("Creating animals in shallows..."); var group = new SimpleGroup( [new SimpleObject(oElephant, 2,3, 0,4)], true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[i+1]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[i+1]))/2) ); createObjectGroup(group, 0); var group = new SimpleGroup( [new SimpleObject(oWildebeest, 5,6, 0,4)], true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[i+1]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[i+1]))/2) ); createObjectGroup(group, 0); } } paintTerrainBasedOnHeight(-6, 2, 1, tWater); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2), avoidClasses(clWater, 2, clPlayer, 20), scaleByMapSize(100, 200)); log("Creating hills..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1), [ new LayeredPainter([tGrass, tCliff, tHill], [1, 2]), new SmoothElevationPainter(ELEVATION_SET, 35, 3), paintClass(clHill) ], avoidClasses(clPlayer, 20, clHill, 15, clWater, 3), scaleByMapSize(1, 4) * numPlayers); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(160, 900, 0.02); var types = [ [[tForestFloor, tGrass, pForest], [tForestFloor, pForest]] ]; var size = forestTrees / (0.5 * scaleByMapSize(2,8) * numPlayers); var num = floor(size / types.length); for (let type of types) createAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 20, clForest, 10, clHill, 0, clWater, 2), num ); RMS.SetProgress(50); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter( [[tGrass, tDirtRocksA], [tDirtRocksA, tDirtRocksB], [tDirtRocksB, tDirtRocksC]], [1, 1]), paintClass(clDirt) ], avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20), scaleByMapSize(15, 45)); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new TerrainPainter(tGrassPatch), avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20), scaleByMapSize(15, 45)); RMS.SetProgress(55); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), scaleByMapSize(4,16), 100 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), scaleByMapSize(4,16), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), scaleByMapSize(4,16), 100 ); RMS.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(8, 131), 50 ); RMS.SetProgress(70); log("Creating wildebeest..."); group = new SimpleGroup( [new SimpleObject(oWildebeest, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); RMS.SetProgress(75); log("Creating gazelle..."); group = new SimpleGroup( [new SimpleObject(oGazelle, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); log("Creating elephant..."); group = new SimpleGroup( [new SimpleObject(oElephant, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); log("Creating giraffe..."); group = new SimpleGroup( [new SimpleObject(oGiraffe, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); log("Creating zebra..."); group = new SimpleGroup( [new SimpleObject(oZebra, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); log("Creating fish..."); group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clFood, 20), stayClasses(clWater, 6)], 25 * numPlayers, 60 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50 ); RMS.SetProgress(85); createStragglerTrees( [oBaobab, oBaobab, oBaobab, oFig], avoidClasses(clWater, 5, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); var planetm = 4; log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 2), planetm * scaleByMapSize(13, 200) ); RMS.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clForest, 0), planetm * scaleByMapSize(13, 200) ); RMS.SetProgress(95); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 1, clPlayer, 1), planetm * scaleByMapSize(13, 200), 50 ); setSkySet("sunny"); setSunRotation(randFloat(0, TWO_PI)); setSunElevation(randFloat(PI/ 5, PI / 4)); setWaterColor(0.478,0.42,0.384); // greyish setWaterTint(0.58,0.22,0.067); // reddish setWaterMurkiness(0.87); setWaterWaviness(0.5); setWaterType("clap"); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/unknown.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/unknown.js (revision 20409) +++ ps/trunk/binaries/data/mods/public/maps/random/unknown.js (revision 20410) @@ -1,1633 +1,1633 @@ RMS.LoadLibrary("rmgen"); RMS.LoadLibrary("rmbiome"); TILE_CENTERED_HEIGHT_MAP = true; setSelectedBiome(); const tMainTerrain = g_Terrains.mainTerrain; const tForestFloor1 = g_Terrains.forestFloor1; const tForestFloor2 = g_Terrains.forestFloor2; const tCliff = g_Terrains.cliff; const tTier1Terrain = g_Terrains.tier1Terrain; const tTier2Terrain = g_Terrains.tier2Terrain; const tTier3Terrain = g_Terrains.tier3Terrain; const tHill = g_Terrains.hill; const tDirt = g_Terrains.dirt; const tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; const tShoreBlend = g_Terrains.shoreBlend; const tShore = g_Terrains.shore; const tWater = g_Terrains.water; const oTree1 = g_Gaia.tree1; const oTree2 = g_Gaia.tree2; const oTree3 = g_Gaia.tree3; const oTree4 = g_Gaia.tree4; const oTree5 = g_Gaia.tree5; const oFruitBush = g_Gaia.fruitBush; const oMainHuntableAnimal = g_Gaia.mainHuntableAnimal; const oFish = g_Gaia.fish; const oSecondaryHuntableAnimal = g_Gaia.secondaryHuntableAnimal; const oStoneLarge = g_Gaia.stoneLarge; const oStoneSmall = g_Gaia.stoneSmall; const oMetalLarge = g_Gaia.metalLarge; const oWood = "gaia/special_treasure_wood"; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; const aReeds = g_Decoratives.reeds; const aLillies = g_Decoratives.lillies; const aRockLarge = g_Decoratives.rockLarge; const aRockMedium = g_Decoratives.rockMedium; const aBushMedium = g_Decoratives.bushMedium; const aBushSmall = g_Decoratives.bushSmall; const pForest1 = [tForestFloor2 + TERRAIN_SEPARATOR + oTree1, tForestFloor2 + TERRAIN_SEPARATOR + oTree2, tForestFloor2]; const pForest2 = [tForestFloor1 + TERRAIN_SEPARATOR + oTree4, tForestFloor1 + TERRAIN_SEPARATOR + oTree5, tForestFloor1]; InitMap(); const numPlayers = getNumPlayers(); const mapSize = getMapSize(); const mapArea = mapSize*mapSize; var clPlayer = createTileClass(); var clHill = createTileClass(); var clForest = createTileClass(); var clWater = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clSettlement = createTileClass(); var clLand = createTileClass(); var clShallow = createTileClass(); initTerrain(tWater); var iberianTowers = false; var md = randIntInclusive(1,13); var needsAdditionalWood = false; //***************************************************************************************************************************** if (md == 1) //archipelago and island { needsAdditionalWood = true; iberianTowers = true; var [playerIDs, playerX, playerZ] = radialPlayerPlacement(); var mdd1 = randIntInclusive(1,3); for (var i = 0; i < numPlayers; ++i) { var radius = scaleByMapSize(17, 29); var shoreRadius = 4; var elevation = 3; var hillSize = PI * radius * radius; // get the x and z in tiles var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // create a player island var placer = new ClumpPlacer(hillSize, 0.80, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tMainTerrain , tMainTerrain, tMainTerrain], // terrains [1, shoreRadius] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type elevation, // elevation shoreRadius // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clPlayer)], null); } if (mdd1 == 1) //archipelago { log("Creating islands..."); placer = new ClumpPlacer(floor(hillSize*randFloat(0.8,1.2)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], null, scaleByMapSize(2, 5)*randIntInclusive(8,14) ); log("Creating shore jaggedness..."); placer = new ClumpPlacer(scaleByMapSize(15, 80), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], borderClasses(clLand, 6, 3), scaleByMapSize(12, 130) * 2, 150 ); } else if (mdd1 == 2) //islands { log("Creating islands..."); placer = new ClumpPlacer(floor(hillSize*randFloat(0.6,1.4)), 0.80, 0.1, randFloat(0.0, 0.2)); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(6, 10)*randIntInclusive(8,14) ); log("Creating small islands..."); placer = new ClumpPlacer(floor(hillSize*randFloat(0.3,0.7)), 0.80, 0.1, 0.07); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 6); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(2, 6)*randIntInclusive(6,15), 25 ); } else if (mdd1 == 3) // tight islands { log("Creating islands..."); placer = new ClumpPlacer(floor(hillSize*randFloat(0.8,1.2)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, randIntInclusive(8, 16), clPlayer, 3), scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } } //******************************************************************************************************** else if (md == 2) //continent { var [playerIDs, playerX, playerZ] = radialPlayerPlacement(0.25); for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); addCivicCenterAreaToClass(ix, iz, clPlayer); } var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.45, 0.9, 0.09, 10, ix, iz); var terrainPainter = new LayeredPainter( [tWater, tShore, tMainTerrain], // terrains [4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); var clPeninsulaSteam = createTileClass(); if (randBool(1/3)) // peninsula { var angle = randFloat(0, TWO_PI); var fx = fractionToTiles(0.5 + 0.25*cos(angle)); var fz = fractionToTiles(0.5 + 0.25*sin(angle)); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.45, 0.9, 0.09, 10, ix, iz); var terrainPainter = new LayeredPainter( [tWater, tShore, tMainTerrain], // terrains [4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); var fx = fractionToTiles(0.5 + 0.35*cos(angle)); var fz = fractionToTiles(0.5 + 0.35*sin(angle)); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.3, 0.9, 0.01, 10, ix, iz); createArea(placer, [paintClass(clPeninsulaSteam)], null); } log("Creating shore jaggedness..."); placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 4); createAreas( placer, [terrainPainter, elevationPainter, unPaintClass(clLand)], [avoidClasses(clPlayer, 20, clPeninsulaSteam, 20), borderClasses(clLand, 7, 7)], scaleByMapSize(7, 130) * 2, 150 ); log("Creating shore jaggedness..."); placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], [avoidClasses(clPlayer, 20), borderClasses(clLand, 7, 7)], scaleByMapSize(7, 130) * 2, 150 ); } //******************************************************************************************************** else if (md == 3) //central sea { var playerIDs = primeSortAllPlayers(); var playerPos = placePlayersRiver(); var playerX = []; var playerZ = []; var playerAngle = []; var mdd1 = randIntInclusive(1,2); if (mdd1 == 1) //vertical for (var i = 0; i < numPlayers; i++) { playerZ[i] = playerPos[i]; playerX[i] = 0.2 + 0.6*(i%2); } else //horizontal for (var i = 0; i < numPlayers; i++) { playerZ[i] = 0.2 + 0.6*(i%2); playerX[i] = playerPos[i]; } paintRiver({ "horizontal": mdd1 != 1, "parallel": false, "position": 0.5, "width": randFloat(0.22, 0.3) + scaleByMapSize(1, 4) / 20, "fadeDist": 0.025, "deviation": 0, "waterHeight": -3, "landHeight": 3, "meanderShort": 20, "meanderLong": 0, "waterFunc": (ix, iz, height) => { placeTerrain(ix, iz, height < -1.5 ? tWater : tShore); if (height < 0) addToClass(ix, iz, clWater); }, "landFunc": (ix, iz, shoreDist1, shoreDist2) => { setHeight(ix, iz, 3.1); addToClass(ix, iz, clLand); } }); if (randBool(1/3)) { // linked if (mdd1 == 1) //vertical { var placer = new PathPlacer(1, fractionToTiles(0.5), fractionToTiles(0.99), fractionToTiles(0.5), scaleByMapSize(randIntInclusive(16,24),randIntInclusive(100,140)), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); } else { var placer = new PathPlacer(fractionToTiles(0.5), 1, fractionToTiles(0.5), fractionToTiles(0.99), scaleByMapSize(randIntInclusive(16,24),randIntInclusive(100,140)), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); } var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3.1, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null); } var mdd2 = randIntInclusive(1,7); if (mdd2 == 1) { log("Creating islands..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23))*randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23)), 0.80, 0.1, randFloat(0.0, 0.2)); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } else if (mdd2 == 2) { log("Creating extentions..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45))*randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], null, scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } } //******************************************************************************************************** else if (md == 4) //central river { for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var playerIDs = primeSortAllPlayers(); var playerPos = placePlayersRiver(); var playerX = []; var playerZ = []; var playerAngle = []; var mdd1 = randIntInclusive(1,2); if (mdd1 == 1) //horizontal for (var i = 0; i < numPlayers; i++) { playerZ[i] = 0.25 + 0.5*(i%2); playerX[i] = playerPos[i]; } else //vertical for (var i = 0; i < numPlayers; i++) { playerZ[i] = playerPos[i]; playerX[i] = 0.25 + 0.5*(i%2); } log("Creating the main river"); if (mdd1 == 2) var placer = new PathPlacer(fractionToTiles(0.5), 1, fractionToTiles(0.5) , fractionToTiles(0.99), scaleByMapSize(14,24), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); else var placer = new PathPlacer(1, fractionToTiles(0.5), fractionToTiles(0.99), fractionToTiles(0.5), scaleByMapSize(14,24), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter], avoidClasses(clPlayer, 4)); if (mdd1 == 1) placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, 1, fractionToTiles(0.5)); else placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5), 1); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 8)); if (mdd1 == 1) placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.99), fractionToTiles(0.5)); else placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5), fractionToTiles(0.99)); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 8)); var mdd2 = randIntInclusive(1,2); if (mdd2 == 1) { log("Creating the shallows of the main river"); for (var i = 0; i <= randIntInclusive(1, scaleByMapSize(4,8)); i++) { var cLocation = randFloat(0.15,0.85); if (mdd1 == 1) - passageMaker(floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); + createShallowsPassage(floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); else - passageMaker(floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), floor(fractionToTiles(cLocation)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); + createShallowsPassage(floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), floor(fractionToTiles(cLocation)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); } } if (randBool()) { for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // create the city patch var cityRadius = scaleByMapSize(17,29)/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); createArea(placer, paintClass(clPlayer), null); } log("Creating tributaries"); for (var i = 0; i <= randIntInclusive(8, (scaleByMapSize(12,20))); i++) { var cLocation = randFloat(0.05,0.95); var tang = randFloat(PI*0.2, PI*0.8)*((randIntInclusive(0, 1)-0.5)*2); if (tang > 0) { var cDistance = 0.05; } else { var cDistance = -0.05; } if (mdd1 == 1) var point = getTIPIADBON([fractionToTiles(cLocation), fractionToTiles(0.5 + cDistance)], [fractionToTiles(cLocation), fractionToTiles(0.5 - cDistance)], [-6, -1.5], 0.5, 5, 0.01); else var point = getTIPIADBON([fractionToTiles(0.5 + cDistance), fractionToTiles(cLocation)], [fractionToTiles(0.5 - cDistance), fractionToTiles(cLocation)], [-6, -1.5], 0.5, 5, 0.01); if (point !== undefined) { if (mdd1 == 1) var placer = new PathPlacer(floor(point[0]), floor(point[1]), floor(fractionToTiles(0.5 + 0.49*cos(tang))), floor(fractionToTiles(0.5 + 0.49*sin(tang))), scaleByMapSize(10,20), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.05); else var placer = new PathPlacer(floor(point[0]), floor(point[1]), floor(fractionToTiles(0.5 + 0.49*sin(tang))), floor(fractionToTiles(0.5 + 0.49*cos(tang))), scaleByMapSize(10,20), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.05); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); var success = createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 3, clWater, 3, clShallow, 2)); if (success !== undefined) { if (mdd1 == 1) placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); else placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*sin(tang)), fractionToTiles(0.5 + 0.49*cos(tang))); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 3)); } } } } } //******************************************************************************************************** else if (md == 5) //rivers and lake { var [playerIDs, playerX, playerZ, playerAngle, startAngle] = radialPlayerPlacement(); for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); addCivicCenterAreaToClass(ix, iz, clPlayer); } for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var mdd1 = randIntInclusive(1,2); if (mdd1 == 1) //lake { var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.09 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); log("Creating shore jaggedness..."); placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], [avoidClasses(clPlayer, 20), borderClasses(clWater, 6, 4)], scaleByMapSize(7, 130) * 2, 150 ); placer = new ClumpPlacer(scaleByMapSize(15, 80), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], borderClasses(clWater, 4, 7), scaleByMapSize(12, 130) * 2, 150 ); } if (randBool()) // rivers { log ("Creating rivers..."); for (var m = 0; m < numPlayers; m++) { var tang = startAngle + (m+0.5)*TWO_PI/(numPlayers); var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5)); placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,50)*scaleByMapSize(10,50)/5), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 0); createArea(placer, [painter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5)); } var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.005, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } if (randBool(1/3) &&(mdd1 == 1))//island { var placer = new ClumpPlacer(mapArea * 0.006 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } } //******************************************************************************************************** else if (md == 6) //edge seas { for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var mdd1 = randIntInclusive(1,2); var playerIDs = sortAllPlayers(); var playerX = []; var playerZ = []; var playerPos = []; for (var i = 0; i < numPlayers; i++) { playerPos[i] = (i + 1) / (numPlayers + 1); if (mdd1 == 1) //horizontal { playerX[i] = playerPos[i]; playerZ[i] = 0.4 + 0.2*(i%2); } else //vertical { playerX[i] = 0.4 + 0.2*(i%2); playerZ[i] = playerPos[i]; } var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); addCivicCenterAreaToClass(ix, iz, clPlayer); } var mdd2 = randIntInclusive(1,3); var fadedistance = 7; if (mdd1 == 1) { if ((mdd2 == 1)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (iz > (0.69+distance) * mapSize) { if (iz < (0.69+distance) * mapSize + fadedistance) { setHeight(ix, iz, 3 - 7 * (iz - (0.69+distance) * mapSize) / fadedistance); if (3 - 7 * (iz - (0.69+distance) * mapSize) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } for (var i = 0; i < scaleByMapSize(20,120); i++) { placer = new ClumpPlacer(scaleByMapSize(50, 70), 0.2, 0.1, 10, randFloat(0.1,0.9)*mapSize, randFloat(0.67+distance,0.74+distance)*mapSize); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3); createArea( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null ); } } if ((mdd2 == 2)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (iz < (0.31-distance) * mapSize) { if (iz > (0.31-distance) * mapSize - fadedistance) { setHeight(ix, iz, 3 - 7 * ((0.31-distance) * mapSize - iz) / fadedistance); if (3 - 7 * ((0.31-distance) * mapSize - iz) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } for (var i = 0; i < scaleByMapSize(20,120); i++) { placer = new ClumpPlacer(scaleByMapSize(50, 70), 0.2, 0.1, 10, randFloat(0.1,0.9)*mapSize, randFloat(0.26-distance,0.34-distance)*mapSize); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3); createArea( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null ); } } } else //vertical { if ((mdd2 == 1)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (ix > (0.69+distance) * mapSize) { if (ix < (0.69+distance) * mapSize + fadedistance) { setHeight(ix, iz, 3 - 7 * (ix - (0.69+distance) * mapSize) / fadedistance); if (3 - 7 * (ix - (0.69+distance) * mapSize) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } } if ((mdd2 == 2)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (ix < (0.31-distance) * mapSize) { if (ix > (0.31-distance) * mapSize - fadedistance) { setHeight(ix, iz, 3 - 7 * ((0.31-distance) * mapSize - ix) / fadedistance); if (3 - 7 * ((0.31-distance) * mapSize - ix) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } } } log("Creating shore jaggedness..."); placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], [avoidClasses(clPlayer, 20), borderClasses(clWater, 6, 4)], scaleByMapSize(7, 130) * 2, 150 ); placer = new ClumpPlacer(scaleByMapSize(15, 80), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], borderClasses(clWater, 4, 7), scaleByMapSize(12, 130) * 2, 150 ); var mdd3 = randIntInclusive(1,3); if (mdd3 == 1) { log("Creating islands..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23))*randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23)), 0.80, 0.1, randFloat(0.0, 0.2)); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } else if (mdd3 == 2) { log("Creating extentions..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45))*randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], null, scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } } //******************************************************************************************************** else if (md == 7) //gulf { for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var mdd1 = randFloat(0,4); var playerIDs = sortAllPlayers(); var playerX = []; var playerZ = []; var playerAngle = []; var startAngle = -PI/6 + (mdd1-1)*PI/2; for (var i = 0; i < numPlayers; i++) { playerAngle[i] = startAngle + Math.PI * 2/3 * (numPlayers == 1 ? 1 : 2 * i / (numPlayers - 1)); playerX[i] = 0.5 + 0.35*cos(playerAngle[i]); playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]); } for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // create the city patch var cityRadius = scaleByMapSize(17,29)/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); createArea(placer, paintClass(clPlayer), null); } fx = fractionToTiles(0.5); fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = 1; var placer = new ClumpPlacer(mapArea * 0.08 * lSize, 0.7, 0.05, 10, ix, iz); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,floor(scaleByMapSize(15,25)))); fx = fractionToTiles(0.5 - 0.2*cos(mdd1*PI/2)); fz = fractionToTiles(0.5 - 0.2*sin(mdd1*PI/2)); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.13 * lSize, 0.7, 0.05, 10, ix, iz); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,floor(scaleByMapSize(15,25)))); fx = fractionToTiles(0.5 - 0.49*cos(mdd1*PI/2)); fz = fractionToTiles(0.5 - 0.49*sin(mdd1*PI/2)); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.15 * lSize, 0.7, 0.05, 10, ix, iz); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,floor(scaleByMapSize(15,25)))); } //******************************************************************************************************** else if (md == 8) //lakes { var [playerIDs, playerX, playerZ, playerAngle] = radialPlayerPlacement(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // create the city patch var cityRadius = scaleByMapSize(17,29)/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); createArea(placer, paintClass(clPlayer), null); } log("Creating lakes..."); placer = new ClumpPlacer(scaleByMapSize(160, 700), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 5); if (randBool()) { createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 12, clWater, 8), scaleByMapSize(5, 16) ); } else { createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 12), scaleByMapSize(5, 16) ); } } //******************************************************************************************************** else if (md == 9) //passes { var [playerIDs, playerX, playerZ, playerAngle, startAngle] = radialPlayerPlacement(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } log ("Creating ranges..."); for (var m = 0; m < numPlayers; m++) { var tang = startAngle + (m+0.5)*TWO_PI/(numPlayers); var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 24, // elevation 3 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5)); placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,50)*scaleByMapSize(10,50)/5), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 24, 0); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 5)); var placer = new PathPlacer(fractionToTiles(0.5 + 0.3*cos(tang) - 0.1 * cos(tang+PI/2)), fractionToTiles(0.5 + 0.3*sin(tang) - 0.1 * sin(tang+PI/2)), fractionToTiles(0.5 + 0.3*cos(tang) + 0.1 * cos(tang+PI/2)), fractionToTiles(0.5 + 0.3*sin(tang) + 0.1 * sin(tang+PI/2)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var painter = new LayeredPainter([tCliff, tCliff], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 2); createArea(placer, [painter, elevationPainter], null); } var mdd1 = randIntInclusive(1,3); if (mdd1 <= 2) { var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.005, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 24, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } else { var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.03 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 3 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } } //******************************************************************************************************** else if (md == 10) //lowlands { var [playerIDs, playerX, playerZ, playerAngle, startAngle] = radialPlayerPlacement(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 30); } } var radius = scaleByMapSize(18,32); var cliffRadius = 2; var elevation = 20; var hillSize = PI * radius * radius; var split = 1; if ((mapSize / 64 == 2)&&(numPlayers <= 2)) { split = 2; } else if ((mapSize / 64 == 3)&&(numPlayers <= 3)) { split = 2; } else if ((mapSize / 64 == 4)&&(numPlayers <= 4)) { split = 2; } else if ((mapSize / 64 == 5)&&(numPlayers <= 4)) { split = 2; } else if ((mapSize / 64 == 6)&&(numPlayers <= 5)) { split = 2; } else if ((mapSize / 64 == 7)&&(numPlayers <= 6)) { split = 2; } for (var i = 0; i < numPlayers*split; i++) { var tang = startAngle + (i)*TWO_PI/(numPlayers*split); var fx = fractionToTiles(0.5 + 0.35*cos(tang)); var fz = fractionToTiles(0.5 + 0.35*sin(tang)); var ix = round(fx); var iz = round(fz); // create the hill var placer = new ClumpPlacer(hillSize, 0.65, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [cliffRadius] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation cliffRadius // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); } var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.091 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); for (var m = 0; m < numPlayers*split; m++) { var tang = startAngle + m*TWO_PI/(numPlayers*split); var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.35*cos(tang)), fractionToTiles(0.5 + 0.35*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } } //******************************************************************************************************** else //mainland { var [playerIDs, playerX, playerZ, playerAngle] = radialPlayerPlacement(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } } paintTerrainBasedOnHeight(3.12, 40, 1, tCliff); paintTerrainBasedOnHeight(3, 3.12, 1, tMainTerrain); paintTerrainBasedOnHeight(1, 3, 1, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); unPaintTileClassBasedOnHeight(0, 3.12, 1, clWater); unPaintTileClassBasedOnHeight(-6, 0, 1, clLand); paintTileClassBasedOnHeight(-6, 0, 1, clWater); paintTileClassBasedOnHeight(0, 3.12, 1, clLand); paintTileClassBasedOnHeight(3.12, 40, 1, clHill); for (var i = 0; i < numPlayers; i++) { var id = playerIDs[i]; log("Creating base for player " + id + "..."); var radius = scaleByMapSize(17,29); var shoreRadius = 4; var elevation = 3; var hillSize = PI * radius * radius; // get the x and z in tiles var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); if (iberianTowers) placeCivDefaultEntities(fx, fz, id, { 'iberWall': 'towers' }); else placeCivDefaultEntities(fx, fz, id); placeDefaultChicken(fx, fz, clBaseResource); // create berry bushes var bbAngle = randFloat(0, TWO_PI); var bbDist = 12; var bbX = round(fx + bbDist * cos(bbAngle)); var bbZ = round(fz + bbDist * sin(bbAngle)); var group = new SimpleGroup( [new SimpleObject(oFruitBush, 5,5, 0,3)], true, clBaseResource, bbX, bbZ ); createObjectGroup(group, 0); if (needsAdditionalWood) { // create woods var bbAngle = randFloat(0, TWO_PI); var bbDist = 13; var bbX = round(fx + bbDist * cos(bbAngle)); var bbZ = round(fz + bbDist * sin(bbAngle)); group = new SimpleGroup( [new SimpleObject(oWood, 14,14, 0,3)], true, clBaseResource, bbX, bbZ ); createObjectGroup(group, 0); } // create metal mine var mAngle = bbAngle; while(abs(mAngle - bbAngle) < PI/3) { mAngle = randFloat(0, TWO_PI); } var mDist = 12; var mX = round(fx + mDist * cos(mAngle)); var mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oMetalLarge, 1,1, 0,0)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); // create stone mines mAngle += randFloat(PI/8, PI/4); mX = round(fx + mDist * cos(mAngle)); mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oStoneLarge, 1,1, 0,2)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); var hillSize = PI * radius * radius; // create starting trees var num = floor(hillSize / 100); var tAngle = randFloat(-PI/3, 4*PI/3); var tDist = randFloat(11, 13); var tX = round(fx + tDist * cos(tAngle)); var tZ = round(fz + tDist * sin(tAngle)); group = new SimpleGroup( [new SimpleObject(oTree1, num, num, 0,5)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); placeDefaultDecoratives(fx, fz, aGrassShort, clBaseResource, radius); } for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // create the city patch var cityRadius = radius/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); var painter = new LayeredPainter([tRoadWild, tRoad], [1]); createArea(placer, [painter, paintClass(clPlayer)], null); } log("Creating bumps..."); placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1); painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2); createAreas( placer, painter, [avoidClasses(clWater, 2, clPlayer, 10), stayClasses(clLand, 3)], randIntInclusive(0,scaleByMapSize(200, 400)) ); log("Creating hills..."); placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 18, 2); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], [avoidClasses(clPlayer, 20, clHill, randIntInclusive(6, 18)), stayClasses(clLand, 0)], randIntInclusive(0, scaleByMapSize(4, 8))*randIntInclusive(1, scaleByMapSize(4, 9)) ); var multiplier = sqrt(randFloat(0.5,1.2)*randFloat(0.5,1.2)); // calculate desired number of trees for map (based on size) if (currentBiome() == "savanna") { var MIN_TREES = floor(200*multiplier); var MAX_TREES = floor(1250*multiplier); var P_FOREST = randFloat(0.02, 0.05); } else if (currentBiome() == "tropic") { var MIN_TREES = floor(1000*multiplier); var MAX_TREES = floor(6000*multiplier); var P_FOREST = randFloat(0.5, 0.7); } else { var MIN_TREES = floor(500*multiplier); var MAX_TREES = floor(3000*multiplier); var P_FOREST = randFloat(0.5,0.8); } var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES); var numForest = totalTrees * P_FOREST; var numStragglers = totalTrees * (1.0 - P_FOREST); log("Creating forests..."); var types = [ [[tForestFloor2, tMainTerrain, pForest1], [tForestFloor2, pForest1]], [[tForestFloor1, tMainTerrain, pForest2], [tForestFloor1, pForest2]] ]; // some variation if (currentBiome() == "savanna") var size = numForest / (0.5 * scaleByMapSize(2,8) * numPlayers); else var size = numForest / (scaleByMapSize(2,8) * numPlayers); var num = floor(size / types.length); for (var i = 0; i < types.length; ++i) { placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 1); painter = new LayeredPainter( types[i], // terrains [2] // widths ); createAreas( placer, [painter, paintClass(clForest)], [avoidClasses(clPlayer, 20, clForest, randIntInclusive(5, 15), clHill, 0), stayClasses(clLand, 4)], num ); } RMS.SetProgress(50); log("Creating dirt patches..."); var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]; var numb = 1; if (currentBiome() == "savanna") numb = 3; for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); painter = new LayeredPainter( [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], // terrains [1,1] // widths ); createAreas( placer, [painter, paintClass(clDirt)], [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 7), stayClasses(clLand, 4)], numb*scaleByMapSize(15, 45) ); } log("Creating grass patches..."); var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]; for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); painter = new TerrainPainter(tTier4Terrain); createAreas( placer, painter, [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 7), stayClasses(clLand, 4)], numb*scaleByMapSize(15, 45) ); } RMS.SetProgress(55); log("Creating stone mines..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), stayClasses(clLand, 4)], randIntInclusive(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), stayClasses(clLand, 4)], randIntInclusive(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), stayClasses(clLand, 4)], randIntInclusive(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100 ); RMS.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 4)], scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 4)], scaleByMapSize(8, 131), 50 ); RMS.SetProgress(70); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oMainHuntableAnimal, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 4)], randIntInclusive(numPlayers+3, 5*numPlayers+4), 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oFruitBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 4)], randIntInclusive(1, 4) * numPlayers + 2, 50 ); RMS.SetProgress(75); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oSecondaryHuntableAnimal, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 4)], randIntInclusive(numPlayers+3, 5*numPlayers+4), 50 ); log("Creating fish..."); group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clLand, 5, clForest, 0, clPlayer, 0, clHill, 0, clFood, 20), randIntInclusive(15, 40) * numPlayers, 60 ); RMS.SetProgress(85); log("Creating straggler trees..."); var types = [oTree1, oTree2, oTree4, oTree3]; // some variation var num = floor(numStragglers / types.length); for (var i = 0; i < types.length; ++i) { group = new SimpleGroup( [new SimpleObject(types[i], 1,1, 0,3)], true, clForest ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 0, clMetal, 6, clRock, 6), stayClasses(clLand, 4)], num ); } var planetm = 1; if (currentBiome() == "tropic") planetm = 8; log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 4)], planetm * scaleByMapSize(13, 200) ); RMS.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 4)], planetm * scaleByMapSize(13, 200) ); RMS.SetProgress(95); log("Creating shallow flora..."); group = new SimpleGroup( [new SimpleObject(aLillies, 1,2, 0,2), new SimpleObject(aReeds, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, stayClasses(clShallow, 1), 60 * scaleByMapSize(13, 200), 80 ); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1), stayClasses(clLand, 3)], planetm * scaleByMapSize(13, 200), 50 ); setSkySet(pickRandom(["cirrus", "cumulus", "sunny", "sunny 1", "mountainous", "stratus"])); setSunRotation(randFloat(0, TWO_PI)); setSunElevation(randFloat(PI/ 5, PI / 3)); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/unknown_land.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/unknown_land.js (revision 20409) +++ ps/trunk/binaries/data/mods/public/maps/random/unknown_land.js (revision 20410) @@ -1,1421 +1,1421 @@ RMS.LoadLibrary("rmgen"); RMS.LoadLibrary("rmbiome"); TILE_CENTERED_HEIGHT_MAP = true; setSelectedBiome(); const tMainTerrain = g_Terrains.mainTerrain; const tForestFloor1 = g_Terrains.forestFloor1; const tForestFloor2 = g_Terrains.forestFloor2; const tCliff = g_Terrains.cliff; const tTier1Terrain = g_Terrains.tier1Terrain; const tTier2Terrain = g_Terrains.tier2Terrain; const tTier3Terrain = g_Terrains.tier3Terrain; const tHill = g_Terrains.hill; const tDirt = g_Terrains.dirt; const tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; const tShoreBlend = g_Terrains.shoreBlend; const tShore = g_Terrains.shore; const tWater = g_Terrains.water; const oTree1 = g_Gaia.tree1; const oTree2 = g_Gaia.tree2; const oTree3 = g_Gaia.tree3; const oTree4 = g_Gaia.tree4; const oTree5 = g_Gaia.tree5; const oFruitBush = g_Gaia.fruitBush; const oMainHuntableAnimal = g_Gaia.mainHuntableAnimal; const oFish = g_Gaia.fish; const oSecondaryHuntableAnimal = g_Gaia.secondaryHuntableAnimal; const oStoneLarge = g_Gaia.stoneLarge; const oStoneSmall = g_Gaia.stoneSmall; const oMetalLarge = g_Gaia.metalLarge; const oWood = "gaia/special_treasure_wood"; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; const aReeds = g_Decoratives.reeds; const aLillies = g_Decoratives.lillies; const aRockLarge = g_Decoratives.rockLarge; const aRockMedium = g_Decoratives.rockMedium; const aBushMedium = g_Decoratives.bushMedium; const aBushSmall = g_Decoratives.bushSmall; const pForest1 = [tForestFloor2 + TERRAIN_SEPARATOR + oTree1, tForestFloor2 + TERRAIN_SEPARATOR + oTree2, tForestFloor2]; const pForest2 = [tForestFloor1 + TERRAIN_SEPARATOR + oTree4, tForestFloor1 + TERRAIN_SEPARATOR + oTree5, tForestFloor1]; InitMap(); const numPlayers = getNumPlayers(); const mapSize = getMapSize(); const mapArea = mapSize*mapSize; var clPlayer = createTileClass(); var clHill = createTileClass(); var clForest = createTileClass(); var clWater = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clSettlement = createTileClass(); var clLand = createTileClass(); var clShallow = createTileClass(); initTerrain(tWater); var md = randIntInclusive(2,13); var needsAdditionalWood = false; //***************************************************************************************************************************** if (md == 2) //continent { var [playerIDs, playerX, playerZ, playerAngle] = radialPlayerPlacement(0.25); for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); addCivicCenterAreaToClass(ix, iz, clPlayer); var placer = new ChainPlacer(2, floor(scaleByMapSize(5, 9)), floor(scaleByMapSize(5, 20)), 1, ix, iz, 0, [floor(scaleByMapSize(23, 50))]); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [elevationPainter, paintClass(clLand)], null); } var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var placer = new ChainPlacer(2, floor(scaleByMapSize(5, 12)), floor(scaleByMapSize(60, 700)), 1, ix, iz, 0, [floor(mapSize * 0.33)]); var terrainPainter = new LayeredPainter( [tWater, tShore, tMainTerrain], // terrains [4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); var clPeninsulaSteam = createTileClass(); if (randBool(1/3)) // peninsula { var angle = randFloat(0, TWO_PI); var fx = fractionToTiles(0.5 + 0.25*cos(angle)); var fz = fractionToTiles(0.5 + 0.25*sin(angle)); ix = round(fx); iz = round(fz); var placer = new ChainPlacer(2, floor(scaleByMapSize(5, 12)), floor(scaleByMapSize(60, 700)), 1, ix, iz, 0, [floor(mapSize * 0.33)]); var terrainPainter = new LayeredPainter( [tWater, tShore, tMainTerrain], // terrains [4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); var fx = fractionToTiles(0.5 + 0.35*cos(angle)); var fz = fractionToTiles(0.5 + 0.35*sin(angle)); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.3, 0.9, 0.01, 10, ix, iz); createArea(placer, [paintClass(clPeninsulaSteam)], null); } } //******************************************************************************************************** else if (md == 3) //central sea { var playerIDs = primeSortAllPlayers(); var playerPos = placePlayersRiver(); var playerX = []; var playerZ = []; var playerAngle = []; var mdd1 = randIntInclusive(1,2); if (mdd1 == 1) //vertical for (var i = 0; i < numPlayers; i++) { playerZ[i] = playerPos[i]; playerX[i] = 0.2 + 0.6*(i%2); } else //horizontal for (var i = 0; i < numPlayers; i++) { playerZ[i] = 0.2 + 0.6*(i%2); playerX[i] = playerPos[i]; } paintRiver({ "horizontal": mdd1 != 1, "parallel": false, "position": 0.5, "width": randFloat(0.22, 0.3) + scaleByMapSize(1, 4) / 20, "fadeDist": 0.025, "deviation": 0, "waterHeight": -3, "landHeight": 3, "meanderShort": 20, "meanderLong": 0, "waterFunc": (ix, iz, height) => { placeTerrain(ix, iz, height < -1.5 ? tWater : tShore); if (height < 0) addToClass(ix, iz, clWater); }, "landFunc": (ix, iz, shoreDist1, shoreDist2) => { setHeight(ix, iz, 3.1); addToClass(ix, iz, clLand); } }); // linked if (mdd1 == 1) //vertical { var placer = new PathPlacer(1, fractionToTiles(0.5), fractionToTiles(0.99), fractionToTiles(0.5), scaleByMapSize(randIntInclusive(16,24),randIntInclusive(100,140)), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); } else { var placer = new PathPlacer(fractionToTiles(0.5), 1, fractionToTiles(0.5), fractionToTiles(0.99), scaleByMapSize(randIntInclusive(16,24),randIntInclusive(100,140)), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); } var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3.1, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null); var mdd2 = randIntInclusive(1,7); if (mdd2 == 1) { log("Creating islands..."); placer = new ChainPlacer(floor(scaleByMapSize(4, 7)), floor(scaleByMapSize(7, 10)), floor(scaleByMapSize(16, 40)), 0.07); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } else if (mdd2 == 2) { log("Creating extentions..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45))*randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], null, scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } } //******************************************************************************************************** else if (md == 4) //central river { for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var playerIDs = primeSortAllPlayers(); var playerPos = placePlayersRiver(); var playerX = []; var playerZ = []; var playerAngle = []; var mdd1 = randIntInclusive(1,2); if (mdd1 == 1) //horizontal for (var i = 0; i < numPlayers; i++) { playerZ[i] = 0.25 + 0.5*(i%2); playerX[i] = playerPos[i]; } else //vertical for (var i = 0; i < numPlayers; i++) { playerZ[i] = playerPos[i]; playerX[i] = 0.25 + 0.5*(i%2); } log("Creating the main river"); if (mdd1 == 2) var placer = new PathPlacer(fractionToTiles(0.5), 1, fractionToTiles(0.5) , fractionToTiles(0.99), scaleByMapSize(14,24), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); else var placer = new PathPlacer(1, fractionToTiles(0.5), fractionToTiles(0.99), fractionToTiles(0.5), scaleByMapSize(14,24), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter], avoidClasses(clPlayer, 4)); if (mdd1 == 1) placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, 1, fractionToTiles(0.5)); else placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5), 1); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 8)); if (mdd1 == 1) placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.99), fractionToTiles(0.5)); else placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5), fractionToTiles(0.99)); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 8)); log("Creating the shallows of the main river"); for (var i = 0; i <= randIntInclusive(1, scaleByMapSize(4,8)); i++) { var cLocation = randFloat(0.15,0.85); if (mdd1 == 1) - passageMaker(floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); + createShallowsPassage(floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); else - passageMaker(floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), floor(fractionToTiles(cLocation)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); + createShallowsPassage(floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), floor(fractionToTiles(cLocation)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); } if (randBool()) { for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // create the city patch var cityRadius = scaleByMapSize(17,29)/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); createArea(placer, paintClass(clPlayer), null); } log("Creating tributaries"); for (var i = 0; i <= randIntInclusive(8, (scaleByMapSize(12,20))); i++) { var cLocation = randFloat(0.05,0.95); var tang = randFloat(PI*0.2, PI*0.8)*((randIntInclusive(0, 1)-0.5)*2); if (tang > 0) { var cDistance = 0.05; } else { var cDistance = -0.05; } if (mdd1 == 1) var point = getTIPIADBON([fractionToTiles(cLocation), fractionToTiles(0.5 + cDistance)], [fractionToTiles(cLocation), fractionToTiles(0.5 - cDistance)], [-6, -1.5], 0.5, 5, 0.01); else var point = getTIPIADBON([fractionToTiles(0.5 + cDistance), fractionToTiles(cLocation)], [fractionToTiles(0.5 - cDistance), fractionToTiles(cLocation)], [-6, -1.5], 0.5, 5, 0.01); if (point !== undefined) { if (mdd1 == 1) var placer = new PathPlacer(floor(point[0]), floor(point[1]), floor(fractionToTiles(0.5 + 0.49*cos(tang))), floor(fractionToTiles(0.5 + 0.49*sin(tang))), scaleByMapSize(10,20), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.05); else var placer = new PathPlacer(floor(point[0]), floor(point[1]), floor(fractionToTiles(0.5 + 0.49*sin(tang))), floor(fractionToTiles(0.5 + 0.49*cos(tang))), scaleByMapSize(10,20), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.05); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); var success = createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 3, clWater, 3, clShallow, 2)); if (success !== undefined) { if (mdd1 == 1) placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); else placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*sin(tang)), fractionToTiles(0.5 + 0.49*cos(tang))); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 3)); } } } } } //******************************************************************************************************** else if (md == 5) //rivers and lake { var [playerIDs, playerX, playerZ] = radialPlayerPlacement(); for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); addCivicCenterAreaToClass(ix, iz, clPlayer); } for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var mdd1 = randIntInclusive(1,2); if (mdd1 == 1) //lake { var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ChainPlacer(2, floor(scaleByMapSize(5, 16)), floor(scaleByMapSize(35, 200)), 1, ix, iz, 0, [floor(mapSize * 0.17 * lSize)]); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); log("Creating shore jaggedness..."); placer = new ChainPlacer(2, floor(scaleByMapSize(4, 6)), 3, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], borderClasses(clWater, 4, 7), scaleByMapSize(12, 130) * 2, 150 ); } if (randBool(1/3) &&(mdd1 == 1))//island { var placer = new ClumpPlacer(mapArea * 0.006 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } } //******************************************************************************************************** else if (md == 6) //edge seas { for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var mdd1 = randIntInclusive(1,2); var playerIDs = sortAllPlayers(); // place players var playerX = []; var playerZ = []; var playerPos = []; for (var i = 0; i < numPlayers; i++) { playerPos[i] = (i + 1) / (numPlayers + 1); if (mdd1 == 1) //horizontal { playerX[i] = playerPos[i]; playerZ[i] = 0.4 + 0.2*(i%2); } else //vertical { playerX[i] = 0.4 + 0.2*(i%2); playerZ[i] = playerPos[i]; } var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); addCivicCenterAreaToClass(ix, iz, clPlayer); } var mdd2 = randIntInclusive(1,3); var fadedistance = 7; if (mdd1 == 1) { if ((mdd2 == 1)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (iz > (0.69+distance) * mapSize) { if (iz < (0.69+distance) * mapSize + fadedistance) { setHeight(ix, iz, 3 - 7 * (iz - (0.69+distance) * mapSize) / fadedistance); if (3 - 7 * (iz - (0.69+distance) * mapSize) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } } if ((mdd2 == 2)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (iz < (0.31-distance) * mapSize) { if (iz > (0.31-distance) * mapSize - fadedistance) { setHeight(ix, iz, 3 - 7 * ((0.31-distance) * mapSize - iz) / fadedistance); if (3 - 7 * ((0.31-distance) * mapSize - iz) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } } } else //vertical { if ((mdd2 == 1)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (ix > (0.69+distance) * mapSize) { if (ix < (0.69+distance) * mapSize + fadedistance) { setHeight(ix, iz, 3 - 7 * (ix - (0.69+distance) * mapSize) / fadedistance); if (3 - 7 * (ix - (0.69+distance) * mapSize) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } } if ((mdd2 == 2)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (ix < (0.31-distance) * mapSize) { if (ix > (0.31-distance) * mapSize - fadedistance) { setHeight(ix, iz, 3 - 7 * ((0.31-distance) * mapSize - ix) / fadedistance); if (3 - 7 * ((0.31-distance) * mapSize - ix) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } } } log("Creating shore jaggedness..."); placer = new ChainPlacer(2, floor(scaleByMapSize(4, 6)), 3, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], [avoidClasses(clPlayer, 20), borderClasses(clWater, 6, 4)], scaleByMapSize(7, 130) * 2, 150 ); placer = new ChainPlacer(2, floor(scaleByMapSize(4, 6)), 3, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], borderClasses(clWater, 4, 7), scaleByMapSize(12, 130) * 2, 150 ); var mdd3 = randIntInclusive(1,5); if (mdd3 == 1) { log("Creating islands..."); placer = new ChainPlacer(floor(scaleByMapSize(4, 7)), floor(scaleByMapSize(7, 10)), floor(scaleByMapSize(16, 40)), 0.07); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } else if (mdd3 == 2) { log("Creating extentions..."); placer = new ChainPlacer(floor(scaleByMapSize(4, 7)), floor(scaleByMapSize(7, 10)), floor(scaleByMapSize(16, 40)), 0.07); terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], null, scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } } //******************************************************************************************************** else if (md == 7) //gulf { for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var mdd1 = randFloat(0,4); var playerIDs = sortAllPlayers(); // place players var playerX = []; var playerZ = []; var playerAngle = []; var startAngle = -PI/6 + (mdd1-1)*PI/2; for (var i = 0; i < numPlayers; i++) { playerAngle[i] = startAngle + Math.PI * 2/3 * (numPlayers == 1 ? 1 : 2 * i / (numPlayers - 1)); playerX[i] = 0.5 + 0.35*cos(playerAngle[i]); playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]); } for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // create the city patch var cityRadius = scaleByMapSize(17,29)/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); createArea(placer, paintClass(clPlayer), null); } fx = fractionToTiles(0.5); fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = 1; var placer = new ChainPlacer(2, floor(scaleByMapSize(5, 16)), floor(scaleByMapSize(35, 200)), 1, ix, iz, 0, [floor(mapSize * 0.17 * lSize)]); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,floor(scaleByMapSize(15,25)))); fx = fractionToTiles(0.5 - 0.2*cos(mdd1*PI/2)); fz = fractionToTiles(0.5 - 0.2*sin(mdd1*PI/2)); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ChainPlacer(2, floor(scaleByMapSize(5, 16)), floor(scaleByMapSize(35, 120)), 1, ix, iz, 0, [floor(mapSize * 0.18 * lSize)]); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,floor(scaleByMapSize(15,25)))); fx = fractionToTiles(0.5 - 0.49*cos(mdd1*PI/2)); fz = fractionToTiles(0.5 - 0.49*sin(mdd1*PI/2)); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ChainPlacer(2, floor(scaleByMapSize(5, 16)), floor(scaleByMapSize(35, 100)), 1, ix, iz, 0, [floor(mapSize * 0.19 * lSize)]); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,floor(scaleByMapSize(15,25)))); } //******************************************************************************************************** else if (md == 8) //lakes { var [playerIDs, playerX, playerZ, playerAngle] = radialPlayerPlacement(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // create the city patch var cityRadius = scaleByMapSize(17,29)/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); createArea(placer, paintClass(clPlayer), null); } var lakeAreas = []; var playerConstraint = new AvoidTileClassConstraint(clPlayer, 20); var waterConstraint = new AvoidTileClassConstraint(clWater, 8); for (var x = 0; x < mapSize; ++x) for (var z = 0; z < mapSize; ++z) if (playerConstraint.allows(x, z) && waterConstraint.allows(x, z)) lakeAreas.push([x, z]); var chosenPoint; var lakeAreaLen; log("Creating lakes..."); var numLakes = scaleByMapSize(5, 16); for (var i = 0; i < numLakes; ++i) { lakeAreaLen = lakeAreas.length; if (!lakeAreaLen) break; chosenPoint = pickRandom(lakeAreas); placer = new ChainPlacer(1, floor(scaleByMapSize(4, 8)), floor(scaleByMapSize(40, 180)), 0.7, chosenPoint[0], chosenPoint[1]); terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 5); var newLake = createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 20, clWater, 8), 1, 1 ); if (newLake && newLake.length) { var n = 0; for (var j = 0; j < lakeAreaLen; ++j) { var x = lakeAreas[j][0], z = lakeAreas[j][1]; if (playerConstraint.allows(x, z) && waterConstraint.allows(x, z)) lakeAreas[n++] = lakeAreas[j]; } lakeAreas.length = n; } } } //******************************************************************************************************** else if (md == 9) //passes { var [playerIDs, playerX, playerZ, playerAngle, startAngle] = radialPlayerPlacement(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } log ("Creating ranges..."); for (var m = 0; m < numPlayers; m++) { var tang = startAngle + (m+0.5)*TWO_PI/(numPlayers); var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 24, // elevation 3 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5)); placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,50)*scaleByMapSize(10,50)/5), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 24, 0); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 5)); var placer = new PathPlacer(fractionToTiles(0.5 + 0.3*cos(tang) - 0.1 * cos(tang+PI/2)), fractionToTiles(0.5 + 0.3*sin(tang) - 0.1 * sin(tang+PI/2)), fractionToTiles(0.5 + 0.3*cos(tang) + 0.1 * cos(tang+PI/2)), fractionToTiles(0.5 + 0.3*sin(tang) + 0.1 * sin(tang+PI/2)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var painter = new LayeredPainter([tCliff, tCliff], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 2); createArea(placer, [painter, elevationPainter], null); } var mdd1 = randIntInclusive (1,3); if (mdd1 <= 2) { var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.005, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 24, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } else { var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.03 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 3 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } } //******************************************************************************************************** else if (md == 10) //lowlands { var [playerIDs, playerX, playerZ, playerAngle, startAngle] = radialPlayerPlacement(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 30); } } var radius = scaleByMapSize(18,32); var cliffRadius = 2; var elevation = 20; var hillSize = PI * radius * radius; var split = 1; if ((mapSize / 64 == 2)&&(numPlayers <= 2)) { split = 2; } else if ((mapSize / 64 == 3)&&(numPlayers <= 3)) { split = 2; } else if ((mapSize / 64 == 4)&&(numPlayers <= 4)) { split = 2; } else if ((mapSize / 64 == 5)&&(numPlayers <= 4)) { split = 2; } else if ((mapSize / 64 == 6)&&(numPlayers <= 5)) { split = 2; } else if ((mapSize / 64 == 7)&&(numPlayers <= 6)) { split = 2; } for (var i = 0; i < numPlayers*split; i++) { var tang = startAngle + (i)*TWO_PI/(numPlayers*split); var fx = fractionToTiles(0.5 + 0.35*cos(tang)); var fz = fractionToTiles(0.5 + 0.35*sin(tang)); var ix = round(fx); var iz = round(fz); // create the hill var placer = new ClumpPlacer(hillSize, 0.65, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain], // terrains [cliffRadius] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation cliffRadius // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); } var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.091 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); for (var m = 0; m < numPlayers*split; m++) { var tang = startAngle + m*TWO_PI/(numPlayers*split); var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.35*cos(tang)), fractionToTiles(0.5 + 0.35*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var terrainPainter = new LayeredPainter( [tMainTerrain, tMainTerrain, tMainTerrain], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } } //******************************************************************************************************** else //mainland { var [playerIDs, playerX, playerZ, playerAngle] = radialPlayerPlacement(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } } paintTerrainBasedOnHeight(3.12, 40, 1, tCliff); paintTerrainBasedOnHeight(3, 3.12, 1, tMainTerrain); paintTerrainBasedOnHeight(1, 3, 1, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); unPaintTileClassBasedOnHeight(0, 3.12, 1, clWater); unPaintTileClassBasedOnHeight(-6, 0, 1, clLand); paintTileClassBasedOnHeight(-6, 0, 1, clWater); paintTileClassBasedOnHeight(0, 3.12, 1, clLand); paintTileClassBasedOnHeight(3.12, 40, 1, clHill); for (var i = 0; i < numPlayers; i++) { var id = playerIDs[i]; log("Creating base for player " + id + "..."); var radius = scaleByMapSize(17,29); var shoreRadius = 4; var elevation = 3; var hillSize = PI * radius * radius; // get the x and z in tiles var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); placeCivDefaultEntities(fx, fz, id); placeDefaultChicken(fx, fz, clBaseResource); // create berry bushes var bbAngle = randFloat(0, TWO_PI); var bbDist = 12; var bbX = round(fx + bbDist * cos(bbAngle)); var bbZ = round(fz + bbDist * sin(bbAngle)); var group = new SimpleGroup( [new SimpleObject(oFruitBush, 5,5, 0,3)], true, clBaseResource, bbX, bbZ ); createObjectGroup(group, 0); if (needsAdditionalWood) { // create woods var bbAngle = randFloat(0, TWO_PI); var bbDist = 13; var bbX = round(fx + bbDist * cos(bbAngle)); var bbZ = round(fz + bbDist * sin(bbAngle)); group = new SimpleGroup( [new SimpleObject(oWood, 14,14, 0,3)], true, clBaseResource, bbX, bbZ ); createObjectGroup(group, 0); } // create metal mine var mAngle = bbAngle; while(abs(mAngle - bbAngle) < PI/3) { mAngle = randFloat(0, TWO_PI); } var mDist = 12; var mX = round(fx + mDist * cos(mAngle)); var mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oMetalLarge, 1,1, 0,0)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); // create stone mines mAngle += randFloat(PI/8, PI/4); mX = round(fx + mDist * cos(mAngle)); mZ = round(fz + mDist * sin(mAngle)); group = new SimpleGroup( [new SimpleObject(oStoneLarge, 1,1, 0,2)], true, clBaseResource, mX, mZ ); createObjectGroup(group, 0); var hillSize = PI * radius * radius; // create starting trees var num = floor(hillSize / 100); var tAngle = randFloat(-PI/3, 4*PI/3); var tDist = randFloat(11, 13); var tX = round(fx + tDist * cos(tAngle)); var tZ = round(fz + tDist * sin(tAngle)); group = new SimpleGroup( [new SimpleObject(oTree1, num, num, 0,5)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); placeDefaultDecoratives(fx, fz, aGrassShort, clBaseResource, radius); } for (var i = 0; i < numPlayers; i++) { var fx = fractionToTiles(playerX[i]); var fz = fractionToTiles(playerZ[i]); var ix = round(fx); var iz = round(fz); // create the city patch var cityRadius = radius/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); var painter = new LayeredPainter([tRoadWild, tRoad], [1]); createArea(placer, [painter, paintClass(clPlayer)], null); } log("Creating bumps..."); placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1); painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2); createAreas( placer, painter, [avoidClasses(clWater, 2, clPlayer, 10), stayClasses(clLand, 3)], randIntInclusive(0,scaleByMapSize(200, 400)) ); log("Creating hills..."); placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(16, 40)), 0.5); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 18, 2); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], [avoidClasses(clPlayer, 20, clHill, randIntInclusive(6, 18)), stayClasses(clLand, 0)], randIntInclusive(0, scaleByMapSize(4, 8))*randIntInclusive(1, scaleByMapSize(4, 9)) ); var multiplier = sqrt(randFloat(0.5,1.2)*randFloat(0.5,1.2)); // calculate desired number of trees for map (based on size) if (currentBiome() == "savanna") { var MIN_TREES = floor(200*multiplier); var MAX_TREES = floor(1250*multiplier); var P_FOREST = 0; } else if (currentBiome() == "tropic") { var MIN_TREES = floor(1000*multiplier); var MAX_TREES = floor(6000*multiplier); var P_FOREST = randFloat(0.5, 0.7); } else { var MIN_TREES = floor(500*multiplier); var MAX_TREES = floor(3000*multiplier); var P_FOREST = randFloat(0.5,0.8); } var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES); var numForest = totalTrees * P_FOREST; var numStragglers = totalTrees * (1.0 - P_FOREST); log("Creating forests..."); var types = [ [[tForestFloor2, tMainTerrain, pForest1], [tForestFloor2, pForest1]], [[tForestFloor1, tMainTerrain, pForest2], [tForestFloor1, pForest2]] ]; // some variation if (currentBiome() != "savanna") { var size = numForest / (scaleByMapSize(3,6) * numPlayers); var num = floor(size / types.length); for (var i = 0; i < types.length; ++i) { placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), numForest / num, 0.5); painter = new LayeredPainter( types[i], // terrains [2] // widths ); createAreas( placer, [painter, paintClass(clForest)], [avoidClasses(clPlayer, 20, clForest, randIntInclusive(5, 15), clHill, 0), stayClasses(clLand, 4)], num ); } } RMS.SetProgress(50); log("Creating dirt patches..."); var sizes = [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]; var numb = 1; if (currentBiome() == "savanna") numb = 3; for (var i = 0; i < sizes.length; i++) { placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5); painter = new LayeredPainter( [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], // terrains [1,1] // widths ); createAreas( placer, [painter, paintClass(clDirt)], [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 7), stayClasses(clLand, 4)], numb*scaleByMapSize(15, 45) ); } log("Creating grass patches..."); var sizes = [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)]; for (var i = 0; i < sizes.length; i++) { placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5); painter = new TerrainPainter(tTier4Terrain); createAreas( placer, painter, [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 7), stayClasses(clLand, 4)], numb*scaleByMapSize(15, 45) ); } RMS.SetProgress(55); log("Creating stone mines..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), stayClasses(clLand, 4)], randIntInclusive(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), stayClasses(clLand, 4)], randIntInclusive(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), stayClasses(clLand, 4)], randIntInclusive(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100 ); RMS.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 4)], scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 4)], scaleByMapSize(8, 131), 50 ); RMS.SetProgress(70); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oMainHuntableAnimal, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 4)], randIntInclusive(numPlayers+3, 5*numPlayers+4), 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oFruitBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 4)], randIntInclusive(1, 4) * numPlayers + 2, 50 ); RMS.SetProgress(75); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oSecondaryHuntableAnimal, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 4)], randIntInclusive(numPlayers+3, 5*numPlayers+4), 50 ); log("Creating fish..."); group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clLand, 5, clForest, 0, clPlayer, 0, clHill, 0, clFood, 20), randIntInclusive(15, 40) * numPlayers, 60 ); RMS.SetProgress(85); log("Creating straggler trees..."); var types = [oTree1, oTree2, oTree4, oTree3]; // some variation var num = floor(numStragglers / types.length); for (var i = 0; i < types.length; ++i) { group = new SimpleGroup( [new SimpleObject(types[i], 1,1, 0,3)], true, clForest ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 1, clForest, 7, clHill, 1, clPlayer, 0, clMetal, 6, clRock, 6), stayClasses(clLand, 4)], num ); } var planetm = 1; if (currentBiome() == "tropic") planetm = 8; log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 4)], planetm * scaleByMapSize(13, 200) ); RMS.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 4)], planetm * scaleByMapSize(13, 200) ); RMS.SetProgress(95); log("Creating shallow flora..."); group = new SimpleGroup( [new SimpleObject(aLillies, 1,2, 0,2), new SimpleObject(aReeds, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, stayClasses(clShallow, 1), 60 * scaleByMapSize(13, 200), 80 ); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1), stayClasses(clLand, 3)], planetm * scaleByMapSize(13, 200), 50 ); setSkySet(pickRandom(["cirrus", "cumulus", "sunny", "sunny 1", "mountainous", "stratus"])); setSunRotation(randFloat(0, TWO_PI)); setSunElevation(randFloat(PI/ 5, PI / 3)); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/unknown_nomad.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/unknown_nomad.js (revision 20409) +++ ps/trunk/binaries/data/mods/public/maps/random/unknown_nomad.js (revision 20410) @@ -1,1455 +1,1455 @@ RMS.LoadLibrary("rmgen"); RMS.LoadLibrary("rmbiome"); TILE_CENTERED_HEIGHT_MAP = true; setSelectedBiome(); var tGrass = g_Terrains.mainTerrain; var tGrassPForest = g_Terrains.forestFloor1; var tGrassDForest = g_Terrains.forestFloor2; var tCliff = g_Terrains.cliff; var tGrassA = g_Terrains.tier1Terrain; var tGrassB = g_Terrains.tier2Terrain; var tGrassC = g_Terrains.tier3Terrain; var tHill = g_Terrains.hill; var tDirt = g_Terrains.dirt; var tRoad = g_Terrains.road; var tRoadWild = g_Terrains.roadWild; var tGrassPatch = g_Terrains.tier4Terrain; var tShoreBlend = g_Terrains.shoreBlend; var tShore = g_Terrains.shore; var tWater = g_Terrains.water; var oOak = g_Gaia.tree1; var oOakLarge = g_Gaia.tree2; var oApple = g_Gaia.tree3; var oPine = g_Gaia.tree4; var oAleppoPine = g_Gaia.tree5; var oBerryBush = g_Gaia.fruitBush; var oDeer = g_Gaia.mainHuntableAnimal; var oFish = g_Gaia.fish; var oSheep = g_Gaia.secondaryHuntableAnimal; var oStoneLarge = g_Gaia.stoneLarge; var oStoneSmall = g_Gaia.stoneSmall; var oMetalLarge = g_Gaia.metalLarge; var oWood = "gaia/special_treasure_wood"; var aGrass = g_Decoratives.grass; var aGrassShort = g_Decoratives.grassShort; var aReeds = g_Decoratives.reeds; var aLillies = g_Decoratives.lillies; var aRockLarge = g_Decoratives.rockLarge; var aRockMedium = g_Decoratives.rockMedium; var aBushMedium = g_Decoratives.bushMedium; var aBushSmall = g_Decoratives.bushSmall; var pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oOak, tGrassDForest + TERRAIN_SEPARATOR + oOakLarge, tGrassDForest]; var pForestP = [tGrassPForest + TERRAIN_SEPARATOR + oPine, tGrassPForest + TERRAIN_SEPARATOR + oAleppoPine, tGrassPForest]; InitMap(); var numPlayers = getNumPlayers(); var mapSize = getMapSize(); var mapArea = mapSize*mapSize; var clPlayer = createTileClass(); var clHill = createTileClass(); var clForest = createTileClass(); var clWater = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clSettlement = createTileClass(); var clLand = createTileClass(); var clShallow = createTileClass(); initTerrain(tWater); var startAngle = randFloat(0, TWO_PI); var md = randIntInclusive(1,13); var needsAdditionalWood = false; //***************************************************************************************************************************** if (md == 1) //archipelago and island { needsAdditionalWood = true; var playerIDs = sortAllPlayers(); var radius = scaleByMapSize(17, 29); var hillSize = PI * radius * radius; var mdd1 = randIntInclusive(1,3); if (mdd1 == 1) //archipelago { log("Creating islands..."); placer = new ClumpPlacer(floor(hillSize*randFloat(0.8,1.2)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], null, scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } else if (mdd1 == 2) //islands { log("Creating islands..."); placer = new ClumpPlacer(floor(hillSize*randFloat(0.6,1.4)), 0.80, 0.1, randFloat(0.0, 0.2)); terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(6, 10)*randIntInclusive(8,14) ); } else if (mdd1 == 3) // tight islands { log("Creating islands..."); placer = new ClumpPlacer(floor(hillSize*randFloat(0.8,1.2)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, randIntInclusive(8, 16), clPlayer, 3), scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } } //******************************************************************************************************** else if (md == 2) //continent { var playerIDs = sortAllPlayers(); var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.45, 0.9, 0.09, 10, ix, iz); var terrainPainter = new LayeredPainter( [tWater, tShore, tGrass], // terrains [4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); if (randBool(1/4)) // peninsula { var angle = randFloat(0, TWO_PI); var fx = fractionToTiles(0.5 + 0.25*cos(angle)); var fz = fractionToTiles(0.5 + 0.25*sin(angle)); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.45, 0.9, 0.09, 10, ix, iz); var terrainPainter = new LayeredPainter( [tWater, tShore, tGrass], // terrains [4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); } var mdd1 = randIntInclusive(1,3); if (mdd1 == 1) { log("Creating islands..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23))*randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23)), 0.80, 0.1, randFloat(0.0, 0.2)); terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } else if (mdd1 == 2) { log("Creating extentions..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45))*randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], null, scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } } //******************************************************************************************************** else if (md == 3) //central sea { var playerIDs = primeSortAllPlayers(); paintRiver({ "horizontal": mdd1 != 1, "parallel": false, "position": 0.5, "width": randFloat(0.22, 0.3) + scaleByMapSize(1, 4) / 20, "fadeDist": 0.025, "deviation": 0, "waterHeight": -3, "landHeight": 3, "meanderShort": 20, "meanderLong": 0, "waterFunc": (ix, iz, height) => { placeTerrain(ix, iz, height < -1.5 ? tWater : tShore); if (height < 0) addToClass(ix, iz, clWater); }, "landFunc": (ix, iz, shoreDist1, shoreDist2) => { setHeight(ix, iz, 3.1); addToClass(ix, iz, clLand); } }); if (randBool(1/3)) { if (mdd1 == 1) //vertical { var placer = new PathPlacer(1, fractionToTiles(0.5), fractionToTiles(0.99), fractionToTiles(0.5), scaleByMapSize(randIntInclusive(16,24),randIntInclusive(100,140)), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); } else { var placer = new PathPlacer(fractionToTiles(0.5), 1, fractionToTiles(0.5), fractionToTiles(0.99), scaleByMapSize(randIntInclusive(16,24),randIntInclusive(100,140)), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); } var terrainPainter = new LayeredPainter( [tGrass, tGrass, tGrass], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3.1, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null); } var mdd2 = randIntInclusive(1,3); if (mdd2 == 1) { log("Creating islands..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23))*randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23)), 0.80, 0.1, randFloat(0.0, 0.2)); terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } else if (mdd2 == 2) { log("Creating extentions..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45))*randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], null, scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } } //******************************************************************************************************** else if (md == 4) //central river { for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var playerIDs = primeSortAllPlayers(); log("Creating the main river"); if (mdd1 == 2) var placer = new PathPlacer(fractionToTiles(0.5), 1, fractionToTiles(0.5) , fractionToTiles(0.99), scaleByMapSize(14,24), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); else var placer = new PathPlacer(1, fractionToTiles(0.5), fractionToTiles(0.99), fractionToTiles(0.5), scaleByMapSize(14,24), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter], avoidClasses(clPlayer, 4)); if (mdd1 == 1) placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, 1, fractionToTiles(0.5)); else placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5), 1); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 8)); if (mdd1 == 1) placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.99), fractionToTiles(0.5)); else placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5), fractionToTiles(0.99)); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 8)); var mdd2 = randIntInclusive(1,2); if (mdd2 == 1) { log("Creating the shallows of the main river"); for (var i = 0; i <= randIntInclusive(1, scaleByMapSize(4,8)); i++) { var cLocation = randFloat(0.15,0.85); if (mdd1 == 1) - passageMaker(fractionToTiles(cLocation), fractionToTiles(0.35), fractionToTiles(cLocation), fractionToTiles(0.65), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); + createShallowsPassage(fractionToTiles(cLocation), fractionToTiles(0.35), fractionToTiles(cLocation), fractionToTiles(0.65), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); else - passageMaker(fractionToTiles(0.35), fractionToTiles(cLocation), fractionToTiles(0.65), fractionToTiles(cLocation), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); + createShallowsPassage(fractionToTiles(0.35), fractionToTiles(cLocation), fractionToTiles(0.65), fractionToTiles(cLocation), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); } } if (randBool()) { log("Creating tributaries"); for (var i = 0; i <= randIntInclusive(8, (scaleByMapSize(12,20))); i++) { var cLocation = randFloat(0.05,0.95); var tang = randFloat(PI*0.2, PI*0.8)*((randIntInclusive(0, 1)-0.5)*2); if (tang > 0) { var cDistance = 0.05; } else { var cDistance = -0.05; } if (mdd1 == 1) var point = getTIPIADBON([fractionToTiles(cLocation), fractionToTiles(0.5 + cDistance)], [fractionToTiles(cLocation), fractionToTiles(0.5 - cDistance)], [-6, -1.5], 0.5, 4, 0.01); else var point = getTIPIADBON([fractionToTiles(0.5 + cDistance), fractionToTiles(cLocation)], [fractionToTiles(0.5 - cDistance), fractionToTiles(cLocation)], [-6, -1.5], 0.5, 4, 0.01); if (point !== undefined) { if (mdd1 == 1) var placer = new PathPlacer(floor(point[0]), floor(point[1]), floor(fractionToTiles(0.5 + 0.49*cos(tang))), floor(fractionToTiles(0.5 + 0.49*sin(tang))), scaleByMapSize(10,20), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.05); else var placer = new PathPlacer(floor(point[0]), floor(point[1]), floor(fractionToTiles(0.5 + 0.49*sin(tang))), floor(fractionToTiles(0.5 + 0.49*cos(tang))), scaleByMapSize(10,20), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.05); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); var success = createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 2, clWater, 3, clShallow, 2)); if (success !== undefined) { if (mdd1 == 1) placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); else placer = new ClumpPlacer(0.95, floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 15)); } } } } } //******************************************************************************************************** else if (md == 5) //rivers and lake { var playerIDs = sortAllPlayers(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var mdd1 = randIntInclusive(1,3); if (mdd1 < 3) //lake { var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.09 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } if (mdd1 > 1) //rivers { log ("Creating rivers..."); for (var m = 0; m < numPlayers; m++) { var tang = startAngle + (m+0.5)*TWO_PI/(numPlayers); var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5)); placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,50)*scaleByMapSize(10,50)/5), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 0); createArea(placer, [painter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5)); } var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.005, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } if (randBool(1/3) && mdd1 < 3)//island { var placer = new ClumpPlacer(mapArea * 0.006 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } } //******************************************************************************************************** else if (md == 6) //edge seas { for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var mdd1 = randIntInclusive(1,2); var playerIDs = sortAllPlayers(); var mdd2 = randIntInclusive(1,3); var fadedistance = 7; if (mdd1 == 1) { if ((mdd2 == 1)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (iz > (0.69+distance) * mapSize) { if (iz < (0.69+distance) * mapSize + fadedistance) { setHeight(ix, iz, 3 - 7 * (iz - (0.69+distance) * mapSize) / fadedistance); if (3 - 7 * (iz - (0.69+distance) * mapSize) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } for (var i = 0; i < scaleByMapSize(20,120); i++) { placer = new ClumpPlacer(scaleByMapSize(50, 70), 0.2, 0.1, 10, randFloat(0.1,0.9)*mapSize, randFloat(0.67+distance,0.74+distance)*mapSize); var terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3); createArea( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null ); } } if ((mdd2 == 2)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (iz < (0.31-distance) * mapSize) { if (iz > (0.31-distance) * mapSize - fadedistance) { setHeight(ix, iz, 3 - 7 * ((0.31-distance) * mapSize - iz) / fadedistance); if (3 - 7 * ((0.31-distance) * mapSize - iz) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } for (var i = 0; i < scaleByMapSize(20,120); i++) { placer = new ClumpPlacer(scaleByMapSize(50, 70), 0.2, 0.1, 10, randFloat(0.1,0.9)*mapSize, randFloat(0.26-distance,0.34-distance)*mapSize); var terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3); createArea( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null ); } } } else //vertical { if ((mdd2 == 1)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (ix > (0.69+distance) * mapSize) { if (ix < (0.69+distance) * mapSize + fadedistance) { setHeight(ix, iz, 3 - 7 * (ix - (0.69+distance) * mapSize) / fadedistance); if (3 - 7 * (ix - (0.69+distance) * mapSize) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } for (var i = 0; i < scaleByMapSize(20,120); i++) { placer = new ClumpPlacer(scaleByMapSize(50, 70), 0.2, 0.1, 10, randFloat(0.67+distance,0.74+distance)*mapSize, randFloat(0.1,0.9)*mapSize); var terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3); createArea( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null ); } } if ((mdd2 == 2)||(mdd2 == 3)) { var distance = randFloat(0., 0.1); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { if (ix < (0.31-distance) * mapSize) { if (ix > (0.31-distance) * mapSize - fadedistance) { setHeight(ix, iz, 3 - 7 * ((0.31-distance) * mapSize - ix) / fadedistance); if (3 - 7 * ((0.31-distance) * mapSize - ix) / fadedistance < 0.5) addToClass(ix, iz, clWater); } else { setHeight(ix, iz, -4); addToClass(ix, iz, clWater); } } } } for (var i = 0; i < scaleByMapSize(20,120); i++) { placer = new ClumpPlacer(scaleByMapSize(50, 70), 0.2, 0.1, 10, randFloat(0.26-distance,0.34-distance)*mapSize, randFloat(0.1,0.9)*mapSize); var terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3); createArea( placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null ); } } } var mdd3 = randIntInclusive(1,3); if (mdd3 == 1) { log("Creating islands..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23))*randIntInclusive(scaleByMapSize(8,15),scaleByMapSize(15,23)), 0.80, 0.1, randFloat(0.0, 0.2)); terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } else if (mdd3 == 2) { log("Creating extentions..."); placer = new ClumpPlacer(randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45))*randIntInclusive(scaleByMapSize(13,24),scaleByMapSize(24,45)), 0.80, 0.1, 10); terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clLand)], null, scaleByMapSize(2, 5)*randIntInclusive(8,14) ); } } //******************************************************************************************************** else if (md == 7) //gulf { for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } var mdd1 = randIntInclusive(1,4); var playerIDs = sortAllPlayers(); var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = 1; var placer = new ClumpPlacer(mapArea * 0.08 * lSize, 0.7, 0.05, 10, ix, iz); var terrainPainter = new LayeredPainter( [tGrass, tGrass, tGrass, tGrass], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,scaleByMapSize(15,25))); var fx = fractionToTiles(0.5 - 0.2*cos(mdd1*PI/2)); var fz = fractionToTiles(0.5 - 0.2*sin(mdd1*PI/2)); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.13 * lSize, 0.7, 0.05, 10, ix, iz); var terrainPainter = new LayeredPainter( [tGrass, tGrass, tGrass, tGrass], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,scaleByMapSize(15,25))); var fx = fractionToTiles(0.5 - 0.49*cos(mdd1*PI/2)); var fz = fractionToTiles(0.5 - 0.49*sin(mdd1*PI/2)); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.15 * lSize, 0.7, 0.05, 10, ix, iz); var terrainPainter = new LayeredPainter( [tGrass, tGrass, tGrass, tGrass], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,scaleByMapSize(15,25))); } //******************************************************************************************************** else if (md == 8) //lakes { var playerIDs = sortAllPlayers(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } log("Creating lakes..."); placer = new ClumpPlacer(scaleByMapSize(160, 700), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 5); if (randBool()) { createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 12, clWater, 8), scaleByMapSize(5, 16) ); } else { createAreas( placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 12), scaleByMapSize(5, 16) ); } } //******************************************************************************************************** else if (md == 9) //passes { var playerIDs = sortAllPlayers(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } //create ranges log ("Creating ranges..."); for (var m = 0; m < numPlayers; m++) { var tang = startAngle + (m+0.5)*TWO_PI/(numPlayers); var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 24, // elevation 3 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5)); placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,50)*scaleByMapSize(10,50)/5), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang))); var painter = new LayeredPainter([tWater, tWater], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 24, 0); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 5)); var placer = new PathPlacer(fractionToTiles(0.5 + 0.3*cos(tang) - 0.1 * cos(tang+PI/2)), fractionToTiles(0.5 + 0.3*sin(tang) - 0.1 * sin(tang+PI/2)), fractionToTiles(0.5 + 0.3*cos(tang) + 0.1 * cos(tang+PI/2)), fractionToTiles(0.5 + 0.3*sin(tang) + 0.1 * sin(tang+PI/2)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var painter = new LayeredPainter([tCliff, tCliff], [1]); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 2); createArea(placer, [painter, elevationPainter], null); } var mdd1 = randIntInclusive(1,3); if (mdd1 <= 2) { var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var placer = new ClumpPlacer(mapArea * 0.005, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 24, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } else { var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.03 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tShore, tWater, tWater, tWater], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type -4, // elevation 3 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } } //******************************************************************************************************** else if (md == 10) //lowlands { var playerIDs = sortAllPlayers(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 30); } } var radius = scaleByMapSize(18,32); var cliffRadius = 2; var elevation = 20; var hillSize = PI * radius * radius; var split = 1; if ((mapSize / 64 == 2)&&(numPlayers <= 2)) { split = 2; } else if ((mapSize / 64 == 3)&&(numPlayers <= 3)) { split = 2; } else if ((mapSize / 64 == 4)&&(numPlayers <= 4)) { split = 2; } else if ((mapSize / 64 == 5)&&(numPlayers <= 4)) { split = 2; } else if ((mapSize / 64 == 6)&&(numPlayers <= 5)) { split = 2; } else if ((mapSize / 64 == 7)&&(numPlayers <= 6)) { split = 2; } for (var i = 0; i < numPlayers*split; i++) { var tang = startAngle + (i)*TWO_PI/(numPlayers*split); var fx = fractionToTiles(0.5 + 0.35*cos(tang)); var fz = fractionToTiles(0.5 + 0.35*sin(tang)); var ix = round(fx); var iz = round(fz); // create the hill var placer = new ClumpPlacer(hillSize, 0.65, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tGrass, tGrass], // terrains [cliffRadius] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation cliffRadius // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); } var fx = fractionToTiles(0.5); var fz = fractionToTiles(0.5); ix = round(fx); iz = round(fz); var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6)))); var placer = new ClumpPlacer(mapArea * 0.091 * lSize, 0.7, 0.1, 10, ix, iz); var terrainPainter = new LayeredPainter( [tGrass, tGrass, tGrass, tGrass], // terrains [1, 4, 2] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); for (var m = 0; m < numPlayers*split; m++) { var tang = startAngle + m*TWO_PI/(numPlayers*split); var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.35*cos(tang)), fractionToTiles(0.5 + 0.35*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05); var terrainPainter = new LayeredPainter( [tGrass, tGrass, tGrass], // terrains [1, 3] // widths ); var elevationPainter = new SmoothElevationPainter( ELEVATION_SET, // type 3, // elevation 4 // blend radius ); createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null); } } //******************************************************************************************************** else //mainland { var playerIDs = sortAllPlayers(); for (var ix = 0; ix < mapSize; ix++) { for (var iz = 0; iz < mapSize; iz++) { var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); setHeight(ix, iz, 3); } } } paintTerrainBasedOnHeight(3.12, 40, 1, tCliff); paintTerrainBasedOnHeight(3, 3.12, 1, tGrass); paintTerrainBasedOnHeight(1, 3, 1, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); unPaintTileClassBasedOnHeight(0, 3.12, 1, clWater); unPaintTileClassBasedOnHeight(-6, 0, 1, clLand); paintTileClassBasedOnHeight(-6, 0, 1, clWater); paintTileClassBasedOnHeight(0, 3.12, 1, clLand); paintTileClassBasedOnHeight(3.12, 40, 1, clHill); var playerX = []; var playerZ = []; var distmin = scaleByMapSize(60,240); distmin *= distmin; for (var i = 0; i < numPlayers; i++) { var placableArea = []; for (var mx = 0; mx < mapSize; mx++) { for (var mz = 0; mz < mapSize; mz++) { if (!g_Map.validT(mx, mz, 3)) continue; var placable = true; for (var c = 0; c < i; c++) if ((playerX[c] - mx)*(playerX[c] - mx) + (playerZ[c] - mz)*(playerZ[c] - mz) < distmin) placable = false; if (!placable) continue; if (g_Map.getHeight(mx, mz) >= 3 && g_Map.getHeight(mx, mz) <= 3.12) placableArea.push([mx, mz]); } } if (!placableArea.length) { for (var mx = 0; mx < mapSize; ++mx) { for (var mz = 0; mz < mapSize; mz++) { if (!g_Map.validT(mx, mz, 3)) continue; var placable = true; for (var c = 0; c < i; c++) if ((playerX[c] - mx)*(playerX[c] - mx) + (playerZ[c] - mz)*(playerZ[c] - mz) < distmin/4) placable = false; if (!placable) continue; if (g_Map.getHeight(mx, mz) >= 3 && g_Map.getHeight(mx, mz) <= 3.12) placableArea.push([mx, mz]); } } } if (!placableArea.length) for (var mx = 0; mx < mapSize; ++mx) for (var mz = 0; mz < mapSize; ++mz) if (g_Map.getHeight(mx, mz) >= 3 && g_Map.getHeight(mx, mz) <= 3.12) placableArea.push([mx, mz]); [playerX[i], playerZ[i]] = pickRandom(placableArea); } for (var i = 0; i < numPlayers; ++i) { var id = playerIDs[i]; log("Creating units for player " + id + "..."); // get the x and z in tiles var ix = playerX[i]; var iz = playerZ[i]; var civEntities = getStartingEntities(id-1); var angle = randFloat(0, TWO_PI); for (var j = 0; j < civEntities.length; ++j) { // TODO: Make an rmlib function to get only non-structure starting entities and loop over those if (!civEntities[j].Template.startsWith("units/")) continue; var count = civEntities[j].Count || 1; var jx = ix + 2 * cos(angle); var jz = iz + 2 * sin(angle); var kAngle = randFloat(0, TWO_PI); for (var k = 0; k < count; ++k) placeObject(jx + cos(kAngle + k*TWO_PI/count), jz + sin(kAngle + k*TWO_PI/count), civEntities[j].Template, id, randFloat(0, TWO_PI)); angle += TWO_PI / 3; } if (md > 9) // maps without water, so we must have enough resources to build a cc { if (g_MapSettings.StartingResources < 500) { var loop = (g_MapSettings.StartingResources < 200) ? 2 : 1; for (let l = 0; l < loop; ++l) { var angle = randFloat(0, TWO_PI); var rad = randFloat(3, 5); var jx = ix + rad * cos(angle); var jz = iz + rad * sin(angle); placeObject(jx, jz, "gaia/special_treasure_wood", 0, randFloat(0, TWO_PI)); var angle = randFloat(0, TWO_PI); var rad = randFloat(3, 5); var jx = ix + rad * cos(angle); var jz = iz + rad * sin(angle); placeObject(jx, jz, "gaia/special_treasure_stone", 0, randFloat(0, TWO_PI)); var angle = randFloat(0, TWO_PI); var rad = randFloat(3, 5); var jx = ix + rad * cos(angle); var jz = iz + rad * sin(angle); placeObject(jx, jz, "gaia/special_treasure_metal", 0, randFloat(0, TWO_PI)); } } } else // we must have enough resources to build a dock { if (g_MapSettings.StartingResources < 200) { var angle = randFloat(0, TWO_PI); var rad = randFloat(3, 5); var jx = ix + rad * cos(angle); var jz = iz + rad * sin(angle); placeObject(jx, jz, "gaia/special_treasure_wood", 0, randFloat(0, TWO_PI)); } } } for (var i = 0; i < numPlayers; i++) { var radius = scaleByMapSize(18,32); var ix = playerX[i]; var iz = playerZ[i]; var cityRadius = radius/3; placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); createArea(placer, paintClass(clPlayer), null); } log("Creating bumps..."); placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1); var painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2); createAreas( placer, painter, [avoidClasses(clWater, 2, clPlayer, 10), stayClasses(clLand, 3)], randIntInclusive(0,scaleByMapSize(200, 400)) ); log("Creating hills..."); placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 18, 2); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], [avoidClasses(clPlayer, 15, clHill, randIntInclusive(6, 18)), stayClasses(clLand, 0)], randIntInclusive(0, scaleByMapSize(4, 8))*randIntInclusive(1, scaleByMapSize(4, 9)) ); var multiplier = sqrt(randFloat(0.5,1.2)*randFloat(0.5,1.2)); // calculate desired number of trees for map (based on size) if (currentBiome() == "savanna") { var MIN_TREES = floor(200*multiplier); var MAX_TREES = floor(1250*multiplier); var P_FOREST = randFloat(0.02, 0.05); } else if (currentBiome() == "tropic") { var MIN_TREES = floor(1000*multiplier); var MAX_TREES = floor(6000*multiplier); var P_FOREST = randFloat(0.5, 0.7); } else { var MIN_TREES = floor(500*multiplier); var MAX_TREES = floor(3000*multiplier); var P_FOREST = randFloat(0.5,0.8); } var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES); var numForest = totalTrees * P_FOREST; var numStragglers = totalTrees * (1.0 - P_FOREST); log("Creating forests..."); var types = [ [[tGrassDForest, tGrass, pForestD], [tGrassDForest, pForestD]], [[tGrassPForest, tGrass, pForestP], [tGrassPForest, pForestP]] ]; // some variation if (currentBiome() == "savanna") { var size = numForest / (0.5 * scaleByMapSize(2,8) * numPlayers); } else { var size = numForest / (scaleByMapSize(2,8) * numPlayers); } var num = floor(size / types.length); for (var i = 0; i < types.length; ++i) { placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 1); painter = new LayeredPainter( types[i], // terrains [2] // widths ); createAreas( placer, [painter, paintClass(clForest)], [avoidClasses(clPlayer, 17, clForest, randIntInclusive(5, 15), clHill, 0), stayClasses(clLand, 4)], num ); } RMS.SetProgress(50); log("Creating dirt patches..."); var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]; var numb = 1; if (currentBiome() == "savanna") numb = 3; for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); painter = new LayeredPainter( [[tGrass,tGrassA],[tGrassA,tGrassB], [tGrassB,tGrassC]], // terrains [1,1] // widths ); createAreas( placer, [painter, paintClass(clDirt)], [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 4)], numb*scaleByMapSize(15, 45) ); } log("Creating grass patches..."); var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]; for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); painter = new TerrainPainter(tGrassPatch); createAreas( placer, painter, [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 4)], numb*scaleByMapSize(15, 45) ); } RMS.SetProgress(55); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill, 1), stayClasses(clLand, 3)], randIntInclusive(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill, 1), stayClasses(clLand, 3)], randIntInclusive(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 10, clMetal, 10, clRock, 5, clHill, 1), stayClasses(clLand, 3)], randIntInclusive(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100 ); RMS.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 3)], scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 3)], scaleByMapSize(8, 131), 50 ); RMS.SetProgress(70); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 8, clHill, 1, clFood, 20), stayClasses(clLand, 2)], randIntInclusive(numPlayers+3, 5*numPlayers+4), 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 8, clHill, 1, clFood, 20), stayClasses(clLand, 2)], randIntInclusive(1, 4) * numPlayers + 2, 50 ); RMS.SetProgress(75); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oSheep, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 8, clHill, 1, clFood, 20), stayClasses(clLand, 2)], randIntInclusive(numPlayers+3, 5*numPlayers+4), 50 ); log("Creating fish..."); group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clLand, 4, clForest, 0, clPlayer, 0, clHill, 0, clFood, 20), randIntInclusive(15, 40) * numPlayers, 60 ); RMS.SetProgress(85); log("Creating straggler trees..."); var types = [oOak, oOakLarge, oPine, oApple]; // some variation var num = floor(numStragglers / types.length); for (var i = 0; i < types.length; ++i) { group = new SimpleGroup( [new SimpleObject(types[i], 1,1, 0,3)], true, clForest ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 0, clMetal, 6, clRock, 6), stayClasses(clLand, 4)], num ); } var planetm = currentBiome() == "tropic" ? 8 : 1; log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 3)], planetm * scaleByMapSize(13, 200) ); RMS.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 3)], planetm * scaleByMapSize(13, 200) ); RMS.SetProgress(95); log("Creating shallow flora..."); group = new SimpleGroup( [new SimpleObject(aLillies, 1,2, 0,2), new SimpleObject(aReeds, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, stayClasses(clShallow, 1), 60 * scaleByMapSize(13, 200), 80 ); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1), stayClasses(clLand, 3)], planetm * scaleByMapSize(13, 200), 50 ); setSkySet(pickRandom(["cirrus", "cumulus", "sunny", "sunny 1", "mountainous", "stratus"])); setSunRotation(randFloat(0, TWO_PI)); setSunElevation(randFloat(PI/ 5, PI / 3)); ExportMap();