Index: ps/trunk/binaries/data/mods/public/maps/random/aegean_sea.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/aegean_sea.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/aegean_sea.js (revision 20185) @@ -1,379 +1,358 @@ RMS.LoadLibrary("rmgen"); TILE_CENTERED_HEIGHT_MAP = true; const tCity = "medit_city_pavement"; const tCityPlaza = "medit_city_pavement"; const tHill = ["medit_grass_shrubs", "medit_rocks_grass_shrubs", "medit_rocks_shrubs", "medit_rocks_grass", "medit_shrubs"]; const tMainDirt = "medit_dirt"; const tCliff = "medit_cliff_aegean"; const tForestFloor = "medit_grass_shrubs"; const tGrass = "medit_grass_field"; const tGrassSand50 = "medit_grass_field_a"; const tGrassSand25 = "medit_grass_field_b"; const tDirt = "medit_dirt_b"; const tDirt2 = "medit_rocks_grass"; const tDirt3 = "medit_rocks_shrubs"; const tDirtCracks = "medit_dirt_c"; const tShore = "medit_sand"; const tWater = "medit_sand_wet"; const tCorals1 = "medit_sea_coral_plants"; const tCorals2 = "medit_sea_coral_deep"; const tSeaDepths = "medit_sea_depths"; const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; const oFish = "gaia/fauna_fish"; const oSheep = "gaia/fauna_sheep"; const oGoat = "gaia/fauna_goat"; const oStoneLarge = "gaia/geology_stonemine_medit_quarry"; const oStoneSmall = "gaia/geology_stone_mediterranean"; const oMetalLarge = "gaia/geology_metal_mediterranean_slabs"; const oDatePalm = "gaia/flora_tree_cretan_date_palm_short"; const oSDatePalm = "gaia/flora_tree_cretan_date_palm_tall"; const oCarob = "gaia/flora_tree_carob"; const oFanPalm = "gaia/flora_tree_medit_fan_palm"; const oPoplar = "gaia/flora_tree_poplar_lombardy"; const oCypress = "gaia/flora_tree_cypress"; const aBush1 = "actor|props/flora/bush_medit_sm.xml"; const aBush2 = "actor|props/flora/bush_medit_me.xml"; const aBush3 = "actor|props/flora/bush_medit_la.xml"; const aBush4 = "actor|props/flora/bush_medit_me.xml"; const aBushes = [aBush1, aBush2, aBush3, aBush4]; const aDecorativeRock = "actor|geology/stone_granite_med.xml"; // terrain + entity (for painting) const pForest = [tForestFloor, tForestFloor + TERRAIN_SEPARATOR + oCarob, tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERRAIN_SEPARATOR + oSDatePalm, tForestFloor]; InitMap(); const numPlayers = getNumPlayers(); const mapSize = getMapSize(); const mapArea = mapSize*mapSize; var clPlayer = 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 clGrass = createTileClass(); var clHill = createTileClass(); var clIsland = createTileClass(); var clCorals = createTileClass(); var playerIDs = primeSortAllPlayers(); var playerPos = placePlayersRiver(); var playerX = []; var playerZ = []; for (var i = 0; i < numPlayers; i++) { playerZ[i] = playerPos[i]; playerX[i] = 0.2 + 0.6*(i%2); } 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 = floor(fx); var iz = floor(fz); addToClass(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([tCityPlaza, tCity], [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 = 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(oCarob, num, num, 0,5)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); placeDefaultDecoratives(fx, fz, aBush1, clBaseResource, radius); } - RMS.SetProgress(30); -const WATER_WIDTH = 0.35; +paintRiver({ + "horizontal": false, + "parallel": false, + "position": 0.5, + "width": 0.35, + "fadeDist": 0.025, + "deviation": 0, + "waterHeight": -3, + "landHeight": 2, + "meanderShort": 20, + "meanderLong": 0, + "waterFunc": (ix, iz, height) => { -log("Creating the sea"); -var theta = randFloat(0, 1); -var theta2 = randFloat(0, 1); -var seed = randFloat(2,3); -var seed2 = randFloat(2,3); -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); - - // add the rough shape of the water - var km = 20/scaleByMapSize(35, 160); - var cu = km*rndRiver(theta+z*0.5*(mapSize/64),seed); - var cu2 = km*rndRiver(theta2+z*0.5*(mapSize/64),seed2); - - var fadeDist = 0.05; - - if ((x > cu + 0.5 - WATER_WIDTH/2) && (x < cu2 + 0.5 + WATER_WIDTH/2)) - { - var h; - if (x < (cu + 0.5 + fadeDist - WATER_WIDTH/2)) - h = 2 - 5.0 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - x)/fadeDist); - else if (x > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2)) - h = 2 - 5.0 * (1 - (x - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist); - else - h = -3.0; - - setHeight(ix, iz, h); - if (h < 0.7) - addToClass(ix, iz, clWater); - } + if (height < 0.7) + addToClass(ix, iz, clWater); } -} +}); paintTerrainBasedOnHeight(-20, 1, 0, tWater); paintTerrainBasedOnHeight(1, 2, 0, tShore); RMS.SetProgress(40); createBumps(avoidClasses(clWater, 2, clPlayer, 20)); createForests( [tForestFloor, tForestFloor, tForestFloor, pForest, pForest], avoidClasses(clPlayer, 20, clForest, 17, clWater, 2, clBaseResource, 3), clForest ); RMS.SetProgress(50); if (randBool()) createHills([tGrass, tCliff, tHill], avoidClasses(clPlayer, 20, clForest, 1, clHill, 15, clWater, 3), clHill, scaleByMapSize(3, 15)); else createMountains(tCliff, avoidClasses(clPlayer, 20, clForest, 1, clHill, 15, clWater, 3), clHill, scaleByMapSize(3, 15)); log("Creating grass patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tGrass,tGrassSand50],[tGrassSand50,tGrassSand25], [tGrassSand25,tGrass]], [1,1], avoidClasses(clForest, 0, clGrass, 2, clPlayer, 10, clWater, 2, clDirt, 2, clHill, 1) ); RMS.SetProgress(55); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [tDirt3, tDirt2,[tDirt,tMainDirt], [tDirtCracks,tMainDirt]], [1,1,1], avoidClasses(clForest, 0, clDirt, 2, clPlayer, 10, clWater, 2, clGrass, 2, clHill, 1) ); RMS.SetProgress(60); log("Creating undersea bumps..."); placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(16, 40)), 0.5); painter = new SmoothElevationPainter(ELEVATION_SET, -2.5, 3); createAreas( placer, [painter, paintClass(clCorals)], stayClasses(clWater, 6), scaleByMapSize(10, 50) ); log("Creating islands..."); placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(30, 80)), 0.5); var terrainPainter = new LayeredPainter( [tWater, tShore, tHill], // terrains [2 ,1] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 6, 4); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clIsland)], [avoidClasses(clPlayer, 8, clForest, 1, clIsland, 15), stayClasses (clWater, 6)], scaleByMapSize(1, 4) * numPlayers ); paintTerrainBasedOnHeight(-20, -3, 3, tSeaDepths); paintTerrainBasedOnHeight(-3, -2, 2, tCorals2); paintTerrainBasedOnHeight(-2, -1.5, 2, tCorals1); log("Creating island stone mines..."); createMines( [ [new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], [new SimpleObject(oStoneSmall, 2,5, 1,3)] ], stayClasses(clIsland, 4) ); log("Creating island metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], stayClasses(clIsland, 4), clMetal ); 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(clForest, 1, clPlayer, 20, clRock, 10, clWater, 1, clHill, 1) ); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clWater, 1, clHill, 1), clMetal ); RMS.SetProgress(65); createDecoration ( [[new SimpleObject(aDecorativeRock, 1,3, 0,1)], [new SimpleObject(aBush2, 1,2, 0,1), new SimpleObject(aBush1, 1,3, 0,2), new SimpleObject(aBush4, 1,2, 0,1), new SimpleObject(aBush3, 1,3, 0,2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(40, 360) ], avoidClasses(clWater, 2, clForest, 0, clPlayer, 0, clHill, 1) ); RMS.SetProgress(70); createFood ( [ [new SimpleObject(oFish, 2,3, 0,2)] ], [ 3*scaleByMapSize(5,20) ], [avoidClasses(clIsland, 2, clFood, 10), stayClasses(clWater, 5)] ); createFood ( [ [new SimpleObject(oSheep, 5,7, 0,4)], [new SimpleObject(oGoat, 2,4, 0,3)], [new SimpleObject(oDeer, 2,4, 0,2)] ], [ scaleByMapSize(5,20), scaleByMapSize(5,20), scaleByMapSize(5,20) ], avoidClasses(clForest, 0, clPlayer, 8, clWater, 1, clFood, 10, clHill, 1) ); createFood ( [ [new SimpleObject(oBerryBush, 5,7, 0,4)] ], [ 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10) ); RMS.SetProgress(90); var types = [oDatePalm, oSDatePalm, oCarob, oFanPalm, oPoplar, oCypress]; // some variation createStragglerTrees(types, avoidClasses(clForest, 1, clWater, 2, clPlayer, 12, clMetal, 6, clHill, 1)); log("Creating straggler island trees..."); g_numStragglerTrees *= 10; createStragglerTrees(types, stayClasses(clIsland, 4)); setSkySet("cumulus"); setSunColor(0.866667, 0.776471, 0.486275); setWaterColor(0, 0.501961, 1); setWaterTint(0.501961, 1, 1); setWaterWaviness(4.0); setWaterType("ocean"); setWaterMurkiness(0.49); setFogFactor(0.3); setFogThickness(0.25); setPPEffect("hdr"); setPPContrast(0.62); setPPSaturation(0.51); setPPBloom(0.12); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/danubius.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/danubius.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/danubius.js (revision 20185) @@ -1,874 +1,861 @@ RMS.LoadLibrary("rmgen"); // Spawn ships away from the shoreline, but patrol close to the shoreline const triggerPointShipSpawn = "trigger/trigger_point_A"; const triggerPointShipPatrol = "trigger/trigger_point_B"; const triggerPointShipUnloadLeft = "trigger/trigger_point_C"; const triggerPointShipUnloadRight = "trigger/trigger_point_D"; const triggerPointLandPatrolLeft = "trigger/trigger_point_E"; const triggerPointLandPatrolRight = "trigger/trigger_point_F"; const triggerPointCCAttackerPatrolLeft = "trigger/trigger_point_G"; const triggerPointCCAttackerPatrolRight = "trigger/trigger_point_H"; // Terrain textures const tRoad = "steppe_river_rocks"; const tIsland = ["temp_grass_long_b_aut", "temp_grass_plants_aut", "temp_forestfloor_aut"]; const tCliff = "temp_cliff_a"; const tForestFloor = "temp_forestfloor_aut"; const tGrass = "medit_shrubs_golden"; const tGrass2 ="grass_mediterranean_dry_1024test"; const tGrass3 = "medit_grass_field_b"; const tShore = "temp_dirt_gravel_b"; const tWater = "steppe_river_rocks_wet"; const tSeaDepths = "medit_sea_depths"; // Gaia entities const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; const oFish = "gaia/fauna_fish"; const oSheep = "gaia/fauna_sheep"; const oGoat = "gaia/fauna_goat"; const oWolf = "gaia/fauna_wolf"; const oHawk = "gaia/fauna_hawk"; const oRabbit = "gaia/fauna_rabbit"; const oBoar = "gaia/fauna_boar"; const oBear = "gaia/fauna_bear"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oStoneRuins = "gaia/special_ruins_standing_stone"; const oMetalLarge = "gaia/geology_metal_mediterranean_slabs"; const oApple = "gaia/flora_tree_apple"; const oAcacia = "gaia/flora_tree_acacia"; const oOak = "gaia/flora_tree_oak_aut"; const oOak2 = "gaia/flora_tree_oak_aut_new"; const oOak3 = "gaia/flora_tree_oak_dead"; const oOak4 = "gaia/flora_tree_oak"; const oPopolar = "gaia/flora_tree_poplar_lombardy"; const oBeech = "gaia/flora_tree_euro_beech_aut"; const oBeech2 = "gaia/flora_tree_euro_beech"; const oTreasures = [ "gaia/special_treasure_food_barrel", "gaia/special_treasure_food_bin", "gaia/special_treasure_stone", "gaia/special_treasure_wood", "gaia/special_treasure_metal" ]; const oCivicCenter = "structures/gaul_civil_centre"; const oHouse = "structures/gaul_house"; const oTemple = "structures/gaul_temple"; const oTavern = "structures/gaul_tavern"; const oTower= "structures/gaul_defense_tower"; const oOutpost = "structures/gaul_outpost"; const oHut = "other/celt_hut"; const oLongHouse = "other/celt_longhouse"; const oPalisadeTower = "other/palisades_rocks_watchtower"; const oTallSpikes = "other/palisades_tall_spikes"; const oAngleSpikes = "other/palisades_angle_spike"; const oFemale = "units/gaul_support_female_citizen"; const oHealer = "units/gaul_support_healer_b"; const oSkirmisher = "units/gaul_infantry_javelinist_b"; const oNakedFanatic = "units/gaul_champion_fanatic"; // Decorative props const aBush1 = "actor|props/flora/bush_tempe_sm.xml"; const aBush2 = "actor|props/flora/bush_tempe_me.xml"; const aBush3 = "actor|props/flora/bush_tempe_la.xml"; const aBush4 = "actor|props/flora/bush_tempe_me.xml"; const aRock1 = "actor|geology/stone_granite_med.xml"; const aRock2 = "actor|geology/stone_granite_boulder.xml"; const aRock3 = "actor|geology/stone_granite_greek_boulder.xml"; const aRock4 = "actor|geology/stonemine_alpine_a.xml"; const aFerns = "actor|props/flora/ferns.xml"; const aBucket = "actor|props/structures/celts/blacksmith_bucket"; const aBarrel = "actor|props/structures/gauls/storehouse_barrel_b"; const aTartan = "actor|props/structures/celts/tartan_a"; const aWheel = "actor|props/special/eyecandy/wheel_laying"; const aWell = "actor|props/special/eyecandy/well_1_b"; const aWoodcord = "actor|props/special/eyecandy/woodcord"; const aWaterLog = "actor|props/flora/water_log.xml"; const aCampfire = "actor|props/special/eyecandy/campfire"; const aBench = "actor|props/special/eyecandy/bench_1"; const aRug = "actor|props/special/eyecandy/rug_stand_iber"; const treeTypes = [oOak, oOak2, oOak3, oOak4, oBeech, oBeech2, oAcacia]; const pForest1 = [ tForestFloor, tForestFloor + TERRAIN_SEPARATOR + oOak, tForestFloor + TERRAIN_SEPARATOR + oOak2, tForestFloor + TERRAIN_SEPARATOR + oOak3, tForestFloor + TERRAIN_SEPARATOR + oOak4, tForestFloor ]; const pForest2 = [ tForestFloor, tForestFloor + TERRAIN_SEPARATOR + oPopolar, tForestFloor + TERRAIN_SEPARATOR + oBeech, tForestFloor + TERRAIN_SEPARATOR + oBeech2, tForestFloor + TERRAIN_SEPARATOR + oAcacia, tForestFloor ]; const smallMapSize = 192; const mediumMapSize = 256; const normalMapSize = 320; // Minimum distance from the map border to ship ungarrison points const ShorelineDistance = 15; InitMap(); const numPlayers = getNumPlayers(); const mapSize = getMapSize(); var clMiddle = createTileClass(); var clPlayer = createTileClass(); var clForest = createTileClass(); var clWater = createTileClass(); var clLand = [createTileClass(), createTileClass()]; var clLandPatrolPoint = [createTileClass(), createTileClass()]; var clCCAttackerPatrolPoint = [createTileClass(), createTileClass()]; var clShore = [createTileClass(), createTileClass()]; var clShoreUngarrisonPoint = [createTileClass(), createTileClass()]; var clShip = createTileClass(); var clShipPatrol = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clHill = createTileClass(); var clIsland = createTileClass(); var clTreasure = createTileClass(); var clWaterLog = createTileClass(); var clGauls = createTileClass(); var clTower = createTileClass(); var clOutpost = createTileClass(); var clPath = createTileClass(); var clRitualPlace = createTileClass(); // Percentage of the mapsize that the river takes up const waterWidth = 0.3; // How many treasures will be placed near the gallic civic centers var gallicCCTreasureCount = randIntInclusive(8, 12); // How many treasures will be placed randomly on the map at most var randomTreasureCount = randIntInclusive(0, 3 * numPlayers); // Place a gallic village on small maps and larger var gallicCC = mapSize >= smallMapSize; if (gallicCC) { log("Creating gallic villages..."); let gaulCityRadius = 12; let gaulCityBorderDistance = mapSize < mediumMapSize ? 10 : 18; // Whether to add a celtic ritual and a path from the gallic city leading to it let addCelticRitual = randBool(0.9); // One village left and right of the river for (let i = 0; i < 2; ++i) { let gX = i == 0 ? gaulCityBorderDistance : mapSize - gaulCityBorderDistance; let gZ = mapSize / 2; if (addCelticRitual) { // Don't position the meeting place at the center of the map let mLocation = randFloat(0.1, 0.4) * (randBool() ? 1 : -1); // Center of the meeting place let mX = i == 0 ? mapSize * waterWidth : mapSize * (1 - waterWidth); let mZ = gZ + mapSize * mLocation; // Radius of the meeting place let mRadius = scaleByMapSize(4, 6); // Create a path connecting the gallic city with a meeting place at the shoreline. // To avoid the path going through the palisade wall, start it at the gate, not at the city center. let placer = new PathPlacer( gX + gaulCityRadius * (i == 0 ? 1 : -1), gZ, mX, mZ, 4, // width 0.4, // waviness 4, // smoothness 0.2, // offset 0.05); // tapering createArea( placer, [ new LayeredPainter([tShore, tRoad, tRoad], [1, 3]), new SmoothElevationPainter(ELEVATION_SET, 5, 4), paintClass(clPath) ]); // Create the meeting place near the shoreline at the end of the path createArea( new ClumpPlacer(mRadius * mRadius * PI, 0.6, 0.3, 10, mX, mZ), [new LayeredPainter([tShore, tShore], [1]), paintClass(clPath), paintClass(clRitualPlace)], null); placeObject(mX, mZ, aCampfire, 0, randFloat(0, 2 * PI)); let femaleCount = Math.round(mRadius * 2); let maleCount = Math.round(mRadius * 3); let benchCount = Math.round(mRadius * 2); let rugCount = Math.round(mRadius * 2.5); let goatCount = Math.round(mRadius * 1.5); let femaleRadius = mRadius * 0.3; let maleRadius = mRadius * 0.4; let benchRadius = mRadius * 0.5; let rugRadius = mRadius * 0.6; let goatRadius = mRadius * 0.8; wallStyles.celt_ritual = { "female": new WallElement("female", oFemale, PI, femaleRadius, 0, 2 * PI / femaleCount), "skirmisher": new WallElement("skirmisher", oSkirmisher, PI, maleRadius, 0, 2 * PI / maleCount), "healer": new WallElement("healer", oHealer, PI, maleRadius, 0, 2 * PI / maleCount), "fanatic": new WallElement("fanatic", oNakedFanatic, PI, maleRadius, 0, 2 * PI / maleCount), "bench": new WallElement("bench", aBench, PI/2, benchRadius, 0, 2 * PI / benchCount), "rug": new WallElement("rug", aRug, 0, rugRadius, 0, 2 * PI / rugCount), "goat": new WallElement("goat", oGoat, PI, goatRadius, 0, 2 * PI / goatCount), }; placeCustomFortress(mX, mZ, new Fortress("celt ritual females", new Array(femaleCount).fill("female")), "celt_ritual", 0, 0); placeCustomFortress(mX, mZ, new Fortress("celt ritual males", new Array(maleCount).fill(0).map(i => pickRandom(["skirmisher", "healer", "fanatic"]))), "celt_ritual", 0, 0); placeCustomFortress(mX, mZ, new Fortress("celt ritual bench", new Array(benchCount).fill("bench")), "celt_ritual", 0, 0); placeCustomFortress(mX, mZ, new Fortress("celt ritual rug", new Array(rugCount).fill("rug")), "celt_ritual", 0, 0); placeCustomFortress(mX, mZ, new Fortress("celt ritual goat", new Array(goatCount).fill("goat")), "celt_ritual", 0, 0); } placeObject(gX, gZ, oCivicCenter, 0, BUILDING_ORIENTATION + PI * 3/2 * i); // Create the city patch createArea( new ClumpPlacer(gaulCityRadius * gaulCityRadius * PI, 0.6, 0.3, 10, gX, gZ), [new LayeredPainter([tShore, tShore], [1]), paintClass(clGauls)], null); // Place palisade fortress and some city buildings // Use actors to avoid players capturing the buildings wallStyles.gaul.house = new WallElement("house", oHouse, PI, 0, 4); wallStyles.gaul.hut = new WallElement("hut", oHut, PI, 0, 4); wallStyles.gaul.longhouse = new WallElement("longhouse", oLongHouse, PI, 0, 4); wallStyles.gaul.tavern = new WallElement("tavern", oTavern, PI * 3/2, 0, 4); wallStyles.gaul.temple = new WallElement("temple", oTemple, PI * 3/2, 0, 4); wallStyles.gaul.defense_tower = new WallElement("defense_tower", mapSize >= normalMapSize ? oTower : oPalisadeTower, PI/2, 0, 4); wallStyles.gaul.palisade_tower = wallStyles.palisades.tower; // Replace stone walls with palisade walls for (let template of ["gate", "wallLong", "cornerIn", "cornerOut"]) wallStyles.gaul[template] = wallStyles.palisades[template]; let wall = [ "gate", "hut", "palisade_tower", "wallLong", "wallLong", "cornerIn", "defense_tower", "wallLong", "wallLong", "temple", "palisade_tower", "wallLong", "house", "gate", "palisade_tower", "longhouse", "wallLong", "wallLong", "cornerIn", "defense_tower", "wallLong", "tavern", "wallLong", "palisade_tower"]; wall = wall.concat(wall); placeCustomFortress(gX, gZ, new Fortress("Geto-Dacian Tribal Confederation", wall), "gaul", 0, PI); // Place spikes wallStyles.palisades.tall_spikes = new WallElement("tall_spikes", oTallSpikes, PI/2, 2); wallStyles.palisades.spikeIn = new WallElement("spikeIn", oAngleSpikes, -PI/4, 2.1, 0.7, PI/2); wallStyles.palisades.spikeMid = new WallElement("spikeIn", oAngleSpikes, -PI/2, 0.7); wallStyles.palisades.gateGap = new WallElement("gateGap", undefined, PI, 3.6); let fourSpikes = new Array(4).fill("tall_spikes"); let sixSpikes = new Array(6).fill("tall_spikes"); let spikes = [ "gateGap", "spikeMid", ...fourSpikes, "spikeIn", ...sixSpikes, "spikeMid", "gateGap", "spikeMid", ...fourSpikes, "spikeIn", ...fourSpikes, "spikeMid" ]; spikes = spikes.concat(spikes); placeCustomFortress(gX, gZ, new Fortress("spikes", spikes), "palisades", 0, PI); // Place treasure, potentially inside buildings for (let i = 0; i < gallicCCTreasureCount; ++i) placeObject( gX + randFloat(-0.8, 0.8) * gaulCityRadius, gZ + randFloat(-0.8, 0.8) * gaulCityRadius, pickRandom(oTreasures), 0, randFloat(0, 2 * PI)); } } RMS.SetProgress(10); var playerIDs = primeSortAllPlayers(); var playerPos = placePlayersRiver(); var playerX = []; var playerZ = []; for (let i = 0; i < numPlayers; ++i) { playerZ[i] = playerPos[i]; playerX[i] = 0.2 + 0.6 * (i % 2); } for (let i = 0; i < numPlayers; ++i) { let id = playerIDs[i]; log("Creating base for player " + id + "..."); let radius = scaleByMapSize(15, 25); let fx = fractionToTiles(playerX[i]); let fz = fractionToTiles(playerZ[i]); let ix = Math.floor(fx); let iz = Math.floor(fz); addToClass(ix, iz, clPlayer); // Create the city patch let cityRadius = radius / 3; createArea( new ClumpPlacer(PI * cityRadius * cityRadius, 0.6, 0.3, 10, ix, iz), new LayeredPainter([tShore, tRoad], [1]), null); placeCivDefaultEntities(fx, fz, id, { 'iberWall': false }); placeDefaultChicken(fx, fz, clBaseResource); // Create berry bushes let angle = randFloat(0, 2 * PI); let dist = 10; createObjectGroup( new SimpleGroup( [new SimpleObject(oBerryBush, 5, 5, 0, 3)], true, clBaseResource, Math.round(fx + dist * Math.cos(angle)), Math.round(fz + dist * Math.sin(angle)) ), 0); // Create metal mine dist = scaleByMapSize(9, 14); angle += randFloat(PI/4, PI/3); createObjectGroup( new SimpleGroup( [new SimpleObject(oMetalLarge, 1, 1, 0, 0)], true, clBaseResource, Math.round(fx + dist * Math.cos(angle)), Math.round(fz + dist * Math.sin(angle)) ), 0); // Create stone mines angle += randFloat(PI/3, PI/2); createObjectGroup( new SimpleGroup( [new SimpleObject(oStoneLarge, 1, 1, 0, 2)], true, clBaseResource, Math.round(fx + dist * Math.cos(angle)), Math.round(fz + dist * Math.sin(angle)) ), 0); // Create starting trees let num = 20; angle += randFloat(-PI/3, PI * 4/3); dist = randFloat(10, 14); createObjectGroup( new SimpleGroup( [new SimpleObject(oOak, num, num, 0, 5)], false, clBaseResource, Math.round(fx + dist * Math.cos(angle)), Math.round(fz + dist * Math.sin(angle)) ), 0, avoidClasses(clBaseResource, 4)); placeDefaultDecoratives(fx, fz, aBush1, clBaseResource, radius); } RMS.SetProgress(20); log("Creating the river"); -var theta = randFloat(0, 0.8); -var theta2 = randFloat(0, 1.2); -var seed = randFloat(3, 5); -var seed2 = randFloat(2, 6); -var fadeDist = 0.05; +paintRiver({ + "horizontal": false, + "parallel": true, + "position": 0.5, + "width": waterWidth, + "fadeDist": 0.025, + "deviation": 0, + "waterHeight": -3, + "landHeight": 2, + "meanderShort": 30, + "meanderLong": 0, + "waterFunc": (ix, iz, height) => { -for (let ix = 0; ix < mapSize; ++ix) - for (let iz = 0; iz < mapSize; ++iz) - { - let x = ix / (mapSize + 1); - let z = iz / (mapSize + 1); - - // Add the rough shape of the water - let km = 30 / scaleByMapSize(35, 100); - let cu = km * rndRiver(theta + z * mapSize / 128, seed); - let cu2 = km * rndRiver(theta2 + z * mapSize / 128, seed2); - - if (x < cu + 0.5 - waterWidth / 2) - { - addToClass(ix, iz, clLand[0]); - continue; - } - - if (x > cu2 + 0.5 + waterWidth / 2) - { - addToClass(ix, iz, clLand[1]); - continue; - } - - let height = -3; - if (x < cu + 0.5 + fadeDist - waterWidth / 2) - height = 2 - 5 * (1 - ((cu + 0.5 + fadeDist - waterWidth / 2) - x) / fadeDist); - else if (x > (cu2 + 0.5 - fadeDist + waterWidth / 2)) - height = 2 - 5 * (1 - (x - (cu2 + 0.5 - fadeDist + waterWidth / 2)) / fadeDist); - - setHeight(ix, iz, height); if (height < 0.7) addToClass(ix, iz, clWater); // Distinguish left and right shoreline if (0 < height && height < 1 && iz > ShorelineDistance && iz < mapSize - ShorelineDistance) addToClass(ix, iz, clShore[ix < mapSize / 2 ? 0 : 1]); + }, + "landFunc": (ix, iz, shoreDist1, shoreDist2) => { + + if (shoreDist1 > 0) + addToClass(ix, iz, clLand[0]); + + if (shoreDist2 < 0) + addToClass(ix, iz, clLand[1]); } +}); + RMS.SetProgress(30); log("Creating shores..."); paintTerrainBasedOnHeight(-20, 1, 0, tWater); paintTerrainBasedOnHeight(1, 2, 0, tShore); RMS.SetProgress(35); log("Creating bumps..."); createBumps(avoidClasses(clPlayer, 6, clWater, 2, clPath, 1), scaleByMapSize(30, 300), 1, 8, 4, 0, 3); RMS.SetProgress(40); log("Creating hills..."); if (randBool()) createHills( [tCliff, tCliff, tCliff], avoidClasses(clPlayer, 18, clHill, 20, clWater, 2, clGauls, 5, clPath, 1), clHill, scaleByMapSize(3, 15)); else createMountains( tCliff, avoidClasses(clPlayer, 18, clHill, 20, clWater, 2, clGauls, 5, clPath, 1), clHill, scaleByMapSize(3, 15)); RMS.SetProgress(45); log("Creating forests..."); createForests( [tForestFloor, tForestFloor, tForestFloor, pForest1, pForest2], avoidClasses(clPlayer, 16, clForest, 17, clWater, 5, clHill, 2, clGauls, 5, clPath, 1), clForest ); RMS.SetProgress(50); log("Creating grass patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tGrass, tGrass2],[tGrass2, tGrass3], [tGrass3, tGrass]], [1, 1], avoidClasses(clForest, 0, clPlayer, 10, clWater, 2, clDirt, 2, clHill, 1, clGauls, 5, clPath, 1), scaleByMapSize(15, 45), clDirt ); RMS.SetProgress(55); log("Creating islands..."); createAreas( new ChainPlacer(Math.floor(scaleByMapSize(3, 4)), Math.floor(scaleByMapSize(4, 8)), Math.floor(scaleByMapSize(50, 80)), 0.5), [ new LayeredPainter([tWater, tShore, tIsland], [2, 1]), new SmoothElevationPainter(ELEVATION_SET, 6, 4), paintClass(clIsland) ], [avoidClasses(clIsland, 30), stayClasses (clWater, 10)], scaleByMapSize(1, 4) * numPlayers ); RMS.SetProgress(60); log("Creating island bumps..."); createBumps(stayClasses(clIsland, 2), scaleByMapSize(50, 400), 1, 8, 4, 0, 3); log("Paint seabed..."); paintTerrainBasedOnHeight(-20, -3, 3, tSeaDepths); log("Creating island metal mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal), 0, [avoidClasses(clMetal, 50, clRock, 10), stayClasses(clIsland, 5)], 500, 1 ); log("Creating island stone mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock), 0, [avoidClasses(clMetal, 10, clRock, 50), stayClasses(clIsland, 5)], 500, 1 ); RMS.SetProgress(65); log("Creating island towers..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oTower, 1, 1, 0, 4)], true, clTower), 0, [avoidClasses(clMetal, 4, clRock, 4, clTower, 20), stayClasses(clIsland, 7)], 500, 1 ); log("Creating island outposts..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oOutpost, 1, 1, 0, 4)], true, clOutpost), 0, [avoidClasses(clMetal, 4, clRock, 4, clTower, 5, clOutpost, 20), stayClasses(clIsland, 7)], 500, 1 ); log("Creating metal mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal), 0, [avoidClasses(clForest, 4, clBaseResource, 20, clMetal, 50, clRock, 20, clWater, 4, clHill, 4, clGauls, 5, clPath, 5)], 500, 1 ); log("Creating stone mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock), 0, [avoidClasses(clForest, 4, clBaseResource, 20, clMetal, 20, clRock, 50, clWater, 4, clHill, 4, clGauls, 5, clPath, 5)], 500, 1 ); log("Creating stone ruins..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oStoneRuins, 1, 1, 0, 4)], true, clRock), 0, [avoidClasses(clForest, 2, clPlayer, 12, clMetal, 6, clRock, 25, clWater, 4, clHill, 4, clGauls, 5, clPath, 1)], 500, 1 ); RMS.SetProgress(70); log("Creating decoratives..."); for (let i = 0; i < 2; ++i) createDecoration( [ [new SimpleObject(aRock1, 1, 1, 0, 1)], [new SimpleObject(aRock2, 1, 1, 0, 1)], [new SimpleObject(aRock3, 1, 1, 0, 1)], [new SimpleObject(aRock4, 1, 1, 0, 1)], [new SimpleObject(aBush1, 1, 3, 0, 2)], [new SimpleObject(aBush2, 1, 2, 0, 1)], [new SimpleObject(aBush3, 1, 3, 0, 2)], [new SimpleObject(aBush4, 1, 2, 0, 1)], [new SimpleObject(aFerns, 2, 5, 2, 4)] ], [ scaleByMapSize(5, 80), scaleByMapSize(5, 80), scaleByMapSize(5, 80), scaleByMapSize(5, 80), scaleByMapSize(5, 80), scaleByMapSize(5, 80), scaleByMapSize(5, 80), scaleByMapSize(5, 80), scaleByMapSize(20, 80) ], i == 0 ? avoidClasses(clWater, 4, clForest, 1, clPlayer, 16, clRock, 4, clMetal, 4, clHill, 4, clGauls, 5, clPath, 1) : [stayClasses(clIsland, 4) , avoidClasses(clForest, 1, clRock, 4, clMetal, 4)] ); RMS.SetProgress(75); log("Creating fish..."); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 20 * scaleByMapSize(5, 20) ], [avoidClasses(clIsland, 2, clFood, 10, clPath, 1), stayClasses(clWater, 5)], clFood ); RMS.SetProgress(80); log("Creating huntable animals..."); createFood( [ [new SimpleObject(oSheep, 5, 5, 0, 4)], [new SimpleObject(oGoat, 5, 5, 0, 4)], [new SimpleObject(oRabbit, 5, 8, 0, 4)], [new SimpleObject(oDeer, 4, 6, 0, 2)], [new SimpleObject(oHawk, 1, 1, 0, 4)] ], [ scaleByMapSize(5, 20), scaleByMapSize(5, 20), scaleByMapSize(5, 20), scaleByMapSize(5, 20), scaleByMapSize(5, 10) ], avoidClasses(clIsland, 2, clFood, 10, clWater, 5, clPlayer, 16, clHill, 2, clGauls, 5, clPath, 1), clFood ); log("Creating violent animals..."); createFood( [ [new SimpleObject(oWolf, 1, 3, 0, 4)], [new SimpleObject(oBoar, 1, 1, 0, 4)], [new SimpleObject(oBear, 1, 1, 0, 4)] ], [ scaleByMapSize(5, 20), scaleByMapSize(5, 20), scaleByMapSize(5, 20) ], avoidClasses(clIsland, 2, clFood, 10, clWater, 5, clPlayer, 24, clHill, 2, clGauls, 5, clPath, 1), clFood ); RMS.SetProgress(85); log("Creating fruits..."); createFood( [ [new SimpleObject(oApple, 3, 5, 4, 7)], [new SimpleObject(oBerryBush, 4, 6, 0, 4)] ], [ scaleByMapSize(5, 20), scaleByMapSize(5, 20) ], avoidClasses(clWater, 5, clForest, 2, clPlayer, 16, clHill, 4, clFood, 10, clMetal, 4, clRock, 4, clGauls, 5, clPath, 1), clFood ); RMS.SetProgress(90); log("Creating straggler trees..."); createStragglerTrees( treeTypes, avoidClasses(clForest, 2, clWater, 8, clPlayer, 16, clMetal, 4, clRock, 4, clFood, 1, clHill, 2, clGauls, 5, clPath, 5), clForest); log("Creating island straggler trees..."); g_numStragglerTrees *= 7; createStragglerTrees(treeTypes, [stayClasses(clIsland, 4), avoidClasses(clMetal, 4, clRock, 4, clTower, 4, clOutpost, 4)], clForest); RMS.SetProgress(95); log("Creating animals on islands..."); createFood( [ [new SimpleObject(oSheep, 4, 6, 0, 4)], [new SimpleObject(oGoat, 4, 6, 0, 4)], [new SimpleObject(oRabbit, 5, 8, 0, 4)] ], [ 10 * scaleByMapSize(5, 20), 10 * scaleByMapSize(5, 20), 10 * scaleByMapSize(5, 20) ], [avoidClasses(clRock, 4, clMetal, 4, clFood, 3, clForest, 1, clOutpost, 2, clTower, 2), stayClasses(clIsland, 4)], clFood ); RMS.SetProgress(98); log("Creating treasures..."); for (let i = 0; i < randomTreasureCount; ++i) createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(pickRandom(oTreasures), 1, 1, 0, 2)], true, clTreasure ), 0, avoidClasses(clForest, 1, clPlayer, 15, clHill, 1, clWater, 5, clFood, 1, clRock, 4, clMetal, 4, clTreasure, 10, clGauls, 5), 1, 50 ); log("Creating gallic decoratives..."); createDecoration( [ [new SimpleObject(aBucket, 1, 1, 0, 1)], [new SimpleObject(aBarrel, 1, 1, 0, 1)], [new SimpleObject(aTartan, 3, 3, 4, 4, PI/4, PI/2)], [new SimpleObject(aWheel, 2, 4, 1, 2)], [new SimpleObject(aWell, 1, 1, 0, 2)], [new SimpleObject(aWoodcord, 1, 2, 2, 2, PI/2, PI/2)] ], [ scaleByMapSize(2, 10), scaleByMapSize(2, 10), scaleByMapSize(2, 10), scaleByMapSize(2, 10), scaleByMapSize(3, 4), scaleByMapSize(2, 10) ], avoidClasses(clForest, 1, clPlayer, 10, clBaseResource, 5, clHill, 1, clFood, 1, clWater, 5, clRock, 4, clMetal, 4, clGauls, 5, clPath, 1) ); log("Creating spawn points for ships..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(triggerPointShipSpawn, 1, 1, 0, 0)], true, clShip), 0, [avoidClasses(clShip, 5, clIsland, 4), stayClasses(clWater, 10)], 10000, 1000 ); log("Creating patrol points for ships..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(triggerPointShipPatrol, 1, 1, 0, 0)], true, clShipPatrol), 0, [avoidClasses(clShipPatrol, 5, clIsland, 3), stayClasses(clWater, 4)], 10000, 1000 ); log("Creating ungarrison points for ships..."); for (let i = 0; i < 2; ++i) createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject( i == 0 ? triggerPointShipUnloadLeft : triggerPointShipUnloadRight, 1, 1, 0, 0)], true, clShoreUngarrisonPoint[i]), 0, [avoidClasses(clShoreUngarrisonPoint[i], 4), stayClasses(clShore[i], 0)], 20000, 1 ); log("Creating patrol points for land attackers..."); addToClass(mapSize/2, mapSize/2, clMiddle); for (let i = 0; i < 2; ++i) { createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject( i == 0 ? triggerPointLandPatrolLeft : triggerPointLandPatrolRight, 1, 1, 0, 0)], true, clLandPatrolPoint[i]), 0, [ avoidClasses(clWater, 5, clForest, 3, clHill, 3, clFood, 1, clRock, 5, clMetal, 5, clPlayer, 10, clGauls, 5, clLandPatrolPoint[i], 5), stayClasses(clLand[i], 0) ], 10000, 100 ); if (gallicCC) createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject( i == 0 ? triggerPointCCAttackerPatrolLeft : triggerPointCCAttackerPatrolRight, 1, 1, 0, 0)], true, clCCAttackerPatrolPoint[i]), 0, [ // Don't avoid the forest, so that as many places as possible on the border are visited avoidClasses( clWater, 5, clHill, 3, clFood, 1, clRock, 4, clMetal, 4, clPlayer, 15, clGauls, 0, clCCAttackerPatrolPoint[i], 5, clMiddle, mapSize * 0.5 - 15), stayClasses(clLand[i], 0) ], 10000, 100 ); } log("Creating water logs..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aWaterLog, 1, 1, 0, 0)], true, clWaterLog), 0, [avoidClasses(clShip, 3, clIsland, 4), stayClasses(clWater, 4)], scaleByMapSize(15, 60), 100 ); if (randBool(2/3)) { // Day setSkySet("cumulus"); setSunColor(0.9, 0.8, 0.5); setFogFactor(0.05); setFogThickness(0.25); setWaterColor(0.317, 0.396, 0.294); setWaterTint(0.439, 0.403, 0.262); setPPContrast(0.62); setPPSaturation(0.51); setPPBloom(0.12); } else { // Night setSkySet("dark"); setSunColor(0.4, 0.9, 1.2); setSunElevation(0.13499); setSunRotation(-2.5); setTerrainAmbientColor(0.25, 0.3, 0.45); setUnitsAmbientColor(0.3, 0.35, 0.5); setFogFactor(0.004); setFogThickness(0.25); setFogColor(0.35, 0.45, 0.5); setWaterColor(0.074, 0.101, 0.090); setWaterTint(0.129, 0.160, 0.137); } setPPEffect("hdr"); setWaterWaviness(2.0); setWaterType("lake"); setWaterMurkiness(0.97); setWaterHeight(21); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/english_channel.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/english_channel.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/english_channel.js (revision 20185) @@ -1,384 +1,358 @@ 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 tDirt = ["temp_plants_bog", "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 tShoreBlend = "temp_grass_plants"; 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"; // terrain + entity (for painting) const pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oBeech, tGrassDForest]; const pForestP = [tGrassPForest + TERRAIN_SEPARATOR + oOak, tGrassPForest]; -const WATER_WIDTH = 0.25; - 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 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 addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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); -log("Creating sea"); - -var theta = randFloat(0, 1); -var theta2 = randFloat(0, 1); - -var seed = randFloat(2,3); -var seed2 = randFloat(2,3); - -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); - - // add the rough shape of the water - var km = 20/scaleByMapSize(35, 160); - - var fadeDist = 0.02; - - var cu = km*rndRiver(theta+x*0.5*(mapSize/64),seed); - var cu2 = km*rndRiver(theta2+x*0.5*(mapSize/64),seed2); - - if (z > cu + 0.5 - WATER_WIDTH/2 && - z < cu2 + 0.5 + WATER_WIDTH/2) - { - var h; - if (z < (cu + 0.5 + fadeDist - WATER_WIDTH/2)) - h = 3 - 7 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - z)/fadeDist); - else if (z > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2)) - h = 3 - 7 * (1 - (z - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist); - else - h = -4.0; - - if (h < -1.5) - placeTerrain(ix, iz, tWater); - else - placeTerrain(ix, iz, tShore); - - setHeight(ix, iz, h); - } - else - setHeight(ix, iz, 3.1); +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 rivers"); 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; var point = getTIPIADBON([fractionToTiles(cLocation), fractionToTiles(0.5 + cDistance)], [fractionToTiles(cLocation), fractionToTiles(0.5 - cDistance)], [-6, -1.5], 0.5, 4, 0.01); if (point !== undefined) { 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); 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, 8, clWater, 3, clShallow, 2)); if (success !== undefined) { 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))); var painter = new LayeredPainter( [tShore, tWater, tWater], // terrains [1, 3] // widths); ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -3, 3); createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 23)); } } } passageMaker(round(fractionToTiles(0.2)), round(fractionToTiles(0.25)), round(fractionToTiles(0.8)), round(fractionToTiles(0.25)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4); passageMaker(round(fractionToTiles(0.2)), round(fractionToTiles(0.75)), round(fractionToTiles(0.8)), round(fractionToTiles(0.75)), 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); createForests( [tGrass, tGrassDForest, tGrassDForest, pForestD, pForestD], avoidClasses(clPlayer, 20, clForest, 17, clHill, 0, clWater, 6), clForest, 1.0 ); 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) ); 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) ); 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) ); 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)] ); log("Creating straggler trees..."); var types = [oBeech, oPoplar, oApple]; // some variation createStragglerTrees(types, avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 8, clMetal, 6, clRock, 6)); 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/guadalquivir_river.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/guadalquivir_river.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/guadalquivir_river.js (revision 20185) @@ -1,394 +1,345 @@ RMS.LoadLibrary("rmgen"); -const tGrass = ["medit_grass_field_a", "medit_grass_field_b"];; +const tGrass = ["medit_grass_field_a", "medit_grass_field_b"]; const tForestFloorC = "medit_plants_dirt"; const tForestFloorP = "medit_grass_shrubs"; const tCliff = ["medit_cliff_grass", "medit_cliff_greek", "medit_cliff_greek_2", "medit_cliff_aegean", "medit_cliff_italia", "medit_cliff_italia_grass"]; const tGrassA = "medit_grass_field_b"; const tGrassB = "medit_grass_field_brown"; const tGrassC = "medit_grass_field_dry"; const tHill = ["medit_rocks_grass_shrubs", "medit_rocks_shrubs"]; const tDirt = ["medit_dirt", "medit_dirt_b"]; const tRoad = "medit_city_tile"; const tRoadWild = "medit_city_tile"; const tGrassPatch = "medit_grass_shrubs"; const tShoreBlend = "medit_sand"; const tShore = "sand_grass_25"; const tWater = "medit_sand_wet"; const oPoplar = "gaia/flora_tree_poplar"; const oApple = "gaia/flora_tree_apple"; const oCarob = "gaia/flora_tree_carob"; const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; const oFish = "gaia/fauna_fish"; const oSheep = "gaia/fauna_sheep"; const oStoneLarge = "gaia/geology_stonemine_medit_quarry"; const oStoneSmall = "gaia/geology_stone_mediterranean"; const oMetalLarge = "gaia/geology_metal_mediterranean_slabs"; const aGrass = "actor|props/flora/grass_soft_large_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; const aLillies = "actor|props/flora/water_lillies.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.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; -// terrain + entity (for painting) - const pForestP = [tForestFloorP + TERRAIN_SEPARATOR + oPoplar, tForestFloorP]; const pForestC = [tForestFloorC + TERRAIN_SEPARATOR + oCarob, tForestFloorC]; InitMap(); const numPlayers = getNumPlayers(); const mapSize = getMapSize(); const mapArea = mapSize*mapSize; var clPlayer = createTileClass(); var clHill = createTileClass(); var clForest = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clSettlement = createTileClass(); var clLand = createTileClass(); -var clUpperLand = createTileClass(); var clRiver = createTileClass(); var clShallow = createTileClass(); -//Create the continent body -var fx = fractionToTiles(0.5); -var fz = fractionToTiles(0.7); -var ix = round(fx); -var iz = round(fz); - -var placer = new RectPlacer(0, floor(mapSize * 0.70), mapSize - 1, mapSize - 1); -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(clUpperLand)], null); - -var placer = new ChainPlacer(2, floor(scaleByMapSize(5, 12)), floor(scaleByMapSize(60, 700)), 1, ix, iz, 0, [floor(mapSize * 0.49)]); -var terrainPainter = new LayeredPainter( - [tGrass, tGrass, tGrass], // terrains - [4, 2] // widths -); -var elevationPainter = new SmoothElevationPainter( - ELEVATION_SET, // type - 3, // elevation - 4 // blend radius -); -createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null); +log("Create the continent body"); +createArea( + new ChainPlacer( + 2, + Math.floor(scaleByMapSize(5, 12)), + Math.floor(scaleByMapSize(60, 700)), + 1, + Math.floor(fractionToTiles(0.5)), + Math.floor(fractionToTiles(0.7)), + 0, + [Math.floor(mapSize * 0.49)]), + [ + new LayeredPainter([tGrass, tGrass, tGrass], [4, 2]), + new SmoothElevationPainter(ELEVATION_SET, 3, 4), + paintClass(clLand) + ], + null); var playerIDs = primeSortAllPlayers(); // place players var playerX = []; var playerZ = []; var playerAngle = []; var startAngle = 0; for (var i = 0; i < numPlayers; i++) { playerAngle[i] = startAngle - 0.23*(i+(i%2))*TWO_PI/numPlayers - (i%2)*PI/2; playerX[i] = 0.5 + 0.35*cos(playerAngle[i]); playerZ[i] = 0.7 + 0.35*sin(playerAngle[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 - fx = fractionToTiles(playerX[i]); - fz = fractionToTiles(playerZ[i]); - ix = round(fx); - iz = round(fz); + let fx = fractionToTiles(playerX[i]); + let fz = fractionToTiles(playerZ[i]); + let ix = Math.round(fx); + let iz = Math.round(fz); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, clPlayer); // create the city patch var cityRadius = radius/3; - placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz); + 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, { 'iberWall': false }); placeDefaultChicken(fx, fz, clBaseResource); // create berry bushes var bbAngle = randFloat(0, TWO_PI); var bbDist = 8; 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 = 10; 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(oPoplar, num, num, 0,5)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); placeDefaultDecoratives(fx, fz, aGrassShort, clBaseResource, radius); } RMS.SetProgress(20); -const WATER_WIDTH = 0.07; - -log("Creating river"); - -var theta = randFloat(0, 1); -var seed = randFloat(2,3); - -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); - - var h = 0; - var distToWater = 0; - - h = 32 * (z - 0.5); - - // add the rough shape of the water - var km = 12/scaleByMapSize(35, 160); - var cu = km*rndRiver(theta+z*0.5*(mapSize/64),seed); - var zk = z*randFloat(0.995,1.005); - var xk = x*randFloat(0.995,1.005); - if (-3.0 < getHeight(ix, iz)){ - if ((xk > cu+((1.0-WATER_WIDTH)/2))&&(xk < cu+((1.0+WATER_WIDTH)/2))) +var shallowHeight = -1.5; +paintRiver({ + "horizontal": false, + "parallel": true, + "constraint": stayClasses(clLand, 0), + "position": 0.5, + "width": 0.07, + "fadeDist": 0.025, + "deviation": 0.005, + "waterHeight": -3, + "landHeight": 2, + "meanderShort": 12, + "meanderLong": 0, + "waterFunc": (ix, iz, height) => { + addToClass(ix, iz, clRiver); + placeTerrain(ix, iz, tWater); + + let z = iz / (mapSize + 1.0); + + if (height < shallowHeight && ( + z > 0.3 && z < 0.4 || + z > 0.5 && z < 0.6 || + z > 0.7 && z < 0.8)) { - if (xk < cu+((1.05-WATER_WIDTH)/2)) - { - h = -3 + 200.0* abs(cu+((1.05-WATER_WIDTH)/2-xk)); - if ((((zk>0.3)&&(zk<0.4))||((zk>0.5)&&(zk<0.6))||((zk>0.7)&&(zk<0.8)))&&(h<-1.5)) - { - h=-1.5; - addToClass(ix, iz, clShallow); - } - - } - else if (xk > (cu+(0.95+WATER_WIDTH)/2)) - { - h = -3 + 200.0*(xk-(cu+((0.95+WATER_WIDTH)/2))); - if ((((zk>0.3)&&(zk<0.4))||((zk>0.5)&&(zk<0.6))||((zk>0.7)&&(zk<0.8)))&&(h<-1.5)) - { - h=-1.5; - addToClass(ix, iz, clShallow); - } - } - else - { - if (((zk>0.3)&&(zk<0.4))||((zk>0.5)&&(zk<0.6))||((zk>0.7)&&(zk<0.8))){ - h = -1.5; - addToClass(ix, iz, clShallow); - } - else - { - h = -3.0; - } - } - setHeight(ix, iz, h); - addToClass(ix, iz, clRiver); - placeTerrain(ix, iz, tWater); - } + setHeight(ix, iz, shallowHeight); + addToClass(ix, iz, clShallow); } } -} +}); paintTerrainBasedOnHeight(1, 3, 0, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); createBumps([avoidClasses(clPlayer, 20, clRiver, 1), stayClasses(clLand, 3)]); createForests( [tGrass, tForestFloorP, tForestFloorC, pForestC, pForestP], [avoidClasses(clPlayer, 20, clForest, 17, clHill, 0, clRiver, 1), stayClasses(clLand, 7)], clForest, 1.0); RMS.SetProgress(50); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tGrass,tGrassA],[tGrassA,tGrassB], [tGrassB,tGrassC]], [1,1], [avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 8, clRiver, 1), stayClasses(clLand, 7)] ); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tGrassPatch, [avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 8, clRiver, 1), stayClasses(clLand, 7)] ); RMS.SetProgress(55); 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(clForest, 1, clPlayer, 20, clRock, 10, clHill, 1, clRiver, 1), stayClasses(clLand, 5)] ); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], [avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1, clRiver, 1), stayClasses(clLand, 5)], clMetal ); RMS.SetProgress(65); 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(clHill, 1, clPlayer, 1, clDirt, 1, clRiver, 1), stayClasses(clLand, 6)] ); -// create water decoration in the shallow parts +log("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) ); RMS.SetProgress(70); createFood ( [ [new SimpleObject(oDeer, 5,7, 0,4)], [new SimpleObject(oSheep, 2,3, 0,2)] ], [ 3 * numPlayers, 3 * numPlayers ], [avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 20, clRiver, 1), stayClasses(clLand, 3)] ); createFood ( [ [new SimpleObject(oBerryBush, 5,7, 0,4)] ], [ randIntInclusive(1, 4) * numPlayers + 2 ], [avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 10, clRiver, 1), stayClasses(clLand, 3)] ); createFood ( [ [new SimpleObject(oFish, 2,3, 0,2)] ], [ 25 * numPlayers ], avoidClasses(clLand, 2, clRiver, 1) ); RMS.SetProgress(85); log("Creating straggler trees..."); var types = [oPoplar, oCarob, oApple]; // some variation createStragglerTrees(types, [avoidClasses(clForest, 1, clHill, 1, clPlayer, 9, clMetal, 6, clRock, 6, clRiver, 1), stayClasses(clLand, 7)]); setSkySet("cumulus"); setWaterColor(0.2,0.312,0.522); setWaterTint(0.1,0.1,0.8); setWaterWaviness(4.0); setWaterType("lake"); setWaterMurkiness(0.73); setFogFactor(0.3); setFogThickness(0.25); setPPEffect("hdr"); setPPContrast(0.62); setPPSaturation(0.51); setPPBloom(0.12); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/hyrcanian_shores.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/hyrcanian_shores.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/hyrcanian_shores.js (revision 20185) @@ -1,454 +1,442 @@ RMS.LoadLibrary("rmgen"); const tGrass = ["temp_grass_clovers"]; const tGrassPForest = "temp_plants_bog"; const tGrassDForest = "alpine_dirt_grass_50"; const tCliff = ["temp_cliff_a", "temp_cliff_b"]; const tGrassA = "temp_grass_d"; const tGrassB = "temp_grass_c"; const tGrassC = "temp_grass_clovers_2"; const tHill = ["temp_highlands", "temp_grass_long_b"]; const tDirt = ["temp_dirt_gravel", "temp_dirt_gravel_b"]; const tRoad = "temp_road"; const tRoadWild = "temp_road_overgrown"; const tGrassPatch = "temp_grass_plants"; const tShoreBlend = "temp_mud_plants"; const tShore = "medit_sand_wet"; const tWater = "medit_sand_wet"; const oPoplar = "gaia/flora_tree_poplar"; const oPalm = "gaia/flora_tree_cretan_date_palm_short"; 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"; // terrain + entity (for painting) const pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oPoplar, tGrassDForest]; const pForestP = [tGrassPForest + TERRAIN_SEPARATOR + oOak, tGrassPForest]; -const WATER_WIDTH = 0.25; - 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 clSea = createTileClass(); var clHighlands = createTileClass(); var clFlatlands = createTileClass(); var playerIDs = sortAllPlayers(); 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((i + 1) / (numPlayers + 1)); var fz = fractionToTiles(0.4 + 0.2 * (i % 2)); var ix = round(fx); var iz = round(fz); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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 = 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); -log("Creating sea and northern hills..."); -var theta = randFloat(0, 1); -var seed = randFloat(2,3); -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); - - // add the rough shape of the water - var km = 20/scaleByMapSize(35, 160); - var cu = km*rndRiver(theta+x*0.5*(mapSize/64),seed); - - var fadeDist = 0.05; - - if (z < 0.25) - addToClass(ix, iz, clHighlands); - - if (z > cu + 0.75) - { - var h; - if ((z < (cu + 0.75 + fadeDist))&&(z > (cu + 0.75))) - h = 1 - 4.0 * (1 - ((cu + 0.75 + fadeDist) - z)/fadeDist); - else - h = -3.0; - - if (h < -1.5) - placeTerrain(ix, iz, tWater); - else - placeTerrain(ix, iz, tShore); - - setHeight(ix, iz, h); - if (h < 0) - addToClass(ix, iz, clWater); - } +paintRiver({ + "horizontal": true, + "parallel": true, + "position": 1, + "width": 0.5, + "fadeDist": 0.05, + "deviation": 0, + "waterHeight": -3, + "landHeight": 1, + "meanderShort": 20, + "meanderLong": 0, + "waterFunc": (ix, iz, height) => { + + if (height < 0) + addToClass(ix, iz, clWater); + + if (height < -1.5) + placeTerrain(ix, iz, tWater); + else + placeTerrain(ix, iz, tShore); + }, + "landFunc": (ix, iz, shoreDist1, shoreDist2) => { + addToClass(ix, iz, clHighlands); } +}); + RMS.SetProgress(20); log("Creating fish..."); num = scaleByMapSize(10, 20); for (var i=0; i < num; i++){ group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [stayClasses(clWater, 2), avoidClasses(clFood, 3)], numPlayers, 50 ); } RMS.SetProgress(25); log("Creating bumps..."); placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1); painter = new SmoothElevationPainter(ELEVATION_MODIFY, 4, 3); createAreas( placer, painter, stayClasses(clHighlands, 1), scaleByMapSize(300, 600) ); RMS.SetProgress(30); log("Creating hills..."); placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1); var terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 15, 2); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clSea, 5, clPlayer, 20, clWater, 5, clHill, 15, clHighlands, 5), scaleByMapSize(1, 4) * numPlayers ); RMS.SetProgress(35); // calculate desired number of trees for map (based on size) const MIN_TREES = 500; const MAX_TREES = 2500; const P_FOREST = 0.7; var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES); var numForest = totalTrees * P_FOREST; var numStragglers = totalTrees * (1.0 - P_FOREST); log("Creating mainland forests..."); var types = [ [[tGrassDForest, tGrass, pForestD], [tGrassDForest, pForestD]] ]; // some variation var size = numForest*1.3 / (scaleByMapSize(2,8) * numPlayers); var num = floor(0.7*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, clWater, 3, clForest, 10, clHill, 0, clSea, 6, clBaseResource, 3), num ); } RMS.SetProgress(45); log("Creating highland forests..."); var types = [ [[tGrassDForest, tGrass, pForestP], [tGrassDForest, pForestP]] ]; // some variation 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, clWater, 3, clForest, 2, clHill, 0, clSea, 6, clFlatlands, 3), num ); } RMS.SetProgress(70); log("Creating dirt patches..."); var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]; 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(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 4, clSea, 0), scaleByMapSize(15, 45) ); } RMS.SetProgress(75); 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 LayeredPainter([tGrassC, tGrassPatch], [2]); createAreas( placer, painter, avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 4, clSea, 0), scaleByMapSize(15, 45) ); } RMS.SetProgress(80); 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(clWater, 0, clForest, 1, clPlayer, 20, clRock, 10, clSea, 2, clHill, 2)], 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, 20, clRock, 10, clSea, 2, clHill, 2)], 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, 20, clMetal, 10, clRock, 5, clSea, 0, clHill, 2)], scaleByMapSize(4,16), 100 ); RMS.SetProgress(85); 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, clSea, 0), scaleByMapSize(16, 262), 50 ); RMS.SetProgress(90); 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, clSea, 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, 20, clHill, 0, clFood, 5, clSea, 0, clFlatlands, 0), 6 * numPlayers, 50 ); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oGoat, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 0, clFood, 20, clSea, 0), 3 * numPlayers, 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 6, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50 ); log("Creating boar..."); group = new SimpleGroup( [new SimpleObject(oBoar, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 0, clFood, 20, clSea, 0, clFlatlands, 0), 2 * numPlayers, 50 ); log("Creating straggler trees..."); var types = [oPoplar, oPalm, 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, 10, clMetal, 6, clRock, 6, clSea, 1, clHighlands, 25), num ); } 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, clSea, 1), 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, clSea, 1), 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, 1, clHill, 1, clPlayer, 1, clDirt, 1, clSea, 1), scaleByMapSize(13, 200), 50 ); setSkySet("cirrus"); setWaterColor(0.114, 0.192, 0.463); setWaterTint(0.255, 0.361, 0.651); setWaterWaviness(2.0); setWaterType("ocean"); setWaterMurkiness(0.83); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/kerala.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/kerala.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/kerala.js (revision 20185) @@ -1,433 +1,430 @@ RMS.LoadLibrary("rmgen"); const tGrass = ["tropic_grass_c", "tropic_grass_c", "tropic_grass_c", "tropic_grass_c", "tropic_grass_plants", "tropic_plants", "tropic_plants_b"]; const tGrassA = "tropic_plants_c"; const tGrassB = "tropic_plants_c"; const tGrassC = "tropic_grass_c"; const tForestFloor = "tropic_grass_plants"; const tCliff = ["tropic_cliff_a", "tropic_cliff_a", "tropic_cliff_a", "tropic_cliff_a_plants"]; const tPlants = "tropic_plants"; const tRoad = "tropic_citytile_a"; const tRoadWild = "tropic_citytile_plants"; const tShoreBlend = "tropic_beach_dry_plants"; const tShore = "tropic_beach_dry"; const tWater = "tropic_beach_wet"; const oTree = "gaia/flora_tree_toona"; const oPalm = "gaia/flora_tree_palm_tropic"; const oStoneLarge = "gaia/geology_stonemine_tropic_quarry"; const oStoneSmall = "gaia/geology_stone_tropic_a"; const oMetalLarge = "gaia/geology_metal_tropic_slabs"; const oFish = "gaia/fauna_fish"; const oDeer = "gaia/fauna_deer"; const oSheep = "gaia/fauna_tiger"; const oBush = "gaia/flora_bush_berry"; const aRockLarge = "actor|geology/stone_granite_large.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aBush1 = "actor|props/flora/plant_tropic_a.xml"; const aBush2 = "actor|props/flora/plant_lg.xml"; const aBush3 = "actor|props/flora/plant_tropic_large.xml"; const pForestD = [tForestFloor + TERRAIN_SEPARATOR + oTree, tForestFloor]; const pForestP = [tForestFloor + TERRAIN_SEPARATOR + oPalm, tForestFloor]; InitMap(); const numPlayers = getNumPlayers(); const mapSize = getMapSize(); const mapArea = mapSize*mapSize; var clPlayer = createTileClass(); var clHill = createTileClass(); var clHill2 = createTileClass(); var clHill3 = createTileClass(); var clHill4 = 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 clMountains = createTileClass(); var playerIDs = sortAllPlayers(); 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(0.45 + 0.2 * (i % 2)); var fz = fractionToTiles((i + 1) / (numPlayers + 1)); var ix = round(fx); var iz = round(fz); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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(oBush, 5,5, 0,3)], true, clBaseResource, bbX, bbZ ); createObjectGroup(group, 0); // create metal mine var bbAngle = randFloat(0, TWO_PI); var bbDist = 12; var bbX = round(fx + bbDist * cos(bbAngle)); var bbZ = round(fz + bbDist * sin(bbAngle)); 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)); var 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 / 60); 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(oTree, num, num, 0,3)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); } RMS.SetProgress(15); -// create western sea -var fadedistance = 8; +const waterPos = 0.31; +const mountainPos = 0.69; -for (var ix = 0; ix < mapSize; ix++) -{ - for (var iz = 0; iz < mapSize; iz++) - { - if (ix < 0.31 * mapSize) - { - if (ix > 0.31 * mapSize - fadedistance) - { - setHeight(ix, iz, 3 - 8 * (0.31 * mapSize - ix) / fadedistance); - if (ix, iz, 3 - 8 * (0.31 * mapSize - ix) / fadedistance < 0.5) - addToClass(ix, iz, clWater); - } - else - { - setHeight(ix, iz, -5); - addToClass(ix, iz, clWater); - } - } - else if (ix > 0.69 * mapSize) - addToClass(ix, iz, clMountains); +paintRiver({ + "horizontal": false, + "parallel": false, + "position": 0, + "width": 2 * waterPos, + "fadeDist": 0.025, + "deviation": 0, + "waterHeight": -5, + "landHeight": 3, + "meanderShort": 20, + "meanderLong": 0, + "waterFunc": (ix, iz, height) => { + addToClass(ix, iz, clWater); + }, + "landFunc": (ix, iz, shoreDist1, shoreDist2) => { + if (ix > mountainPos * mapSize) + addToClass(ix, iz, clMountains) } -} +}); log("Creating shores..."); for (var i = 0; i < scaleByMapSize(20,120); i++) { placer = new ChainPlacer( 1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 30)), 1, randIntExclusive(0.28 * mapSize, 0.34 * mapSize), randIntExclusive(0.1 * mapSize, 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 ); } paintTerrainBasedOnHeight(-6, 1, 1, tWater); paintTerrainBasedOnHeight(1, 2.8, 1, tShoreBlend); paintTerrainBasedOnHeight(0, 1, 1, tShore); paintTileClassBasedOnHeight(-6, 0.5, 1, clWater); RMS.SetProgress(45); log("Creating hills..."); placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(16, 40)), 0.1); var terrainPainter = new LayeredPainter( [tCliff, tGrass], // terrains [3] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 25, 3); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], [avoidClasses(clPlayer, 20, clHill, 5, clWater, 2, clBaseResource, 2), stayClasses(clMountains, 0)], scaleByMapSize(5, 40) * numPlayers ); // calculate desired number of trees for map (based on size) var MIN_TREES = 1000; var MAX_TREES = 6000; var P_FOREST = 0.7; var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES); var numForest = totalTrees * P_FOREST; var numStragglers = totalTrees * (1.0 - P_FOREST); log("Creating forests..."); var types = [ [[tGrass, tGrass, tGrass, tGrass, pForestD], [tGrass, tGrass, tGrass, pForestD]], [[tGrass, tGrass, tGrass, tGrass, pForestP], [tGrass, tGrass, tGrass, pForestP]] ]; // some variation 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 * floor(scaleByMapSize(2,4))), 0.5); painter = new LayeredPainter( types[i], // terrains [2] // widths ); createAreas( placer, [painter, paintClass(clForest)], avoidClasses(clPlayer, 20, clForest, 10, clHill, 0, clWater, 8), num ); } RMS.SetProgress(70); log("Creating grass patches..."); var sizes = [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]; for (var i = 0; i < sizes.length; i++) { placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5); painter = new LayeredPainter( [tGrassC,tGrassA,tGrassB], // terrains [2,1] // widths ); createAreas( placer, [painter, paintClass(clDirt)], avoidClasses(clWater, 8, clForest, 0, clHill, 0, clPlayer, 12, clDirt, 16), scaleByMapSize(20, 80) ); } 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 LayeredPainter( [tPlants,tPlants], // terrains [1] // widths ); createAreas( placer, [painter, paintClass(clDirt)], avoidClasses(clWater, 8, clForest, 0, clHill, 0, clPlayer, 12, clDirt, 16), scaleByMapSize(20, 80) ); } 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(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 ); 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), 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), 3*scaleByMapSize(8, 131), 50 ); log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aBush1, 1,2, 0,1, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), 8 * scaleByMapSize(13, 200) ); RMS.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aBush2, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aBush1, 3,6, 1.2,2.5, -PI/8,PI/8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), 8 * scaleByMapSize(13, 200) ); RMS.SetProgress(95); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBush3, 1,2, 0,2), new SimpleObject(aBush2, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1), 8 * scaleByMapSize(13, 200), 50 ); RMS.SetProgress(95); log("Creating straggler trees..."); var types = [oTree, oPalm]; // 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, 5, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), num ); } log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); RMS.SetProgress(75); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 6, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50 ); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oSheep, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 22, clHill, 1, clFood, 20), 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 ); setSunColor(0.6, 0.6, 0.6); setSunElevation(PI/ 3); setWaterColor(0.524,0.734,0.839); setWaterTint(0.369,0.765,0.745); setWaterWaviness(1.0); setWaterType("ocean"); setWaterMurkiness(0.35); setFogFactor(0.4); setFogThickness(0.2); setPPEffect("hdr"); setPPContrast(0.7); setPPSaturation(0.65); setPPBloom(0.6); setSkySet("cirrus"); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/phoenician_levant.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/phoenician_levant.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/phoenician_levant.js (revision 20185) @@ -1,431 +1,419 @@ RMS.LoadLibrary("rmgen"); //TILE_CENTERED_HEIGHT_MAP = true; const tCity = "medit_city_pavement"; const tCityPlaza = "medit_city_pavement"; const tHill = ["medit_dirt", "medit_dirt_b", "medit_dirt_c", "medit_rocks_grass", "medit_rocks_grass"]; const tMainDirt = "medit_dirt"; const tCliff = "medit_cliff_aegean"; const tForestFloor = "medit_rocks_shrubs"; const tGrass = "medit_rocks_grass"; const tRocksShrubs = "medit_rocks_shrubs"; const tRocksGrass = "medit_rocks_grass"; const tDirt = "medit_dirt_b"; const tDirtB = "medit_dirt_c"; const tShore = "medit_sand"; const tWater = "medit_sand_wet"; const oGrapeBush = "gaia/flora_bush_grapes"; const oDeer = "gaia/fauna_deer"; const oFish = "gaia/fauna_fish"; const oSheep = "gaia/fauna_sheep"; const oGoat = "gaia/fauna_goat"; const oStoneLarge = "gaia/geology_stonemine_medit_quarry"; const oStoneSmall = "gaia/geology_stone_mediterranean"; const oMetalLarge = "gaia/geology_metal_mediterranean_slabs"; const oDatePalm = "gaia/flora_tree_cretan_date_palm_short"; const oSDatePalm = "gaia/flora_tree_cretan_date_palm_tall"; const oCarob = "gaia/flora_tree_carob"; const oFanPalm = "gaia/flora_tree_medit_fan_palm"; const oPoplar = "gaia/flora_tree_poplar_lombardy"; const oCypress = "gaia/flora_tree_cypress"; const aBush1 = "actor|props/flora/bush_medit_sm.xml"; const aBush2 = "actor|props/flora/bush_medit_me.xml"; const aBush3 = "actor|props/flora/bush_medit_la.xml"; const aBush4 = "actor|props/flora/bush_medit_me.xml"; const aBushes = [aBush1, aBush2, aBush3, aBush4]; const aDecorativeRock = "actor|geology/stone_granite_med.xml"; // terrain + entity (for painting) const pForest = [tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERRAIN_SEPARATOR + oSDatePalm, tForestFloor + TERRAIN_SEPARATOR + oCarob, tForestFloor, tForestFloor]; InitMap(); const numPlayers = getNumPlayers(); const mapSize = getMapSize(); const mapArea = mapSize*mapSize; var clPlayer = 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 clGrass = createTileClass(); var clHill = createTileClass(); var clIsland = createTileClass(); var playerIDs = sortAllPlayers(); 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(0.66 + 0.2 * (i % 2)); var fz = fractionToTiles((i + 1) / (numPlayers + 1)); var ix = floor(fx); var iz = floor(fz); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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([tCityPlaza, tCity], [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(oGrapeBush, 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(oCarob, num, num, 0,5)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); placeDefaultDecoratives(fx, fz, aBush1, clBaseResource, radius); } RMS.SetProgress(30); -log("Creating sea"); - -var theta = randFloat(0, 1); -var seed = randFloat(2,3); -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); - - // add the rough shape of the water - var km = 20/scaleByMapSize(35, 160); - var cu = km*rndRiver(theta+z*0.5*(mapSize/64),seed); - - var fadeDist = 0.05; - - if (x < cu + 0.5) - { - var h; - if (x < (cu + 0.5 + fadeDist)) - h = 1 + 4.0 * (1 - ((cu + 0.5 + fadeDist) - x)/fadeDist); - else - h = -3.0; - - if (h < -1.5) - placeTerrain(ix, iz, tWater); - else - placeTerrain(ix, iz, tShore); - - setHeight(ix, iz, h); - if (h < 0) - addToClass(ix, iz, clWater); - } +paintRiver({ + "horizontal": false, + "parallel": true, + "position": 0, + "width": 1, + "fadeDist": 0.05, + "deviation": 0, + "waterHeight": -3, + "landHeight": 1, + "meanderShort": 20, + "meanderLong": 0, + "waterFunc": (ix, iz, height) => { + + if (height < 0) + addToClass(ix, iz, clWater); + + if (height < -1.5) + placeTerrain(ix, iz, tWater); + else + placeTerrain(ix, iz, tShore); } +}); RMS.SetProgress(40); 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, 20), scaleByMapSize(100, 200) ); log("Creating hills..."); placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(16, 40)), 0.5); var terrainPainter = new LayeredPainter( [tCliff, tHill], // terrains [2] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 15, 2); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 20, clForest, 1, clHill, 15, clWater, 0), scaleByMapSize(1, 4) * numPlayers * 3 ); // calculate desired number of trees for map (based on size) const MIN_TREES = 500; const MAX_TREES = 2500; const P_FOREST = 0.5; var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES); var numForest = totalTrees * P_FOREST; var numStragglers = totalTrees * (1.0 - P_FOREST); log("Creating forests..."); var num = scaleByMapSize(10,42); placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), numForest / (num * floor(scaleByMapSize(2,5))), 0.5); painter = new TerrainPainter([tForestFloor, pForest]); createAreas(placer, [painter, paintClass(clForest)], avoidClasses(clPlayer, 20, clForest, 10, clWater, 1, clHill, 1, clBaseResource, 3), num, 50 ); RMS.SetProgress(50); log("Creating grass patches..."); var sizes = [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]; for (var i = 0; i < sizes.length; i++) { placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5); painter = new LayeredPainter( [[tGrass,tRocksShrubs],[tRocksShrubs,tRocksGrass], [tRocksGrass,tGrass]], // terrains [1,1] // widths ); createAreas( placer, [painter, paintClass(clDirt)], avoidClasses(clForest, 0, clGrass, 5, clPlayer, 10, clWater, 4, clDirt, 5, clHill, 1), scaleByMapSize(15, 45) ); } RMS.SetProgress(55); log("Creating dirt patches..."); var sizes = [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]; for (var i = 0; i < sizes.length; i++) { placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5); painter = new LayeredPainter( [[tDirt,tDirtB],[tDirt,tMainDirt], [tDirtB,tMainDirt]], // terrains [1,1] // widths ); createAreas( placer, [painter, paintClass(clDirt)], avoidClasses(clForest, 0, clDirt, 5, clPlayer, 10, clWater, 4, clGrass, 5, clHill, 1), scaleByMapSize(15, 45) ); } RMS.SetProgress(60); log("Creating cyprus..."); placer = new ClumpPlacer(4.5 * scaleByMapSize(60, 540), 0.2, 0.1, 0.01); var terrainPainter = new LayeredPainter( [tShore, tHill], // terrains [12] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 6, 8); createAreas( placer, [terrainPainter, elevationPainter, paintClass(clIsland)], [stayClasses (clWater, 5)], 1 ); log("Creating cyprus stone mines..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock); createObjectGroupsDeprecated(group, 0, stayClasses(clIsland, 9), 14 * scaleByMapSize(4,16), 100 ); log("Creating cyprus small stone mines..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, stayClasses(clIsland, 9), 14 * scaleByMapSize(4,16), 100 ); log("Creating cyprus metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroupsDeprecated(group, 0, stayClasses(clIsland, 9), 14 * scaleByMapSize(4,16), 100 ); 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, clWater, 3, 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(clForest, 1, clPlayer, 20, clRock, 10, clWater, 3, 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(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clWater, 3, clHill, 1), scaleByMapSize(4,16), 100 ); RMS.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aDecorativeRock, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 1, clForest, 0, clPlayer, 0, clHill, 1), scaleByMapSize(16, 262), 50 ); log("Creating shrubs..."); group = new SimpleGroup( [new SimpleObject(aBush2, 1,2, 0,1), new SimpleObject(aBush1, 1,3, 0,2), new SimpleObject(aBush4, 1,2, 0,1), new SimpleObject(aBush3, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 3, clPlayer, 0, clHill, 1), scaleByMapSize(40, 360), 50 ); RMS.SetProgress(70); log("Creating fish..."); group = new SimpleGroup([new SimpleObject(oFish, 1,3, 2,6)], true, clFood); createObjectGroupsDeprecated(group, 0, [avoidClasses(clIsland, 2, clFood, 10), stayClasses(clWater, 5)], 3*scaleByMapSize(5,20), 50 ); log("Creating sheeps..."); group = new SimpleGroup([new SimpleObject(oSheep, 5,7, 0,4)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 7, clWater, 3, clFood, 10, clHill, 1), scaleByMapSize(5,20), 50 ); log("Creating goats..."); group = new SimpleGroup([new SimpleObject(oGoat, 2,4, 0,3)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 7, clWater, 3, clFood, 10, clHill, 1), scaleByMapSize(5,20), 50 ); log("Creating deers..."); group = new SimpleGroup([new SimpleObject(oDeer, 2,4, 0,2)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 7, clWater, 3, clFood, 10, clHill, 1), scaleByMapSize(5,20), 50 ); log("Creating grape bushes..."); group = new SimpleGroup( [new SimpleObject(oGrapeBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 15, clHill, 1, clFood, 7), randIntInclusive(1, 4) * numPlayers + 2, 50 ); RMS.SetProgress(90); log("Creating straggler trees..."); var types = [oDatePalm, oSDatePalm, oCarob, oFanPalm, oPoplar, oCypress]; // 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,0)], true); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clWater, 1, clPlayer, 8, clMetal, 6, clHill, 1), num ); } log("Creating straggler trees..."); var types = [oDatePalm, oSDatePalm, oCarob, oFanPalm, oPoplar, oCypress]; // some variation var num = 3*floor(numStragglers / types.length); for (var i = 0; i < types.length; ++i) { group = new SimpleGroup([new SimpleObject(types[i], 1,1, 0,0)], true); createObjectGroupsDeprecated(group, 0, stayClasses(clIsland, 9), num ); } setSkySet("sunny"); setSunColor(0.917, 0.828, 0.734); setWaterColor(0.263,0.314,0.631); setWaterTint(0.133, 0.725,0.855); setWaterWaviness(2.0); setWaterType("ocean"); setWaterMurkiness(0.8); setTerrainAmbientColor(0.57, 0.58, 0.55); setUnitsAmbientColor(0.447059, 0.509804, 0.54902); setSunElevation(0.671884); setSunRotation(-0.582913); setFogFactor(0.2); setFogThickness(0.15); setFogColor(0.8, 0.7, 0.6); setPPEffect("hdr"); setPPContrast(0.53); setPPSaturation(0.47); setPPBloom(0.52); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/rmgen/misc.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/rmgen/misc.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/rmgen/misc.js (revision 20185) @@ -1,881 +1,960 @@ ///////////////////////////////////////////////////////////////////////////////////////// // 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); } } ///////////////////////////////////////////////////////////////////////////////////////// // paintTerrainBasedOnHeight // // paints the tiles which have a height between minheight and maxheight with the given terrain // minheight: minimum height of the tile // maxheight: maximum height of the tile // mode: accepts 4 values. 0 means the it will select tiles with height more than minheight and less than maxheight. // 1 means it selects tiles with height more than or equal to minheight and less than max height. 2 means more than // minheight and less than or equal to maxheight. 3 means more than or equal to minheight and less than or equal to maxheight // terrain: intended terrain texture // /////////////////////////////////////////////////////////////////////////////////////////// function paintTerrainBasedOnHeight(minheight, maxheight, mode, terrain) { var mSize = g_Map.size; for (var qx = 0; qx < mSize; qx++) { for (var qz = 0; qz < mSize; qz++) { if (mode == 0) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { placeTerrain(qx, qz, terrain); } } else if (mode == 1) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { placeTerrain(qx, qz, terrain); } } else if (mode == 2) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { placeTerrain(qx, qz, terrain); } } else if (mode == 3) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { placeTerrain(qx, qz, terrain); } } } } } ///////////////////////////////////////////////////////////////////////////////////////// // paintTileClassBasedOnHeight and unPaintTileClassBasedOnHeight // // paints or unpaints the tiles which have a height between minheight and maxheight with the given tile class // minheight: minimum height of the tile // maxheight: maximum height of the tile // mode: accepts 4 values. 0 means the it will select tiles with height more than minheight and less than maxheight. // 1 means it selects tiles with height more than or equal to minheight and less than max height. 2 means more than // minheight and less than or equal to maxheight. 3 means more than or equal to minheight and less than or equal to maxheight // tileclass: intended tile class // /////////////////////////////////////////////////////////////////////////////////////////// function paintTileClassBasedOnHeight(minheight, maxheight, mode, tileclass) { var mSize = g_Map.size; for (var qx = 0; qx < mSize; qx++) { for (var qz = 0; qz < mSize; qz++) { if (mode == 0) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { addToClass(qx, qz, tileclass); } } else if (mode == 1) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { addToClass(qx, qz, tileclass); } } else if (mode == 2) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { addToClass(qx, qz, tileclass); } } else if (mode == 3) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { addToClass(qx, qz, tileclass); } } } } } function unPaintTileClassBasedOnHeight(minheight, maxheight, mode, tileclass) { var mSize = g_Map.size; for (var qx = 0; qx < mSize; qx++) { for (var qz = 0; qz < mSize; qz++) { if (mode == 0) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { removeFromClass(qx, qz, tileclass); } } else if (mode == 1) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) < maxheight)) { removeFromClass(qx, qz, tileclass); } } else if (mode == 2) { if ((g_Map.getHeight(qx, qz) > minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { removeFromClass(qx, qz, tileclass); } } else if (mode == 3) { if ((g_Map.getHeight(qx, qz) >= minheight)&&(g_Map.getHeight(qx, qz) <= maxheight)) { 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; } ///////////////////////////////////////////////////////////////////////////////////////// // doIntersect // // determines if two lines with the width "width" intersect or collide with each other // x1, y1, x2, y2: determine the position of the first line // x3, y3, x4, y4: determine the position of the second line // width: determines the width of the lines // /////////////////////////////////////////////////////////////////////////////////////////// function checkIfIntersect (x1, y1, x2, y2, x3, y3, x4, y4, width) { if (x1 == x2) { if (((x3 - x1) < width) || ((x4 - x2) < width)) return true; } else { var m = (y1 - y2) / (x1 - x2); var b = y1 - m * x1; var m2 = sqrt(m * m + 1); if ((Math.abs((y3 - x3 * m - b)/m2) < width) || (Math.abs((y4 - x4 * m - b)/m2) < width)) return true; //neccessary for some situations. if (x3 == x4) { if (((x1 - x3) < width) || ((x2 - x4) < width)) return true; } else { var m = (y3 - y4) / (x3 - x4); var b = y3 - m * x3; var m2 = sqrt(m * m + 1); if ((Math.abs((y1 - x1 * m - b)/m2) < width) || (Math.abs((y2 - x2 * m - b)/m2) < width)) return true; } } var s = ((x1 - x2) * (y3 - y1) - (y1 - y2) * (x3 - x1)), p = ((x1 - x2) * (y4 - y1) - (y1 - y2) * (x4 - x1)); if ((s * p) <= 0) { s = ((x3 - x4) * (y1 - y3) - (y3 - y4) * (x1 - x3)); p = ((x3 - x4) * (y2 - y3) - (y3 - y4) * (x2 - x3)); if ((s * p) <= 0) return true; } return false; } ///////////////////////////////////////////////////////////////////////////////////////// // distanceOfPointFromLine // // returns the distance of a point from a line // x1, y1, x2, y2: determine the position of the line // x3, y3: determine the position of the point // /////////////////////////////////////////////////////////////////////////////////////////// function distanceOfPointFromLine (x1, y1, x2, y2, x3, y3) { if (x1 == x2) { return Math.abs(x3 - x1); } else if (y1 == y2) { return Math.abs(y3 - y1); } else { var m = (y1 - y2) / (x1 - x2); var b = y1 - m * x1; var m2 = sqrt(m * m + 1); return Math.abs((y3 - x3 * m - b)/m2); } } ///////////////////////////////////////////////////////////////////////////////////////// // 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 = mapArea / 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/the_nile.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/the_nile.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/the_nile.js (revision 20185) @@ -1,523 +1,504 @@ RMS.LoadLibrary("rmgen"); var tCity = "desert_city_tile"; var tCityPlaza = "desert_city_tile_plaza"; var tSand = ["desert_dirt_rough", "desert_dirt_rough_2", "desert_sand_dunes_50", "desert_sand_smooth"]; var tDunes = "desert_sand_dunes_100"; var tFineSand = "desert_sand_smooth"; var tCliff = ["desert_cliff_badlands", "desert_cliff_badlands_2"]; var tForestFloor = "desert_forestfloor_palms"; var tGrass = "desert_dirt_rough_2"; var tGrassSand50 = "desert_sand_dunes_50"; var tGrassSand25 = "desert_dirt_rough"; var tDirt = "desert_dirt_rough"; var tDirtCracks = "desert_dirt_cracks"; var tShore = "desert_sand_wet"; var tLush = "desert_grass_a"; var tSLush = "desert_grass_a_sand"; var tSDry = "desert_plants_b"; var oBerryBush = "gaia/flora_bush_berry"; var oCamel = "gaia/fauna_camel"; var oFish = "gaia/fauna_fish"; var oGazelle = "gaia/fauna_gazelle"; var oGiraffe = "gaia/fauna_giraffe"; var oGoat = "gaia/fauna_goat"; var oWildebeest = "gaia/fauna_wildebeest"; var oStoneLarge = "gaia/geology_stonemine_desert_badlands_quarry"; var oStoneSmall = "gaia/geology_stone_desert_small"; var oMetalLarge = "gaia/geology_metal_desert_slabs"; var oDatePalm = "gaia/flora_tree_date_palm"; var oSDatePalm = "gaia/flora_tree_cretan_date_palm_short"; var eObelisk = "other/obelisk"; var ePyramid = "other/pyramid_minor"; var oWood = "gaia/special_treasure_wood"; var oFood = "gaia/special_treasure_food_bin"; var aBush1 = "actor|props/flora/bush_desert_a.xml"; var aBush2 = "actor|props/flora/bush_desert_dry_a.xml"; var aBush3 = "actor|props/flora/bush_medit_sm_dry.xml"; var aBush4 = "actor|props/flora/plant_desert_a.xml"; var aBushes = [aBush1, aBush2, aBush3, aBush4]; var aDecorativeRock = "actor|geology/stone_desert_med.xml"; var aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; var aLillies = "actor|props/flora/water_lillies.xml"; // terrain + entity (for painting) var pForest = [tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERRAIN_SEPARATOR + oSDatePalm, tForestFloor]; var pForestOasis = [tGrass + TERRAIN_SEPARATOR + oDatePalm, tGrass + TERRAIN_SEPARATOR + oSDatePalm, tGrass]; InitMap(); var mapSize = getMapSize(); var aPlants = mapSize < 256 ? "actor|props/flora/grass_tropical.xml" : "actor|props/flora/grass_tropic_field_tall.xml"; var numPlayers = getNumPlayers(); var mapArea = mapSize*mapSize; var clPlayer = 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 clGrass = createTileClass(); var clDesert = createTileClass(); var clPond = createTileClass(); var clShore = createTileClass(); var clTreasure = createTileClass(); var playerIDs = primeSortAllPlayers(); var playerPos = placePlayersRiver(); var playerX = []; var playerZ = []; for (var i = 0; i < numPlayers; i++) { playerZ[i] = playerPos[i]; playerX[i] = 0.30 + 0.4*(i%2); } 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 = floor(fx); var iz = floor(fz); addToClass(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([tCityPlaza, tCity], [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 = radius - 4; 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(oDatePalm, num, num, 0,5)], false, clBaseResource, tX, tZ ); createObjectGroup(group, 0, avoidClasses(clBaseResource,2)); placeDefaultDecoratives(fx, fz, aBush1, clBaseResource, radius); } RMS.SetProgress(30); -const WATER_WIDTH = 0.1; - -log("Creating river"); -var theta = randFloat(0, 1); -var seed = randFloat(2,3); -var theta2 = randFloat(0, 1); -var seed2 = randFloat(2,3); -var rifp = 0; -var rifp2 = 0; - -for (var ix = 0; ix < mapSize; ix++) - for (var iz = 0; iz < mapSize; iz++) +const riverTextures = [ { - var x = ix / (mapSize + 1.0); - var z = iz / (mapSize + 1.0); - - var h = 0; - var distToWater = 0; + "left": 0, + "right": 0.04, + "tileClass": tLush + }, + { + "left": 0.04, + "right": 0.06, + "tileClass": tSLush + }, + { + "left": 0.06, + "right": 0.09, + "tileClass": tSDry + } +]; - h = 32 * (z - 0.5); - if ((x < 0.25)||(x > 0.75)) - addToClass(ix, iz, clDesert); +const plantFrequency = 2; - // add the rough shape of the water - var km = 12/scaleByMapSize(35, 160); - var cu = km*rndRiver(theta+z*0.5*(mapSize/64),seed)+(50/scaleByMapSize(35, 100))*rndRiver(theta2+z*0.5*(mapSize/128),seed2); - var zk = z*randFloat(0.995,1.005); - var xk = x*randFloat(0.995,1.005); +var plantID = 0; - if (-3.0 >= getHeight(ix, iz)) - continue; +paintRiver({ + "horizontal": false, + "parallel": true, + "position": 0.5, + "width": 0.1, + "fadeDist": 0.025, + "deviation": 0.005, + "waterHeight": -3, + "landHeight": 2, + "meanderShort": 12, + "meanderLong": 50, + "waterFunc": (ix, iz, height) => { + + addToClass(ix, iz, clWater); + placeTerrain(ix, iz, tShore); + + // Place river bushes + if (height <= -0.2 || height >= 0.1) + return; - if ((xk > cu+((1.0-WATER_WIDTH)/2))&&(xk < cu+((1.0+WATER_WIDTH)/2))) + if (plantID % plantFrequency == 0) { - if (xk < cu+((1.05-WATER_WIDTH)/2)) - { - h = -3 + 200.0* abs(cu+((1.05-WATER_WIDTH)/2-xk)); - if ((h < 0.1)&&(h>-0.2)) - { - if (rifp%2 == 0) - { - rifp = 0; - placeObject(ix, iz, aPlants, 0, randFloat(0,TWO_PI)); - } - ++rifp; - } - } - else if (xk > (cu+(0.95+WATER_WIDTH)/2)) - { - h = -3 + 200.0*(xk-(cu+((0.95+WATER_WIDTH)/2))); - if ((h < 0.1)&&(h>-0.2)) - { - if (rifp2%2 == 0) - { - rifp2 = 0; - placeObject(ix, iz, aPlants, 0, randFloat(0,TWO_PI)); - } - ++rifp2; - } - } - else - h = -3.0; - - setHeight(ix, iz, h); - addToClass(ix, iz, clWater); - placeTerrain(ix, iz, tShore); + plantID = 0; + placeObject(ix, iz, aPlants, 0, randFloat(0, TWO_PI)); } + ++plantID; + }, + "landFunc": (ix, iz, shoreDist1, shoreDist2) => { - if (((xk > cu+((1.0-WATER_WIDTH)/2)-0.04)&&(xk < cu+((1.0-WATER_WIDTH)/2)))||((xk > cu+((1.0+WATER_WIDTH)/2))&&(xk < cu+((1.0+WATER_WIDTH)/2) + 0.04))) - { - placeTerrain(ix, iz, tLush); - addToClass(ix, iz, clShore); - } - else if (((xk > cu+((1.0-WATER_WIDTH)/2)-0.06)&&(xk < cu+((1.0-WATER_WIDTH)/2)-0.04))||((xk > cu+((1.0+WATER_WIDTH)/2)+0.04)&&(xk < cu+((1.0+WATER_WIDTH)/2) + 0.06))) - { - placeTerrain(ix, iz, tSLush); - addToClass(ix, iz, clShore); - } - else if (((xk > cu+((1.0-WATER_WIDTH)/2)-0.09)&&(xk < cu+((1.0-WATER_WIDTH)/2)-0.06))||((xk > cu+((1.0+WATER_WIDTH)/2)+0.06)&&(xk < cu+((1.0+WATER_WIDTH)/2) + 0.09))) - { - placeTerrain(ix, iz, tSDry); - addToClass(ix, iz, clShore); - } + let x = ix / (mapSize + 1.0); + if (x < 0.25 || x > 0.75) + addToClass(ix, iz, clDesert); + + for (let riv of riverTextures) + if (-shoreDist1 > -riv.right && -shoreDist1 < -riv.left || + -shoreDist2 > riv.left && -shoreDist2 < riv.right) + { + placeTerrain(ix, iz, riv.tileClass); + addToClass(ix, iz, clShore); + } } +}); + RMS.SetProgress(40); 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, 6), scaleByMapSize(100, 200) ); log("Creating ponds..."); var numLakes = round(scaleByMapSize(1,4) * numPlayers / 2); placer = new ClumpPlacer(scaleByMapSize(100,250), 0.8, 0.1, 10); var terrainPainter = new LayeredPainter( [tShore, tShore, tShore], // terrains [1,1] // widths ); var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -7, 4); var waterAreas = createAreas( placer, [terrainPainter, elevationPainter, paintClass(clPond)], avoidClasses(clPlayer, 25, clWater, 20, clPond, 10), numLakes ); log("Creating reeds..."); group = new SimpleGroup( [new SimpleObject(aReeds, 1,3, 0,1)], true ); createObjectGroupsByAreasDeprecated(group, 0, stayClasses(clPond, 1), numLakes, 100, waterAreas ); log("Creating lillies..."); group = new SimpleGroup( [new SimpleObject(aLillies, 1,3, 0,1)], true ); createObjectGroupsByAreasDeprecated(group, 0, stayClasses(clPond, 1), numLakes, 100, waterAreas ); waterAreas = []; // calculate desired number of trees for map (based on size) const MIN_TREES = 700; const MAX_TREES = 3500; const P_FOREST = 0.5; var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES); var numForest = totalTrees * P_FOREST; var numStragglers = totalTrees * (1.0 - P_FOREST); log("Creating forests..."); var num = scaleByMapSize(10,30); placer = new ClumpPlacer(numForest / num, 0.15, 0.1, 0.5); painter = new TerrainPainter([pForest, tForestFloor]); createAreas(placer, [painter, paintClass(clForest)], avoidClasses(clPlayer, 19, clForest, 4, clWater, 1, clDesert, 5, clPond, 2, clBaseResource, 3), num, 50 ); RMS.SetProgress(50); log("Creating grass patches..."); var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]; for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); painter = new LayeredPainter( [[tGrass,tGrassSand50],[tGrassSand50,tGrassSand25], [tGrassSand25,tGrass]], // terrains [1,1] // widths ); createAreas( placer, [painter, paintClass(clDirt)], avoidClasses(clForest, 0, clGrass, 5, clPlayer, 10, clWater, 1, clDirt, 5, clShore, 1, clPond, 1), scaleByMapSize(15, 45) ); } RMS.SetProgress(55); log("Creating dirt patches..."); var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]; for (var i = 0; i < sizes.length; i++) { placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5); painter = new LayeredPainter( [[tDirt,tDirtCracks],[tDirt,tFineSand], [tDirtCracks,tFineSand]], // terrains [1,1] // widths ); createAreas( placer, [painter, paintClass(clDirt)], avoidClasses(clForest, 0, clDirt, 5, clPlayer, 10, clWater, 1, clGrass, 5, clShore, 1, clPond, 1), scaleByMapSize(15, 45) ); } RMS.SetProgress(60); 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, clWater, 1, clPond, 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(clForest, 1, clPlayer, 20, clRock, 10, clWater, 1, clPond, 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(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clWater, 1, clPond, 1), scaleByMapSize(4,16), 100 ); 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, clWater, 1, clPond, 1), stayClasses(clDesert, 3)], scaleByMapSize(6,20), 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, clWater, 1, clPond, 1), stayClasses(clDesert, 3)], scaleByMapSize(6,20), 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, clWater, 1, clPond, 1), stayClasses(clDesert, 3)], scaleByMapSize(6,20), 100 ); RMS.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aDecorativeRock, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 1, clForest, 0, clPlayer, 0, clPond, 1), scaleByMapSize(16, 262), 50 ); log("Creating shrubs..."); group = new SimpleGroup( [new SimpleObject(aBush2, 1,2, 0,1), new SimpleObject(aBush1, 1,3, 0,2), new SimpleObject(aBush4, 1,2, 0,1), new SimpleObject(aBush3, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 1, clPlayer, 0, clPond, 1), scaleByMapSize(20, 180), 50 ); RMS.SetProgress(70); log("Creating gazelles..."); group = new SimpleGroup([new SimpleObject(oGazelle, 5,7, 0,4)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 20, clWater, 1, clFood, 10, clDesert, 5, clPond, 1), 3*scaleByMapSize(5,20), 50 ); log("Creating goats..."); group = new SimpleGroup([new SimpleObject(oGoat, 2,4, 0,3)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 20, clWater, 1, clFood, 10, clDesert, 5, clPond, 1), 3*scaleByMapSize(5,20), 50 ); log("Creating treasures..."); group = new SimpleGroup([new SimpleObject(oFood, 1,1, 0,2)], true, clTreasure); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 20, clWater, 1, clFood, 2, clDesert, 5, clTreasure, 6, clPond, 1), 3*scaleByMapSize(5,20), 50 ); group = new SimpleGroup([new SimpleObject(oWood, 1,1, 0,2)], true, clTreasure); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 20, clWater, 1, clFood, 2, clDesert, 5, clTreasure, 6, clPond, 1), 3*scaleByMapSize(5,20), 50 ); log("Creating camels..."); group = new SimpleGroup([new SimpleObject(oCamel, 2,4, 0,2)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 20, clWater, 1, clFood, 10, clDesert, 5, clTreasure, 2, clPond, 1), 3*scaleByMapSize(5,20), 50 ); RMS.SetProgress(90); log("Creating straggler trees..."); var types = [oDatePalm, oSDatePalm]; // some variation var num = floor(0.5 * numStragglers / types.length); for (var i = 0; i < types.length; ++i) { group = new SimpleGroup([new SimpleObject(types[i], 1,1, 0,0)], true); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clWater, 1, clPlayer, 20, clMetal, 6, clDesert, 1, clTreasure, 2, clPond, 1), num ); } var types = [oDatePalm, oSDatePalm]; // some variation var num = floor(0.1 * numStragglers / types.length); for (var i = 0; i < types.length; ++i) { group = new SimpleGroup([new SimpleObject(types[i], 1,1, 0,0)], true); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clWater, 1, clPlayer, 20, clMetal, 6, clTreasure, 2), num ); } log("Creating straggler trees..."); var types = [oDatePalm, oSDatePalm]; // 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,0)], true); createObjectGroupsDeprecated(group, 0, borderClasses(clPond, 1, 4), num ); } log("Creating obelisks"); group = new SimpleGroup( [new SimpleObject(eObelisk, 1,1, 0,1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clWater, 4, clForest, 3, clPlayer, 20, clMetal, 6, clRock, 2, clPond, 4, clTreasure, 2), stayClasses(clDesert, 3)], scaleByMapSize(5, 30), 50 ); log("Creating pyramids"); group = new SimpleGroup( [new SimpleObject(ePyramid, 1,1, 0,1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clWater, 7, clForest, 6, clPlayer, 20, clMetal, 5, clRock, 5, clPond, 7, clTreasure, 2), stayClasses(clDesert, 3)], scaleByMapSize(2, 6), 50 ); setSkySet("sunny"); setSunColor(0.711, 0.746, 0.574); setWaterColor(0.541,0.506,0.416); setWaterTint(0.694,0.592,0.522); setWaterMurkiness(1); setWaterWaviness(3.0); setWaterType("lake"); ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/unknown.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/unknown.js (revision 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/unknown.js (revision 20185) @@ -1,1724 +1,1643 @@ 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); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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]; } - var WATER_WIDTH = randFloat(0.22,0.3)+scaleByMapSize(1,4)/20; - log("Creating sea"); - var theta = randFloat(0, 1); - var theta2 = randFloat(0, 1); - var seed = randFloat(2,3); - var seed2 = randFloat(2,3); - 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); - - // add the rough shape of the water - var km = 20/scaleByMapSize(35, 160); - - var fadeDist = 0.05; - - if (mdd1 == 1) //vertical - { - var cu = km*rndRiver(theta+z*0.5*(mapSize/64),seed); - var cu2 = km*rndRiver(theta2+z*0.5*(mapSize/64),seed2); - - if ((x > cu + 0.5 - WATER_WIDTH/2) && (x < cu2 + 0.5 + WATER_WIDTH/2)) - { - var h; - if (x < (cu + 0.5 + fadeDist - WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - x)/fadeDist); - } - else if (x > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - (x - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist); - } - else - { - h = -3.0; - } - - if (h < -1.5) - { - placeTerrain(ix, iz, tWater); - } - else - { - placeTerrain(ix, iz, tShore); - } - - setHeight(ix, iz, h); - if (h < 0){ - addToClass(ix, iz, clWater); - } - } - else - { - setHeight(ix, iz, 3.1); - addToClass(ix, iz, clLand); - } - } - else //horizontal - { - var cu = km*rndRiver(theta+x*0.5*(mapSize/64),seed); - var cu2 = km*rndRiver(theta2+x*0.5*(mapSize/64),seed2); - - if ((z > cu + 0.5 - WATER_WIDTH/2) && (z < cu2 + 0.5 + WATER_WIDTH/2)) - { - var h; - if (z < (cu + 0.5 + fadeDist - WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - z)/fadeDist); - } - else if (z > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - (z - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist); - } - else - { - h = -3.0; - } - - if (h < -1.5) - { - placeTerrain(ix, iz, tWater); - } - else - { - placeTerrain(ix, iz, tShore); - } - - setHeight(ix, iz, h); - if (h < 0){ - addToClass(ix, iz, clWater); - } - } - else - { - setHeight(ix, iz, 3.1); - addToClass(ix, iz, clLand); - } - } + 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); 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); } } 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); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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 + i*TWO_PI/(numPlayers-1)*2/3; 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] = 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] = 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 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/unknown_land.js (revision 20185) @@ -1,1511 +1,1430 @@ 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); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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]; } - var WATER_WIDTH = randFloat(0.22,0.3)+scaleByMapSize(1,4)/20; - log("Creating sea"); - var theta = randFloat(0, 1); - var theta2 = randFloat(0, 1); - var seed = randFloat(2,3); - var seed2 = randFloat(2,3); - 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); - - // add the rough shape of the water - var km = 20/scaleByMapSize(35, 160); - - var fadeDist = 0.05; - - if (mdd1 == 1) //vertical - { - var cu = km*rndRiver(theta+z*0.5*(mapSize/64),seed); - var cu2 = km*rndRiver(theta2+z*0.5*(mapSize/64),seed2); - - if ((x > cu + 0.5 - WATER_WIDTH/2) && (x < cu2 + 0.5 + WATER_WIDTH/2)) - { - var h; - if (x < (cu + 0.5 + fadeDist - WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - x)/fadeDist); - } - else if (x > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - (x - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist); - } - else - { - h = -3.0; - } - - if (h < -1.5) - { - placeTerrain(ix, iz, tWater); - } - else - { - placeTerrain(ix, iz, tShore); - } - - setHeight(ix, iz, h); - if (h < 0){ - addToClass(ix, iz, clWater); - } - } - else - { - setHeight(ix, iz, 3.1); - addToClass(ix, iz, clLand); - } - } - else //horizontal - { - var cu = km*rndRiver(theta+x*0.5*(mapSize/64),seed); - var cu2 = km*rndRiver(theta2+x*0.5*(mapSize/64),seed2); - - if ((z > cu + 0.5 - WATER_WIDTH/2) && (z < cu2 + 0.5 + WATER_WIDTH/2)) - { - var h; - if (z < (cu + 0.5 + fadeDist - WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - z)/fadeDist); - } - else if (z > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - (z - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist); - } - else - { - h = -3.0; - } - - if (h < -1.5) - { - placeTerrain(ix, iz, tWater); - } - else - { - placeTerrain(ix, iz, tShore); - } - - setHeight(ix, iz, h); - if (h < 0){ - addToClass(ix, iz, clWater); - } - } - else - { - setHeight(ix, iz, 3.1); - addToClass(ix, iz, clLand); - } - } + 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); 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); } 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); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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); addToClass(ix, iz, clPlayer); addToClass(ix+5, iz, clPlayer); addToClass(ix, iz+5, clPlayer); addToClass(ix-5, iz, clPlayer); addToClass(ix, iz-5, 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 + i*TWO_PI/(numPlayers-1)*2/3; 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] = 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] = 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 20184) +++ ps/trunk/binaries/data/mods/public/maps/random/unknown_nomad.js (revision 20185) @@ -1,1536 +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(); - var WATER_WIDTH = randFloat(0.22,0.3)+scaleByMapSize(1,4)/20; - log("Creating sea"); - var theta = randFloat(0, 1); - var theta2 = randFloat(0, 1); - var seed = randFloat(2,3); - var seed2 = randFloat(2,3); - 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); - - // add the rough shape of the water - var km = 20/scaleByMapSize(35, 160); - - var fadeDist = 0.05; - - if (mdd1 == 1) //vertical - { - var cu = km*rndRiver(theta+z*0.5*(mapSize/64),seed); - var cu2 = km*rndRiver(theta2+z*0.5*(mapSize/64),seed2); - - if ((x > cu + 0.5 - WATER_WIDTH/2) && (x < cu + 0.5 + WATER_WIDTH/2)) - { - var h; - if (x < (cu + 0.5 + fadeDist - WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - x)/fadeDist); - } - else if (x > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - (x - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist); - } - else - { - h = -3.0; - } - - if (h < -1.5) - { - placeTerrain(ix, iz, tWater); - } - else - { - placeTerrain(ix, iz, tShore); - } - - setHeight(ix, iz, h); - if (h < 0){ - addToClass(ix, iz, clWater); - } - } - else - { - setHeight(ix, iz, 3.1); - addToClass(ix, iz, clLand); - } - } - else //horizontal - { - var cu = km*rndRiver(theta+x*0.5*(mapSize/64),seed); - var cu2 = km*rndRiver(theta2+x*0.5*(mapSize/64),seed2); - - if ((z > cu + 0.5 - WATER_WIDTH/2) && (z < cu + 0.5 + WATER_WIDTH/2)) - { - var h; - if (z < (cu + 0.5 + fadeDist - WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - z)/fadeDist); - } - else if (z > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2)) - { - h = 3 - 6 * (1 - (z - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist); - } - else - { - h = -3.0; - } - - if (h < -1.5) - { - placeTerrain(ix, iz, tWater); - } - else - { - placeTerrain(ix, iz, tShore); - } - - setHeight(ix, iz, h); - if (h < 0){ - addToClass(ix, iz, clWater); - } - } - else - { - setHeight(ix, iz, 3.1); - addToClass(ix, iz, clLand); - } - } + 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); else passageMaker(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, 6)) 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, 6)) 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();