Index: ps/trunk/binaries/data/mods/public/maps/random/aegean_sea.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/aegean_sea.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/aegean_sea.js (revision 21000) @@ -1,309 +1,309 @@ Engine.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 tShoreUpper = "medit_sand"; const tShoreLower = "medit_sand_wet"; const tCoralsUpper = "medit_sea_coral_plants"; const tCoralsLower = "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 aDecorativeRock = "actor|geology/stone_granite_med.xml"; const pForest = [tForestFloor, tForestFloor + TERRAIN_SEPARATOR + oCarob, tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERRAIN_SEPARATOR + oSDatePalm, tForestFloor]; const heightSeaGround = -3; const heightSeaBump = -2.5; const heightCorralsLower = -2; const heightCorralsUpper = -1.5; const heightShore = 1; const heightLand = 2; const heightIsland = 6; var g_Map = new RandomMap(heightShore, tHill); const numPlayers = getNumPlayers(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -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 clGrass = createTileClass(); -var clHill = createTileClass(); -var clIsland = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clGrass = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clIsland = g_Map.createTileClass(); var startAngle = randomAngle(); placePlayerBases({ "PlayerPlacement": playerPlacementRiver(startAngle , fractionToTiles(0.6)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tCityPlaza, "innerTerrain": tCity }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oCarob, "count": 2 }, "Decoratives": { "template": aBush1 } }); Engine.SetProgress(30); paintRiver({ "parallel": false, "start": new Vector2D(mapCenter.x, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(mapCenter.x, mapBounds.bottom).rotateAround(startAngle, mapCenter), "width": fractionToTiles(0.35), "fadeDist": scaleByMapSize(6, 25), "deviation": 0, "heightRiverbed": heightSeaGround, "heightLand": heightLand, "meanderShort": 20, "meanderLong": 0 }); paintTileClassBasedOnHeight(-Infinity, 0.7, Elevation_ExcludeMin_ExcludeMax, clWater); paintTerrainBasedOnHeight(-Infinity, heightShore, Elevation_ExcludeMin_ExcludeMax, tShoreLower); paintTerrainBasedOnHeight(heightShore, heightLand, Elevation_ExcludeMin_ExcludeMax, tShoreUpper); Engine.SetProgress(40); createBumps(avoidClasses(clWater, 2, clPlayer, 20)); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tForestFloor, tForestFloor, tForestFloor, pForest, pForest], avoidClasses(clPlayer, 20, clForest, 17, clWater, 2, clBaseResource, 3), clForest, forestTrees); Engine.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), scaleByMapSize(15, 45), clDirt); Engine.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), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(60); log("Creating undersea bumps..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.5), new SmoothElevationPainter(ELEVATION_SET, heightSeaBump, 3), stayClasses(clWater, 6), scaleByMapSize(10, 50)); log("Creating islands..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(30, 80)), 0.5), [ new LayeredPainter([tShoreLower, tShoreUpper, tHill], [2 ,1]), new SmoothElevationPainter(ELEVATION_SET, heightIsland, 4), paintClass(clIsland) ], [avoidClasses(clPlayer, 8, clForest, 1, clIsland, 15), stayClasses (clWater, 6)], scaleByMapSize(1, 4) * numPlayers ); paintTerrainBasedOnHeight(-Infinity, heightSeaGround, Elevation_IncludeMin_IncludeMax, tSeaDepths); paintTerrainBasedOnHeight(heightSeaGround, heightCorralsLower, Elevation_ExcludeMin_IncludeMax, tCoralsLower); paintTerrainBasedOnHeight(heightCorralsLower, heightCorralsUpper, Elevation_ExcludeMin_IncludeMax, tCoralsUpper); 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), clRock); 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), clRock); 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 ); Engine.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)); Engine.SetProgress(70); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 3 * scaleByMapSize(5, 20) ], [avoidClasses(clIsland, 2, clFood, 10), stayClasses(clWater, 5)], clFood); 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, clBaseResource, 4, clWater, 1, clFood, 10, clHill, 1), clFood); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); Engine.SetProgress(90); var types = [oDatePalm, oSDatePalm, oCarob, oFanPalm, oPoplar, oCypress]; createStragglerTrees( types, avoidClasses(clForest, 1, clWater, 2, clPlayer, 12, clMetal, 6, clHill, 1), clForest, stragglerTrees); createStragglerTrees( types, stayClasses(clIsland, 4), clForest, stragglerTrees * 10); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clIsland, 10, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); 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); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/african_plains.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/african_plains.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/african_plains.js (revision 21000) @@ -1,286 +1,286 @@ Engine.LoadLibrary("rmgen"); var tPrimary = "savanna_grass_a"; var tForestFloor = "savanna_forestfloor_a"; var tCliff = ["savanna_cliff_a", "savanna_cliff_a_red", "savanna_cliff_b", "savanna_cliff_b_red"]; var tSecondary = "savanna_grass_b"; var tGrassShrubs = "savanna_shrubs_a"; var tDirt = "savanna_dirt_a"; var tDirt2 = "savanna_dirt_a_red"; var tDirt3 = "savanna_dirt_b"; var tDirt4 = "savanna_dirt_rocks_a"; var tCitytiles = "savanna_tile_a"; var tShore = "savanna_riparian_bank"; var tWater = "savanna_riparian_wet"; var oBaobab = "gaia/flora_tree_baobab"; var oPalm = "gaia/flora_tree_senegal_date_palm"; var oBerryBush = "gaia/flora_bush_berry"; var oWildebeest = "gaia/fauna_wildebeest"; var oZebra = "gaia/fauna_zebra"; var oRhino = "gaia/fauna_rhino"; var oLion = "gaia/fauna_lion"; var oLioness = "gaia/fauna_lioness"; var oHawk = "gaia/fauna_hawk"; var oGiraffe = "gaia/fauna_giraffe"; var oGiraffe2 = "gaia/fauna_giraffe_infant"; var oGazelle = "gaia/fauna_gazelle"; var oElephant = "gaia/fauna_elephant_african_bush"; var oElephant2 = "gaia/fauna_elephant_african_infant"; var oCrocodile = "gaia/fauna_crocodile"; var oFish = "gaia/fauna_fish"; var oStoneSmall = "gaia/geology_stone_savanna_small"; var oMetalLarge = "gaia/geology_metal_savanna_slabs"; var aBush = "actor|props/flora/bush_medit_sm_dry.xml"; var aRock = "actor|geology/stone_savanna_med.xml"; const pForest = [tForestFloor + TERRAIN_SEPARATOR + oPalm, tForestFloor]; var heightSeaGround = -5; var heightLand = 2; var heightCliff = 3; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tPrimary, "innerTerrain": tCitytiles }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "type": "stone_formation", "template": oStoneSmall, "terrain": tDirt4 } ] }, "Trees": { "template": oBaobab, "count": scaleByMapSize(3, 12), "minDistGroup": 2, "maxDistGroup": 6, "minDist": 15, "maxDist": 16 } // No decoratives }); Engine.SetProgress(20); createHills([tDirt2, tCliff, tGrassShrubs], avoidClasses(clPlayer, 35, clForest, 20, clHill, 20, clWater, 2), clHill, scaleByMapSize(5, 8)); Engine.SetProgress(30); log("Creating water holes..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), Math.floor(scaleByMapSize(60, 100)), 5), [ new LayeredPainter([tShore, tWater], [1]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 7), paintClass(clWater) ], avoidClasses(clPlayer, 22, clWater, 8, clHill, 2), scaleByMapSize(2, 5)); Engine.SetProgress(45); paintTerrainBasedOnHeight(heightCliff, Infinity, 0, tCliff); createBumps(avoidClasses(clWater, 2, clPlayer, 20)); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tPrimary, tForestFloor, tForestFloor, pForest, pForest], avoidClasses(clPlayer, 20, clForest, 20, clHill, 0, clWater, 2), clForest, forestTrees); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tDirt,tDirt3], [tDirt2,tDirt4]], [2], avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating shrubs..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tGrassShrubs, avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tSecondary, avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(60); log("Creating stone mines..."); createMines( [ [new SimpleObject(oStoneSmall, 0,2, 0,4)], [new SimpleObject(oStoneSmall, 2,5, 1,3)] ], avoidClasses(clWater, 4, clForest, 4, clPlayer, 20, clRock, 10, clHill, 4), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 4, clForest, 4, clPlayer, 20, clMetal, 18, clRock, 5, clHill, 4), clMetal ); Engine.SetProgress(70); createDecoration( [ [new SimpleObject(aBush, 1,3, 0,1)], [new SimpleObject(aRock, 1,2, 0,1)] ], [ scaleByMapSize(8, 131), scaleByMapSize(8, 131) ], avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0)); Engine.SetProgress(75); log("Creating giraffes..."); var group = new SimpleGroup( [new SimpleObject(oGiraffe, 2,4, 0,4), new SimpleObject(oGiraffe2, 0,2, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clPlayer, 20, clFood, 11, clHill, 4), scaleByMapSize(4,12), 50 ); log("Creating elephants..."); group = new SimpleGroup( [new SimpleObject(oElephant, 2,4, 0,4), new SimpleObject(oElephant2, 0,2, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clPlayer, 20, clFood, 11, clHill, 4), scaleByMapSize(4,12), 50 ); log("Creating lions..."); group = new SimpleGroup( [new SimpleObject(oLion, 0,1, 0,4), new SimpleObject(oLioness, 2,3, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clPlayer, 20, clFood, 11, clHill, 4), scaleByMapSize(4,12), 50 ); createFood( [ [new SimpleObject(oHawk, 1, 1, 0, 3)], [new SimpleObject(oGazelle, 3, 5, 0, 3)], [new SimpleObject(oZebra, 3, 5, 0, 3)], [new SimpleObject(oWildebeest, 4, 6, 0, 3)], [new SimpleObject(oRhino, 1, 1, 0, 3)] ], [ 3 * numPlayers, 3 * numPlayers, 3 * numPlayers, 3 * numPlayers, 3 * numPlayers, ], avoidClasses(clFood, 20, clWater, 5, clHill, 2, clPlayer, 16), clFood); createFood( [ [new SimpleObject(oCrocodile, 2, 3, 0, 3)] ], [ 3 * numPlayers, ], stayClasses(clWater, 6), clFood); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ randIntInclusive(1, 4) * numPlayers + 2 ], avoidClasses(clWater, 3, clForest, 2, clPlayer, 20, clHill, 3, clFood, 10), clFood); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 15 * numPlayers ], [avoidClasses(clFood, 20), stayClasses(clWater, 6)], clFood); Engine.SetProgress(85); createStragglerTrees( [oBaobab], avoidClasses(clWater, 5, clForest, 2, clHill, 3, clPlayer, 12, clMetal, 4, clRock, 4), clForest, stragglerTrees); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setPPEffect("hdr"); setPPSaturation(0.48); setPPContrast(0.53); setPPBloom(0.12); setFogThickness(0.25); setFogFactor(0.25); setFogColor(0.8, 0.7, 0.5); setSkySet("sunny"); setSunRotation(randomAngle()); setSunElevation(Math.PI * randFloat(1/4, 1/2)); setWaterColor(0.223, 0.247, 0.2); // dark majestic blue setWaterTint(0.462, 0.756, 0.566); // light blue setWaterMurkiness(5.92); setWaterWaviness(0); setWaterType("clap"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/alpine_lakes.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/alpine_lakes.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/alpine_lakes.js (revision 21000) @@ -1,269 +1,269 @@ Engine.LoadLibrary("rmgen"); if (randBool()) { log("Late spring biome..."); setFogThickness(0.26); setFogFactor(0.4); setPPEffect("hdr"); setPPSaturation(0.48); setPPContrast(0.53); setPPBloom(0.12); var tPrimary = ["alpine_dirt_grass_50"]; var tForestFloor = "alpine_forrestfloor"; var tCliff = ["alpine_cliff_a", "alpine_cliff_b", "alpine_cliff_c"]; var tSecondary = "alpine_grass_rocky"; var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"]; var tSnowLimited = ["alpine_snow_rocky"]; var tDirt = "alpine_dirt"; var tRoad = "new_alpine_citytile"; var tRoadWild = "new_alpine_citytile"; var tShore = "alpine_shore_rocks_grass_50"; var tWater = "alpine_shore_rocks"; var oPine = "gaia/flora_tree_pine"; var oBerryBush = "gaia/flora_bush_berry"; var oDeer = "gaia/fauna_deer"; var oFish = "gaia/fauna_fish"; var oRabbit = "gaia/fauna_rabbit"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; var aGrass = "actor|props/flora/grass_soft_small_tall.xml"; var aGrassShort = "actor|props/flora/grass_soft_large.xml"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; var aBushMedium = "actor|props/flora/bush_medit_me.xml"; var aBushSmall = "actor|props/flora/bush_medit_sm.xml"; } else { log("Winter biome..."); setFogFactor(0.35); setFogThickness(0.19); setPPSaturation(0.37); setPPEffect("hdr"); var tPrimary = ["alpine_snow_a", "alpine_snow_b"]; var tForestFloor = "alpine_forrestfloor_snow"; var tCliff = ["alpine_cliff_snow"]; var tSecondary = "alpine_grass_snow_50"; var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"]; var tSnowLimited = ["alpine_snow_a", "alpine_snow_b"]; var tDirt = "alpine_dirt"; var tRoad = "new_alpine_citytile"; var tRoadWild = "new_alpine_citytile"; var tShore = "alpine_shore_rocks_icy"; var tWater = "alpine_shore_rocks"; var oPine = "gaia/flora_tree_pine_w"; var oBerryBush = "gaia/flora_bush_berry"; var oDeer = "gaia/fauna_deer"; var oFish = "gaia/fauna_fish"; var oRabbit = "gaia/fauna_rabbit"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; var aGrass = "actor|props/flora/grass_soft_dry_small_tall.xml"; var aGrassShort = "actor|props/flora/grass_soft_dry_large.xml"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; var aBushMedium = "actor|props/flora/bush_medit_me_dry.xml"; var aBushSmall = "actor|props/flora/bush_medit_sm_dry.xml"; } const pForest = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor]; var heightSeaGround = -5; var heightLand = 3; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oPine, "count": scaleByMapSize(3, 12) }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); log("Creating hills..."); createMountains(tCliff, avoidClasses(clPlayer, 20, clHill, 8), clHill, scaleByMapSize(10, 40) * numPlayers, Math.floor(scaleByMapSize(40, 60)), Math.floor(scaleByMapSize(4, 5)), Math.floor(scaleByMapSize(7, 15)), Math.floor(scaleByMapSize(5, 15))); Engine.SetProgress(30); log("Creating lakes..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 8)), Math.floor(scaleByMapSize(40, 180)), 0.7), [ new LayeredPainter([tShore, tWater, tWater], [1, 3]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 5), paintClass(clWater) ], avoidClasses(clPlayer, 20, clWater, 8), scaleByMapSize(5, 16), 1); paintTerrainBasedOnHeight(3, Math.floor(scaleByMapSize(20, 40)), 0, tCliff); paintTerrainBasedOnHeight(Math.floor(scaleByMapSize(20, 40)), 100, 3, tSnowLimited); createBumps(avoidClasses(clWater, 2, clPlayer, 20)); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tPrimary, tForestFloor, tForestFloor, pForest, pForest], avoidClasses(clPlayer, 20, clForest, 17, clHill, 0, clWater, 2), clForest, forestTrees); Engine.SetProgress(60); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tDirt,tHalfSnow], [tHalfSnow,tSnowLimited]], [2], avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tSecondary, avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(65); 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, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), clMetal ); Engine.SetProgress(70); 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [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, 0, clForest, 0, clPlayer, 0, clHill, 0)); Engine.SetProgress(75); createFood( [ [new SimpleObject(oDeer, 5, 7, 0, 4)], [new SimpleObject(oRabbit, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), clFood); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ randIntInclusive(1, 4) * numPlayers + 2 ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 15 * numPlayers ], [avoidClasses(clFood, 20), stayClasses(clWater, 6)], clFood); Engine.SetProgress(85); createStragglerTrees( [oPine], avoidClasses(clWater, 5, clForest, 3, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet(pickRandom(["cirrus", "cumulus", "sunny"])); setSunRotation(randomAngle()); setSunElevation(Math.PI * randFloat(1/5, 1/3)); setWaterColor(0.0, 0.047, 0.286); // dark majestic blue setWaterTint(0.471, 0.776, 0.863); // light blue setWaterMurkiness(0.82); setWaterWaviness(3.0); setWaterType("clap"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/alpine_valley.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/alpine_valley.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/alpine_valley.js (revision 21000) @@ -1,542 +1,542 @@ Engine.LoadLibrary("rmgen"); TILE_CENTERED_HEIGHT_MAP = true; /** * This class creates random mountainranges without enclosing any area completely. * * To determine their location, a graph is created where each vertex is a possible starting or * ending location of a mountainrange and each edge a possible mountainrange. * * That graph starts nearly complete (i.e almost every vertex is connected to most other vertices). * After a random edge was chosen and placed as a mountainrange, * all edges that intersect, that leave a too small gap to another mountainrange or that are connected to * too many other mountainranges are removed from the graph. * This is repeated until all edges were removed. */ function MountainRangeBuilder(args) { /** * These parameters paint the mountainranges after their location was determined. */ this.pathplacer = args.pathplacer; this.painters = args.painters; this.constraint = args.constraint; this.mountainWidth = args.mountainWidth; /** * Minimum geometric distance between two mountains that don't end in one place (disjoint edges). */ this.minDistance = args.mountainWidth + args.passageWidth; /** * Array of Vector2D locations where a mountainrange can start or end. */ this.vertices = args.points; /** * Number of mountainranges starting or ending at the given point. */ this.vertexDegree = this.vertices.map(p => 0); /** * Highest number of mountainranges that can meet in one point (maximum degree of each vertex). */ this.maxDegree = args.maxDegree; /** * Each possible edge is an array containing two vertex indices. * The algorithm adds possible edges consecutively and removes subsequently invalid edges. */ this.possibleEdges = []; this.InitPossibleEdges(); /** * A two-dimensional array of booleans that are true if the two corresponding vertices may be connected by a new edge (mountainrange). * It is initialized with some points that should never be connected and updated with every placed edge. * The purpose is to rule out any cycles in the graph, i.e. prevent any territory enclosed by mountainranges. */ this.verticesConnectable = []; this.InitConnectable(); /** * Currently iterated item of possibleEdges that is either used as a mountainrange or removed from the possibleEdges. */ this.index = undefined; /** * These variables hold the indices of the two points of that edge and the location of them as a Vector2D. */ this.currentEdge = undefined; this.currentEdgeStart = undefined; this.currentEdgeEnd = undefined; } MountainRangeBuilder.prototype.InitPossibleEdges = function() { for (let i = 0; i < this.vertices.length; ++i) for (let j = numPlayers; j < this.vertices.length; ++j) if (j > i) this.possibleEdges.push([i, j]); }; MountainRangeBuilder.prototype.InitConnectable = function() { for (let i = 0; i < this.vertices.length; ++i) { this.verticesConnectable[i] = []; for (let j = 0; j < this.vertices.length; ++j) this.verticesConnectable[i][j] = i >= numPlayers || j >= numPlayers || i == j || i != j - 1 && i != j + 1; } }; MountainRangeBuilder.prototype.SetConnectable = function(isConnectable) { this.verticesConnectable[this.currentEdge[0]][this.currentEdge[1]] = isConnectable; this.verticesConnectable[this.currentEdge[1]][this.currentEdge[0]] = isConnectable; }; MountainRangeBuilder.prototype.UpdateCurrentEdge = function() { this.currentEdge = this.possibleEdges[this.index]; this.currentEdgeStart = this.vertices[this.currentEdge[0]]; this.currentEdgeEnd = this.vertices[this.currentEdge[1]]; }; /** * Remove all edges that are too close to the current mountainrange or intersect. */ MountainRangeBuilder.prototype.RemoveInvalidEdges = function() { for (let i = 0; i < this.possibleEdges.length; ++i) { this.UpdateCurrentEdge(); let comparedEdge = this.possibleEdges[i]; let comparedEdgeStart = this.vertices[comparedEdge[0]]; let comparedEdgeEnd = this.vertices[comparedEdge[1]]; let edge0Equal = this.currentEdgeStart == comparedEdgeStart; let edge1Equal = this.currentEdgeStart == comparedEdgeEnd; let edge2Equal = this.currentEdgeEnd == comparedEdgeEnd; let edge3Equal = this.currentEdgeEnd == comparedEdgeStart; if (!edge0Equal && !edge2Equal && !edge1Equal && !edge3Equal && testLineIntersection(this.currentEdgeStart, this.currentEdgeEnd, comparedEdgeStart, comparedEdgeEnd, this.minDistance) || ( edge0Equal && !edge2Equal || !edge1Equal && edge3Equal) && distanceOfPointFromLine(this.currentEdgeStart, this.currentEdgeEnd, comparedEdgeEnd) < this.minDistance || (!edge0Equal && edge2Equal || edge1Equal && !edge3Equal) && distanceOfPointFromLine(this.currentEdgeStart, this.currentEdgeEnd, comparedEdgeStart) < this.minDistance) { this.possibleEdges.splice(i, 1); --i; if (this.index > i) --this.index; } } }; /** * Tests using depth-first-search if the graph according to pointsConnectable contains a cycle, * i.e. if adding the currentEdge would result in an area enclosed by mountainranges. */ MountainRangeBuilder.prototype.HasCycles = function() { let tree = []; let backtree = []; let pointQueue = [this.currentEdge[0]]; while (pointQueue.length) { let selectedPoint = pointQueue.shift(); if (tree.indexOf(selectedPoint) == -1) { tree.push(selectedPoint); backtree.push(-1); } for (let i = 0; i < this.vertices.length; ++i) { if (this.verticesConnectable[selectedPoint][i] || i == backtree[tree.lastIndexOf(selectedPoint)]) continue; // If the current point was encountered already, then a cycle was identified. if (tree.indexOf(i) != -1) return true; // Otherwise visit this point next pointQueue.unshift(i); tree.push(i); backtree.push(selectedPoint); } } return false; }; MountainRangeBuilder.prototype.PaintCurrentEdge = function() { this.pathplacer.start = this.currentEdgeStart; this.pathplacer.end = this.currentEdgeEnd; this.pathplacer.width = this.mountainWidth; log("Creating mountainrange..."); if (!createArea(this.pathplacer, this.painters, this.constraint)) return false; log("Creating circular mountains at both ends of that mountainrange..."); for (let point of [this.currentEdgeStart, this.currentEdgeEnd]) createArea( new ClumpPlacer(diskArea(this.mountainWidth / 2), 0.95, 0.6, 10, point), this.painters, this.constraint); return true; }; /** * This is the only function meant to be publicly accessible. */ MountainRangeBuilder.prototype.CreateMountainRanges = function() { while (this.possibleEdges.length) { this.index = randIntExclusive(0, this.possibleEdges.length); this.UpdateCurrentEdge(); this.SetConnectable(false); if (this.vertexDegree[this.currentEdge[0]] < this.maxDegree && this.vertexDegree[this.currentEdge[1]] < this.maxDegree && !this.HasCycles() && this.PaintCurrentEdge()) { ++this.vertexDegree[this.currentEdge[0]]; ++this.vertexDegree[this.currentEdge[1]]; this.RemoveInvalidEdges(); } else this.SetConnectable(true); this.possibleEdges.splice(this.index, 1); } }; if (randBool()) { log("Late spring biome..."); var tPrimary = ["alpine_dirt_grass_50"]; var tForestFloor = "alpine_forrestfloor"; var tCliff = ["alpine_cliff_a", "alpine_cliff_b", "alpine_cliff_c"]; var tSecondary = "alpine_grass_rocky"; var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"]; var tSnowLimited = ["alpine_snow_rocky"]; var tDirt = "alpine_dirt"; var tRoad = "new_alpine_citytile"; var tRoadWild = "new_alpine_citytile"; var oPine = "gaia/flora_tree_pine"; var oBerryBush = "gaia/flora_bush_berry"; var oDeer = "gaia/fauna_deer"; var oRabbit = "gaia/fauna_rabbit"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; var aGrass = "actor|props/flora/grass_soft_small_tall.xml"; var aGrassShort = "actor|props/flora/grass_soft_large.xml"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; var aBushMedium = "actor|props/flora/bush_medit_me.xml"; var aBushSmall = "actor|props/flora/bush_medit_sm.xml"; } else { log("Winter biome..."); var tPrimary = ["alpine_snow_a", "alpine_snow_b"]; var tForestFloor = "alpine_forrestfloor_snow"; var tCliff = ["alpine_cliff_snow"]; var tSecondary = "alpine_grass_snow_50"; var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"]; var tSnowLimited = ["alpine_snow_a", "alpine_snow_b"]; var tDirt = "alpine_dirt"; var tRoad = "new_alpine_citytile"; var tRoadWild = "new_alpine_citytile"; var oPine = "gaia/flora_tree_pine_w"; var oBerryBush = "gaia/flora_bush_berry"; var oDeer = "gaia/fauna_deer"; var oRabbit = "gaia/fauna_rabbit"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; var aGrass = "actor|props/flora/grass_soft_dry_small_tall.xml"; var aGrassShort = "actor|props/flora/grass_soft_dry_large.xml"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; var aBushMedium = "actor|props/flora/bush_medit_me_dry.xml"; var aBushSmall = "actor|props/flora/bush_medit_sm_dry.xml"; } var heightLand = 3; var heightOffsetBump = 2; var snowlineHeight = 29; var heightMountain = 30; const pForest = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor]; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); const mapCenter = g_Map.getCenter(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var [playerIDs, playerPosition, playerAngle, startAngle] = playerPlacementCircle(fractionToTiles(0.35)); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oPine }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); new MountainRangeBuilder({ "pathplacer": new PathPlacer(undefined, undefined, undefined, 0.4, scaleByMapSize(3, 12), 0.1, 0.1, 0.1), "painters":[ new LayeredPainter([tCliff, tPrimary], [3]), new SmoothElevationPainter(ELEVATION_SET, heightMountain, 2), paintClass(clHill) ], "constraint": avoidClasses(clPlayer, 20), "passageWidth": scaleByMapSize(10, 15), "mountainWidth": scaleByMapSize(9, 15), "maxDegree": 3, "points": [ // Four points near each player ...distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers, fractionToTiles(0.49), mapCenter)[0], ...distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers * 1.4, fractionToTiles(0.34), mapCenter)[0], ...distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers * 0.6, fractionToTiles(0.34), mapCenter)[0], ...distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers, fractionToTiles(0.18), mapCenter)[0], mapCenter ] }).CreateMountainRanges(); Engine.SetProgress(35); paintTerrainBasedOnHeight(heightLand + 0.1, snowlineHeight, 0, tCliff); paintTerrainBasedOnHeight(snowlineHeight, heightMountain, 3, tSnowLimited); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), avoidClasses(clPlayer, 10), scaleByMapSize(100, 200)); Engine.SetProgress(40); log("Creating hills..."); createAreas( new ClumpPlacer(scaleByMapSize(40, 150), 0.2, 0.1, 1), [ new LayeredPainter([tCliff, tSnowLimited], [2]), new SmoothElevationPainter(ELEVATION_SET, heightMountain, 2), paintClass(clHill) ], avoidClasses(clPlayer, 20, clHill, 14), scaleByMapSize(10, 80) * numPlayers ); Engine.SetProgress(50); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); var types = [ [[tForestFloor, tPrimary, pForest], [tForestFloor, pForest]] ]; var size = forestTrees / (scaleByMapSize(2,8) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 12, clForest, 10, clHill, 0), num); Engine.SetProgress(60); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter([[tDirt, tHalfSnow], [tHalfSnow, tSnowLimited]], [2]), paintClass(clDirt) ], avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45)); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new TerrainPainter(tSecondary), avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45)); Engine.SetProgress(65); 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, 20, clRock, 10, clHill, 1), scaleByMapSize(4,16), 100 ); log("Creating small stone mines..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(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(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), scaleByMapSize(4,16), 100 ); Engine.SetProgress(70); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(8, 131), 50 ); Engine.SetProgress(75); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50 ); log("Creating rabbit..."); group = new SimpleGroup( [new SimpleObject(oRabbit, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); Engine.SetProgress(85); createStragglerTrees( [oPine], avoidClasses(clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); log("Creating small grass tufts..."); var planetm = 1; group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clHill, 2, clPlayer, 2, clDirt, 0), planetm * scaleByMapSize(13, 200) ); Engine.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), planetm * scaleByMapSize(13, 200) ); Engine.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(clHill, 1, clPlayer, 1, clDirt, 1), planetm * scaleByMapSize(13, 200), 50 ); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet(pickRandom(["cirrus", "cumulus", "sunny"])); setSunRotation(randomAngle()); setSunElevation(Math.PI * randFloat(1/5, 1/3)); setWaterColor(0.0, 0.047, 0.286); // dark majestic blue setWaterTint(0.471, 0.776, 0.863); // light blue setWaterMurkiness(0.72); setWaterWaviness(2.0); setWaterType("lake"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/anatolian_plateau.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/anatolian_plateau.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/anatolian_plateau.js (revision 21000) @@ -1,248 +1,248 @@ Engine.LoadLibrary("rmgen"); const tPrimary = ["steppe_grass_a", "steppe_grass_c", "steppe_grass_d"]; const tGrass = ["steppe_grass_a", "steppe_grass_b", "steppe_grass_c", "steppe_grass_d"]; const tForestFloor = "steppe_grass_c"; const tGrassA = "steppe_grass_b"; const tGrassB = "steppe_grass_c"; const tGrassC = ["steppe_grass_b", "steppe_grass_c", "steppe_grass_d"]; const tGrassD = "steppe_grass_a"; const tDirt = ["steppe_dirt_a", "steppe_dirt_b"]; const tRoad = "road_stones"; const tRoadWild = "road_stones"; const oPoplar = "gaia/flora_tree_poplar_lombardy"; const oBush = "gaia/flora_bush_temperate"; const oBerryBush = "gaia/flora_bush_berry"; const oRabbit = "gaia/fauna_rabbit"; 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_small_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aRockLarge = "actor|geology/stone_granite_med.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aBushMedium = "actor|props/flora/bush_medit_me.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; const pForest = [tForestFloor + TERRAIN_SEPARATOR + oPoplar, tForestFloor]; var heightLand = 1; var heightOffsetBump = 2; var g_Map = new RandomMap(heightLand, tPrimary); var numPlayers = getNumPlayers(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oPoplar }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); log("Creating bumps..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(2, 5)), 0.5), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), avoidClasses(clPlayer, 13), scaleByMapSize(300, 800)); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(220, 1000, 0.65); var types = [[[tForestFloor, tGrass, pForest], [tForestFloor, pForest]]]; var size = forestTrees / (scaleByMapSize(2,8) * numPlayers); var num = 4 * Math.floor(size / types.length); for (let type of types) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(2, 3)), 4, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 13, clForest, 20, clHill, 1), num); Engine.SetProgress(50); log("Creating grass patches..."); createLayeredPatches( [scaleByMapSize(5, 48), scaleByMapSize(6, 84), scaleByMapSize(8, 128)], [[tGrass,tGrassA,tGrassC],[tGrass,tGrassA,tGrassC], [tGrass,tGrassA,tGrassC]], [1,1], avoidClasses(clForest, 0, clHill, 0, clDirt, 2, clPlayer, 10), scaleByMapSize(50, 70), clDirt); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(5, 32), scaleByMapSize(6, 48), scaleByMapSize(7, 80)], [tGrassD ,tDirt], [1], avoidClasses(clForest, 0, clHill, 0, clDirt, 2, clPlayer, 10), scaleByMapSize(50, 90), clDirt); Engine.SetProgress(55); log("Creating big patches..."); createLayeredPatches( [scaleByMapSize(10, 60), scaleByMapSize(15, 90), scaleByMapSize(20, 120)], [tGrassB ,tGrassA], [1], avoidClasses(clHill, 0, clPlayer, 8), scaleByMapSize(30, 90), clDirt); Engine.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, 20, clRock, 10, clHill, 1), scaleByMapSize(1,4), 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), scaleByMapSize(1,4), 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), scaleByMapSize(2,8), 100 ); Engine.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 10, clHill, 0), scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 10, clHill, 0), scaleByMapSize(8, 131), 50 ); Engine.SetProgress(70); log("Creating rabbits..."); group = new SimpleGroup( [new SimpleObject(oRabbit, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 6 * numPlayers, 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), randIntInclusive(1, 4) * numPlayers + 2, 50 ); Engine.SetProgress(75); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oSheep, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); Engine.SetProgress(85); createStragglerTrees( [oBush, oPoplar], avoidClasses(clForest, 1, clHill, 1, clPlayer, 13, clMetal, 6, clRock, 6), clForest, stragglerTrees); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clHill, 2, clPlayer, 10, clDirt, 1, clForest, 0), scaleByMapSize(13, 200) ); Engine.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(clHill, 1, clPlayer, 1, clDirt, 1), scaleByMapSize(13, 200), 50 ); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setFogThickness(0.1); setFogFactor(0.2); setPPEffect("hdr"); setPPSaturation(0.45); setPPContrast(0.62); setPPBloom(0.2); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/archipelago.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/archipelago.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/archipelago.js (revision 21000) @@ -1,267 +1,267 @@ Engine.LoadLibrary("rmgen"); Engine.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 tTier4Terrain = g_Terrains.dirt; const tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; 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 oWoodTreasure = "gaia/special_treasure_wood"; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; 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]; var heightSeaGround = -5; var heightLand = 3; var heightShore = 1; var g_Map = new RandomMap(heightSeaGround, tWater); const numPlayers = getNumPlayers(); -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 clLand = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clLand = g_Map.createTileClass(); var islandRadius = scaleByMapSize(22, 31); var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); log("Creating player islands..."); for (let i = 0; i < numPlayers; ++i) createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 10)), Math.floor(scaleByMapSize(25, 60)), 1, playerPosition[i], 0, [Math.floor(islandRadius)]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 4)); log("Creating random islands..."); createAreas( new ChainPlacer( Math.floor(scaleByMapSize(4, 8)), Math.floor(scaleByMapSize(8, 14)), Math.floor(scaleByMapSize(25, 60)), 0.07, undefined, scaleByMapSize(30, 70)), [ new SmoothElevationPainter(ELEVATION_SET, heightLand, 4), paintClass(clLand) ], null, scaleByMapSize(1, 5) * randIntInclusive(5, 10)); paintTerrainBasedOnHeight(heightLand - 0.6, heightLand + 0.4, 3, tMainTerrain); paintTerrainBasedOnHeight(heightShore, heightLand, 0, tShore); paintTerrainBasedOnHeight(heightSeaGround, heightShore, 2, tWater); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], // PlayerTileClass marked below "BaseResourceClass": clBaseResource, "Walls": "towers", "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad, "radius": islandRadius / 3, "painters": [ paintClass(clPlayer) ] }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Treasures": { "types": [ { "template": oWoodTreasure, "count": 14 } ] }, "Trees": { "template": oTree1, "count": scaleByMapSize(15, 30) }, "Decoratives": { "template": aGrassShort, } }); createBumps([avoidClasses(clPlayer, 10), stayClasses(clLand, 5)]); if (randBool()) createHills([tMainTerrain, tCliff, tHill], [avoidClasses(clPlayer, 2, clHill, 15), stayClasses(clLand, 0)], clHill, scaleByMapSize(1, 4) * numPlayers); else createMountains(tCliff, [avoidClasses(clPlayer, 2, clHill, 15), stayClasses(clLand, 0)], clHill, scaleByMapSize(1, 4) * numPlayers); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], [avoidClasses(clPlayer, 20, clForest, 17, clHill, 0), stayClasses(clLand, 4)], clForest, forestTrees); Engine.SetProgress(50); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], [1,1], [avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 12), stayClasses(clLand, 7)], scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tTier4Terrain, [avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 12), stayClasses(clLand, 7)], scaleByMapSize(15, 45), clDirt); Engine.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, 7, clRock, 10, clHill, 1), stayClasses(clLand, 6)], clRock ); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], [avoidClasses(clForest, 1, clPlayer, 7, clMetal, 10, clRock, 5, clHill, 1), stayClasses(clLand, 6)], clMetal ); Engine.SetProgress(65); var planetm = currentBiome() == "tropic" ? 8 : 1; 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200) ], [avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 5)]); Engine.SetProgress(70); createFood( [ [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], [avoidClasses(clForest, 0, clPlayer, 1, clHill, 1, clFood, 20), stayClasses(clLand, 3)], clFood); Engine.SetProgress(75); createFood( [ [new SimpleObject(oFruitBush, 5, 7, 0, 4)] ], [ 3 * numPlayers ], [avoidClasses(clForest, 0, clPlayer, 1, clHill, 1, clFood, 10), stayClasses(clLand, 3)], clFood); Engine.SetProgress(80); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 25 * numPlayers ], avoidClasses(clLand, 3, clPlayer, 2, clFood, 20), clFood); Engine.SetProgress(85); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], [avoidClasses(clForest, 7, clHill, 1, clPlayer, 3, clMetal, 6, clRock, 6), stayClasses(clLand, 7)], clForest, stragglerTrees); placePlayersNomad( clPlayer, new AndConstraint([ stayClasses(clLand, 4), avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)])); setWaterWaviness(4.0); setWaterType("ocean"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/arctic_summer.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/arctic_summer.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/arctic_summer.js (revision 21000) @@ -1,325 +1,325 @@ Engine.LoadLibrary("rmgen"); setFogThickness(0.46); setFogFactor(0.5); setPPEffect("hdr"); setPPSaturation(0.48); setPPContrast(0.53); setPPBloom(0.12); var tPrimary = ["alpine_grass_rocky"]; var tForestFloor = "alpine_grass"; var tCliff = ["polar_cliff_a", "polar_cliff_b", "polar_cliff_snow"]; var tSecondary = "alpine_grass"; var tHalfSnow = ["polar_grass_snow", "ice_dirt"]; var tSnowLimited = ["polar_snow_rocks", "polar_ice"]; var tDirt = "ice_dirt"; var tShore = "alpine_shore_rocks"; var tWater = "polar_ice_b"; var tHill = "polar_ice_cracked"; var oBush = "gaia/flora_bush_badlands"; var oBush2 = "gaia/flora_bush_temperate"; var oBerryBush = "gaia/flora_bush_berry"; var oRabbit = "gaia/fauna_rabbit"; var oMuskox = "gaia/fauna_muskox"; var oDeer = "gaia/fauna_deer"; var oWolf = "gaia/fauna_wolf"; var oWhaleFin = "gaia/fauna_whale_fin"; var oWhaleHumpback = "gaia/fauna_whale_humpback"; var oFish = "gaia/fauna_fish"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; var oWoodTreasure = "gaia/special_treasure_wood"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; const pForest = [tForestFloor + TERRAIN_SEPARATOR + oBush, tForestFloor + TERRAIN_SEPARATOR + oBush2, tForestFloor]; var heightSeaGround = -5; var heightLand = 2; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tPrimary, "innerTerrain": tSecondary }, "Chicken": { "template": oRabbit }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Treasures": { "types": [ { "template": oWoodTreasure, "count": 10 } ] }, "Trees": { "template": oBush, "count": 20, "maxDistGroup": 3 } // No decoratives }); Engine.SetProgress(20); log("Creating hills..."); createHills( [tPrimary, tCliff, tHill], avoidClasses( clPlayer, 35, clForest, 20, clHill, 50, clWater, 2), clHill, scaleByMapSize(1, 240)); Engine.SetProgress(30); log("Creating lakes..."); createAreas( new ChainPlacer( 1, Math.floor(scaleByMapSize(4, 8)), Math.floor(scaleByMapSize(40, 180)), 1), [ new LayeredPainter([tShore, tWater, tWater], [1, 3]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 5), paintClass(clWater) ], avoidClasses(clPlayer, 15), scaleByMapSize(1, 20)); Engine.SetProgress(45); log("Creating bumps..."); createBumps(avoidClasses(clPlayer, 6, clWater, 2), scaleByMapSize(30, 300), 1, 8, 4, 0, 3); paintTerrainBasedOnHeight(4, 15, 0, tCliff); paintTerrainBasedOnHeight(15, 100, 3, tSnowLimited); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tSecondary, tForestFloor, tForestFloor, pForest, pForest], avoidClasses( clPlayer, 20, clForest, 14, clHill, 20, clWater, 2), clForest, forestTrees); Engine.SetProgress(60); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tDirt,tHalfSnow], [tHalfSnow,tSnowLimited]], [2], avoidClasses( clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating shrubs..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tSecondary, avoidClasses( clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tSecondary, avoidClasses( clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(65); 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, 3, clForest, 1, clPlayer, 20, clRock, 18, clHill, 1), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1, 1, 0, 4)] ], avoidClasses( clWater, 3, clForest, 1, clPlayer, 20, clMetal, 18, clRock, 5, clHill, 1), clMetal); Engine.SetProgress(70); createDecoration( [ [ new SimpleObject(aRockMedium, 1, 3, 0, 1) ], [ new SimpleObject(aRockLarge, 1, 2, 0, 1), new SimpleObject(aRockMedium, 1, 3, 0, 1) ] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), ], avoidClasses( clWater, 0, clForest, 0, clPlayer, 0, clHill, 0)); Engine.SetProgress(75); createFood( [ [new SimpleObject(oWolf, 3, 5, 0, 3)], [new SimpleObject(oRabbit, 6, 8, 0, 6)], [new SimpleObject(oDeer, 3, 4, 0, 3)], [new SimpleObject(oMuskox, 3, 4, 0, 3)] ], [ 3 * numPlayers, 3 * numPlayers, 3 * numPlayers, 3 * numPlayers ], avoidClasses( clFood, 20, clHill, 5, clWater, 5), clFood); createFood( [ [new SimpleObject(oWhaleFin, 1, 1, 0, 3)], [new SimpleObject(oWhaleHumpback, 1, 1, 0, 3)] ], [ 3 * numPlayers, 3 * numPlayers ], [ avoidClasses(clFood, 20), stayClasses(clWater, 6) ], clFood); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ randIntInclusive(1, 4) * numPlayers + 2 ], avoidClasses( clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 15 * numPlayers ], [ avoidClasses(clFood, 20), stayClasses(clWater, 6) ], clFood); Engine.SetProgress(85); createStragglerTrees( [oBush, oBush2], avoidClasses( clWater, 5, clForest, 3, clHill, 1, clPlayer, 12, clMetal, 4, clRock, 4), clForest, stragglerTrees); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clWater, 4, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("sunset 1"); setSunRotation(randomAngle()); setSunColor(0.8, 0.7, 0.6); setTerrainAmbientColor(0.7, 0.6, 0.7); setUnitsAmbientColor(0.6, 0.5, 0.6); setSunElevation(Math.PI * randFloat(1/12, 1/7)); setWaterColor(0, 0.047, 0.286); setWaterTint(0.462, 0.756, 0.866); setWaterMurkiness(0.92); setWaterWaviness(1); setWaterType("clap"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/ardennes_forest.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/ardennes_forest.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/ardennes_forest.js (revision 21000) @@ -1,462 +1,462 @@ Engine.LoadLibrary("rmgen"); const tPrimary = ["temp_forestfloor_pine", "temp_forestfloor_pine", "alpine_cliff_c", "alpine_grass_rocky"]; const tGrass = ["new_alpine_grass_b", "new_alpine_grass_c", "new_alpine_grass_d"]; const tPineForestFloor = "temp_forestfloor_pine"; const tForestFloor = [tPineForestFloor, tPineForestFloor, "alpine_dirt_grass_50"]; const tCliff = ["alpine_cliff_c", "alpine_cliff_c", "alpine_grass_rocky"]; const tCity = ["new_alpine_citytile", "new_alpine_grass_dirt_a"]; const tGrassPatch = ["alpine_grass_a", "alpine_grass_b"]; const oBoar = "gaia/fauna_boar"; const oDeer = "gaia/fauna_deer"; const oBear = "gaia/fauna_bear"; const oPig = "gaia/fauna_pig"; const oBerryBush = "gaia/flora_bush_berry"; const oMetalSmall = "gaia/geology_metal_alpine"; const oMetalLarge = "gaia/geology_metal_temperate_slabs"; const oStoneSmall = "gaia/geology_stone_alpine_a"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oOak = "gaia/flora_tree_oak"; const oOakLarge = "gaia/flora_tree_oak_large"; const oPine = "gaia/flora_tree_pine"; const oAleppoPine = "gaia/flora_tree_aleppo_pine"; const aTreeA = "actor|flora/trees/oak.xml"; const aTreeB = "actor|flora/trees/oak_large.xml"; const aTreeC = "actor|flora/trees/pine.xml"; const aTreeD = "actor|flora/trees/aleppo_pine.xml"; const aTrees = [aTreeA, aTreeB, aTreeC, aTreeD]; const aGrassLarge = "actor|props/flora/grass_soft_large.xml"; const aWoodLarge = "actor|props/special/eyecandy/wood_pile_1_b.xml"; const aWoodA = "actor|props/special/eyecandy/wood_sm_pile_a.xml"; const aWoodB = "actor|props/special/eyecandy/wood_sm_pile_b.xml"; const aBarrel = "actor|props/special/eyecandy/barrel_a.xml"; const aWheel = "actor|props/special/eyecandy/wheel_laying.xml"; const aCeltHomestead = "actor|structures/celts/homestead.xml"; const aCeltHouse = "actor|structures/celts/house.xml"; const aCeltLongHouse = "actor|structures/celts/longhouse.xml"; var pForest = [ tPineForestFloor+TERRAIN_SEPARATOR+oOak, tForestFloor, tPineForestFloor+TERRAIN_SEPARATOR+oPine, tForestFloor, tPineForestFloor+TERRAIN_SEPARATOR+oAleppoPine, tForestFloor, tForestFloor ]; const heightRavineValley = 2; const heightLand = 30; const heightRavineHill = 40; const heightHill = 50; const heightOffsetRavine = 10; var g_Map = new RandomMap(heightHill, tPrimary); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clForestJoin = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clHillDeco = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clForestJoin = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clHillDeco = g_Map.createTileClass(); log("Creating the central dip..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.42)), 0.94, 0.05, 0.1, mapCenter), [ new LayeredPainter([tCliff, tGrass], [3]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 3) ]); Engine.SetProgress(5); // Find all hills var noise0 = new Noise2D(20); for (var ix = 0; ix < mapSize; ix++) for (var iz = 0; iz < mapSize; iz++) { let position = new Vector2D(ix, iz); let h = g_Map.getHeight(position); if (h > heightRavineHill) { addToClass(ix,iz,clHill); // Add hill noise var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); var n = (noise0.get(x, z) - 0.5) * heightRavineHill; g_Map.setHeight(position, h + n); } } var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.3)); function distanceToPlayers(x, z) { var r = 10000; for (var i = 0; i < numPlayers; i++) { var dx = x - playerPosition[i].x; var dz = z - playerPosition[i].y; r = Math.min(r, Math.square(dx) + Math.square(dz)); } return Math.sqrt(r); } function playerNearness(x, z) { var d = fractionToTiles(distanceToPlayers(x,z)); if (d < 13) return 0; if (d < 19) return (d-13)/(19-13); return 1; } Engine.SetProgress(10); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "BaseResourceClass": clBaseResource, // Playerclass marked below "CityPatch": { "outerTerrain": tCity, "innerTerrain": tCity, "radius": scaleByMapSize(5, 6), "smoothness": 0.05 }, "Chicken": { "template": oPig }, "Berries": { "template": oBerryBush, "minCount": 3, "maxCount": 3 }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ], "distance": 16 }, "Trees": { "template": oOak, "count": 2 } // No decoratives }); log("Marking player territory larger than the city patch..."); for (let i = 0; i < numPlayers; ++i) createArea( new ClumpPlacer(250, 0.95, 0.3, 0.1, playerPosition[i]), paintClass(clPlayer)); Engine.SetProgress(30); log("Creating hills..."); for (let size of [scaleByMapSize(50, 800), scaleByMapSize(50, 400), scaleByMapSize(10, 30), scaleByMapSize(10, 30)]) { let mountains = createAreas( new ClumpPlacer(size, 0.1, 0.2, 0.1), [ new LayeredPainter([tCliff, [tForestFloor, tForestFloor, tCliff]], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, size < 50 ? 2 : 4), paintClass(clHill) ], avoidClasses(clPlayer, 8, clBaseResource, 2, clHill, 5), scaleByMapSize(1, 4)); if (size > 100 && mountains.length) createAreasInAreas( new ClumpPlacer(size * 0.3, 0.94, 0.05, 0.1), [ new LayeredPainter([tCliff, tForestFloor], [2]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetRavine, 3) ], stayClasses(clHill, 4), mountains.length * 2, 20, mountains); let ravine = createAreas( new ClumpPlacer(size, 0.1, 0.2, 0.1), [ new LayeredPainter([tCliff, tForestFloor], [2]), new SmoothElevationPainter(ELEVATION_SET, heightRavineValley, 2), paintClass(clHill) ], avoidClasses(clPlayer, 6, clBaseResource, 2, clHill, 5), scaleByMapSize(1, 3)); if (size > 150 && ravine.length) { log("Placing huts in ravines..."); createObjectGroupsByAreasDeprecated( new RandomGroup( [ new SimpleObject(aCeltHouse, 0, 1, 4, 5), new SimpleObject(aCeltLongHouse, 1, 1, 4, 5) ], true, clHillDeco), 0, [avoidClasses(clHillDeco, 3), stayClasses(clHill, 3)], ravine.length * 5, 20, ravine); createObjectGroupsByAreasDeprecated( new RandomGroup([new SimpleObject(aCeltHomestead, 1, 1, 1, 1)], true, clHillDeco), 0, [avoidClasses(clHillDeco, 5), stayClasses(clHill, 4)], ravine.length * 2, 100, ravine); // Place noise createAreasInAreas( new ClumpPlacer(size * 0.3, 0.94, 0.05, 0.1), [ new LayeredPainter([tCliff, tForestFloor], [2]), new SmoothElevationPainter(ELEVATION_SET, heightRavineValley, 2) ], [avoidClasses(clHillDeco, 2), stayClasses(clHill, 0)], ravine.length * 2, 20, ravine); createAreasInAreas( new ClumpPlacer(size * 0.1, 0.3, 0.05, 0.1), [ new LayeredPainter([tCliff, tForestFloor], [2]), new SmoothElevationPainter(ELEVATION_SET, heightRavineHill, 2), paintClass(clHill) ], [avoidClasses(clHillDeco, 2), borderClasses(clHill, 15, 1)], ravine.length * 2, 50, ravine); } } Engine.SetProgress(50); var explorablePoints = []; var playerClass = getTileClass(clPlayer); var hillDecoClass = getTileClass(clHillDeco); for (var ix = 0; ix < mapSize; ix++) for (var iz = 0; iz < mapSize; iz++) { let position = new Vector2D(ix, iz); let h = g_Map.getHeight(position); if(h > 15 && h < 45 && playerClass.countMembersInRadius(ix, iz, 1) == 0) explorablePoints.push(position); if (h > 35 && randBool(0.1) || h < 15 && randBool(0.05) && hillDecoClass.countMembersInRadius(ix, iz, 1) == 0) placeObject(ix + randFloat(0, 1), iz + randFloat(0, 1), pickRandom(aTrees), 0, randomAngle()); } var explorableArea = g_Map.createArea(explorablePoints); Engine.SetProgress(55); // Add some general noise - after placing height dependant trees for (var ix = 0; ix < mapSize; ix++) { var x = ix / (mapSize + 1.0); for (var iz = 0; iz < mapSize; iz++) { let position = new Vector2D(ix, iz); var z = iz / (mapSize + 1.0); var h = g_Map.getHeight(position); var pn = playerNearness(x,z); var n = (noise0.get(x,z) - 0.5) * 10; g_Map.setHeight(position, h + (n * pn)); } } Engine.SetProgress(60); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(400, 6000, 0.8); var [forestTreesJoin, forestTrees] = getTreeCounts(forestTrees, forestTrees, 0.25); var num = forestTrees / (scaleByMapSize(6, 16) * numPlayers); createAreasInAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new TerrainPainter(pForest), paintClass(clForest) ], avoidClasses(clPlayer, 5, clBaseResource, 4, clForest, 6, clHill, 4), num, 100, [explorableArea] ); var num = forestTreesJoin / (scaleByMapSize(4,6) * numPlayers); createAreasInAreas( new ClumpPlacer(forestTreesJoin / num, 0.1, 0.1, 1), [ new TerrainPainter(pForest), paintClass(clForest), paintClass(clForestJoin) ], [avoidClasses(clPlayer, 5, clBaseResource, 4, clForestJoin, 5, clHill, 4), borderClasses(clForest, 1, 4)], num, 100, [explorableArea] ); Engine.SetProgress(70); log("Creating grass patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new LayeredPainter([[tGrass, tGrassPatch], [tGrassPatch, tGrass], [tGrass, tGrassPatch]], [1, 1]), avoidClasses(clForest, 0, clHill, 2, clPlayer, 5), scaleByMapSize(15, 45)); log("Creating chopped forest patches..."); for (let size of [scaleByMapSize(20, 120)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new TerrainPainter(tForestFloor), avoidClasses(clForest, 1, clHill, 2, clPlayer, 5), scaleByMapSize(4, 12)); Engine.SetProgress(75); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 1,2, 0,4), new SimpleObject(oStoneLarge, 0,1, 0,4)], true, clRock); createObjectGroupsByAreasDeprecated(group, 0, [avoidClasses(clHill, 4, clForest, 2, clPlayer, 20, clRock, 10)], scaleByMapSize(6,20), 100, [explorableArea] ); log("Creating small stone mines..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsByAreasDeprecated(group, 0, [avoidClasses(clHill, 4, clForest, 2, clPlayer, 20, clRock, 10)], scaleByMapSize(6,20), 100, [explorableArea] ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalSmall, 1,2, 0,4), new SimpleObject(oMetalLarge, 0,1, 0,4)], true, clMetal); createObjectGroupsByAreasDeprecated(group, 0, [avoidClasses(clHill, 4, clForest, 2, clPlayer, 20, clMetal, 10, clRock, 5)], scaleByMapSize(6,20), 100, [explorableArea] ); Engine.SetProgress(80); log("Creating wildlife..."); group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); createObjectGroupsByAreasDeprecated(group, 0, avoidClasses(clHill, 4, clForest, 0, clPlayer, 0, clBaseResource, 20), 3 * numPlayers, 100, [explorableArea] ); group = new SimpleGroup( [new SimpleObject(oBoar, 2,3, 0,5)], true, clFood ); createObjectGroupsByAreasDeprecated(group, 0, avoidClasses(clHill, 4, clForest, 0, clPlayer, 0, clBaseResource, 15), numPlayers, 50, [explorableArea] ); group = new SimpleGroup( [new SimpleObject(oBear, 1,1, 0,4)], false, clFood ); createObjectGroupsByAreasDeprecated(group, 0, avoidClasses(clHill, 4, clForest, 0, clPlayer, 20), scaleByMapSize(3, 12), 200, [explorableArea] ); Engine.SetProgress(85); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 20, clHill, 4, clFood, 20), randIntInclusive(3, 12) * numPlayers + 2, 50 ); log("Creating decorative props..."); group = new SimpleGroup( [ new SimpleObject(aWoodA, 1,2, 0,1), new SimpleObject(aWoodB, 1,3, 0,1), new SimpleObject(aWheel, 0,2, 0,1), new SimpleObject(aWoodLarge, 0,1, 0,1), new SimpleObject(aBarrel, 0,2, 0,1) ], true ); createObjectGroupsByAreasDeprecated( group, 0, avoidClasses(clForest, 0), scaleByMapSize(5, 50), 50, [explorableArea] ); Engine.SetProgress(90); log("Creating straggler trees..."); var types = [oOak, oOakLarge, oPine, oAleppoPine]; var num = Math.floor(stragglerTrees / types.length); for (let type of types) createObjectGroupsByAreasDeprecated( new SimpleGroup([new SimpleObject(type, 1, 1, 0, 3)], true, clForest), 0, avoidClasses(clForest, 4, clHill, 5, clPlayer, 10, clBaseResource, 2, clMetal, 5, clRock, 5), num, 20, [explorableArea]); Engine.SetProgress(95); log("Creating grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassLarge, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsByAreasDeprecated(group, 0, avoidClasses(clHill, 2, clPlayer, 2), scaleByMapSize(50, 300), 20, [explorableArea] ); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setTerrainAmbientColor(0.44,0.51,0.56); setUnitsAmbientColor(0.44,0.51,0.56); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/atlas_mountains.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/atlas_mountains.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/atlas_mountains.js (revision 21000) @@ -1,223 +1,223 @@ Engine.LoadLibrary("rmgen"); const tPrimary = ["medit_rocks_grass", "medit_rocks_grass", "medit_rocks_grass", "medit_rocks_grass", "medit_rocks_grass_shrubs", "medit_rocks_shrubs"]; const tGrass = ["medit_rocks_grass_shrubs", "medit_rocks_shrubs"]; const tForestFloor = "medit_grass_field_dry"; const tCliff = "medit_cliff_italia"; const tGrassDirt = "medit_rocks_grass"; const tDirt = "medit_dirt"; const tRoad = "medit_city_tile"; const tRoadWild = "medit_city_tile"; const tGrass2 = "medit_rocks_grass_shrubs"; const tGrassPatch = "medit_grass_wild"; const oCarob = "gaia/flora_tree_carob"; const oAleppoPine = "gaia/flora_tree_aleppo_pine"; const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; 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 oWoodTreasure = "gaia/special_treasure_wood"; const oFoodTreasure = "gaia/special_treasure_food_bin"; 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.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; const aCarob = "actor|flora/trees/carob.xml"; const aAleppoPine = "actor|flora/trees/aleppo_pine.xml"; const pForest1 = [tForestFloor + TERRAIN_SEPARATOR + oCarob, tForestFloor]; const pForest2 = [tForestFloor + TERRAIN_SEPARATOR + oAleppoPine, tForestFloor]; const heightLand = 3; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); -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 clTreasure = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clTreasure = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oCarob, "count": scaleByMapSize(2, 8) }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(10); createBumps(avoidClasses(clPlayer, 9)); createMountains(tCliff, avoidClasses(clPlayer, 20, clHill, 8), clHill, scaleByMapSize(20, 120)); Engine.SetProgress(25); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tGrass, tForestFloor, tForestFloor, pForest1, pForest2], avoidClasses(clPlayer, 20, clForest, 14, clHill, 1), clForest, forestTrees); Engine.SetProgress(40); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [tGrassDirt,tDirt], [2], avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 10), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createLayeredPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], [tGrass2,tGrassPatch], [1], avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 10), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(50); 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, clMetal, 10, clRock, 5, clHill, 2), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 2), clMetal ); Engine.SetProgress(60); 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [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(clForest, 0, clPlayer, 0, clHill, 0)); Engine.SetProgress(75); createFood( [ [new SimpleObject(oSheep, 5, 7, 0, 4)], [new SimpleObject(oDeer, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), clFood); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ randIntInclusive(3, 12) * numPlayers + 2 ], avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); log("Creating food treasures..."); var group = new SimpleGroup( [new SimpleObject(oFoodTreasure, 2,3, 0,2)], true, clTreasure ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 18, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); log("Creating food treasures..."); group = new SimpleGroup( [new SimpleObject(oWoodTreasure, 2,3, 0,2)], true, clTreasure ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 18, clHill, 1), 3 * numPlayers, 50 ); Engine.SetProgress(80); createStragglerTrees( [oCarob, oAleppoPine], avoidClasses(clForest, 1, clHill, 1, clPlayer, 10, clMetal, 6, clRock, 6, clTreasure, 4), clForest, stragglerTrees); createStragglerTrees( [aCarob, aAleppoPine], stayClasses(clHill, 2), clForest, stragglerTrees / 5); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setFogFactor(0.2); setFogThickness(0.14); setPPEffect("hdr"); setPPContrast(0.45); setPPSaturation(0.56); setPPBloom(0.1); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/belgian_uplands.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/belgian_uplands.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/belgian_uplands.js (revision 21000) @@ -1,413 +1,413 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("heightmap"); const tPrimary = ["temp_grass", "temp_grass_b", "temp_grass_c", "temp_grass_d", "temp_grass_long_b", "temp_grass_clovers_2", "temp_grass_mossy", "temp_grass_plants"]; const heightLand = 0; var g_Map = new RandomMap(heightLand, tPrimary); var numPlayers = getNumPlayers(); var mapSize = g_Map.getSize(); var mapCenter = g_Map.getCenter(); // Function to apply a heightmap function setReliefmap(reliefmap) { // g_Map.height = reliefmap; for (var x = 0; x <= mapSize; x++) for (var y = 0; y <= mapSize; y++) g_Map.setHeight(new Vector2D(x, y), reliefmap[x][y]); } // Set target min and max height depending on map size to make average stepness the same on all map sizes var heightRange = {"min": MIN_HEIGHT * mapSize / 8192, "max": MAX_HEIGHT * mapSize / 8192}; // Set average water coverage var averageWaterCoverage = 1/3; // NOTE: Since errosion is not predictable actual water coverage might differ much with the same value if (mapSize < 200) // Sink the waterlevel on tiny maps to ensure enough space averageWaterCoverage = 2/3 * averageWaterCoverage; var heightSeaGround = -MIN_HEIGHT + heightRange.min + averageWaterCoverage * (heightRange.max - heightRange.min); var heightSeaGroundAdjusted = heightSeaGround + MIN_HEIGHT; setWaterHeight(heightSeaGround); // Prepare terrain texture by height placement var textueByHeight = []; // Deep water textueByHeight.push({"upperHeightLimit": heightRange.min + 1/3 * (heightSeaGroundAdjusted - heightRange.min), "terrain": "temp_sea_rocks"}); // Medium deep water (with fish) var terrains = ["temp_sea_weed"]; terrains = terrains.concat(terrains, terrains, terrains, terrains); terrains = terrains.concat(terrains, terrains, terrains, terrains); terrains.push("temp_sea_weed|gaia/fauna_fish"); textueByHeight.push({"upperHeightLimit": heightRange.min + 2/3 * (heightSeaGroundAdjusted - heightRange.min), "terrain": terrains}); // Flat Water textueByHeight.push({"upperHeightLimit": heightRange.min + 3/3 * (heightSeaGroundAdjusted - heightRange.min), "terrain": "temp_mud_a"}); // Water surroundings/bog (with stone/metal some rabits and bushes) var terrains = ["temp_plants_bog", "temp_plants_bog_aut", "temp_dirt_gravel_plants", "temp_grass_d"]; terrains = terrains.concat(terrains, terrains, terrains, terrains, terrains); terrains = ["temp_plants_bog|gaia/flora_bush_temperate"].concat(terrains, terrains); terrains = ["temp_dirt_gravel_plants|gaia/geology_metal_temperate", "temp_dirt_gravel_plants|gaia/geology_stone_temperate", "temp_plants_bog|gaia/fauna_rabbit"].concat(terrains, terrains); terrains = ["temp_plants_bog_aut|gaia/flora_tree_dead"].concat(terrains, terrains); textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 1/6 * (heightRange.max - heightSeaGroundAdjusted), "terrain": terrains}); // Juicy grass near bog textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 2/6 * (heightRange.max - heightSeaGroundAdjusted), "terrain": ["temp_grass", "temp_grass_d", "temp_grass_long_b", "temp_grass_plants"]}); // Medium level grass // var testActor = "actor|geology/decal_stone_medit_a.xml"; textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 3/6 * (heightRange.max - heightSeaGroundAdjusted), "terrain": ["temp_grass", "temp_grass_b", "temp_grass_c", "temp_grass_mossy"]}); // Long grass near forest border textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 4/6 * (heightRange.max - heightSeaGroundAdjusted), "terrain": ["temp_grass", "temp_grass_b", "temp_grass_c", "temp_grass_d", "temp_grass_long_b", "temp_grass_clovers_2", "temp_grass_mossy", "temp_grass_plants"]}); // Forest border (With wood/food plants/deer/rabits) var terrains = ["temp_grass_plants|gaia/flora_tree_euro_beech", "temp_grass_mossy|gaia/flora_tree_poplar", "temp_grass_mossy|gaia/flora_tree_poplar_lombardy", "temp_grass_long|gaia/flora_bush_temperate", "temp_mud_plants|gaia/flora_bush_temperate", "temp_mud_plants|gaia/flora_bush_badlands", "temp_grass_long|gaia/flora_tree_apple", "temp_grass_clovers|gaia/flora_bush_berry", "temp_grass_clovers_2|gaia/flora_bush_grapes", "temp_grass_plants|gaia/fauna_deer", "temp_grass_long_b|gaia/fauna_rabbit"]; var numTerrains = terrains.length; for (var i = 0; i < numTerrains; i++) terrains.push("temp_grass_plants"); textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 5/6 * (heightRange.max - heightSeaGroundAdjusted), "terrain": terrains}); // Unpassable woods textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 6/6 * (heightRange.max - heightSeaGroundAdjusted), "terrain": ["temp_grass_mossy|gaia/flora_tree_oak", "temp_forestfloor_pine|gaia/flora_tree_pine", "temp_grass_mossy|gaia/flora_tree_oak", "temp_forestfloor_pine|gaia/flora_tree_pine", "temp_mud_plants|gaia/flora_tree_dead", "temp_plants_bog|gaia/flora_tree_oak_large", "temp_dirt_gravel_plants|gaia/flora_tree_aleppo_pine", "temp_forestfloor_autumn|gaia/flora_tree_carob"]}); var minTerrainDistToBorder = 3; Engine.SetProgress(5); // - Generate Heightmap // - Search valid start position tiles // - Choose a good start position derivation (largest distance between closest players) // - Restart the loop if start positions are invalid or two players are to close to each other var goodStartPositionsFound = false; var minDistBetweenPlayers = 16 + mapSize / 16; // Don't set this higher than 25 for tiny maps! It will take forever with 8 players! var enoughTiles = false; var tries = 0; var lowerHeightLimit = textueByHeight[3].upperHeightLimit; var upperHeightLimit = textueByHeight[6].upperHeightLimit; while (!goodStartPositionsFound) { tries++; log("Starting giant while loop try " + tries); // Generate reliefmap var myReliefmap = clone(g_Map.height); setRandomHeightmap(heightRange.min, heightRange.max, myReliefmap); for (var i = 0; i < 50 + mapSize/4; i++) // Cycles depend on mapsize (more cycles -> bigger structures) globalSmoothHeightmap(0.8, myReliefmap); rescaleHeightmap(heightRange.min, heightRange.max, myReliefmap); setReliefmap(myReliefmap); // Find good start position tiles var possibleStartPositions = []; var neededDistance = 7; var distToBorder = 2 * neededDistance; // Has to be greater than neededDistance! Otherwise the check if low/high ground is near will fail... // Check for valid points by height for (var x = distToBorder + minTerrainDistToBorder; x < mapSize - distToBorder - minTerrainDistToBorder; x++) for (var y = distToBorder + minTerrainDistToBorder; y < mapSize - distToBorder - minTerrainDistToBorder; y++) { let position = new Vector2D(x, y); let actualHeight = g_Map.getHeight(position); if (actualHeight > lowerHeightLimit && actualHeight < upperHeightLimit) { // Check for points within a valid area by height (rectangular since faster) var isPossible = true; for (var offX = - neededDistance; offX <= neededDistance; offX++) for (var offY = - neededDistance; offY <= neededDistance; offY++) { var testHeight = g_Map.getHeight(Vector2D.add(position, new Vector2D(offX, offY))); if (testHeight <= lowerHeightLimit || testHeight >= upperHeightLimit) { isPossible = false; break; } } if (isPossible) possibleStartPositions.push([x, y]); } } // Trying to reduce the number of possible start locations... // Reduce to tiles in a circle of mapSize / 2 distance to the center (to avoid players placed in corners) var possibleStartPositionsTemp = []; for (var i = 0; i < possibleStartPositions.length; i++) { if (Math.euclidDistance2D(...possibleStartPositions[i], mapCenter.x, mapCenter.y) < mapSize / 2) possibleStartPositionsTemp.push(possibleStartPositions[i]); } possibleStartPositions = clone(possibleStartPositionsTemp); // Reduce to tiles near low and high ground (Rectangular check since faster) to make sure each player has access to all resource types. var possibleStartPositionsTemp = []; var maxDistToResources = distToBorder; // Has to be <= distToBorder! var minNumLowTiles = 10; var minNumHighTiles = 10; for (var i = 0; i < possibleStartPositions.length; i++) { var numLowTiles = 0; var numHighTiles = 0; for (var dx = - maxDistToResources; dx < maxDistToResources; dx++) { for (var dy = - maxDistToResources; dy < maxDistToResources; dy++) { var testHeight = g_Map.getHeight(new Vector2D(possibleStartPositions[i][0] + dx, possibleStartPositions[i][1] + dy)); if (testHeight < lowerHeightLimit) numLowTiles++; if (testHeight > upperHeightLimit) numHighTiles++; if (numLowTiles > minNumLowTiles && numHighTiles > minNumHighTiles) break; } if (numLowTiles > minNumLowTiles && numHighTiles > minNumHighTiles) break; } if (numLowTiles > minNumLowTiles && numHighTiles > minNumHighTiles) possibleStartPositionsTemp.push(possibleStartPositions[i]); } possibleStartPositions = clone(possibleStartPositionsTemp); if(possibleStartPositions.length > numPlayers) enoughTiles = true; else { enoughTiles = false; log("possibleStartPositions.length < numPlayers, possibleStartPositions.length = " + possibleStartPositions.length + ", numPlayers = " + numPlayers); } // Find a good start position derivation if (enoughTiles) { // Get some random start location derivations. NOTE: Iterating over all possible derivations is just too much (valid points * numPlayers) var maxTries = 100000; var possibleDerivations = []; for (var i = 0; i < maxTries; i++) { var vector = []; for (var p = 0; p < numPlayers; p++) vector.push(randIntExclusive(0, possibleStartPositions.length)); possibleDerivations.push(vector); } // Choose the start location derivation with the greatest minimum distance between players var maxMinDist = 0; for (var d = 0; d < possibleDerivations.length; d++) { var minDist = 2 * mapSize; for (var p1 = 0; p1 < numPlayers - 1; p1++) { for (var p2 = p1 + 1; p2 < numPlayers; p2++) { if (p1 != p2) { minDist = Math.min(minDist, Math.euclidDistance2D(...possibleStartPositions[possibleDerivations[d][p1]], ...possibleStartPositions[possibleDerivations[d][p2]])); if (minDist < maxMinDist) break; } } if (minDist < maxMinDist) break; } if (minDist > maxMinDist) { maxMinDist = minDist; var bestDerivation = possibleDerivations[d]; } } if (maxMinDist > minDistBetweenPlayers) { goodStartPositionsFound = true; log("Exiting giant while loop after " + tries + " tries with a minimum player distance of " + maxMinDist); } else log("maxMinDist <= " + minDistBetweenPlayers + ", maxMinDist = " + maxMinDist); } } Engine.SetProgress(60); log("Painting terrain by height and add props..."); var propDensity = 1; // 1 means as determined in the loop, less for large maps as set below if (mapSize > 500) propDensity = 1/4; else if (mapSize > 400) propDensity = 3/4; for(var x = minTerrainDistToBorder; x < mapSize - minTerrainDistToBorder; x++) { for (var y = minTerrainDistToBorder; y < mapSize - minTerrainDistToBorder; y++) { let position = new Vector2D(x, y); var textureMinHeight = heightRange.min; for (var i = 0; i < textueByHeight.length; i++) { if (g_Map.getHeight(position) >= textureMinHeight && g_Map.getHeight(position) <= textueByHeight[i].upperHeightLimit) { createTerrain(textueByHeight[i].terrain).place(position); // Add some props at... if (i == 0) // ...deep water { if (randBool(propDensity / 100)) placeObject(x, y, "actor|props/flora/pond_lillies_large.xml", 0, randomAngle()); else if (randBool(propDensity / 40)) placeObject(x, y, "actor|props/flora/water_lillies.xml", 0, randomAngle()); } if (i == 1) // ...medium water (with fish) { if (randBool(propDensity / 200)) placeObject(x, y, "actor|props/flora/pond_lillies_large.xml", 0, randomAngle()); else if (randBool(propDensity / 100)) placeObject(x, y, "actor|props/flora/water_lillies.xml", 0, randomAngle()); } if (i == 2) // ...low water/mud { if (randBool(propDensity / 200)) placeObject(x, y, "actor|props/flora/water_log.xml", 0, randomAngle()); else if (randBool(propDensity / 100)) placeObject(x, y, "actor|props/flora/water_lillies.xml", 0, randomAngle()); else if (randBool(propDensity / 40)) placeObject(x, y, "actor|geology/highland_c.xml", 0, randomAngle()); else if (randBool(propDensity / 20)) placeObject(x, y, "actor|props/flora/reeds_pond_lush_b.xml", 0, randomAngle()); else if (randBool(propDensity / 10)) placeObject(x, y, "actor|props/flora/reeds_pond_lush_a.xml", 0, randomAngle()); } if (i == 3) // ...water suroundings/bog { if (randBool(propDensity / 200)) placeObject(x, y, "actor|props/flora/water_log.xml", 0, randomAngle()); else if (randBool(propDensity / 100)) placeObject(x, y, "actor|geology/highland_c.xml", 0, randomAngle()); else if (randBool(propDensity / 40)) placeObject(x, y, "actor|props/flora/reeds_pond_lush_a.xml", 0, randomAngle()); } if (i == 4) // ...low height grass { if (randBool(propDensity / 800)) placeObject(x, y, "actor|props/flora/grass_field_flowering_tall.xml", 0, randomAngle()); else if (randBool(propDensity / 400)) placeObject(x, y, "actor|geology/gray_rock1.xml", 0, randomAngle()); else if (randBool(propDensity / 200)) placeObject(x, y, "actor|props/flora/bush_tempe_sm_lush.xml", 0, randomAngle()); else if (randBool(propDensity / 100)) placeObject(x, y, "actor|props/flora/bush_tempe_b.xml", 0, randomAngle()); else if (randBool(propDensity / 40)) placeObject(x, y, "actor|props/flora/grass_soft_small_tall.xml", 0, randomAngle()); } if (i == 5) // ...medium height grass { if (randBool(propDensity / 800)) placeObject(x, y, "actor|geology/decal_stone_medit_a.xml", 0, randomAngle()); else if (randBool(propDensity / 400)) placeObject(x, y, "actor|props/flora/decals_flowers_daisies.xml", 0, randomAngle()); else if (randBool(propDensity / 200)) placeObject(x, y, "actor|props/flora/bush_tempe_underbrush.xml", 0, randomAngle()); else if (randBool(propDensity / 100)) placeObject(x, y, "actor|props/flora/grass_soft_small_tall.xml", 0, randomAngle()); else if (randBool(propDensity / 40)) placeObject(x, y, "actor|props/flora/grass_temp_field.xml", 0, randomAngle()); } if (i == 6) // ...high height grass { if (randBool(propDensity / 400)) placeObject(x, y, "actor|geology/stone_granite_boulder.xml", 0, randomAngle()); else if (randBool(propDensity / 200)) placeObject(x, y, "actor|props/flora/foliagebush.xml", 0, randomAngle()); else if (randBool(propDensity / 100)) placeObject(x, y, "actor|props/flora/bush_tempe_underbrush.xml", 0, randomAngle()); else if (randBool(propDensity / 40)) placeObject(x, y, "actor|props/flora/grass_soft_small_tall.xml", 0, randomAngle()); else if (randBool(propDensity / 20)) placeObject(x, y, "actor|props/flora/ferns.xml", 0, randomAngle()); } if (i == 7) // ...forest border (with wood/food plants/deer/rabits) { if (randBool(propDensity / 400)) placeObject(x, y, "actor|geology/highland_c.xml", 0, randomAngle()); else if (randBool(propDensity / 200)) placeObject(x, y, "actor|props/flora/bush_tempe_a.xml", 0, randomAngle()); else if (randBool(propDensity / 100)) placeObject(x, y, "actor|props/flora/ferns.xml", 0, randomAngle()); else if (randBool(propDensity / 40)) placeObject(x, y, "actor|props/flora/grass_soft_tuft_a.xml", 0, randomAngle()); } if (i == 8) // ...woods { if (randBool(propDensity / 200)) placeObject(x, y, "actor|geology/highland2_moss.xml", 0, randomAngle()); else if (randBool(propDensity / 100)) placeObject(x, y, "actor|props/flora/grass_soft_tuft_a.xml", 0, randomAngle()); else if (randBool(propDensity / 40)) placeObject(x, y, "actor|props/flora/ferns.xml", 0, randomAngle()); } break; } else textureMinHeight = textueByHeight[i].upperHeightLimit; } } } Engine.SetProgress(90); if (isNomad()) - placePlayersNomad(createTileClass(), new HeightConstraint(lowerHeightLimit, upperHeightLimit)); + placePlayersNomad(g_Map.createTileClass(), new HeightConstraint(lowerHeightLimit, upperHeightLimit)); else { log("Placing players and starting resources..."); let playerIDs = sortAllPlayers(); let resourceDistance = 8; let resourceSpacing = 1; let resourceCount = 4; for (let i = 0; i < numPlayers; ++i) { let playerPos = new Vector2D(possibleStartPositions[bestDerivation[i]][0], possibleStartPositions[bestDerivation[i]][1]); placeCivDefaultStartingEntities(playerPos, playerIDs[i], false); for (let j = 1; j <= 4; ++j) { let uAngle = BUILDING_ORIENTATION - Math.PI * (2-j) / 2; for (let k = 0; k < resourceCount; ++k) { let pos = Vector2D.sum([ playerPos, new Vector2D(resourceDistance, 0).rotate(-uAngle), new Vector2D(k * resourceSpacing, 0).rotate(-uAngle - Math.PI/2), new Vector2D(-0.75 * resourceSpacing * Math.floor(resourceCount / 2), 0).rotate(-uAngle - Math.PI/2) ]); placeObject(pos.x, pos.y, j % 2 ? "gaia/flora_tree_cypress" : "gaia/flora_bush_berry", 0, randomAngle()); } } } } g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/botswanan_haven.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/botswanan_haven.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/botswanan_haven.js (revision 21000) @@ -1,397 +1,397 @@ Engine.LoadLibrary("rmgen"); const tGrassA = "savanna_shrubs_a_wetseason"; const tGrassB = "savanna_shrubs_a"; const tCliff = "savanna_cliff_a"; const tHill = "savanna_grass_a_wetseason"; const tMud = "savanna_mud_a"; const tShoreBlend = "savanna_grass_b_wetseason"; const tShore = "savanna_riparian_wet"; const tWater = "savanna_mud_a"; const tCityTile = "savanna_tile_a"; const oBush = "gaia/flora_bush_temperate"; const oBaobab = "gaia/flora_tree_baobab"; const oToona = "gaia/flora_tree_toona"; const oBerryBush = "gaia/flora_bush_berry"; const oGazelle = "gaia/fauna_gazelle"; const oZebra = "gaia/fauna_zebra"; const oWildebeest = "gaia/fauna_wildebeest"; const oLion = "gaia/fauna_lion"; const oRhino = "gaia/fauna_rhino"; const oCrocodile = "gaia/fauna_crocodile"; const oElephant = "gaia/fauna_elephant_north_african"; const oElephantInfant = "gaia/fauna_elephant_african_infant"; const oLioness = "gaia/fauna_lioness"; const oRabbit = "gaia/fauna_rabbit"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oStoneSmall = "gaia/geology_stone_savanna_small"; const oMetalLarge = "gaia/geology_metal_savanna_slabs"; const aGrass = "actor|props/flora/grass_field_lush_tall.xml"; const aGrass2 = "actor|props/flora/grass_tropic_field_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aRockLarge = "actor|geology/stone_granite_med.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; const aReeds2 = "actor|props/flora/reeds_pond_lush_b.xml"; const aLillies = "actor|props/flora/water_lillies.xml"; const aBushMedium = "actor|props/flora/bush_tropic_b.xml"; const aBushSmall = "actor|props/flora/bush_tropic_a.xml"; const aShrub = "actor|props/flora/shrub_tropic_plant_flower.xml"; const aFlower = "actor|props/flora/flower_bright.xml"; const aPalm = "actor|props/flora/shrub_fanpalm.xml"; const heightMarsh = -2; const heightLand = 3; const heightHill = 15; const heightOffsetBump1 = 2; const heightOffsetBump2 = 1; var g_Map = new RandomMap(heightLand, tShoreBlend); const numPlayers = getNumPlayers(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clForest = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tCityTile, "innerTerrain": tCityTile }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oBaobab }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(15); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.6, 0.1, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump1, 2), avoidClasses(clPlayer, 13), scaleByMapSize(300, 800)); log("Creating hills..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.5), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], avoidClasses(clPlayer, 20, clHill, 15, clWater, 0), scaleByMapSize(1, 4) * numPlayers * 3); log("Creating marshes..."); for (let i = 0; i < 2; ++i) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(6, 12)), Math.floor(scaleByMapSize(15, 60)), 0.8), [ new LayeredPainter([tShoreBlend, tShore, tWater], [1, 1]), new SmoothElevationPainter(ELEVATION_SET, heightMarsh, 3), paintClass(clWater) ], avoidClasses(clPlayer, 25, clWater, Math.round(scaleByMapSize(7, 16) * randFloat(0.8, 1.35))), scaleByMapSize(4, 20)); log("Creating reeds..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(aReeds, 20, 40, 0, 4), new SimpleObject(aReeds2, 20, 40, 0, 4), new SimpleObject(aLillies, 10, 30, 0, 4) ], true), 0, stayClasses(clWater, 1), scaleByMapSize(400, 1000), 100); Engine.SetProgress(40); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump2, 2), stayClasses(clWater, 2), scaleByMapSize(50, 100)); log("Creating mud patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(2, Math.floor(scaleByMapSize(3, 6)), size, 1), [ new LayeredPainter([tGrassA, tGrassB, tMud], [1, 1]), paintClass(clDirt) ], avoidClasses(clWater, 1, clHill, 0, clDirt, 5, clPlayer, 8), scaleByMapSize(15, 45)); Engine.SetProgress(50); log("Creating stone mines..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4) ], true, clRock), 0, [avoidClasses(clWater, 0, clPlayer, 20, clRock, 10, clHill, 1)], scaleByMapSize(4, 16), 100); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oStoneSmall, 2, 5, 1, 3)], true, clRock), 0, [avoidClasses(clWater, 0, clPlayer, 20, clRock, 10, clHill, 1)], scaleByMapSize(4, 16), 100); log("Creating metal mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal), 0, [avoidClasses(clWater, 0, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1)], scaleByMapSize(4, 16), 100); Engine.SetProgress(60); log("Creating small decorative rocks..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aRockMedium, 1, 3, 0, 1)], true), 0, avoidClasses(clPlayer, 1), scaleByMapSize(16, 262), 50); Engine.SetProgress(65); log("Creating large decorative rocks..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(aRockLarge, 1, 2, 0, 1), new SimpleObject(aRockMedium, 1, 3, 0, 2) ], true), 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(8, 131), 50); Engine.SetProgress(70); log("Creating lions..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(oLion, 0, 1, 0, 4), new SimpleObject(oLioness, 2, 3, 0, 4) ], true, clFood), 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11, clHill, 1), scaleByMapSize(4, 12), 50); log("Creating zebras..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oZebra, 4, 6, 0, 4)], true, clFood), 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 13), 3 * numPlayers, 50); log("Creating wildebeest..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oWildebeest, 2, 4, 0, 4)], true, clFood), 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 13), 3 * numPlayers, 50); log("Creating crocodiles..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oCrocodile, 2, 3, 0, 4)], true, clFood), 0, [avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 13), stayClasses(clWater, 3)], 5 * numPlayers, 200); log("Creating gazelles..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oGazelle, 4, 6, 0, 4)], true, clFood), 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 13), 3 * numPlayers, 50); Engine.SetProgress(75); log("Creating rabbits..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oRabbit, 6, 8, 0, 2)], true, clFood), 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 13), 6 * numPlayers, 50); log("Creating rhinos..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oRhino, 1, 1, 0, 2)], true, clFood), 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 13), 3 * numPlayers, 50); log("Creating elephants..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oElephant, 2, 3, 0, 4), new SimpleObject(oElephantInfant, 1, 1, 0, 4)], true, clFood), 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 13), 3 * numPlayers, 50); log("Creating berry bushes..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oBerryBush, 5, 7, 0, 4)], true, clFood), 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50); Engine.SetProgress(80); createStragglerTrees( [oToona, oBaobab, oBush, oBush], avoidClasses(clForest, 1, clWater, 1, clHill, 1, clPlayer, 13, clMetal, 1, clRock, 1), clForest, scaleByMapSize(60, 500)); Engine.SetProgress(85); log("Creating small grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aGrassShort, 1, 2, 0, 1, -Math.PI / 8, Math.PI / 8)]), 0, avoidClasses(clWater, 2, clPlayer, 13, clDirt, 0), scaleByMapSize(13, 200)); Engine.SetProgress(90); log("Creating large grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup([ new SimpleObject(aGrass, 2, 4, 0, 1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5, -Math.PI / 8, Math.PI / 8) ]), 0, avoidClasses(clWater, 3, clPlayer, 13, clDirt, 1, clForest, 0), scaleByMapSize(13, 200)); Engine.SetProgress(95); log("Creating bushes..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2) ]), 0, avoidClasses(clWater, 1, clPlayer, 13, clDirt, 1), scaleByMapSize(13, 200), 50); log("Creating flowering shrubs..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aShrub, 1, 1, 0, 2)]), 0, avoidClasses(clWater, 1, clPlayer, 13, clDirt, 1), scaleByMapSize(13, 200), 50); log("Creating decorative palms..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aPalm, 1, 3, 0, 2)]), 0, avoidClasses(clWater, 2, clPlayer, 12, clDirt, 1), scaleByMapSize(13, 200), 50); log("Creating shrubs,flowers and other decorations..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(aFlower, 0, 6, 0, 2), new SimpleObject(aGrass2, 2, 5, 0, 2) ]), 0, avoidClasses(clWater, 1, clHill, 1, clPlayer, 13, clDirt, 1), scaleByMapSize(13, 200), 50); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("cirrus"); setWaterColor(0.553, 0.635, 0.345); setWaterTint(0.161, 0.514, 0.635); setWaterMurkiness(0.8); setWaterWaviness(1.0); setWaterType("clap"); setFogThickness(0.25); setFogFactor(0.6); setPPEffect("hdr"); setPPSaturation(0.44); setPPBloom(0.3); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/caledonian_meadows.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/caledonian_meadows.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/caledonian_meadows.js (revision 21000) @@ -1,447 +1,447 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); Engine.LoadLibrary("heightmap"); var g_Map = new RandomMap(0, "whiteness"); /** * Drags a path to a target height smoothing it at the edges and return some points along the path. */ function placeRandomPathToHeight( start, target, targetHeight, tileClass = undefined, texture = "road_rome_a", width = 10, distance = 4, strength = 0.08, heightmap = g_Map.height) { let pathPoints = []; let position = clone(start); while (true) { rectangularSmoothToHeight(position, width, width, targetHeight, strength, heightmap); if (texture) { let painters = [new TerrainPainter(texture)]; if (tileClass !== undefined) painters.push(paintClass(tileClass)); createArea( new ClumpPlacer(diskArea(0.3 * width), 1, 1, 1, position), painters); } pathPoints.push({ "x": position.x, "y": position.y, "dist": distance }); // Check for distance to target and setup for next loop if needed if (Math.euclidDistance2D(position.x, position.y, target.x, target.y) < distance / 2) break; let angleToTarget = getAngle(position.x, position.y, target.x, target.y); let angleOff = randFloat(-1, 1) * Math.PI / 2; position.x += distance * Math.cos(angleToTarget + angleOff); position.y += distance * Math.sin(angleToTarget + angleOff); } return pathPoints; } /** * Design resource spots */ // Mines let decorations = [ "actor|geology/gray1.xml", "actor|geology/gray_rock1.xml", "actor|geology/highland1.xml", "actor|geology/highland2.xml", "actor|geology/highland3.xml", "actor|geology/highland_c.xml", "actor|geology/highland_d.xml", "actor|geology/highland_e.xml", "actor|props/flora/bush.xml", "actor|props/flora/bush_dry_a.xml", "actor|props/flora/bush_highlands.xml", "actor|props/flora/bush_tempe_a.xml", "actor|props/flora/bush_tempe_b.xml", "actor|props/flora/ferns.xml" ]; function placeMine(point, centerEntity) { placeObject(point.x, point.y, centerEntity, 0, randomAngle()); let quantity = randIntInclusive(11, 23); let dAngle = 2 * Math.PI / quantity; for (let i = 0; i < quantity; ++i) { let angle = dAngle * randFloat(i, i + 1); let dist = randFloat(2, 5); placeObject(point.x + dist * Math.cos(angle), point.y + dist * Math.sin(angle), pickRandom(decorations), 0, randomAngle()); } } // Food, fences with domestic animals g_WallStyles.other = { "overlap": 0, "fence": readyWallElement("other/fence_long", "gaia"), "fence_short": readyWallElement("other/fence_short", "gaia"), "bench": { "angle": Math.PI / 2, "length": 1.5, "indent": 0, "bend": 0, "templateName": "other/bench" }, "sheep": { "angle": 0, "length": 0, "indent": 0.75, "bend": 0, "templateName": "gaia/fauna_sheep" }, "foodBin": { "angle": Math.PI / 2, "length": 1.5, "indent": 0, "bend": 0, "templateName": "gaia/special_treasure_food_bin" }, "farmstead": { "angle": Math.PI, "length": 0, "indent": -3, "bend": 0, "templateName": "structures/brit_farmstead" } }; let fences = [ new Fortress("fence", [ "foodBin", "farmstead", "bench", "turn_0.25", "sheep", "turn_0.25", "fence", "turn_0.25", "sheep", "turn_0.25", "fence", "turn_0.25", "sheep", "turn_0.25", "fence" ]), new Fortress("fence", [ "foodBin", "farmstead", "fence", "turn_0.25", "sheep", "turn_0.25", "fence", "turn_0.25", "sheep", "turn_0.25", "bench", "sheep", "fence", "turn_0.25", "sheep", "turn_0.25", "fence" ]), new Fortress("fence", [ "foodBin", "farmstead", "turn_0.5", "bench", "turn_-0.5", "fence_short", "turn_0.25", "sheep", "turn_0.25", "fence", "turn_0.25", "sheep", "turn_0.25", "fence", "turn_0.25", "sheep", "turn_0.25", "fence_short", "sheep", "fence" ]), new Fortress("fence", [ "foodBin", "farmstead", "turn_0.5", "fence_short", "turn_-0.5", "bench", "turn_0.25", "sheep", "turn_0.25", "fence", "turn_0.25", "sheep", "turn_0.25", "fence", "turn_0.25", "sheep", "turn_0.25", "fence_short", "sheep", "fence" ]), new Fortress("fence", [ "foodBin", "farmstead", "fence", "turn_0.25", "sheep", "turn_0.25", "bench", "sheep", "fence", "turn_0.25", "sheep", "turn_0.25", "fence_short", "sheep", "fence", "turn_0.25", "sheep", "turn_0.25", "fence_short", "sheep", "fence" ]) ]; let num = fences.length; for (let i = 0; i < num; ++i) fences.push(new Fortress("fence", clone(fences[i].wall).reverse())); // Groves, only Wood let groveEntities = ["gaia/flora_bush_temperate", "gaia/flora_tree_euro_beech"]; let groveActors = [ "actor|geology/highland1_moss.xml", "actor|geology/highland2_moss.xml", "actor|props/flora/bush.xml", "actor|props/flora/bush_dry_a.xml", "actor|props/flora/bush_highlands.xml", "actor|props/flora/bush_tempe_a.xml", "actor|props/flora/bush_tempe_b.xml", "actor|props/flora/ferns.xml" ]; -let clGrove = createTileClass(); +let clGrove = g_Map.createTileClass(); function placeGrove(point) { placeObject(point.x, point.y, pickRandom(["structures/gaul_outpost", "gaia/flora_tree_oak_new"]), 0, randomAngle()); let quantity = randIntInclusive(20, 30); let dAngle = 2 * Math.PI / quantity; for (let i = 0; i < quantity; ++i) { let angle = dAngle * randFloat(i, i + 1); let dist = randFloat(2, 5); let objectList = groveEntities; if (i % 3 == 0) objectList = groveActors; let position = Vector2D.add(point, new Vector2D(dist, 0).rotate(-angle)); placeObject(position.x, position.y, pickRandom(objectList), 0, randomAngle()); createArea( new ClumpPlacer(5, 1, 1, 1, position), [ new TerrainPainter("temp_grass_plants"), paintClass(clGrove) ]); } } // Camps with fire and gold treasure function placeCamp(point, centerEntity = "actor|props/special/eyecandy/campfire.xml", otherEntities = ["gaia/special_treasure_metal", "gaia/special_treasure_standing_stone", "units/brit_infantry_slinger_b", "units/brit_infantry_javelinist_b", "units/gaul_infantry_slinger_b", "units/gaul_infantry_javelinist_b", "units/gaul_champion_fanatic", "actor|props/special/common/waypoint_flag.xml", "actor|props/special/eyecandy/barrel_a.xml", "actor|props/special/eyecandy/basket_celt_a.xml", "actor|props/special/eyecandy/crate_a.xml", "actor|props/special/eyecandy/dummy_a.xml", "actor|props/special/eyecandy/handcart_1.xml", "actor|props/special/eyecandy/handcart_1_broken.xml", "actor|props/special/eyecandy/sack_1.xml", "actor|props/special/eyecandy/sack_1_rough.xml" ] ) { placeObject(point.x, point.y, centerEntity, 0, randomAngle()); let quantity = randIntInclusive(5, 11); let dAngle = 2 * Math.PI / quantity; for (let i = 0; i < quantity; ++i) { let angle = dAngle * randFloat(i, i + 1); let dist = randFloat(1, 3); placeObject(point.x + dist * Math.cos(angle), point.y + dist * Math.sin(angle), pickRandom(otherEntities), 0, randomAngle()); } } function placeStartLocationResources(point, foodEntities = ["gaia/flora_bush_berry", "gaia/fauna_chicken", "gaia/fauna_chicken"]) { let currentAngle = randomAngle(); // Stone and chicken let dAngle = 4/9 * Math.PI; let angle = currentAngle + randFloat(1, 3) * dAngle / 4; let stonePosition = Vector2D.add(point, new Vector2D(12, 0).rotate(-angle)); placeMine(stonePosition, "gaia/geology_stonemine_temperate_quarry"); currentAngle += dAngle; // Wood let quantity = 80; dAngle = 2 * Math.PI / quantity / 3; for (let i = 0; i < quantity; ++i) { angle = currentAngle + randFloat(0, dAngle); let objectList = groveEntities; if (i % 2 == 0) objectList = groveActors; let woodPosition = Vector2D.add(point, new Vector2D(randFloat(10, 15), 0).rotate(-angle)); placeObject(woodPosition.x, woodPosition.y, pickRandom(objectList), 0, randomAngle()); createArea( new ClumpPlacer(5, 1, 1, 1, woodPosition), [ new TerrainPainter("temp_grass_plants"), paintClass(clGrove) ]); currentAngle += dAngle; } // Metal and chicken dAngle = 2 * Math.PI * 2 / 9; angle = currentAngle + dAngle * randFloat(1, 3) / 4; let metalPosition = Vector2D.add(point, new Vector2D(13, 0).rotate(-angle)); placeMine(metalPosition, "gaia/geology_metal_temperate_slabs"); currentAngle += dAngle; // Berries quantity = 15; dAngle = 2 * Math.PI / quantity * 2 / 9; for (let i = 0; i < quantity; ++i) { angle = currentAngle + randFloat(0, dAngle); let berriesPosition = Vector2D.add(point, new Vector2D(randFloat(10, 15), 0).rotate(-angle)); placeObject(berriesPosition.x, berriesPosition.y, pickRandom(foodEntities), 0, randomAngle()); currentAngle += dAngle; } } /** * Environment settings */ setBiome("alpine"); g_Environment.Fog.FogColor = { "r": 0.8, "g": 0.8, "b": 0.8, "a": 0.01 }; g_Environment.Water.WaterBody.Colour = { "r" : 0.3, "g" : 0.05, "b" : 0.1, "a" : 0.1 }; g_Environment.Water.WaterBody.Murkiness = 0.4; /** * Base terrain shape generation and settings */ let heightScale = (g_Map.size + 256) / 768 / 4; let heightRange = { "min": MIN_HEIGHT * heightScale, "max": MAX_HEIGHT * heightScale }; // Water coverage let averageWaterCoverage = 1/5; // NOTE: Since terrain generation is quite unpredictable actual water coverage might vary much with the same value let heightSeaGround = -MIN_HEIGHT + heightRange.min + averageWaterCoverage * (heightRange.max - heightRange.min); // Water height in environment and the engine let heightSeaGroundAdjusted = heightSeaGround + MIN_HEIGHT; // Water height in RMGEN setWaterHeight(heightSeaGround); log("Generating terrain using diamon-square..."); let medH = (heightRange.min + heightRange.max) / 2; let initialHeightmap = [[medH, medH], [medH, medH]]; setBaseTerrainDiamondSquare(heightRange.min, heightRange.max, initialHeightmap, 0.8); log("Apply erosion..."); for (let i = 0; i < 5; ++i) splashErodeMap(0.1); rescaleHeightmap(heightRange.min, heightRange.max); Engine.SetProgress(25); let heighLimits = [ heightRange.min + 1/3 * (heightSeaGroundAdjusted - heightRange.min), // 0 Deep water heightRange.min + 2/3 * (heightSeaGroundAdjusted - heightRange.min), // 1 Medium Water heightRange.min + (heightSeaGroundAdjusted - heightRange.min), // 2 Shallow water heightSeaGroundAdjusted + 1/8 * (heightRange.max - heightSeaGroundAdjusted), // 3 Shore heightSeaGroundAdjusted + 2/8 * (heightRange.max - heightSeaGroundAdjusted), // 4 Low ground heightSeaGroundAdjusted + 3/8 * (heightRange.max - heightSeaGroundAdjusted), // 5 Player and path height heightSeaGroundAdjusted + 4/8 * (heightRange.max - heightSeaGroundAdjusted), // 6 High ground heightSeaGroundAdjusted + 5/8 * (heightRange.max - heightSeaGroundAdjusted), // 7 Lower forest border heightSeaGroundAdjusted + 6/8 * (heightRange.max - heightSeaGroundAdjusted), // 8 Forest heightSeaGroundAdjusted + 7/8 * (heightRange.max - heightSeaGroundAdjusted), // 9 Upper forest border heightSeaGroundAdjusted + (heightRange.max - heightSeaGroundAdjusted)]; // 10 Hilltop let playerHeight = (heighLimits[4] + heighLimits[5]) / 2; // Average player height log("Determining height-dependent biome..."); // Texture and actor presets let myBiome = []; myBiome.push({ // 0 Deep water "texture": ["shoreline_stoney_a"], "actor": [["gaia/fauna_fish", "actor|geology/stone_granite_boulder.xml"], 0.02], "textureHS": ["alpine_mountainside"], "actorHS": [["gaia/fauna_fish"], 0.1] }); myBiome.push({ // 1 Medium Water "texture": ["shoreline_stoney_a", "alpine_shore_rocks"], "actor": [["actor|geology/stone_granite_boulder.xml", "actor|geology/stone_granite_med.xml"], 0.03], "textureHS": ["alpine_mountainside"], "actorHS": [["actor|geology/stone_granite_boulder.xml", "actor|geology/stone_granite_med.xml"], 0.0] }); myBiome.push({ // 2 Shallow water "texture": ["alpine_shore_rocks"], "actor": [["actor|props/flora/reeds_pond_dry.xml", "actor|geology/stone_granite_large.xml", "actor|geology/stone_granite_med.xml", "actor|props/flora/reeds_pond_lush_b.xml"], 0.2], "textureHS": ["alpine_mountainside"], "actorHS": [["actor|props/flora/reeds_pond_dry.xml", "actor|geology/stone_granite_med.xml"], 0.1] }); myBiome.push({ // 3 Shore "texture": ["alpine_shore_rocks_grass_50", "alpine_grass_rocky"], "actor": [["gaia/flora_tree_pine", "gaia/flora_bush_badlands", "actor|geology/highland1_moss.xml", "actor|props/flora/grass_soft_tuft_a.xml", "actor|props/flora/bush.xml"], 0.3], "textureHS": ["alpine_mountainside"], "actorHS": [["actor|props/flora/grass_soft_tuft_a.xml"], 0.1] }); myBiome.push({ // 4 Low ground "texture": ["alpine_dirt_grass_50", "alpine_grass_rocky"], "actor": [["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_soft_tuft_a.xml", "actor|props/flora/bush.xml", "actor|props/flora/grass_medit_flowering_tall.xml"], 0.2], "textureHS": ["alpine_grass_rocky"], "actorHS": [["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_soft_tuft_a.xml"], 0.1] }); myBiome.push({ // 5 Player and path height "texture": ["new_alpine_grass_c", "new_alpine_grass_b", "new_alpine_grass_d"], "actor": [["actor|geology/stone_granite_small.xml", "actor|props/flora/grass_soft_small.xml", "actor|props/flora/grass_medit_flowering_tall.xml"], 0.2], "textureHS": ["alpine_grass_rocky"], "actorHS": [["actor|geology/stone_granite_small.xml", "actor|props/flora/grass_soft_small.xml"], 0.1] }); myBiome.push({ // 6 High ground "texture": ["new_alpine_grass_a", "alpine_grass_rocky"], "actor": [["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_tufts_a.xml", "actor|props/flora/bush_highlands.xml", "actor|props/flora/grass_medit_flowering_tall.xml"], 0.2], "textureHS": ["alpine_grass_rocky"], "actorHS": [["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_tufts_a.xml"], 0.1] }); myBiome.push({ // 7 Lower forest border "texture": ["new_alpine_grass_mossy", "alpine_grass_rocky"], "actor": [["gaia/flora_tree_pine", "gaia/flora_tree_oak", "actor|props/flora/grass_tufts_a.xml", "gaia/flora_bush_berry", "actor|geology/highland2_moss.xml", "gaia/fauna_goat", "actor|props/flora/bush_tempe_underbrush.xml"], 0.3], "textureHS": ["alpine_cliff_c"], "actorHS": [["actor|props/flora/grass_tufts_a.xml", "actor|geology/highland2_moss.xml"], 0.1] }); myBiome.push({ // 8 Forest "texture": ["alpine_forrestfloor"], "actor": [["gaia/flora_tree_pine", "gaia/flora_tree_pine", "gaia/flora_tree_pine", "gaia/flora_tree_pine", "actor|geology/highland2_moss.xml", "actor|props/flora/bush_highlands.xml"], 0.5], "textureHS": ["alpine_cliff_c"], "actorHS": [["actor|geology/highland2_moss.xml", "actor|geology/stone_granite_med.xml"], 0.1] }); myBiome.push({ // 9 Upper forest border "texture": ["alpine_forrestfloor_snow", "new_alpine_grass_dirt_a"], "actor": [["gaia/flora_tree_pine", "actor|geology/snow1.xml"], 0.3], "textureHS": ["alpine_cliff_b"], "actorHS": [["actor|geology/stone_granite_med.xml", "actor|geology/snow1.xml"], 0.1] }); myBiome.push({ // 10 Hilltop "texture": ["alpine_cliff_a", "alpine_cliff_snow"], "actor": [["actor|geology/highland1.xml"], 0.05], "textureHS": ["alpine_cliff_c"], "actorHS": [["actor|geology/highland1.xml"], 0.0] }); let [playerIDs, startLocations] = sortPlayersByLocation(getStartLocationsByHeightmap({ "min": heighLimits[4], "max": heighLimits[5] }, 1000, 30)); Engine.SetProgress(30); log("Smooth player locations..."); for (let p = 0; p < playerIDs.length; ++p) rectangularSmoothToHeight(startLocations[p], 35, 35, playerHeight, 0.7); log("Creating paths..."); let tchm = getTileCenteredHeightmap(); // Calculate tileCenteredHeightMap (This has nothing to to with TILE_CENTERED_HEIGHT_MAP which should be false) let pathPoints = []; -let clPath = createTileClass(); +let clPath = g_Map.createTileClass(); for (let i = 0; i < startLocations.length; ++i) { let start = startLocations[i]; let target = startLocations[(i + 1) % startLocations.length]; pathPoints = pathPoints.concat(placeRandomPathToHeight(start, target, playerHeight, clPath)); } Engine.SetProgress(45); log("Determining resource locations..."); let avoidPoints = clone(startLocations); for (let i = 0; i < avoidPoints.length; ++i) avoidPoints[i].dist = 30; let resourceSpots = getPointsByHeight({ "min": (heighLimits[3] + heighLimits[4]) / 2, "max": (heighLimits[5] + heighLimits[6]) / 2 }, avoidPoints, clPath); Engine.SetProgress(55); /** * Divide tiles in areas by height and avoid paths */ let areas = heighLimits.map(heightLimit => []); for (let x = 0; x < tchm.length; ++x) for (let y = 0; y < tchm[0].length; ++y) { if (g_Map.tileClasses[clPath].inclusionCount[x][y] > 0) // Avoid paths continue; let minHeight = heightRange.min; for (let h = 0; h < heighLimits.length; ++h) { if (tchm[x][y] >= minHeight && tchm[x][y] <= heighLimits[h]) { areas[h].push(new Vector2D(x, y)); break; } else minHeight = heighLimits[h]; } } /** * Get max slope of each area */ let slopeMap = getSlopeMap(); let minSlope = []; let maxSlope = []; for (let h = 0; h < heighLimits.length; ++h) { minSlope[h] = Infinity; maxSlope[h] = 0; for (let point of areas[h]) { let slope = slopeMap[point.x][point.y]; if (slope > maxSlope[h]) maxSlope[h] = slope; if (slope < minSlope[h]) minSlope[h] = slope; } } log("Painting areas by height and slope..."); for (let h = 0; h < heighLimits.length; ++h) for (let point of areas[h]) { let actor; let texture = pickRandom(myBiome[h].texture); if (slopeMap[point.x][point.y] < 0.4 * (minSlope[h] + maxSlope[h])) { if (randBool(myBiome[h].actor[1])) actor = pickRandom(myBiome[h].actor[0]); } else { texture = pickRandom(myBiome[h].textureHS); if (randBool(myBiome[h].actorHS[1])) actor = pickRandom(myBiome[h].actorHS[0]); } g_Map.setTexture(point, texture); if (actor) placeObject(point.x + randFloat(0, 1), point.y + randFloat(0, 1), actor, 0, randomAngle()); } Engine.SetProgress(80); log("Placing players..."); if (isNomad()) - placePlayersNomad(createTileClass(), new HeightConstraint(heighLimits[4], heighLimits[5])); + placePlayersNomad(g_Map.createTileClass(), new HeightConstraint(heighLimits[4], heighLimits[5])); else for (let p = 0; p < playerIDs.length; ++p) { let point = startLocations[p]; placeCivDefaultStartingEntities(point, playerIDs[p], true); placeStartLocationResources(startLocations[p]); } log("Placing resources, farmsteads, groves and camps..."); for (let i = 0; i < resourceSpots.length; ++i) { let choice = i % 5; if (choice == 0) placeMine(resourceSpots[i], "gaia/geology_stonemine_temperate_formation"); if (choice == 1) placeMine(resourceSpots[i], "gaia/geology_metal_temperate_slabs"); if (choice == 2) placeCustomFortress(resourceSpots[i].x, resourceSpots[i].y, pickRandom(fences), "other", 0, randomAngle()); if (choice == 3) placeGrove(resourceSpots[i]); if (choice == 4) placeCamp(resourceSpots[i]); } g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/cantabrian_highlands.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/cantabrian_highlands.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/cantabrian_highlands.js (revision 21000) @@ -1,282 +1,282 @@ Engine.LoadLibrary("rmgen"); const tPrimary = "temp_grass_long"; 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 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_plants_bog"; const tWater = "temp_mud_a"; const oOak = "gaia/flora_tree_oak"; const oOakLarge = "gaia/flora_tree_oak_large"; const oApple = "gaia/flora_tree_apple"; const oPine = "gaia/flora_tree_pine"; const oAleppoPine = "gaia/flora_tree_aleppo_pine"; 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_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 aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; const aLillies = "actor|props/flora/pond_lillies_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.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; const pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oOak, tGrassDForest + TERRAIN_SEPARATOR + oOakLarge, tGrassDForest]; const pForestP = [tGrassPForest + TERRAIN_SEPARATOR + oPine, tGrassPForest + TERRAIN_SEPARATOR + oAleppoPine, tGrassPForest]; const heightSeaGround = -7; const heightLand = 3; const heightHill = 20; var g_Map = new RandomMap(heightLand, tPrimary); var numPlayers = getNumPlayers(); var mapSize = g_Map.getSize(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var playerHillRadius = defaultPlayerBaseRadius() / (isNomad() ? 1.5 : 1); var [playerIDs, playerPosition, playerAngle] = playerPlacementCircle(fractionToTiles(0.35)); log("Creating player hills and ramps..."); for (let i = 0; i < numPlayers; ++i) { createArea( new ClumpPlacer(diskArea(playerHillRadius), 0.95, 0.6, 10, playerPosition[i]), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clPlayer) ]); let angle = playerAngle[i] + Math.PI * (1 + randFloat(-1, 1) / 8); createPassage({ "start": Vector2D.add(playerPosition[i], new Vector2D(playerHillRadius + 15, 0).rotate(-angle)), "end": Vector2D.add(playerPosition[i], new Vector2D(playerHillRadius - 3, 0).rotate(-angle)), "startWidth": 10, "endWidth": 10, "smoothWidth": 2, "tileClass": clPlayer, "terrain": tHill, "edgeTerrain": tCliff }); } placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "Walls": false, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oOak, "count": 2 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(10); log("Creating lakes..."); var numLakes = Math.round(scaleByMapSize(1,4) * numPlayers); var waterAreas = createAreas( new ClumpPlacer(scaleByMapSize(100, 250), 0.8, 0.1, 10), [ new LayeredPainter([tShoreBlend, tShore, tWater], [1, 1]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 6), paintClass(clWater) ], avoidClasses(clPlayer, 2, clWater, 20), numLakes ); Engine.SetProgress(15); log("Creating reeds..."); var group = new SimpleGroup( [new SimpleObject(aReeds, 5,10, 0,4), new SimpleObject(aLillies, 0,1, 0,4)], true ); createObjectGroupsByAreasDeprecated(group, 0, [borderClasses(clWater, 3, 0), stayClasses(clWater, 1)], numLakes, 100, waterAreas ); Engine.SetProgress(20); log("Creating fish..."); createObjectGroupsByAreasDeprecated( new SimpleGroup( [new SimpleObject(oFish, 1,1, 0,1)], true, clFood ), 0, [stayClasses(clWater, 4), avoidClasses(clFood, 8)], numLakes / 4, 50, waterAreas ); Engine.SetProgress(25); createBumps(avoidClasses(clWater, 2, clPlayer, 0)); Engine.SetProgress(30); log("Creating hills..."); createHills([tCliff, tCliff, tHill], avoidClasses(clPlayer, 2, clWater, 5, clHill, 15), clHill, scaleByMapSize(1, 4) * numPlayers); Engine.SetProgress(35); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tGrass, tGrassDForest, tGrassPForest, pForestP, pForestD], avoidClasses(clPlayer, 1, clWater, 3, clForest, 17, clHill, 1), clForest, forestTrees); Engine.SetProgress(40); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tGrass,tGrassA],[tGrassA,tGrassB], [tGrassB,tGrassC]], [1,1], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(45); log("Creating grass patches..."); createLayeredPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], [tGrassPatchBlend, tGrassPatch], [1], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(50); 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, 0, clForest, 1, clPlayer, 5, clRock, 10, clHill, 1), clRock); Engine.SetProgress(55); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 0, clForest, 1, clPlayer, 5, clMetal, 10, clRock, 5, clHill, 1), clMetal ); Engine.SetProgress(60); 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [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, 0, clForest, 0, clPlayer, 0, clHill, 0)); Engine.SetProgress(70); createFood( [ [new SimpleObject(oSheep, 2, 3, 0, 2)], [new SimpleObject(oDeer, 5, 7, 0, 4)] ], [ 3 * numPlayers, 3 * numPlayers ], avoidClasses(clWater, 0, clForest, 0, clPlayer, 1, clHill, 1, clFood, 20), clFood); Engine.SetProgress(80); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ randIntInclusive(1, 4) * numPlayers + 2 ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); Engine.SetProgress(85); createStragglerTrees( [oOak, oOakLarge, oPine, oApple], avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 1, clMetal, 6, clRock, 6), clForest, stragglerTrees); Engine.SetProgress(90); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("cirrus"); setWaterColor(0.447, 0.412, 0.322); // muddy brown setWaterTint(0.447, 0.412, 0.322); setWaterMurkiness(1.0); setWaterWaviness(3.0); setWaterType("lake"); setFogThickness(0.25); setFogFactor(0.4); setPPEffect("hdr"); setPPSaturation(0.62); setPPContrast(0.62); setPPBloom(0.3); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/canyon.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/canyon.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/canyon.js (revision 21000) @@ -1,347 +1,347 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); 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 tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; 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 oSecondaryHuntableAnimal = g_Gaia.secondaryHuntableAnimal; const oStoneLarge = g_Gaia.stoneLarge; const oStoneSmall = g_Gaia.stoneSmall; const oMetalLarge = g_Gaia.metalLarge; const oWoodTreasure = "gaia/special_treasure_wood"; const oFoodTreasure = "gaia/special_treasure_food_bin"; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; const aRockLarge = g_Decoratives.rockLarge; const aRockMedium = g_Decoratives.rockMedium; const aBushMedium = g_Decoratives.bushMedium; const aBushSmall = g_Decoratives.bushSmall; const aTree = g_Decoratives.tree; const pForest1 = [tForestFloor2 + TERRAIN_SEPARATOR + oTree1, tForestFloor2 + TERRAIN_SEPARATOR + oTree2, tForestFloor2]; const pForest2 = [tForestFloor1 + TERRAIN_SEPARATOR + oTree4, tForestFloor1 + TERRAIN_SEPARATOR + oTree5, tForestFloor1]; const heightLand = 3; const heightHill = 30; var g_Map = new RandomMap(heightHill, tMainTerrain); var numPlayers = getNumPlayers(); var mapSize = g_Map.getSize(); var mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clHill2 = createTileClass(); -var clForest = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clLand = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clHill2 = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clLand = g_Map.createTileClass(); var playerCanyonRadius = scaleByMapSize(18, 32); var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); log("Reserving space for the players, their initial forests and some less space therein without trees..."); for (let i = 0; i < numPlayers; ++i) for (let j = 1; j <= 2; ++j) createArea( new ClumpPlacer(diskArea(playerCanyonRadius / j), 0.65, 0.1, 10, playerPosition[i]), [ new LayeredPainter([tMainTerrain, tMainTerrain], [2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 2), paintClass(j == 1 || isNomad() ? clLand : clPlayer) ]); log("Creating center area..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.16)), 0.7, 0.1, 10, mapCenter), [ new LayeredPainter([tMainTerrain, tMainTerrain], [3]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 3), paintClass(clLand) ]); createArea( new ClumpPlacer(150, 0.6, 0.3, 10, mapCenter), paintClass(clHill)); log("Creating hills..."); for (let i = 0; i < scaleByMapSize(9, 16); ++i) createArea( new PathPlacer( new Vector2D(randIntExclusive(1, mapSize), randIntExclusive(1, mapSize)), new Vector2D(randIntExclusive(1, mapSize), randIntExclusive(1, mapSize)), scaleByMapSize(11, 16), 0.4, 3 * scaleByMapSize(1, 4), 0.1, 0), [ new SmoothElevationPainter(ELEVATION_SET, heightHill, 3), paintClass(clHill2) ], avoidClasses(clPlayer, 6, clHill2, 3, clHill, 2)); for (let g = 0; g < scaleByMapSize(5, 30); ++g) { let position = new Vector2D(randIntInclusive(1, mapSize - 1), randIntInclusive(1, mapSize - 1)); let newarea = createArea( new ClumpPlacer(diskArea(fractionToTiles(0.06)), 0.7, 0.1, 10, position), [ new LayeredPainter([tMainTerrain, tMainTerrain], [3]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 3), paintClass(clLand) ], avoidClasses(clLand, 6)); if (newarea !== null) { var distances = []; var d1 = 9999; var d2 = 9999; var p1 = -1; var p2 = 0; for (let i = 0; i < numPlayers; ++i) distances.push(position.distanceTo(playerPosition[i])); for (let a = 0; a < numPlayers; ++a) { if (d1 >= distances[a]) { d2 = d1; d1 = distances[a]; p2 = p1; p1 = a; } else if (d2 >= distances[a]) { d2 = distances[a]; p2 = a; } } for (let playerID of [p1, p2]) if (playerPosition[playerID]) createArea( new PathPlacer(position, playerPosition[playerID], scaleByMapSize(11, 17), 0.4, scaleByMapSize(3, 12), 0.1, 0.1), [ new LayeredPainter([tMainTerrain, tMainTerrain], [3]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 3), paintClass(clLand) ]); } } for (let i = 0; i < numPlayers; ++i) { log("Creating path from player to center and to neighbor..."); let neighbor = i + 1 < numPlayers ? i + 1 : 0; for (let position of [playerPosition[neighbor], mapCenter]) createArea( new PathPlacer( playerPosition[i], position, scaleByMapSize(8, 13), 0.4, 3 * scaleByMapSize(1, 4), 0.1, 0), [ new LayeredPainter([tRoadWild, tRoad], [1]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 2), paintClass(clLand), paintClass(clHill) ]); } log("Painting center place..."); createArea( new ClumpPlacer(150, 0.6, 0.3, 10, mapCenter), new LayeredPainter([tRoad, tRoad], [1])); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], // PlayerTileClass already marked above "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoad, "innerTerrain": tRoad, "radius": playerCanyonRadius / 3 }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ], "distance": 11 }, "Trees": { "template": oTree1 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); paintTerrainBasedOnHeight(3.1, 29, 0, tCliff); paintTileClassBasedOnHeight(3.1, 32, 0, clHill2); createBumps([avoidClasses(clPlayer, 2), stayClasses(clLand, 2)]); createHills([tCliff, tCliff, tHill], [avoidClasses(clPlayer, 2, clHill, 8, clHill2, 8), stayClasses(clLand, 5)], clHill, scaleByMapSize(10, 40)); // create hills outside the canyon createHills([tCliff, tCliff, tMainTerrain], avoidClasses(clLand, 1, clHill, 1), clHill, scaleByMapSize(20, 150), undefined, undefined, undefined, undefined, 40); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], [avoidClasses(clPlayer, 1, clForest, 15, clHill, 1, clHill2, 0), stayClasses(clLand, 4)], clForest, forestTrees); Engine.SetProgress(50); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], [1,1], [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 4, clHill2, 0), stayClasses(clLand, 3)], scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tTier4Terrain, [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 4, clHill2, 0), stayClasses(clLand, 3)], scaleByMapSize(15, 45), clDirt); 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, 3, clRock, 10, clHill, 1, clHill2, 1), stayClasses(clLand, 2)], clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], [avoidClasses(clForest, 1, clPlayer, 3, clMetal, 10, clRock, 5, clHill, 1, clHill2, 1), stayClasses(clLand, 2)], clMetal ); Engine.SetProgress(65); var planetm = 1; if (currentBiome() == "tropic") planetm = 8; 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ 3 * scaleByMapSize(16, 262), 3 * scaleByMapSize(8, 131), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200) ], avoidClasses(clForest, 0, clPlayer, 0, clHill, 0)); log("Creating actor trees..."); var group = new SimpleGroup( [new SimpleObject(aTree, 1,1, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clLand, 5), scaleByMapSize(200, 800), 50 ); Engine.SetProgress(70); createFood( [ [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], [avoidClasses(clForest, 0, clPlayer, 4, clHill, 1, clFood, 20, clHill2, 1), stayClasses(clLand, 3)], clFood); createFood( [ [new SimpleObject(oFruitBush, 5, 7, 0, 4)] ], [ 3 * numPlayers ], [avoidClasses(clForest, 0, clPlayer, 4, clHill, 1, clFood, 10, clHill2, 1), stayClasses(clLand, 3)], clFood); Engine.SetProgress(85); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], [avoidClasses(clForest, 1, clHill, 1, clPlayer, 9, clMetal, 6, clRock, 6, clHill2, 1), stayClasses(clLand, 3)], clForest, stragglerTrees); log("Creating treasures..."); for (let i = 0; i < randIntInclusive(3, 8); ++i) for (let template of [oFoodTreasure, oWoodTreasure]) placeObject(mapCenter.x + randFloat(-7, 7), mapCenter.y + randFloat(-7, 7), template, 0, randomAngle()); placePlayersNomad( clPlayer, [stayClasses(clLand, 4), avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clHill2, 4, clFood, 2)]); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/continent.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/continent.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/continent.js (revision 21000) @@ -1,256 +1,256 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); 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 tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; 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 aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; 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]; const heightSeaGround = -5; const heightLand = 3; var g_Map = new RandomMap(heightSeaGround, tWater); var numPlayers = getNumPlayers(); var mapSize = g_Map.getSize(); var mapCenter = g_Map.getCenter(); -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 clLand = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clLand = g_Map.createTileClass(); log("Creating continent..."); createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 12)), Math.floor(scaleByMapSize(60, 700)), 1, mapCenter, 0, [Math.floor(fractionToTiles(0.33))]), [ new SmoothElevationPainter(ELEVATION_SET, heightLand, 4), paintClass(clLand) ]); var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.25)); log("Ensuring initial player land..."); for (let i = 0; i < numPlayers; ++i) createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 9)), Math.floor(scaleByMapSize(5, 20)), 1, playerPosition[i], 0, [Math.floor(scaleByMapSize(23, 50))]), [ new SmoothElevationPainter(ELEVATION_SET, heightLand, 4), paintClass(clLand) ]); Engine.SetProgress(20); paintTerrainBasedOnHeight(3, 4, 3, tMainTerrain); paintTerrainBasedOnHeight(1, 3, 0, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree1, "count": 2 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(30); createBumps([avoidClasses(clPlayer, 10), stayClasses(clLand, 5)]); if (randBool()) createHills([tMainTerrain, tCliff, tHill], [avoidClasses(clPlayer, 20, clHill, 15, clBaseResource, 3), stayClasses(clLand, 5)], clHill, scaleByMapSize(1, 4) * numPlayers); else createMountains(tCliff, [avoidClasses(clPlayer, 20, clHill, 15, clBaseResource, 3), stayClasses(clLand, 5)], clHill, scaleByMapSize(1, 4) * numPlayers); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], [avoidClasses(clPlayer, 20, clForest, 17, clHill, 0, clBaseResource,2), stayClasses(clLand, 4)], clForest, forestTrees); Engine.SetProgress(50); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], [1,1], [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), stayClasses(clLand, 5)], scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tTier4Terrain, [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), stayClasses(clLand, 5)], scaleByMapSize(15, 45), clDirt); Engine.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), stayClasses(clLand, 6)], clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], [avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), stayClasses(clLand, 6)], clMetal ); Engine.SetProgress(65); // create decoration var planetm = 1; if (currentBiome() == "tropic") planetm = 8; 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200) ], [avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 5)]); Engine.SetProgress(70); createFood( [ [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], [avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 5)], clFood); createFood( [ [new SimpleObject(oFruitBush, 5, 7, 0, 4)] ], [ 3 * numPlayers ], [avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), stayClasses(clLand, 5)], clFood); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 25 * numPlayers ], avoidClasses(clLand, 2, clFood, 20), clFood); Engine.SetProgress(85); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], [avoidClasses(clForest, 7, clHill, 1, clPlayer, 9, clMetal, 6, clRock, 6), stayClasses(clLand, 7)], clForest, stragglerTrees); placePlayersNomad( clPlayer, [stayClasses(clLand, 4), avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)]); setWaterWaviness(1.0); setWaterType("ocean"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/corinthian_isthmus.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/corinthian_isthmus.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/corinthian_isthmus.js (revision 21000) @@ -1,268 +1,268 @@ Engine.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", "medit_grass_field_a"]; 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 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 aDecorativeRock = "actor|geology/stone_granite_med.xml"; const pForest = [tForestFloor, tForestFloor + TERRAIN_SEPARATOR + oCarob, tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERRAIN_SEPARATOR + oSDatePalm, tForestFloor]; var heightSeaGround = -4; var heightLand = 3; var g_Map = new RandomMap(heightLand, tHill); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -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 clGrass = createTileClass(); -var clHill = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clGrass = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); log("Creating the main river"); var riverAngle = randomAngle(); var riverWidth = scaleByMapSize(15, 70); var riverStart = new Vector2D(mapCenter.x, 0).rotateAround(riverAngle, mapCenter); var riverEnd = new Vector2D(mapCenter.x, mapSize).rotateAround(riverAngle, mapCenter); createArea( new PathPlacer(riverStart, riverEnd, riverWidth, 0.2, 15 * scaleByMapSize(1, 3), 0.04, 0.01), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4)); log("Creating small puddles at the map border to ensure players being separated..."); for (let point of [riverStart, riverEnd]) createArea( new ClumpPlacer(diskArea(riverWidth / 2), 0.95, 0.6, 10, point), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4)); log("Creating passage connecting the two riversides..."); var passageStart = riverStart.rotateAround(Math.PI / 2, mapCenter); var passageEnd = riverEnd.rotateAround(Math.PI / 2, mapCenter); createArea( new PathPlacer( passageStart, passageEnd, scaleByMapSize(10, 30), 0.5, 3 * scaleByMapSize(1, 4), 0.1, 0.01), new SmoothElevationPainter(ELEVATION_SET, heightLand, 4)); paintTerrainBasedOnHeight(-6, 1, 1, tWater); paintTerrainBasedOnHeight(1, 2, 1, tShore); paintTerrainBasedOnHeight(2, 5, 1, tGrass); paintTileClassBasedOnHeight(-6, 0.5, 1, clWater); placePlayerBases({ "PlayerPlacement": playerPlacementRiver(riverAngle, fractionToTiles(0.6)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "Walls": "towers", "CityPatch": { "outerTerrain": tCityPlaza, "innerTerrain": tCity }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oCarob, "count": 2 }, "Decoratives": { "template": aBush1 } }); Engine.SetProgress(40); createBumps(avoidClasses(clWater, 2, clPlayer, 20)); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tForestFloor, tForestFloor, tForestFloor, pForest, pForest], avoidClasses(clPlayer, 20, clForest, 17, clWater, 2, clBaseResource, 3), clForest, forestTrees); Engine.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), scaleByMapSize(15, 45), clDirt); Engine.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), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(60); 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, 4, clPlayer, 15, clRock, 10, clWater, 4, clHill, 4), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clForest, 4, clPlayer, 15, clMetal, 10, clRock, 5, clWater, 4, clHill, 4), clMetal ); Engine.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, 5, clBaseResource, 6, clHill, 1, clRock, 6, clMetal, 6)); Engine.SetProgress(70); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 3 * scaleByMapSize(5, 20) ], [avoidClasses(clFood, 10), stayClasses(clWater, 5)], clFood); 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, 10, clBaseResource, 6, clWater, 1, clFood, 10, clHill, 1, clRock, 6, clMetal, 6), clFood); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10, clRock, 6, clMetal, 6), clFood); Engine.SetProgress(90); createStragglerTrees( [oDatePalm, oSDatePalm, oCarob, oFanPalm, oPoplar, oCypress], avoidClasses(clForest, 1, clWater, 2, clPlayer, 8, clBaseResource, 6, clMetal, 6, clRock, 6, clHill, 1), clForest, stragglerTrees); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("sunny"); setSunColor(0.917, 0.828, 0.734); setWaterColor(0, 0.501961, 1); setWaterTint(0.501961, 1, 1); setWaterWaviness(2.5); setWaterType("ocean"); setWaterMurkiness(0.49); setFogFactor(0.3); setFogThickness(0.25); setPPEffect("hdr"); setPPContrast(0.62); setPPSaturation(0.51); setPPBloom(0.12); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/corsica.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/corsica.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/corsica.js (revision 21000) @@ -1,519 +1,519 @@ Engine.LoadLibrary("rmgen"); var tGrass = ["medit_grass_field", "medit_grass_field_b", "temp_grass_c"]; var tLushGrass = ["medit_grass_field","medit_grass_field_a"]; var tSteepCliffs = ["temp_cliff_b", "temp_cliff_a"]; var tCliffs = ["temp_cliff_b", "medit_cliff_italia", "medit_cliff_italia_grass"]; var tHill = ["medit_cliff_italia_grass","medit_cliff_italia_grass", "medit_grass_field", "medit_grass_field", "temp_grass"]; var tMountain = ["medit_cliff_italia_grass","medit_cliff_italia"]; var tRoad = ["medit_city_tile","medit_rocks_grass","medit_grass_field_b"]; var tRoadWild = ["medit_rocks_grass","medit_grass_field_b"]; var tShoreBlend = ["medit_sand_wet","medit_rocks_wet"]; var tShore = ["medit_rocks","medit_sand","medit_sand"]; var tSandTransition = ["medit_sand","medit_rocks_grass","medit_rocks_grass","medit_rocks_grass"]; var tVeryDeepWater = ["medit_sea_depths","medit_sea_coral_deep"]; var tDeepWater = ["medit_sea_coral_deep","tropic_ocean_coral"]; var tCreekWater = "medit_sea_coral_plants"; var ePine = "gaia/flora_tree_aleppo_pine"; var ePalmTall = "gaia/flora_tree_cretan_date_palm_tall"; var eFanPalm = "gaia/flora_tree_medit_fan_palm"; var eApple = "gaia/flora_tree_apple"; var eBush = "gaia/flora_bush_berry"; var eFish = "gaia/fauna_fish"; var ePig = "gaia/fauna_pig"; var eStoneMine = "gaia/geology_stonemine_medit_quarry"; var eMetalMine = "gaia/geology_metal_mediterranean_slabs"; var aRock = "actor|geology/stone_granite_med.xml"; var aLargeRock = "actor|geology/stone_granite_large.xml"; var aBushA = "actor|props/flora/bush_medit_sm_lush.xml"; var aBushB = "actor|props/flora/bush_medit_me_lush.xml"; var aPlantA = "actor|props/flora/plant_medit_artichoke.xml"; var aPlantB = "actor|props/flora/grass_tufts_a.xml"; var aPlantC = "actor|props/flora/grass_soft_tuft_a.xml"; var aStandingStone = "actor|props/special/eyecandy/standing_stones.xml"; var heightSeaGround = -8; var heightCreeks = -5; var heightBeaches = -1; var heightMain = 5; var heightOffsetMainRelief = 30; var heightOffsetLevel1 = 9; var heightOffsetLevel2 = 8; var heightOffsetBumps = 2; var heightOffsetAntiBumps = -5; var g_Map = new RandomMap(heightSeaGround, tVeryDeepWater); var numPlayers = getNumPlayers(); var mapSize = g_Map.getSize(); var mapCenter = g_Map.getCenter(); -var clIsland = createTileClass(); -var clCreek = createTileClass(); -var clWater = createTileClass(); -var clCliffs = createTileClass(); -var clForest = createTileClass(); -var clShore = createTileClass(); -var clPlayer = createTileClass(); -var clBaseResource = createTileClass(); -var clPassage = createTileClass(); -var clSettlement = createTileClass(); +var clIsland = g_Map.createTileClass(); +var clCreek = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clCliffs = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clShore = g_Map.createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clPassage = g_Map.createTileClass(); +var clSettlement = g_Map.createTileClass(); var radiusBeach = fractionToTiles(0.57); var radiusCreeks = fractionToTiles(0.52); var radiusIsland = fractionToTiles(0.4); var radiusLevel1 = fractionToTiles(0.35); var radiusPlayer = fractionToTiles(0.25); var radiusLevel2 = fractionToTiles(0.2); var creeksArea = () => randBool() ? randFloat(10, 50) : scaleByMapSize(75, 100) + randFloat(0, 20); var nbCreeks = scaleByMapSize(6, 15); var nbSubIsland = 5; var nbBeaches = scaleByMapSize(2, 5); var nbPassagesLevel1 = scaleByMapSize(4, 8); var nbPassagesLevel2 = scaleByMapSize(2, 4); log("Creating Corsica and Sardinia..."); var swapAngle = randBool() ? Math.PI / 2 : 0; var islandLocations = [new Vector2D(0.05, 0.05), new Vector2D(0.95, 0.95)].map(v => v.mult(mapSize).rotateAround(-swapAngle, mapCenter)); for (let island = 0; island < 2; ++island) { log("Creating island area..."); createArea( new ClumpPlacer(diskArea(radiusIsland), 1, 0.5, 10, islandLocations[island]), [ new LayeredPainter([tCliffs, tGrass], [2]), new SmoothElevationPainter(ELEVATION_SET, heightMain, 0), paintClass(clIsland) ]); log("Creating subislands..."); for (let i = 0; i < nbSubIsland + 1; ++i) { let angle = Math.PI * (island + i / (nbSubIsland * 2)) + swapAngle; let location = Vector2D.add(islandLocations[island], new Vector2D(radiusIsland, 0).rotate(-angle)); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.09)), 0.6, 0.03, 10, location), [ new LayeredPainter([tCliffs, tGrass], [2]), new SmoothElevationPainter(ELEVATION_SET, heightMain, 1), paintClass(clIsland) ]); } log("Creating creeks..."); for (let i = 0; i < nbCreeks + 1; ++i) { let angle = Math.PI * (island + i * (1 / (nbCreeks * 2))) + swapAngle; let location = Vector2D.add(islandLocations[island], new Vector2D(radiusCreeks, 0).rotate(-angle)); createArea( new ClumpPlacer(creeksArea(), 0.4, 0.01, 10, location), [ new TerrainPainter(tSteepCliffs), new SmoothElevationPainter(ELEVATION_SET, heightCreeks, 0), paintClass(clCreek) ]); } log("Creating beaches..."); for (let i = 0; i < nbBeaches + 1; ++i) { let angle = Math.PI * (island + (i / (nbBeaches * 2.5)) + 1 / (nbBeaches * 6) + randFloat(-1, 1) / (nbBeaches * 7)) + swapAngle; let start = Vector2D.add(islandLocations[island], new Vector2D(radiusIsland, 0).rotate(-angle)); let end = Vector2D.add(islandLocations[island], new Vector2D(radiusBeach, 0).rotate(-angle)); createArea( new ClumpPlacer(130, 0.7, 0.8, 10, Vector2D.add(start, Vector2D.mult(end, 3)).div(4)), new SmoothElevationPainter(ELEVATION_SET, heightBeaches, 5)); createPassage({ "start": start, "end": end, "startWidth": 18, "endWidth": 25, "smoothWidth": 4, "tileClass": clShore }); } log("Creating main relief..."); createArea( new ClumpPlacer(diskArea(radiusIsland), 1, 0.2, 10, islandLocations[island]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetMainRelief, fractionToTiles(0.45))); log("Creating first level plateau..."); createArea( new ClumpPlacer(diskArea(radiusLevel1), 0.95, 0.02, 10, islandLocations[island]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetLevel1, 1)); log("Creating first level passages..."); for (let i = 0; i <= nbPassagesLevel1; ++i) { let angle = Math.PI * (i / 7 + 1 / 9 + island) + swapAngle; createPassage({ "start": Vector2D.add(islandLocations[island], new Vector2D(radiusLevel1 + 10, 0).rotate(-angle)), "end": Vector2D.add(islandLocations[island], new Vector2D(radiusLevel1 - 4, 0).rotate(-angle)), "startWidth": 10, "endWidth": 6, "smoothWidth": 3, "tileClass": clPassage }); } if (mapSize > 150) { log("Creating second level plateau..."); createArea( new ClumpPlacer(diskArea(radiusLevel2), 0.98, 0.04, 10, islandLocations[island]), [ new LayeredPainter([tCliffs, tGrass], [2]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetLevel2, 1) ]); log("Creating second level passages..."); for (let i = 0; i < nbPassagesLevel2; ++i) { let angle = Math.PI * (i / (2 * nbPassagesLevel2) + 1 / (4 * nbPassagesLevel2) + island) + swapAngle; createPassage({ "start": Vector2D.add(islandLocations[island], new Vector2D(radiusLevel2 + 3, 0).rotate(-angle)), "end": Vector2D.add(islandLocations[island], new Vector2D(radiusLevel2 - 6, 0).rotate(-angle)), "startWidth": 4, "endWidth": 6, "smoothWidth": 2, "tileClass": clPassage }); } } } Engine.SetProgress(30); log("Determining player locations..."); var playerIDs = sortAllPlayers(); var playerPosition = []; var playerAngle = []; var p = 0; for (let island = 0; island < 2; ++island) { let playersPerIsland = island == 0 ? Math.ceil(numPlayers / 2) : Math.floor(numPlayers / 2); for (let i = 0; i < playersPerIsland; ++i) { playerAngle[p] = Math.PI * ((i + 0.5) / (2 * playersPerIsland) + island) + swapAngle; playerPosition[p] = Vector2D.add(islandLocations[island], new Vector2D(radiusPlayer).rotate(-playerAngle[p])); ++p; } } placePlayerBases({ "PlayerPlacement": [sortAllPlayers(), playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "Walls": false, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad, "coherence": 0.8, "radius": 6, "painters": [ paintClass(clSettlement) ] }, "Chicken": { }, "Berries": { "template": eBush }, "Mines": { "types": [ { "template": eMetalMine }, { "template": eStoneMine } ] } // Sufficient starting trees around, no decoratives }); Engine.SetProgress(40); log("Creating bumps..."); createAreas( new ClumpPlacer(70, 0.6, 0.1, 4), [new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBumps, 3)], [ stayClasses(clIsland, 2), avoidClasses(clPlayer, 6, clPassage, 2) ], scaleByMapSize(20, 100), 5); log("Creating anti bumps..."); createAreas( new ClumpPlacer(120, 0.3, 0.1, 4), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetAntiBumps, 6), avoidClasses(clPlayer, 6, clPassage, 2, clIsland, 2), scaleByMapSize(20, 100), 5); log("Painting water..."); paintTileClassBasedOnHeight(-Infinity, 0, Elevation_ExcludeMin_ExcludeMax, clWater); log("Painting land..."); for (let mapX = 0; mapX < mapSize; ++mapX) for (let mapZ = 0; mapZ < mapSize; ++mapZ) { let position = new Vector2D(mapX, mapZ); let terrain = getCosricaSardiniaTerrain(mapX, mapZ); if (!terrain) continue; createTerrain(terrain).place(position); if (terrain == tCliffs || terrain == tSteepCliffs) addToClass(mapX, mapZ, clCliffs); } function getCosricaSardiniaTerrain(mapX, mapZ) { let position = new Vector2D(mapX, mapZ); let isWater = getTileClass(clWater).countMembersInRadius(mapX, mapZ, 3); let isShore = getTileClass(clShore).countMembersInRadius(mapX, mapZ, 2); let isPassage = getTileClass(clPassage).countMembersInRadius(mapX, mapZ, 2); let isSettlement = getTileClass(clSettlement).countMembersInRadius(mapX, mapZ, 2); if (isSettlement) return undefined; let height = g_Map.getHeight(position); let slope = g_Map.getSlope(position); if (height >= 0.5 && height < 1.5 && isShore) return tSandTransition; // Paint land cliffs and grass if (height >= 1 && !isWater) { if (isPassage) return tGrass; if (slope >= 1.25) return height > 25 ? tSteepCliffs : tCliffs; if (height < 17) return tGrass; if (slope < 0.625) return tHill; return tMountain; } if (slope >= 1.125) return tCliffs; if (height >= 1.5) return undefined; if (height >= -0.75) return tShore; if (height >= -3) return tShoreBlend; if (height >= -6) return tCreekWater; if (height > -10 && slope < 0.75) return tDeepWater; return undefined; } Engine.SetProgress(65); log("Creating mines..."); for (let mine of [eMetalMine, eStoneMine]) createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(mine, 1,1, 0,0), new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3) ], true, clBaseResource), 0, [ stayClasses(clIsland, 1), avoidClasses( clWater, 3, clPlayer, 6, clBaseResource, 4, clPassage, 2, clCliffs, 1) ], scaleByMapSize(6, 25), 1000); log("Creating grass patches..."); createAreas( new ClumpPlacer(20, 0.3, 0.06, 0.5), [ new TerrainPainter(tLushGrass), paintClass(clForest) ], avoidClasses( clWater, 1, clPlayer, 6, clBaseResource, 3, clCliffs, 1), scaleByMapSize(10, 40)); log("Creating forests..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(ePine, 3, 6, 1, 3), new SimpleObject(ePalmTall, 1, 3, 1, 3), new SimpleObject(eFanPalm, 0, 2, 0, 2), new SimpleObject(eApple, 0, 1, 1, 2) ], true, clForest), 0, [ stayClasses(clIsland, 3), avoidClasses( clWater, 1, clForest, 0, clPlayer, 3, clBaseResource, 4, clPassage, 2, clCliffs, 2) ], scaleByMapSize(350, 2500), 100); Engine.SetProgress(75); log("Creating small decorative rocks..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(aRock, 1, 3, 0, 1), new SimpleObject(aStandingStone, 0, 2, 0, 3) ], true), 0, avoidClasses( clWater, 0, clForest, 0, clPlayer, 6, clBaseResource, 4, clPassage, 2), scaleByMapSize(16, 262), 50); log("Creating large decorative rocks..."); var rocksGroup = new SimpleGroup( [ new SimpleObject(aLargeRock, 1, 2, 0, 1), new SimpleObject(aRock, 1, 3, 0, 2) ], true); createObjectGroupsDeprecated( rocksGroup, 0, avoidClasses( clWater, 0, clForest, 0, clPlayer, 6, clBaseResource, 4, clPassage, 2), scaleByMapSize(8, 131), 50); createObjectGroupsDeprecated( rocksGroup, 0, borderClasses(clWater, 5, 10), scaleByMapSize(100, 800), 500); log("Creating decorative plants..."); var plantGroups = [ new SimpleGroup( [ new SimpleObject(aPlantA, 3, 7, 0, 3), new SimpleObject(aPlantB, 3,6, 0, 3), new SimpleObject(aPlantC, 1,4, 0, 4) ], true), new SimpleGroup( [ new SimpleObject(aPlantB, 5, 20, 0, 5), new SimpleObject(aPlantC, 4,10, 0,4) ], true) ]; for (let group of plantGroups) createObjectGroupsDeprecated( group, 0, avoidClasses( clWater, 0, clBaseResource, 4, clShore, 3), scaleByMapSize(100, 600), 50); Engine.SetProgress(80); log("Creating animals..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(ePig, 2,4, 0,3)]), 0, avoidClasses( clWater, 3, clBaseResource, 4, clPlayer, 6), scaleByMapSize(20, 100), 50); log("Creating fish..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(eFish, 1,2, 0,3)]), 0, [ stayClasses(clWater, 3), avoidClasses(clCreek, 3, clShore, 3) ], scaleByMapSize(50, 150), 100); Engine.SetProgress(95); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clBaseResource, 4, clCliffs, 4)); setSkySet(pickRandom(["cumulus", "sunny"])); setSunColor(0.8, 0.66, 0.48); setSunElevation(0.828932); setSunRotation((swapAngle ? 0.288 : 0.788) * Math.PI); setTerrainAmbientColor(0.564706,0.543726,0.419608); setUnitsAmbientColor(0.53,0.55,0.45); setWaterColor(0.2,0.294,0.49); setWaterTint(0.208, 0.659, 0.925); setWaterMurkiness(0.72); setWaterWaviness(2.0); setWaterType("ocean"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/cycladic_archipelago.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/cycladic_archipelago.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/cycladic_archipelago.js (revision 21000) @@ -1,362 +1,362 @@ Engine.LoadLibrary("rmgen"); const tOceanRockDeep = "medit_sea_coral_deep"; const tOceanCoral = "medit_sea_coral_plants"; const tBeachWet = "medit_sand_wet"; const tBeachDry = "medit_sand"; const tBeach = ["medit_rocks_grass","medit_sand", "medit_rocks_grass_shrubs"]; const tBeachBlend = ["medit_rocks_grass", "medit_rocks_grass_shrubs"]; const tCity = "medit_city_tile"; const tGrassDry = ["medit_grass_field_dry", "medit_grass_field_b"]; const tGrass = ["medit_rocks_grass", "medit_rocks_grass","medit_dirt","medit_rocks_grass_shrubs"]; const tGrassShrubs = "medit_shrubs"; const tCliffShrubs = ["medit_cliff_aegean_shrubs", "medit_cliff_italia_grass","medit_cliff_italia"]; const tCliff = ["medit_cliff_italia", "medit_cliff_italia", "medit_cliff_italia_grass"]; const tForestFloor = "medit_forestfloor_a"; const oBeech = "gaia/flora_tree_euro_beech"; const oBerryBush = "gaia/flora_bush_berry"; const oCarob = "gaia/flora_tree_carob"; const oCypress1 = "gaia/flora_tree_cypress"; const oCypress2 = "gaia/flora_tree_cypress"; const oLombardyPoplar = "gaia/flora_tree_poplar_lombardy"; const oPalm = "gaia/flora_tree_medit_fan_palm"; const oPine = "gaia/flora_tree_aleppo_pine"; const oDateT = "gaia/flora_tree_cretan_date_palm_tall"; const oDateS = "gaia/flora_tree_cretan_date_palm_short"; const oDeer = "gaia/fauna_deer"; const oFish = "gaia/fauna_fish"; const oWhale = "gaia/fauna_whale_humpback"; const oStoneLarge = "gaia/geology_stonemine_medit_quarry"; const oStoneSmall = "gaia/geology_stone_mediterranean"; const oMetalLarge = "gaia/geology_metal_mediterranean_slabs"; const oShipwreck = "other/special_treasure_shipwreck"; const oShipDebris = "other/special_treasure_shipwreck_debris"; const aRockLarge = "actor|geology/stone_granite_large.xml"; const aRockMed = "actor|geology/stone_granite_med.xml"; const aRockSmall = "actor|geology/stone_granite_small.xml"; const pPalmForest = [tForestFloor+TERRAIN_SEPARATOR+oPalm, tGrass]; const pPineForest = [tForestFloor+TERRAIN_SEPARATOR+oPine, tGrass]; const pPoplarForest = [tForestFloor+TERRAIN_SEPARATOR+oLombardyPoplar, tGrass]; const pMainForest = [tForestFloor+TERRAIN_SEPARATOR+oCarob, tForestFloor+TERRAIN_SEPARATOR+oBeech, tGrass, tGrass]; const heightSeaGround = -5; const heightLand = 3; const heightHill = 12; const heightOffsetBump = 2; var g_Map = new RandomMap(heightSeaGround, tWater); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clCoral = createTileClass(); -var clPlayer = createTileClass(); -var clIsland = createTileClass(); -var clCity = createTileClass(); -var clDirt = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); +var clCoral = g_Map.createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clIsland = g_Map.createTileClass(); +var clCity = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); //array holding starting islands based on number of players var startingPlaces=[[0],[0,3],[0,2,4],[0,1,3,4],[0,1,2,3,4],[0,1,2,3,4,5]]; var startAngle = randomAngle(); var islandRadius = scaleByMapSize(15, 40); var islandCount = Math.max(6, numPlayers); var islandPosition = distributePointsOnCircle(islandCount, startAngle, fractionToTiles(0.39), mapCenter)[0].map(position => position.round()); var centralIslandRadius = scaleByMapSize(15, 30); var centralIslandCount = Math.floor(scaleByMapSize(1, 4)); var centralIslandPosition = new Array(numPlayers).fill(0).map((v, i) => Vector2D.add(mapCenter, new Vector2D(fractionToTiles(randFloat(0.1, 0.16)), 0).rotate( -startAngle - Math.PI * (i * 2 / centralIslandCount + randFloat(-1, 1) / 8)).round())); var areas = []; var nPlayer = 0; var playerPosition = []; function createCycladicArchipelagoIsland(position, tileClass, radius, coralRadius) { log("Creating deep ocean rocks..."); createArea( new ClumpPlacer(diskArea(radius + coralRadius), 0.7, 0.1, 10, position), [ new LayeredPainter([tOceanRockDeep, tOceanCoral], [5]), paintClass(clCoral) ], avoidClasses(clCoral, 0, clPlayer, 0)); log("Creating island..."); areas.push( createArea( new ClumpPlacer(diskArea(radius), 0.7, 0.1, 10, position), [ new LayeredPainter([tOceanCoral, tBeachWet, tBeachDry, tBeach, tBeachBlend, tGrass], [1, 3, 1, 1, 2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 5), paintClass(tileClass) ], avoidClasses(clPlayer, 0))); } log("Creating player islands..."); for (let i = 0; i < islandCount; ++i) { let isPlayerIsland = numPlayers >= 6 || i == startingPlaces[numPlayers - 1][nPlayer]; if (isPlayerIsland) { playerPosition[nPlayer] = islandPosition[i]; ++nPlayer; } createCycladicArchipelagoIsland(islandPosition[i], isPlayerIsland ? clPlayer : clIsland, islandRadius, scaleByMapSize(1, 5)); } log("Creating central islands..."); for (let position of centralIslandPosition) createCycladicArchipelagoIsland(position, clIsland, centralIslandRadius, 2); placePlayerBases({ "PlayerPlacement": [sortAllPlayers(), playerPosition], // PlayerTileClass is clCity here and painted below "BaseResourceClass": clBaseResource, "Walls": "towers", "CityPatch": { "radius": 6, "outerTerrain": tGrass, "innerTerrain": tCity, "painters": [ paintClass(clCity) ] }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oPalm, "count": 2 } // No decoratives }); Engine.SetProgress(20); log("Creating bumps..."); createAreasInAreas( new ClumpPlacer(scaleByMapSize(20, 60), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 3), avoidClasses(clCity, 0), scaleByMapSize(25, 75),15, areas); Engine.SetProgress(34); log("Creating hills..."); createAreasInAreas( new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1), [ new LayeredPainter([tCliff, tCliffShrubs], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], avoidClasses(clCity, 15, clHill, 15), scaleByMapSize(5, 30), 15, areas); Engine.SetProgress(38); paintTileClassBasedOnHeight(-Infinity, 0, Elevation_ExcludeMin_ExcludeMax, clWater); log("Creating forests..."); var forestTypes = [ [[tForestFloor, tGrass, pPalmForest], [tForestFloor, pPalmForest]], [[tForestFloor, tGrass, pPineForest], [tForestFloor, pPineForest]], [[tForestFloor, tGrass, pPoplarForest], [tForestFloor, pPoplarForest]], [[tForestFloor, tGrass, pMainForest], [tForestFloor, pMainForest]] ]; for (let type of forestTypes) createAreasInAreas( new ClumpPlacer(randIntInclusive(6, 17), 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clCity, 1, clWater, 3, clForest, 3, clHill, 1, clBaseResource, 4), scaleByMapSize(10, 64), 20, areas); Engine.SetProgress(42); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock); createObjectGroupsByAreasDeprecated(group, 0, [avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 5, clRock, 6)], scaleByMapSize(4,16), 200, areas ); Engine.SetProgress(46); log("Creating small stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsByAreasDeprecated(group, 0, [avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 5, clRock, 2)], scaleByMapSize(4,16), 200, areas ); Engine.SetProgress(50); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroupsByAreasDeprecated(group, 0, [avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 5, clMetal, 6, clRock, 6)], scaleByMapSize(4,16), 200, areas ); Engine.SetProgress(54); log("Creating shrub patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreasInAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter([tBeachBlend, tGrassShrubs], [1]), paintClass(clDirt) ], avoidClasses(clWater, 3, clHill, 0, clDirt, 6, clCity, 0, clBaseResource, 4), scaleByMapSize(4, 16), 20, areas); Engine.SetProgress(58); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreasInAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter([tGrassDry], []), paintClass(clDirt) ], avoidClasses(clWater, 3, clHill, 0, clDirt, 6, clCity, 0, clBaseResource, 4), scaleByMapSize(4, 16), 20, areas); Engine.SetProgress(62); log("Creating straggler trees..."); for (let tree of [oCarob, oBeech, oLombardyPoplar, oLombardyPoplar, oPine]) createObjectGroupsByAreasDeprecated( new SimpleGroup([new SimpleObject(tree, 1,1, 0,1)], true, clForest), 0, avoidClasses(clWater, 2, clForest, 2, clCity, 3, clBaseResource, 4, clRock, 6, clMetal, 6, clPlayer, 1, clHill, 1), scaleByMapSize(2, 38), 50, areas ); Engine.SetProgress(66); log("Create straggler cypresses..."); group = new SimpleGroup( [new SimpleObject(oCypress2, 1,3, 0,3), new SimpleObject(oCypress1, 0,2, 0,2)], true ); createObjectGroupsByAreasDeprecated(group, 0, avoidClasses(clWater, 2, clForest, 2, clCity, 3, clBaseResource, 4, clRock, 6, clMetal, 6, clPlayer, 1, clHill, 1), scaleByMapSize(5, 75), 50, areas ); Engine.SetProgress(70); log("Create straggler date palms..."); group = new SimpleGroup( [new SimpleObject(oDateS, 1,3, 0,3), new SimpleObject(oDateT, 0,2, 0,2)], true ); createObjectGroupsByAreasDeprecated(group, 0, avoidClasses(clWater, 2, clForest, 1, clCity, 0, clBaseResource, 4, clRock, 6, clMetal, 6, clPlayer, 1, clHill, 1), scaleByMapSize(5, 75), 50, areas ); Engine.SetProgress(74); log("Creating rocks..."); group = new SimpleGroup( [new SimpleObject(aRockSmall, 0,3, 0,2), new SimpleObject(aRockMed, 0,2, 0,2), new SimpleObject(aRockLarge, 0,1, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clCity, 0), scaleByMapSize(30, 180), 50 ); Engine.SetProgress(78); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 5, clForest, 1, clHill, 1, clCity, 10, clMetal, 6, clRock, 2, clFood, 8), 3 * numPlayers, 50 ); Engine.SetProgress(82); log("Creating berry bushes..."); group = new SimpleGroup([new SimpleObject(oBerryBush, 5,7, 0,3)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clForest, 1, clHill, 1, clCity, 10, clMetal, 6, clRock, 2, clFood, 8), 1.5 * numPlayers, 100 ); Engine.SetProgress(86); log("Creating Fish..."); group = new SimpleGroup([new SimpleObject(oFish, 1,1, 0,3)], true, clFood); createObjectGroupsDeprecated(group, 0, [stayClasses(clWater,1),avoidClasses(clFood, 8)], scaleByMapSize(40,200), 100 ); Engine.SetProgress(90); log("Creating Whales..."); group = new SimpleGroup([new SimpleObject(oWhale, 1,1, 0,3)], true, clFood); createObjectGroupsDeprecated(group, 0, [stayClasses(clWater,1),avoidClasses(clFood, 8, clPlayer,4,clIsland,4)], scaleByMapSize(10,40), 100 ); Engine.SetProgress(94); log("Creating shipwrecks..."); group = new SimpleGroup([new SimpleObject(oShipwreck, 1,1, 0,3)], true, clFood); createObjectGroupsDeprecated(group, 0, [stayClasses(clWater,1),avoidClasses(clFood, 8)], scaleByMapSize(6,16), 100 ); Engine.SetProgress(98); log("Creating shipwreck debris..."); group = new SimpleGroup([new SimpleObject(oShipDebris, 1,2, 0,4)], true, clFood); createObjectGroupsDeprecated(group, 0, [stayClasses(clWater,1),avoidClasses(clFood, 8)], scaleByMapSize(10,20), 100 ); Engine.SetProgress(99); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clBaseResource, 4, clHill, 4, clMetal, 4, clRock, 4, clFood, 1)); setSkySet("sunny"); setWaterColor(0.2,0.294,0.49); setWaterTint(0.208, 0.659, 0.925); setWaterMurkiness(0.72); setWaterWaviness(3.0); setWaterType("ocean"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/danubius.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/danubius.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/danubius.js (revision 21000) @@ -1,814 +1,814 @@ Engine.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"; const triggerPointRiverDirection = "trigger/trigger_point_I"; const tPrimary = ["temp_grass_aut", "temp_grass_plants_aut", "temp_grass_c_aut", "temp_grass_d_aut"]; 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"; 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 oSentryTower = "structures/gaul_sentry_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"; 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; const heightSeaGround = -3; const heightShore = 1; const heightLand = 3; const heightPath = 5; const heightIsland = 6; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -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(); +var clMiddle = g_Map.createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clLand = [g_Map.createTileClass(), g_Map.createTileClass()]; +var clLandPatrolPoint = [g_Map.createTileClass(), g_Map.createTileClass()]; +var clCCAttackerPatrolPoint = [g_Map.createTileClass(), g_Map.createTileClass()]; +var clShore = [g_Map.createTileClass(), g_Map.createTileClass()]; +var clShoreUngarrisonPoint = [g_Map.createTileClass(), g_Map.createTileClass()]; +var clShip = g_Map.createTileClass(); +var clShipPatrol = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clIsland = g_Map.createTileClass(); +var clTreasure = g_Map.createTileClass(); +var clWaterLog = g_Map.createTileClass(); +var clGauls = g_Map.createTileClass(); +var clTower = g_Map.createTileClass(); +var clOutpost = g_Map.createTileClass(); +var clPath = g_Map.createTileClass(); +var clRitualPlace = g_Map.createTileClass(); var startAngle = randomAngle(); var waterWidth = fractionToTiles(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); var ritualParticipants = [ { "radius": 0.6, "templates": [oFemale], "count": 9, "angle": Math.PI }, { "radius": 0.8, "templates": [oSkirmisher, oHealer, oNakedFanatic], "count": 15, "angle": Math.PI }, { "radius": 1, "templates": [aBench], "count": 10, "angle": Math.PI / 2 }, { "radius": 1.1, "templates": [oGoat], "count": 7, "angle": 0 }, { "radius": 1.2, "templates": [aRug], "count": 8, "angle": Math.PI } ]; // 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 civicCenterPosition = new Vector2D( i == 0 ? mapBounds.left + gaulCityBorderDistance : mapBounds.right - gaulCityBorderDistance, mapCenter.y).rotateAround(startAngle, mapCenter); if (addCelticRitual) { // Don't position the meeting place at the center of the map let meetingPlacePosition = new Vector2D( i == 0 ? mapBounds.left + waterWidth : mapBounds.right - waterWidth, mapCenter.y + fractionToTiles(randFloat(0.1, 0.4)) * (randBool() ? 1 : -1)).rotateAround(startAngle, mapCenter); // 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 pathStart = Vector2D.add(civicCenterPosition, new Vector2D(gaulCityRadius * (i == 0 ? 1 : -1), 0).rotate(startAngle)); createArea( new PathPlacer(pathStart, meetingPlacePosition, 4, 0.4, 4, 0.2, 0.05), [ new LayeredPainter([tShore, tRoad, tRoad], [1, 3]), new SmoothElevationPainter(ELEVATION_SET, heightPath, 4), paintClass(clPath) ]); // Create the meeting place near the shoreline at the end of the path createArea( new ClumpPlacer(diskArea(mRadius), 0.6, 0.3, 10, meetingPlacePosition), [ new TerrainPainter(tShore), paintClass(clPath), paintClass(clRitualPlace) ]); placeObject(meetingPlacePosition.x, meetingPlacePosition.y, aCampfire, 0, randomAngle()); for (let participants of ritualParticipants) { let [positions, angles] = distributePointsOnCircle(participants.count, startAngle, participants.radius * mRadius, meetingPlacePosition); for (let i = 0; i < positions.length; ++i) placeObject(positions[i].x, positions[i].y, pickRandom(participants.templates), 0, angles[i] + participants.angle); } } placeObject(civicCenterPosition.x, civicCenterPosition.y, oCivicCenter, 0, startAngle + BUILDING_ORIENTATION + Math.PI * 3/2 * i); // Create the city patch createArea( new ClumpPlacer(diskArea(gaulCityRadius), 0.6, 0.3, 10, civicCenterPosition), [ new TerrainPainter(tShore), paintClass(clGauls) ]); // Place palisade fortress and some city buildings // Use actors to avoid players capturing the buildings g_WallStyles.gaul = clone(g_WallStyles.gaul_stone); g_WallStyles.gaul.house = { "angle": Math.PI, "length": 0, "indent": 4, "bend": 0, "templateName": oHouse }; g_WallStyles.gaul.hut = { "angle": Math.PI, "length": 0, "indent": 4, "bend": 0, "templateName": oHut }; g_WallStyles.gaul.longhouse = { "angle": Math.PI, "length": 0, "indent": 4, "bend": 0, "templateName": oLongHouse }; g_WallStyles.gaul.tavern = { "angle": Math.PI * 3/2, "length": 0, "indent": 4, "bend": 0, "templateName": oTavern }; g_WallStyles.gaul.temple = { "angle": Math.PI * 3/2, "length": 0, "indent": 4, "bend": 0, "templateName": oTemple }; g_WallStyles.gaul.defense_tower = { "angle": Math.PI / 2, "length": 0, "indent": 4, "bend": 0, "templateName": mapSize >= normalMapSize ? (isNomad() ? oSentryTower : oTower) : oPalisadeTower }; // Replace stone walls with palisade walls for (let element of ["gate", "long", "short", "cornerIn", "cornerOut", "tower"]) g_WallStyles.gaul[element] = getWallElement(element, "palisade"); let wall = [ "gate", "hut", "tower", "long", "long", "cornerIn", "defense_tower", "long", "long", "temple", "tower", "long", "house", "short", "tower", "gate", "tower", "longhouse", "long", "long", "cornerIn", "defense_tower", "long", "tavern", "long", "tower"]; wall = wall.concat(wall); placeCustomFortress(civicCenterPosition.x, civicCenterPosition.y, new Fortress("Geto-Dacian Tribal Confederation", wall), "gaul", 0, startAngle + Math.PI); // Place spikes g_WallStyles.palisade.spikes_tall = readyWallElement("other/palisades_tall_spikes", "gaia"); g_WallStyles.palisade.spike_single = readyWallElement("other/palisades_angle_spike", "gaia"); let threeSpikes = new Array(3).fill("spikes_tall"); let fiveSpikes = new Array(5).fill("spikes_tall"); let spikes = [ "gap_3.6", "spike_single", ...threeSpikes, "turn_0.25", "spike_single", "turn_0.25", ...fiveSpikes, "spike_single", "gap_3.6", "spike_single", ...threeSpikes, "turn_0.25", "spike_single", "turn_0.25", ...threeSpikes, "spike_single" ]; spikes = spikes.concat(spikes); placeCustomFortress(civicCenterPosition.x, civicCenterPosition.y, new Fortress("spikes", spikes), "palisade", 0, startAngle + Math.PI); // Place treasure, potentially inside buildings for (let i = 0; i < gallicCCTreasureCount; ++i) placeObject( civicCenterPosition.x + randFloat(-0.8, 0.8) * gaulCityRadius, civicCenterPosition.y + randFloat(-0.8, 0.8) * gaulCityRadius, pickRandom(oTreasures), 0, randomAngle()); } } Engine.SetProgress(10); placePlayerBases({ "PlayerPlacement": playerPlacementRiver(startAngle, fractionToTiles(0.6)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "Walls": false, "CityPatch": { "outerTerrain": tShore, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": aBush1 }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ], "distance": scaleByMapSize(9, 14) }, "Trees": { "template": oOak, "count": 20, "minDist": 10, "maxDist": 14 }, "Decoratives": { "template": aBush1 } }); Engine.SetProgress(20); paintRiver({ "parallel": true, "start": new Vector2D(mapCenter.x, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(mapCenter.x, mapBounds.bottom).rotateAround(startAngle, mapCenter), "width": waterWidth, "fadeDist": scaleByMapSize(6, 25), "deviation": 0, "heightRiverbed": heightSeaGround, "heightLand": heightLand, "meanderShort": 30, "meanderLong": 0, "waterFunc": (position, height, riverFraction) => { // Distinguish left and right shoreline if (0 < height && height < 1 && position.y > ShorelineDistance && position.y < mapSize - ShorelineDistance) addToClass(position.x, position.y, clShore[position.x < mapCenter.x ? 0 : 1]); }, "landFunc": (position, shoreDist1, shoreDist2) => { if (shoreDist1 > 0) addToClass(position.x, position.y, clLand[0]); if (shoreDist2 < 0) addToClass(position.x, position.y, clLand[1]); } }); Engine.SetProgress(30); paintTileClassBasedOnHeight(-Infinity, 0.7, Elevation_ExcludeMin_ExcludeMax, clWater); log("Creating shores..."); paintTerrainBasedOnHeight(-Infinity, heightShore, 0, tWater); paintTerrainBasedOnHeight(heightShore, heightLand, 0, tShore); Engine.SetProgress(35); log("Creating bumps..."); createBumps(avoidClasses(clPlayer, 6, clWater, 2, clPath, 1, clGauls, 1), scaleByMapSize(30, 300), 1, 8, 4, 0, 3); Engine.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)); Engine.SetProgress(45); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tForestFloor, tForestFloor, tForestFloor, pForest1, pForest2], avoidClasses(clPlayer, 16, clForest, 17, clWater, 5, clHill, 2, clGauls, 5, clPath, 1), clForest, forestTrees); Engine.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); Engine.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, heightIsland, 4), paintClass(clIsland) ], [avoidClasses(clIsland, 30), stayClasses (clWater, 10)], scaleByMapSize(1, 4) * numPlayers ); Engine.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 ); Engine.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 ); Engine.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)] ); Engine.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 ); Engine.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..."); if (!isNomad()) 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); Engine.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); Engine.SetProgress(90); createStragglerTrees( treeTypes, avoidClasses(clForest, 2, clWater, 8, clPlayer, 16, clMetal, 4, clRock, 4, clFood, 1, clHill, 2, clGauls, 5, clPath, 5), clForest, stragglerTrees); createStragglerTrees( treeTypes, [stayClasses(clIsland, 4), avoidClasses(clMetal, 4, clRock, 4, clTower, 4, clOutpost, 4)], clForest, stragglerTrees * 7); Engine.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 ); Engine.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, Math.PI/4, Math.PI/2)], [new SimpleObject(aWheel, 2, 4, 1, 2)], [new SimpleObject(aWell, 1, 1, 0, 2)], [new SimpleObject(aWoodcord, 1, 2, 2, 2, Math.PI/2, Math.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(mapCenter.x, mapCenter.y, clMiddle); var riverDirectionPosition = Vector2D.add(mapCenter, new Vector2D(0, 1).rotate(startAngle)); placeObject(riverDirectionPosition.x, riverDirectionPosition.y, triggerPointRiverDirection, 0, 0); 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 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clMetal, 4, clRock, 4, clIsland, 4, clGauls, 20, clRitualPlace, 20, clForest, 1, clBaseResource, 4, clHill, 4, clFood, 2)); 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); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/deep_forest.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/deep_forest.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/deep_forest.js (revision 21000) @@ -1,202 +1,202 @@ Engine.LoadLibrary("rmgen"); var templateStone = "gaia/geology_stone_temperate"; var templateStoneMine = "gaia/geology_stonemine_temperate_quarry"; var templateMetalMine = "gaia/geology_metal_temperate_slabs"; var templateTemple = "other/unfinished_greek_temple"; var terrainPrimary = ["temp_grass", "temp_grass_b", "temp_grass_c", "temp_grass_d", "temp_grass_long_b", "temp_grass_clovers_2", "temp_grass_mossy", "temp_grass_plants"]; var terrainWood = ['temp_grass_mossy|gaia/flora_tree_oak', 'temp_forestfloor_pine|gaia/flora_tree_pine', 'temp_mud_plants|gaia/flora_tree_dead', 'temp_plants_bog|gaia/flora_tree_oak_large', "temp_dirt_gravel_plants|gaia/flora_tree_aleppo_pine", 'temp_forestfloor_autumn|gaia/flora_tree_carob']; //'temp_forestfloor_autumn|gaia/flora_tree_fig' var terrainWoodBorder = ['temp_grass_plants|gaia/flora_tree_euro_beech', 'temp_grass_mossy|gaia/flora_tree_poplar', 'temp_grass_mossy|gaia/flora_tree_poplar_lombardy', 'temp_grass_long|gaia/flora_bush_temperate', 'temp_mud_plants|gaia/flora_bush_temperate', 'temp_mud_plants|gaia/flora_bush_badlands', 'temp_grass_long|gaia/flora_tree_apple', 'temp_grass_clovers|gaia/flora_bush_berry', 'temp_grass_clovers_2|gaia/flora_bush_grapes', 'temp_grass_plants|gaia/fauna_deer', "temp_grass_long_b|gaia/fauna_rabbit", "temp_grass_plants"]; var terrainBase = ["temp_dirt_gravel", "temp_grass_b"]; var terrainBaseBorder = ["temp_grass_b", "temp_grass_b", "temp_grass", "temp_grass_c", "temp_grass_mossy"]; var terrainBaseCenter = ['temp_dirt_gravel', 'temp_dirt_gravel', 'temp_grass_b']; var terrainPath = ['temp_road', "temp_road_overgrown", 'temp_grass_b']; var terrainHill = ["temp_highlands", "temp_highlands", "temp_highlands", "temp_dirt_gravel_b", "temp_cliff_a"]; var terrainHillBorder = ["temp_highlands", "temp_highlands", "temp_highlands", "temp_dirt_gravel_b", "temp_dirt_gravel_plants", "temp_highlands", "temp_highlands", "temp_highlands", "temp_dirt_gravel_b", "temp_dirt_gravel_plants", "temp_highlands", "temp_highlands", "temp_highlands", "temp_cliff_b", "temp_dirt_gravel_plants", "temp_highlands", "temp_highlands", "temp_highlands", "temp_cliff_b", "temp_dirt_gravel_plants", "temp_highlands|gaia/fauna_goat"]; var heightPath = -2; var heightLand = 0; var heightOffsetRandomPath = 1; var g_Map = new RandomMap(heightLand, terrainPrimary); var mapSize = g_Map.getSize(); var mapRadius = mapSize/2; var mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clPath = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clBaseResource = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clPath = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var numPlayers = getNumPlayers(); var baseRadius = 20; var minPlayerRadius = Math.min(mapRadius - 1.5 * baseRadius, 5/8 * mapRadius); var maxPlayerRadius = Math.min(mapRadius - baseRadius, 3/4 * mapRadius); var playerPosition = []; var playerAngle = []; var playerAngleStart = randomAngle(); var playerAngleAddAvrg = 2 * Math.PI / numPlayers; var playerAngleMaxOff = playerAngleAddAvrg/4; var radiusEC = Math.max(mapRadius/8, baseRadius/2); var resourceRadius = fractionToTiles(1/3); var resourcePerPlayer = [templateStone, templateMetalMine]; // For large maps there are memory errors with too many trees. A density of 256*192/mapArea works with 0 players. // Around each player there is an area without trees so with more players the max density can increase a bit. var maxTreeDensity = Math.min(256 * (192 + 8 * numPlayers) / Math.square(mapSize), 1); // Has to be tweeked but works ok var bushChance = 1/3; // 1 means 50% chance in deepest wood, 0.5 means 25% chance in deepest wood var playerIDs = sortAllPlayers(); for (var i=0; i < numPlayers; i++) { playerAngle[i] = (playerAngleStart + i * playerAngleAddAvrg + randFloat(0, playerAngleMaxOff)) % (2 * Math.PI); playerPosition[i] = Vector2D.add(mapCenter, new Vector2D(randFloat(minPlayerRadius, maxPlayerRadius), 0).rotate(-playerAngle[i]).round()); } Engine.SetProgress(10); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "BaseResourceClass": clBaseResource, // player class painted below "CityPatch": { "radius": 0.8 * baseRadius, "smoothness": 1/8, "painters": [ new LayeredPainter([terrainBaseBorder, terrainBase, terrainBaseCenter], [baseRadius/4, baseRadius/4]), paintClass(clPlayer) ] }, "Chicken": { }, "Berries": { "template": "gaia/flora_bush_grapes", "minCount": 2, "maxCount": 2, "distance": 12, "minDist": 5, "maxDist": 8 }, "Mines": { "types": [ { "template": templateMetalMine }, { "template": templateStoneMine } ], "minAngle": Math.PI / 2, "maxAngle": Math.PI }, "Trees": { "template": "gaia/flora_tree_oak_large", "count": 2 } }); Engine.SetProgress(10); log("Painting paths..."); var pathBlending = numPlayers <= 4; for (let i = 0; i < numPlayers + (pathBlending ? 1 : 0); ++i) for (let j = pathBlending ? 0 : i + 1; j < numPlayers + 1; ++j) { let pathStart = i < numPlayers ? playerPosition[i] : mapCenter; let pathEnd = j < numPlayers ? playerPosition[j] : mapCenter; createArea( new RandomPathPlacer(pathStart, pathEnd, 1.25, baseRadius / 2, pathBlending), [ new TerrainPainter(terrainPath), new SmoothElevationPainter(ELEVATION_SET, heightPath, 2, heightOffsetRandomPath), paintClass(clPath) ], avoidClasses(clHill, 0, clBaseResource, 4)); } Engine.SetProgress(50); log("Placing expansion resources..."); for (let i = 0; i < numPlayers; ++i) for (let rIndex = 0; rIndex < resourcePerPlayer.length; ++rIndex) { let angleDist = numPlayers > 1 ? (playerAngle[(i + 1) % numPlayers] - playerAngle[i] + 2 * Math.PI) % (2 * Math.PI) : 2 * Math.PI; // they are supposed to be in between players on the same radius let angle = playerAngle[i] + angleDist * (rIndex + 1) / (resourcePerPlayer.length + 1); let position = Vector2D.add(mapCenter, new Vector2D(resourceRadius, 0).rotate(-angle)).round(); placeObject(position.x, position.y, resourcePerPlayer[rIndex], 0, randomAngle()); createArea( new ClumpPlacer(40, 1/2, 1/8, 1, position), [ new LayeredPainter([terrainHillBorder, terrainHill], [1]), new ElevationPainter(randFloat(1, 2)), paintClass(clHill) ]); } Engine.SetProgress(60); log("Placing temple..."); placeObject(mapCenter.x, mapCenter.y, templateTemple, 0, randomAngle()); addToClass(mapCenter.x, mapCenter.y, clBaseResource); log("Creating central mountain..."); createArea( new ClumpPlacer(Math.square(radiusEC), 1/2, 1/8, 1, mapCenter), [ new LayeredPainter([terrainHillBorder, terrainHill], [radiusEC/4]), new ElevationPainter(randFloat(1, 2)), paintClass(clHill) ]); // Woods and general hight map for (var x = 0; x < mapSize; x++) for (var z = 0;z < mapSize;z++) { let position = new Vector2D(x, z); // The 0.5 is a correction for the entities placed on the center of tiles var radius = mapCenter.distanceTo(Vector2D.add(position, new Vector2D(0.5, 0.5))); var minDistToSL = mapSize; for (var i=0; i < numPlayers; i++) minDistToSL = Math.min(minDistToSL, position.distanceTo(playerPosition[i])); // Woods tile based var tDensFactSL = Math.max(Math.min((minDistToSL - baseRadius) / baseRadius, 1), 0); var tDensFactRad = Math.abs((resourceRadius - radius) / resourceRadius); var tDensFactEC = Math.max(Math.min((radius - radiusEC) / radiusEC, 1), 0); var tDensActual = maxTreeDensity * tDensFactSL * tDensFactRad * tDensFactEC; if (randBool(tDensActual) && g_Map.validTile(position)) { let border = tDensActual < randFloat(0, bushChance * maxTreeDensity); createArea( new RectPlacer(position.x, position.y, position.x, position.y), [ new TerrainPainter(border ? terrainWoodBorder : terrainWood), new ElevationPainter(randFloat(0, 1)), paintClass(clForest) ], avoidClasses(clPath, 1, clHill, border ? 0 : 1)); } // General height map let hVarMiddleHill = fractionToTiles(1 / 64) * (1 + Math.cos(3/2 * Math.PI * radius / mapRadius)); var hVarHills = 5 * (1 + Math.sin(x / 10) * Math.sin(z / 10)); g_Map.setHeight(position, g_Map.getHeight(position) + hVarMiddleHill + hVarHills + 1); } Engine.SetProgress(95); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clBaseResource, 4)); g_Map.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 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/english_channel.js (revision 21000) @@ -1,266 +1,266 @@ Engine.LoadLibrary("rmgen"); const tPrimary = "temp_grass_long"; const tGrass = ["temp_grass", "temp_grass", "temp_grass_d"]; const tGrassDForest = "temp_plants_bog"; const tGrassA = "temp_grass_plants"; const tGrassB = "temp_plants_bog"; const tGrassC = "temp_mud_a"; const tHill = ["temp_highlands", "temp_grass_long_b"]; const tCliff = ["temp_cliff_a", "temp_cliff_b"]; const tRoad = "temp_road"; const tRoadWild = "temp_road_overgrown"; const tGrassPatchBlend = "temp_grass_long_b"; const tGrassPatch = ["temp_grass_d", "temp_grass_clovers"]; const tShore = "temp_dirt_gravel"; const tWater = "temp_dirt_gravel_b"; const oBeech = "gaia/flora_tree_euro_beech"; const oPoplar = "gaia/flora_tree_poplar"; const oApple = "gaia/flora_tree_apple"; const oOak = "gaia/flora_tree_oak"; const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; const oFish = "gaia/fauna_fish"; const oGoat = "gaia/fauna_goat"; const oBoar = "gaia/fauna_boar"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oStoneSmall = "gaia/geology_stone_temperate"; const oMetalLarge = "gaia/geology_metal_temperate_slabs"; const aGrass = "actor|props/flora/grass_soft_large_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aRockLarge = "actor|geology/stone_granite_large.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aBushMedium = "actor|props/flora/bush_medit_me_lush.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm_lush.xml"; const aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; const aLillies = "actor|props/flora/water_lillies.xml"; const pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oBeech, tGrassDForest]; var heightSeaGround = -4; var heightShore = 1; var heightLand = 3; var g_Map = new RandomMap(heightShore, tPrimary); const numPlayers = getNumPlayers(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clShallow = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clShallow = g_Map.createTileClass(); var startAngle = randomAngle(); placePlayerBases({ "PlayerPlacement": playerPlacementRiver(startAngle + Math.PI / 2, fractionToTiles(0.6)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oOak, "count": 2 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(10); paintRiver({ "parallel": false, "start": new Vector2D(mapBounds.left, mapCenter.y).rotateAround(startAngle, mapCenter), "end": new Vector2D(mapBounds.right, mapCenter.y).rotateAround(startAngle, mapCenter), "width": fractionToTiles(0.25), "fadeDist": scaleByMapSize(3, 10), "deviation": 0, "heightRiverbed": heightSeaGround, "heightLand": heightLand, "meanderShort": 20, "meanderLong": 0, "waterFunc": (position, height, riverFraction) => { createTerrain(height < -1.5 ? tWater : tShore).place(position); }, "landFunc": (position, shoreDist1, shoreDist2) => { g_Map.setHeight(position, heightLand + 0.1); } }); Engine.SetProgress(20); createTributaryRivers( startAngle, randIntInclusive(9, scaleByMapSize(13, 21)), scaleByMapSize(10, 20), heightSeaGround, [-6, -1.5], Math.PI / 5, clWater, clShallow, avoidClasses(clPlayer, 8, clBaseResource, 4)); paintTerrainBasedOnHeight(-5, 1, 1, tWater); paintTerrainBasedOnHeight(1, heightLand, 1, tShore); paintTileClassBasedOnHeight(-6, 0.5, 1, clWater); Engine.SetProgress(25); createBumps(avoidClasses(clWater, 5, clPlayer, 20)); Engine.SetProgress(30); createHills([tCliff, tCliff, tHill], avoidClasses(clPlayer, 20, clHill, 15, clWater, 5), clHill, scaleByMapSize(1, 4) * numPlayers); Engine.SetProgress(50); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tGrass, tGrassDForest, tGrassDForest, pForestD, pForestD], avoidClasses(clPlayer, 20, clForest, 17, clHill, 0, clWater, 6), clForest, forestTrees); Engine.SetProgress(70); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tGrass,tGrassA], tGrassB, [tGrassB,tGrassC]], [1,1], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], [tGrassPatchBlend, tGrassPatch], [1], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(80); log("Creating stone mines..."); createMines( [ [new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], [new SimpleObject(oStoneSmall, 2,5, 1,3)] ], avoidClasses(clWater, 2, clForest, 1, clPlayer, 20, clRock, 10, clHill, 2), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 2, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 2), clMetal ); Engine.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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [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)); 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), clFood); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ randIntInclusive(1, 4) * numPlayers + 2 ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [scaleByMapSize(3, 25) * numPlayers], [avoidClasses(clFood, 6), stayClasses(clWater, 4)], clFood); createStragglerTrees( [oBeech, oPoplar, oApple], avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 8, clMetal, 6, clRock, 6), clForest, stragglerTrees); setSkySet("cirrus"); setWaterColor(0.114, 0.192, 0.463); setWaterTint(0.255, 0.361, 0.651); setWaterWaviness(3.0); setWaterType("ocean"); setWaterMurkiness(0.83); setFogThickness(0.35); setFogFactor(0.55); setPPEffect("hdr"); setPPSaturation(0.62); setPPContrast(0.62); setPPBloom(0.37); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/extinct_volcano.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/extinct_volcano.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/extinct_volcano.js (revision 21000) @@ -1,465 +1,465 @@ Engine.LoadLibrary("rmgen"); const tHillDark = "cliff volcanic light"; const tHillMedium1 = "ocean_rock_a"; const tHillMedium2 = "ocean_rock_b"; const tHillVeryDark = ["cliff volcanic coarse", "cave_walls"]; const tRoad = "road1"; const tRoadWild = "road1"; const tForestFloor1 = tHillMedium1; const tForestFloor2 = tHillMedium2; const tGrassA = "cliff volcanic light"; const tGrassB = "ocean_rock_a"; const tGrassPatchBlend = "temp_grass_long_b"; const tGrassPatch = ["temp_grass_d", "temp_grass_clovers"]; const tShoreBlend = "cliff volcanic light"; const tShore = "ocean_rock_a"; const tWater = "ocean_rock_b"; const oTree = "gaia/flora_tree_dead"; const oTree2 = "gaia/flora_tree_euro_beech"; const oTree3 = "gaia/flora_tree_oak"; const oTree4 = "gaia/flora_tree_oak_dead"; const oBush = "gaia/flora_bush_temperate"; const oFruitBush = "gaia/flora_bush_berry"; const oRabbit = "gaia/fauna_rabbit"; const oGoat = "gaia/fauna_goat"; const oBear = "gaia/fauna_bear"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oStoneSmall = "gaia/geology_stone_temperate"; const oMetalLarge = "gaia/geology_metal_temperate_slabs"; const oTower = "other/palisades_rocks_fort"; const aRockLarge = "actor|geology/stone_granite_med.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aBushMedium = "actor|props/flora/bush_tempe_me.xml"; const aBushSmall = "actor|props/flora/bush_tempe_sm.xml"; const aGrass = "actor|props/flora/grass_soft_large_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aRain = "actor|particle/rain_shower.xml"; const pForestD = [ tForestFloor1 + TERRAIN_SEPARATOR + oTree, tForestFloor2 + TERRAIN_SEPARATOR + oTree2, tForestFloor1 ]; const pForestP = [ tForestFloor1 + TERRAIN_SEPARATOR + oTree3, tForestFloor2 + TERRAIN_SEPARATOR + oTree4, tForestFloor1 ]; var heightSeaGround = -4; var heightLand = 1; var heightHill = 18; var heightPlayerHill = 25; var g_Map = new RandomMap(heightLand, tHillMedium1); var numPlayers = getNumPlayers(); var mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clFood = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clGrass = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clBaseResource = createTileClass(); -var clBumps = createTileClass(); -var clTower = createTileClass(); -var clRain = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clGrass = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clBumps = g_Map.createTileClass(); +var clTower = g_Map.createTileClass(); +var clRain = g_Map.createTileClass(); var playerMountainSize = defaultPlayerBaseRadius(); var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); log("Creating CC mountains..."); if (!isNomad()) for (let i = 0; i < numPlayers; ++i) { // This one consists of many bumps, creating an omnidirectional ramp createMountain( heightPlayerHill, playerMountainSize, playerMountainSize, Math.floor(scaleByMapSize(4, 10)), undefined, playerPosition[i].x, playerPosition[i].y, tHillDark, clPlayer, 14); // Flatten the initial CC area createArea( new ClumpPlacer(diskArea(playerMountainSize), 0.95, 0.6, 10, playerPosition[i]), [ new LayeredPainter([tHillVeryDark, tHillMedium1], [playerMountainSize]), new SmoothElevationPainter(ELEVATION_SET, heightPlayerHill, playerMountainSize), paintClass(clPlayer) ]); } Engine.SetProgress(8); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], // PlayerTileClass already marked above "BaseResourceClass": clBaseResource, "Walls": "towers", "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree2 } // No decoratives }); Engine.SetProgress(15); createVolcano(mapCenter, clHill, tHillVeryDark, undefined, false, ELEVATION_SET); Engine.SetProgress(20); log("Creating lakes..."); createAreas( new ChainPlacer(5, 6, Math.floor(scaleByMapSize(10, 14)), 0.1), [ new LayeredPainter([tShoreBlend, tShore, tWater], [1, 1]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 3), paintClass(clWater) ], avoidClasses(clPlayer, 0, clHill, 2, clWater, 12), Math.round(scaleByMapSize(6, 12))); Engine.SetProgress(25); createBumps(avoidClasses(clPlayer, 0, clHill, 0), scaleByMapSize(50, 300), 1, 10, 3, 0, scaleByMapSize(4, 10)); paintTileClassBasedOnHeight(10, 100, 0, clBumps); Engine.SetProgress(30); log("Creating hills..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1), [ new LayeredPainter([tHillDark, tHillDark, tHillDark], [2, 2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], avoidClasses(clPlayer, 0, clHill, 15, clWater, 2, clBaseResource, 2), scaleByMapSize(2, 8) * numPlayers); Engine.SetProgress(35); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(1200, 3000, 0.7); var types = [ [[tGrassB, tGrassA, pForestD], [tGrassB, pForestD]], [[tGrassB, tGrassA, pForestP], [tGrassB, pForestP]] ]; var size = forestTrees / (scaleByMapSize(4, 12) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses( clPlayer, 4, clForest, 10, clHill, 0, clWater, 2), num); Engine.SetProgress(40); log("Creating hill patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) for (let type of [[tHillMedium1, tHillDark], [tHillDark, tHillMedium2], [tHillMedium1, tHillMedium2]]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter(type, [1]), paintClass(clGrass) ], avoidClasses( clWater, 3, clForest, 0, clHill, 0, clBumps, 0, clPlayer, 0), scaleByMapSize(20, 80)); Engine.SetProgress(45); log("Creating grass patches..."); createLayeredPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], [tGrassPatchBlend, tGrassPatch], [1], avoidClasses( clWater, 1, clForest, 0, clHill, 0, clGrass, 5, clBumps, 0, clPlayer, 0), scaleByMapSize(3, 8), clDirt); Engine.SetProgress(50); log("Creating stone mines..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4) ], true, clRock), 0, [ stayClasses(clBumps, 1), avoidClasses( clWater, 3, clForest, 1, clPlayer, 0, clRock, 15, clHill, 0) ], 100, 100); Engine.SetProgress(55); log("Creating small stone quarries..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oStoneSmall, 2, 5, 1, 3)], true, clRock), 0, [ stayClasses(clBumps, 1), avoidClasses( clWater, 3, clForest, 1, clPlayer, 0, clRock, 15, clHill, 0) ], 100, 100); Engine.SetProgress(60); log("Creating metal mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal), 0, [ stayClasses(clBumps, 1), avoidClasses( clWater, 3, clForest, 1, clPlayer, 0, clMetal, 15, clRock, 10, clHill, 0) ], 100, 100); Engine.SetProgress(65); if (!isNomad()) { log("Creating towers..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oTower, 1, 1, 0, 4)], true, clTower), 0, [ stayClasses(clBumps, 3), avoidClasses( clMetal, 5, clRock, 5, clHill, 0, clTower, 60, clPlayer, 10, clForest, 2) ], 500, 1); } Engine.SetProgress(67); createDecoration( [ [ new SimpleObject(aGrassShort, 1, 2, 0, 1) ], [ new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5) ], [ new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2) ] ], [ scaleByMapSize(15, 200), scaleByMapSize(15, 200), scaleByMapSize(15, 200) ], [ stayClasses(clGrass, 0), avoidClasses( clWater, 0, clForest, 0, clPlayer, 0, clHill, 0) ]); Engine.SetProgress(70); createDecoration( [ [ new SimpleObject(aRockMedium, 1, 3, 0, 1) ], [ new SimpleObject(aRockLarge, 1, 2, 0, 1), new SimpleObject(aRockMedium, 1, 3, 0, 2) ] ], [ scaleByMapSize(15, 250), scaleByMapSize(15, 150) ], avoidClasses( clWater, 0, clForest, 0, clPlayer, 0, clHill, 0 )); Engine.SetProgress(75); createFood( [ [new SimpleObject(oRabbit, 5, 7, 2, 4)], [new SimpleObject(oGoat, 3, 5, 2, 4)] ], [ scaleByMapSize(1, 6) * numPlayers, scaleByMapSize(3, 10) * numPlayers ], [ avoidClasses( clWater, 1, clForest, 0, clPlayer, 0, clHill, 1, clFood, 20) ], clFood); Engine.SetProgress(78); createFood( [ [new SimpleObject(oBear, 1, 1, 0, 2)] ], [ 3 * numPlayers ], [ avoidClasses( clWater, 1, clForest, 0, clPlayer, 0, clHill, 1, clFood, 20 ), stayClasses(clForest, 2) ], clFood); Engine.SetProgress(81); createFood( [ [new SimpleObject(oFruitBush, 1, 2, 0, 4)] ], [ 3 * numPlayers ], [stayClasses(clGrass, 1), avoidClasses(clWater, 1, clForest, 0, clPlayer, 0, clHill, 1, clFood, 10)], clFood); Engine.SetProgress(85); createStragglerTrees( [oTree, oTree2, oTree3, oTree4, oBush], [ stayClasses(clGrass, 1), avoidClasses( clWater, 5, clForest, 1, clHill, 1, clPlayer, 0, clMetal, 1, clRock, 1) ], clForest, stragglerTrees); Engine.SetProgress(90); log("Creating straggler bushes..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oBush, 1, 3, 0, 3)], true, clForest ), 0, [ stayClasses(clGrass, 3), avoidClasses( clWater, 1, clForest, 1, clPlayer, 0, clMetal, 1, clRock, 1) ], stragglerTrees); Engine.SetProgress(95); log("Creating rain drops..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(aRain, 2, 2, 1, 4)], true, clRain), 0, avoidClasses(clRain, 5), scaleByMapSize(80, 250)); Engine.SetProgress(95); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clHill, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("rain"); setWaterType("lake"); setWaterWaviness(2); setWaterColor(0.1, 0.13, 0.15); setWaterTint(0.058, 0.05, 0.035); setWaterMurkiness(0.9); setPPEffect("hdr"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/flood.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/flood.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/flood.js (revision 21000) @@ -1,303 +1,303 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); 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 tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; const tShore = g_Terrains.shore; const tWater = g_Terrains.water; var tHill = g_Terrains.hill; var tDirt = g_Terrains.dirt; if (currentBiome() == "temperate") { tDirt = ["medit_shrubs_a", "grass_field"]; tHill = ["grass_field", "peat_temp"]; } 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 oMetalLarge = g_Gaia.metalLarge; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; 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]; const heightSeaGround = -2; const heightLand = 2; const shoreRadius = 6; var g_Map = new RandomMap(heightSeaGround, tWater); -const clPlayer = createTileClass(); -const clHill = createTileClass(); -const clMountain = createTileClass(); -const clForest = createTileClass(); -const clDirt = createTileClass(); -const clRock = createTileClass(); -const clMetal = createTileClass(); -const clFood = createTileClass(); -const clBaseResource = createTileClass(); +const clPlayer = g_Map.createTileClass(); +const clHill = g_Map.createTileClass(); +const clMountain = g_Map.createTileClass(); +const clForest = g_Map.createTileClass(); +const clDirt = g_Map.createTileClass(); +const clRock = g_Map.createTileClass(); +const clMetal = g_Map.createTileClass(); +const clFood = g_Map.createTileClass(); +const clBaseResource = g_Map.createTileClass(); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); log("Creating player islands...") var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.38)); for (let i = 0; i < numPlayers; ++i) createArea( new ClumpPlacer(diskArea(1.4 * defaultPlayerBaseRadius()), 0.8, 0.1, 10, playerPosition[i]), [ new LayeredPainter([tShore, tMainTerrain], [shoreRadius]), new SmoothElevationPainter(ELEVATION_SET, heightLand, shoreRadius), paintClass(clHill) ]); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "Walls": false, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree2, "count": 50, "maxDist": 16, "maxDistGroup": 7 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(40); log("Creating central island..."); createArea( new ChainPlacer( 6, Math.floor(scaleByMapSize(10, 15)), Math.floor(scaleByMapSize(200, 300)), 1, mapCenter, 0, [Math.floor(fractionToTiles(0.01))]), [ new LayeredPainter([tShore, tMainTerrain], [shoreRadius, 100]), new SmoothElevationPainter(ELEVATION_SET, heightLand, shoreRadius), paintClass(clHill) ], avoidClasses(clPlayer, 40)); for (let m = 0; m < randIntInclusive(20, 34); ++m) { let elevRand = randIntInclusive(6, 20); createArea( new ChainPlacer( 7, 15, Math.floor(scaleByMapSize(15, 20)), 1, new Vector2D(fractionToTiles(randFloat(0, 1)), fractionToTiles(randFloat(0, 1))), 0, [Math.floor(fractionToTiles(0.01))]), [ new LayeredPainter([tDirt, tHill], [Math.floor(elevRand / 3), 40]), new SmoothElevationPainter(ELEVATION_SET, elevRand, Math.floor(elevRand / 3)), paintClass(clHill) ], [avoidClasses(clBaseResource, 2, clPlayer, 40), stayClasses(clHill, 6)]); } for (let m = 0; m < randIntInclusive(8, 17); ++m) { let elevRand = randIntInclusive(15, 29); createArea( new ChainPlacer( 5, 8, Math.floor(scaleByMapSize(15, 20)), 1, new Vector2D(randIntExclusive(0, mapSize), randIntExclusive(0, mapSize)), 0, [Math.floor(fractionToTiles(0.01))]), [ new LayeredPainter([tCliff, tForestFloor2], [Math.floor(elevRand / 3), 40]), new SmoothElevationPainter(ELEVATION_MODIFY, elevRand, Math.floor(elevRand / 3)), paintClass(clMountain) ], [avoidClasses(clBaseResource, 2, clPlayer, 40), stayClasses(clHill, 6)]); } log("Creating center bounty..."); createObjectGroup( new SimpleGroup( [new SimpleObject(oMetalLarge, 3, 6, 25, Math.floor(fractionToTiles(0.25)))], true, clBaseResource, mapCenter.x, mapCenter.y), 0, [avoidClasses(clBaseResource, 20, clPlayer, 40, clMountain, 4), stayClasses(clHill, 10)]); createObjectGroup( new SimpleGroup( [new SimpleObject(oStoneLarge, 3, 6, 25, Math.floor(fractionToTiles(0.25)))], true, clBaseResource, mapCenter.x, mapCenter.y), 0, [avoidClasses(clBaseResource, 20, clPlayer, 40, clMountain, 4), stayClasses(clHill, 10)]); log("Creating fish..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oFish, 2, 3, 0, 2)], true, clFood), 0, avoidClasses(clHill, 10, clFood, 20), 10 * numPlayers, 60); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(0.7)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], [avoidClasses(clPlayer, 25, clForest, 10, clBaseResource, 3, clMetal, 6, clRock, 3, clMountain, 2), stayClasses(clHill, 6)], clForest, forestTrees); let types = [oTree1, oTree2, oTree4, oTree3]; createStragglerTrees( types, [avoidClasses(clBaseResource, 2, clMetal, 6, clRock, 3, clMountain, 2, clPlayer, 25), stayClasses(clHill, 6)], clForest, stragglerTrees); Engine.SetProgress(65); log("Creating dirt patches..."); var numb = currentBiome() == "savanna" ? 3 : 1; for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]], [1, 1]), paintClass(clDirt) ], avoidClasses(clForest, 0, clMountain, 0, clDirt, 5, clPlayer, 10), numb * scaleByMapSize(15, 45)); log("Painting shorelines..."); paintTerrainBasedOnHeight(1, heightLand, 0, tMainTerrain); paintTerrainBasedOnHeight(heightSeaGround, 1, 3, tTier1Terrain); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), new TerrainPainter(tTier4Terrain), avoidClasses(clForest, 0, clMountain, 0, clDirt, 5, clPlayer, 10), numb * scaleByMapSize(15, 45)); log("Creating food..."); createFood( [ [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)] ], [3 * numPlayers, 3 * numPlayers], [avoidClasses(clForest, 0, clPlayer, 20, clMountain, 1, clFood, 4, clRock, 6, clMetal, 6), stayClasses(clHill, 6)], clFood); Engine.SetProgress(75); createFood( [ [new SimpleObject(oFruitBush, 5, 7, 0, 4)] ], [3 * numPlayers], [avoidClasses(clForest, 0, clPlayer, 15, clMountain, 1, clFood, 4, clRock, 6, clMetal, 6), stayClasses(clHill, 6)], clFood); Engine.SetProgress(85); log("Creating decoration..."); var planetm = currentBiome() == "tropic" ? 8 : 1; 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, 2, 15, 0, 1)], [new SimpleObject(aGrass, 2, 10, 0, 1.8), new SimpleObject(aGrassShort, 3, 10, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 5, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200) ], avoidClasses(clForest, 2, clPlayer, 20, clMountain, 5, clFood, 1, clBaseResource, 2)); log("Creating water forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(0.1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], avoidClasses(clPlayer, 30, clHill, 10, clFood, 5), clForest, forestTrees); log("Creating small grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aGrassShort, 1, 2, 0, 1)]), 0, [avoidClasses(clMountain, 2, clPlayer, 2, clDirt, 0), stayClasses(clHill, 8)], planetm * scaleByMapSize(13, 200)); placePlayersNomad( clPlayer, new AndConstraint([ stayClasses(clHill, 2), avoidClasses(clMountain, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)])); setSkySet(pickRandom(["cloudless", "cumulus", "overcast"])); setWaterMurkiness(0.4); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/fortress.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/fortress.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/fortress.js (revision 21000) @@ -1,308 +1,308 @@ Engine.LoadLibrary("rmgen"); const tGrass = ["temp_grass_aut", "temp_grass_aut", "temp_grass_d_aut"]; const tForestFloor = "temp_grass_aut"; const tGrassA = "temp_grass_plants_aut"; const tGrassB = "temp_grass_b_aut"; const tGrassC = "temp_grass_c_aut"; const tHill = ["temp_highlands_aut", "temp_grass_long_b_aut"]; const tCliff = ["temp_cliff_a", "temp_cliff_b"]; const tRoad = "temp_road_aut"; const tGrassPatch = "temp_grass_plants_aut"; const tShore = "temp_plants_bog_aut"; const tWater = "temp_mud_a"; const oBeech = "gaia/flora_tree_euro_beech_aut"; const oOak = "gaia/flora_tree_oak_aut"; const oPine = "gaia/flora_tree_pine"; const oDeer = "gaia/fauna_deer"; const oFish = "gaia/fauna_fish"; const oSheep = "gaia/fauna_rabbit"; const oBerryBush = "gaia/flora_bush_berry"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oStoneSmall = "gaia/geology_stone_temperate"; const oMetalLarge = "gaia/geology_metal_temperate_slabs"; const oFoodTreasure = "gaia/special_treasure_food_bin"; const oWoodTreasure = "gaia/special_treasure_wood"; const oStoneTreasure = "gaia/special_treasure_stone"; const oMetalTreasure = "gaia/special_treasure_metal"; const aGrass = "actor|props/flora/grass_soft_dry_small_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_dry_large.xml"; const aRockLarge = "actor|geology/stone_granite_med.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aReeds = "actor|props/flora/reeds_pond_dry.xml"; const aLillies = "actor|props/flora/water_lillies.xml"; const aBushMedium = "actor|props/flora/bush_medit_me_dry.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm_dry.xml"; const pForestD = [tForestFloor + TERRAIN_SEPARATOR + oBeech, tForestFloor]; const pForestO = [tForestFloor + TERRAIN_SEPARATOR + oOak, tForestFloor]; const pForestP = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor]; var heightSeaGround = -4; var heightLand = 3; var g_Map = new RandomMap(heightLand, tGrass); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var treasures = [ { "template": oFoodTreasure, "distance": 5 }, { "template": oWoodTreasure, "distance": 5 }, { "template": oMetalTreasure, "distance": 3 }, { "template": oMetalTreasure, "distance": 2 }, ]; var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); for (let i = 0; i < numPlayers; ++i) { if (isNomad()) break; log("Creating base for player " + playerIDs[i] + "..."); for (let dist of [6, 8]) { let ents = getStartingEntities(playerIDs[i]); if (dist == 8) ents = ents.filter(ent => ent.Template.indexOf("female") != -1 || ent.Template.indexOf("infantry") != -1); placeStartingEntities(playerPosition[i], playerIDs[i], ents, dist); } log("Creating treasure for player " + playerIDs[i] + "..."); let bbAngle = BUILDING_ORIENTATION; for (let treasure of treasures) { let position = Vector2D.add(playerPosition[i], new Vector2D(10, 0).rotate(-bbAngle)) createObjectGroup(new SimpleGroup([new SimpleObject(oFoodTreasure, 5, 5, 0, 2)], true, clBaseResource, position.x, position.y), 0); bbAngle += Math.PI / 2; } log("Painting ground texture for player " + playerIDs[i] + "..."); var civ = getCivCode(playerIDs[i]); var tilesSize = civ == "cart" ? 24 : 22; const minBoundX = Math.max(0, playerPosition[i].x - tilesSize); const minBoundY = Math.max(0, playerPosition[i].y - tilesSize); const maxBoundX = Math.min(mapSize, playerPosition[i].x + tilesSize); const maxBoundY = Math.min(mapSize, playerPosition[i].y + tilesSize); for (var tx = minBoundX; tx < maxBoundX; ++tx) for (var ty = minBoundY; ty < maxBoundY; ++ty) { let position = new Vector2D(tx, ty); var unboundSumOfXY = tx + ty - minBoundX - minBoundY; if (unboundSumOfXY > tilesSize && unboundSumOfXY < tilesSize * 3 && tx - ty + minBoundY - minBoundX < tilesSize && ty - tx - minBoundY + minBoundX < tilesSize) { createTerrain(tRoad).place(position); addToClass(tx, ty, clPlayer); } } log("Placing fortress for player " + playerIDs[i] + "..."); if (civ == "brit" || civ == "gaul" || civ == "iber") { var wall = ["gate", "tower", "long", "cornerIn", "long", "barracks", "tower", "long", "tower", "house", "long", "cornerIn", "long", "house", "tower", "gate", "tower", "house", "long", "cornerIn", "long", "house", "tower", "long", "tower", "house", "long", "cornerIn", "long", "house", "tower"]; } else { var wall = ["gate", "tower", "long", "cornerIn", "long", "barracks", "tower", "long", "tower", "long", "cornerIn", "long", "house", "tower", "gate", "tower", "long", "cornerIn", "long", "house", "tower", "long", "tower", "long", "cornerIn", "long", "house", "tower"]; } placeCustomFortress(playerPosition[i].x, playerPosition[i].y, new Fortress("Spahbod", wall), civ, playerIDs[i], -Math.PI/4); } log("Creating lakes..."); var numLakes = Math.round(scaleByMapSize(1,4) * numPlayers); var waterAreas = createAreas( new ClumpPlacer(scaleByMapSize(100,250), 0.8, 0.1, 10), [ new LayeredPainter([tShore, tWater, tWater], [1, 1]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 3), paintClass(clWater) ], avoidClasses(clPlayer, 7, clWater, 20), numLakes); Engine.SetProgress(15); log("Creating reeds..."); createObjectGroupsByAreasDeprecated( new SimpleGroup([new SimpleObject(aReeds, 5,10, 0,4), new SimpleObject(aLillies, 0,1, 0,4)], true), 0, [borderClasses(clWater, 3, 0), stayClasses(clWater, 1)], numLakes, 100, waterAreas); Engine.SetProgress(25); log("Creating fish..."); createObjectGroupsByAreasDeprecated( new SimpleGroup( [new SimpleObject(oFish, 1,1, 0,1)], true, clFood ), 0, [stayClasses(clWater, 4), avoidClasses(clFood, 8)], numLakes / 4, 50, waterAreas); Engine.SetProgress(30); createBumps(avoidClasses(clWater, 2, clPlayer, 5)); Engine.SetProgress(35); log("Creating hills..."); createHills([tCliff, tCliff, tHill], avoidClasses(clPlayer, 5, clWater, 5, clHill, 15), clHill, scaleByMapSize(1, 4) * numPlayers); Engine.SetProgress(40); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(500, 2500, 0.7); var types = [ [[tForestFloor, tGrass, pForestD], [tForestFloor, pForestD]], [[tForestFloor, tGrass, pForestO], [tForestFloor, pForestO]], [[tForestFloor, tGrass, pForestP], [tForestFloor, pForestP]] ]; var size = forestTrees / (scaleByMapSize(3,6) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), forestTrees / num, 0.5), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 5, clWater, 3, clForest, 15, clHill, 1), num); Engine.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(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 1), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(55); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tGrassPatch, avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 1), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(60); 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, 0, clForest, 1, clPlayer, 5, clRock, 10, clHill, 1), clRock); Engine.SetProgress(65); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 0, clForest, 1, clPlayer, 5, clMetal, 10, clRock, 5, clHill, 1), clMetal ); Engine.SetProgress(70); 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [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, 0, clForest, 0, clPlayer, 1, clHill, 0)); Engine.SetProgress(80); createFood( [ [new SimpleObject(oSheep, 2, 3, 0, 2)], [new SimpleObject(oDeer, 5, 7, 0, 4)] ], [ 3 * numPlayers, 3 * numPlayers ], avoidClasses(clWater, 0, clForest, 0, clPlayer, 6, clHill, 1, clFood, 20), clFood); Engine.SetProgress(85); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ randIntInclusive(1, 4) * numPlayers + 2 ], avoidClasses(clWater, 2, clForest, 0, clPlayer, 6, clHill, 1, clFood, 10), clFood); Engine.SetProgress(90); createStragglerTrees( [oOak, oBeech, oPine], avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 1, clMetal, 6, clRock, 6), clForest, stragglerTrees); Engine.SetProgress(95); placePlayersNomad(clPlayer, avoidClasses(clWater, 2, clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("sunny"); setWaterColor(0.157, 0.149, 0.443); setWaterTint(0.443,0.42,0.824); setWaterWaviness(2.0); setWaterType("lake"); setWaterMurkiness(0.83); setFogFactor(0.35); setFogThickness(0.22); setFogColor(0.82,0.82, 0.73); setPPSaturation(0.56); setPPContrast(0.56); setPPBloom(0.38); setPPEffect("hdr"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/gear.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/gear.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/gear.js (revision 21000) @@ -1,312 +1,312 @@ Engine.LoadLibrary("rmgen"); Engine.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.mainTerrain; const tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; 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 aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; 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]; var heightSeaGround = -4; var heightShallow = -2; var heightLand = 3; var heightRing = 4; var heightHill = 20; var g_Map = new RandomMap(heightLand, tMainTerrain); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var radiusPlayers = fractionToTiles(0.35); var radiusCentralLake = fractionToTiles(0.27); var radiusCentralRingLand = fractionToTiles(0.21); var radiusCentralWaterRing = fractionToTiles(0.17); var radiusCentralIsland = fractionToTiles(0.14); var radiusCentralHill = fractionToTiles(0.12); var [playerIDs, playerPosition, playerAngle, startAngle] = playerPlacementCircle(radiusPlayers); log("Determining number of rivers between players..."); var split = 1; if (mapSize == 128 && numPlayers <= 2) split = 2; else if (mapSize == 192 && numPlayers <= 3) split = 2; else if (mapSize == 256) { if (numPlayers <= 3) split = 3; else if (numPlayers == 4) split = 2; } else if (mapSize == 320) { if (numPlayers <= 3) split = 3; else if (numPlayers == 4) split = 2; } else if (mapSize == 384) { if (numPlayers <= 3) split = 4; else if (numPlayers == 4) split = 3; else if (numPlayers == 5) split = 2; } else if (mapSize == 448) { if (numPlayers <= 2) split = 5; else if (numPlayers <= 4) split = 4; else if (numPlayers == 5) split = 3; else if (numPlayers == 6) split = 2; } log("Creating big circular lake..."); createArea( new ClumpPlacer(diskArea(radiusCentralLake), 1, 1, 10, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightShallow, 4)); for (let m = 0; m < numPlayers * split; ++m) { log("Creating rivers between players..."); let angle = startAngle + (m + 0.5) * 2 * Math.PI / (numPlayers * split); let position1 = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.15), 0).rotate(-angle)); let position2 = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.6), 0).rotate(-angle)); createArea( new PathPlacer(position1, position2, scaleByMapSize(14, 40), 0, scaleByMapSize(3, 9), 0.2, 0.05), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), avoidClasses(clPlayer, 5)); log("Create path from the island to the center..."); angle = startAngle + m * 2 * Math.PI / (numPlayers * split); position1 = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.05), 0).rotate(-angle)); position2 = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.49), 0).rotate(-angle)); createArea( new PathPlacer(position1, position2, scaleByMapSize(10, 40), 0, scaleByMapSize(3, 9), 0.2, 0.05), new SmoothElevationPainter(ELEVATION_SET, heightLand, 4)); } log("Creating ring of land connecting players..."); createArea( new ClumpPlacer(diskArea(radiusCentralRingLand), 1, 1, 10, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightRing, 4)); log("Creating ring of water separating the central hill from the ring..."); createArea( new ClumpPlacer(diskArea(radiusCentralWaterRing), 1, 1, 10, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightShallow, 3)); log("Creating central island..."); createArea( new ClumpPlacer(diskArea(radiusCentralIsland), 1, 1, 10, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightRing, 3)); log("Creating hill on the central island..."); createArea( new ClumpPlacer(diskArea(radiusCentralHill), 1, 1, 10, mapCenter), new SmoothElevationPainter(ELEVATION_SET, heightHill, 8)); paintTerrainBasedOnHeight(-6, 1, 1, tWater); paintTerrainBasedOnHeight(1, 2, 1, tShore); paintTerrainBasedOnHeight(2, 21, 1, tMainTerrain); paintTileClassBasedOnHeight(-6, 0.5, 1, clWater); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "baseResourceConstraint": avoidClasses(clWater, 2), "Walls": "towers", "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree1, "count": 2 }, "Decoratives": { "template": aGrassShort } }); if (randBool()) createHills([tMainTerrain, tCliff, tHill], avoidClasses(clPlayer, 20, clHill, 15, clWater, 2), clHill, scaleByMapSize(1, 4) * numPlayers); else createMountains(tCliff, avoidClasses(clPlayer, 20, clHill, 15, clWater, 2), clHill, scaleByMapSize(1, 4) * numPlayers); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], avoidClasses(clPlayer, 20, clForest, 17, clHill, 0, clWater, 2), clForest, forestTrees); Engine.SetProgress(50); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], [1,1], avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tTier4Terrain, avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); Engine.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(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), clMetal ); log("Creating fish..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oFish, 1,1, 0,3)], true, clFood), 0, [stayClasses(clWater, 8), avoidClasses(clFood, 14)], scaleByMapSize(400, 2000), 100); Engine.SetProgress(65); var planetm = 1; if (currentBiome() == "tropic") planetm = 8; 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200) ], avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0)); Engine.SetProgress(70); createFood( [ [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), clFood); createFood( [ [new SimpleObject(oFruitBush, 5, 7, 0, 4)] ], [ 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], avoidClasses(clWater, 5, clForest, 7, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/gulf_of_bothnia.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/gulf_of_bothnia.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/gulf_of_bothnia.js (revision 21000) @@ -1,336 +1,336 @@ Engine.LoadLibrary("rmgen"); TILE_CENTERED_HEIGHT_MAP = true; var biome = pickRandom(["late_spring", "winter", "frozen_lake"]); if (biome == "late_spring") { log("Late spring biome..."); var heightSeaGround = -3; var heightShore = 1; var heightLand = 3; var fishCount = { "min": 20, "max": 80 }; var bushCount = { "min": 13, "max": 200 }; setFogThickness(0.26); setFogFactor(0.4); setPPEffect("hdr"); setPPSaturation(0.48); setPPContrast(0.53); setPPBloom(0.12); var tPrimary = ["alpine_dirt_grass_50"]; var tForestFloor = "alpine_forrestfloor"; var tCliff = ["alpine_cliff_a", "alpine_cliff_b", "alpine_cliff_c"]; var tSecondary = "alpine_grass_rocky"; var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"]; var tSnowLimited = ["alpine_snow_rocky"]; var tRoad = "new_alpine_citytile"; var tRoadWild = "new_alpine_citytile"; var tShore = "alpine_shore_rocks_grass_50"; var tWater = "alpine_shore_rocks"; var oPine = "gaia/flora_tree_pine"; var oBerryBush = "gaia/flora_bush_berry"; var oDeer = "gaia/fauna_deer"; var oFish = "gaia/fauna_fish"; var oRabbit = "gaia/fauna_rabbit"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; var aGrass = "actor|props/flora/grass_soft_small_tall.xml"; var aGrassShort = "actor|props/flora/grass_soft_large.xml"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; var aBushMedium = "actor|props/flora/bush_medit_me.xml"; var aBushSmall = "actor|props/flora/bush_medit_sm.xml"; } else if (biome == "winter") { log("Winter biome..."); var heightSeaGround = -3; var heightShore = 1; var heightLand = 3; var fishCount = { "min": 20, "max": 80 }; var bushCount = { "min": 13, "max": 200 }; setFogFactor(0.35); setFogThickness(0.19); setPPSaturation(0.37); setPPEffect("hdr"); var tPrimary = ["alpine_snow_a", "alpine_snow_b"]; var tForestFloor = "alpine_forrestfloor_snow"; var tCliff = ["alpine_cliff_snow"]; var tSecondary = "alpine_grass_snow_50"; var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"]; var tSnowLimited = ["alpine_snow_a", "alpine_snow_b"]; var tRoad = "new_alpine_citytile"; var tRoadWild = "new_alpine_citytile"; var tShore = "alpine_shore_rocks_icy"; var tWater = "alpine_shore_rocks"; var oPine = "gaia/flora_tree_pine_w"; var oBerryBush = "gaia/flora_bush_berry"; var oDeer = "gaia/fauna_deer"; var oFish = "gaia/fauna_fish"; var oRabbit = "gaia/fauna_rabbit"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; var aGrass = "actor|props/flora/grass_soft_dry_small_tall.xml"; var aGrassShort = "actor|props/flora/grass_soft_dry_large.xml"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; var aBushMedium = "actor|props/flora/bush_medit_me_dry.xml"; var aBushSmall = "actor|props/flora/bush_medit_sm_dry.xml"; } else if (biome == "frozen_lake") { log("Frozen lake biome..."); var heightSeaGround = 0; var heightShore = 2; var heightLand = 3; var fishCount = { "min": 0, "max": 0 }; var bushCount = { "min": 0, "max": 0 }; setFogFactor(0.41); setFogThickness(0.23); setPPSaturation(0.34); setPPEffect("hdr"); var tPrimary = ["alpine_snow_a", "alpine_snow_b"]; var tForestFloor = "alpine_snow_a"; var tCliff = ["alpine_cliff_snow"]; var tSecondary = "polar_ice_snow"; var tHalfSnow = ["polar_ice_cracked"]; var tSnowLimited = ["alpine_snow_a", "alpine_snow_b"]; var tRoad = "new_alpine_citytile"; var tRoadWild = "new_alpine_citytile"; var tShore = "polar_ice_snow"; var tWater = ["polar_ice_snow", "polar_ice"]; var oPine = "gaia/flora_tree_pine_w"; var oBerryBush = "gaia/flora_bush_berry"; var oDeer = "gaia/fauna_deer"; var oFish = "gaia/fauna_fish"; var oRabbit = "gaia/fauna_rabbit"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; var aGrass = "actor|props/flora/grass_soft_dry_small_tall.xml"; var aGrassShort = "actor|props/flora/grass_soft_dry_large.xml"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; var aBushMedium = "actor|props/flora/bush_medit_me_dry.xml"; var aBushSmall = "actor|props/flora/bush_medit_sm_dry.xml"; } const pForest = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor]; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var startAngle = randomAngle(); placePlayerBases({ "PlayerPlacement": [sortAllPlayers(), ...playerPlacementCustomAngle( fractionToTiles(0.35), mapCenter, i => startAngle + 1/3 * Math.PI * (1 + 2 * (numPlayers == 1 ? 1 : 2 * i / (numPlayers - 1))))], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oPine, "count": 2 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); log("Creating the gulf..."); var gulfLakePositions = [ { "numCircles": 200, "x": fractionToTiles(0), "radius": fractionToTiles(0.175) }, { "numCircles": 120, "x": fractionToTiles(0.3), "radius": fractionToTiles(0.2) }, { "numCircles": 100, "x": fractionToTiles(0.5), "radius": fractionToTiles(0.225) } ]; for (let gulfLake of gulfLakePositions) { let position = Vector2D.add(mapCenter, new Vector2D(gulfLake.x, 0).rotate(-startAngle)).round(); createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 16)), Math.floor(scaleByMapSize(35, gulfLake.numCircles)), 1, position, 0, [Math.floor(gulfLake.radius)]), [ new LayeredPainter([tPrimary, tPrimary, tPrimary, tPrimary], [1, 4, 2]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), paintClass(clWater) ], avoidClasses(clPlayer,scaleByMapSize(20, 28))); } paintTerrainBasedOnHeight(heightShore, heightLand, Elevation_ExcludeMin_ExcludeMax, tShore); paintTerrainBasedOnHeight(-Infinity, heightShore, Elevation_ExcludeMin_IncludeMax, tWater); createBumps(avoidClasses(clWater, 2, clPlayer, 10)); if (randBool()) createHills([tPrimary, tCliff, tPrimary], avoidClasses(clPlayer, 20, clHill, 15, clWater, 0), clHill, scaleByMapSize(1, 4) * numPlayers); else createMountains(tCliff, avoidClasses(clPlayer, 20, clHill, 15, clWater, 0), clHill, scaleByMapSize(1, 4) * numPlayers); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tPrimary, tForestFloor, tForestFloor, pForest, pForest], avoidClasses(clPlayer, 20, clForest, 16, clHill, 0, clWater, 2), clForest, forestTrees); Engine.SetProgress(60); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tPrimary,tSecondary],[tSecondary,tHalfSnow], [tHalfSnow,tSnowLimited]], [1,1], avoidClasses(clWater, 6, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tHalfSnow, avoidClasses(clWater, 6, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(65); 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, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), clMetal ); Engine.SetProgress(70); 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), scaleByMapSize(bushCount.min, bushCount.max), scaleByMapSize(bushCount.min, bushCount.max), scaleByMapSize(bushCount.min, bushCount.max) ], avoidClasses(clWater, 0, clForest, 0, clPlayer, 5, clHill, 0, clBaseResource, 5)); Engine.SetProgress(75); createFood( [ [new SimpleObject(oDeer, 5, 7, 0, 4)], [new SimpleObject(oRabbit, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), clFood); createFood( [[new SimpleObject(oBerryBush, 5, 7, 0, 4)]], [randIntInclusive(1, 4) * numPlayers + 2], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); createFood( [[new SimpleObject(oFish, 2, 3, 0, 2)]], [scaleByMapSize(fishCount.min, fishCount.max)], [avoidClasses(clFood, 20), stayClasses(clWater, 6)], clFood); Engine.SetProgress(85); createStragglerTrees( [oPine], avoidClasses(clWater, 3, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); // Avoid the lake, even if frozen placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("stormy"); setSunRotation(randomAngle()); setSunElevation(Math.PI * randFloat(1/6, 1/4)); setWaterColor(0.035,0.098,0.314); setWaterTint(0.28, 0.3, 0.59); setWaterWaviness(5.0); setWaterType("lake"); setWaterMurkiness(0.88); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/india.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/india.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/india.js (revision 21000) @@ -1,271 +1,271 @@ Engine.LoadLibrary("rmgen"); const tGrass1 = "savanna_grass_a"; const tDirt1 = "savanna_dirt_a"; const tDirt4 = "savanna_dirt_b"; const tCityTiles = "savanna_tile_a_dirt_red"; const tShore = "savanna_riparian_bank"; const tWater = "savanna_riparian_wet"; const oTree = "gaia/flora_tree_palm_tropic"; const oBerryBush = "gaia/flora_bush_berry"; const oRabbit = "gaia/fauna_rabbit"; const oTiger = "gaia/fauna_tiger"; const oCrocodile = "gaia/fauna_crocodile"; const oFish = "gaia/fauna_fish"; const oElephant = "gaia/fauna_elephant_asian"; const oElephantInfant = "gaia/fauna_elephant_asian_infant"; const oBoar = "gaia/fauna_boar"; const oStoneSmall = "gaia/geology_stone_savanna_small"; const oMetalLarge = "gaia/geology_metal_savanna_slabs"; const aBush = "actor|props/flora/bush_medit_sm_dry.xml"; const aRock = "actor|geology/stone_savanna_med.xml"; const heightSeaGround = -3; const heightLand = 1; const heightShore = 3; const heightOffsetBump = 2; var g_Map = new RandomMap(heightLand, tGrass1); var numPlayers = getNumPlayers(); var mapSize = g_Map.getSize(); var mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, // No city patch "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "type": "stone_formation", "template": oStoneSmall, "terrain": tDirt1 } ] }, "Trees": { "template": oTree, "count": scaleByMapSize(3, 7), "minDist": 13, "maxDist": 15, "minDistGroup": 4, "maxDistGroup": 6 } // No decoratives }); Engine.SetProgress(20); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.5, 0.08, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), avoidClasses(clPlayer, 13), scaleByMapSize(300, 800) ); log("Creating the half dried-up lake..."); createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(2, 16)), Math.floor(scaleByMapSize(35, 200)), 1, mapCenter, 0, [Math.floor(scaleByMapSize(15, 40))]), [ new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), paintClass(clWater) ], avoidClasses(clPlayer, 2)); log("Creating more shore jaggedness..."); createAreas( new ChainPlacer(2, Math.floor(scaleByMapSize(4, 6)), 3, 1), [ new SmoothElevationPainter(ELEVATION_SET, heightShore, 4), unPaintClass(clWater) ], borderClasses(clWater, 4, 7), scaleByMapSize(12, 130) * 2, 150 ); paintTerrainBasedOnHeight(2.4, 3.4, 3, tGrass1); paintTerrainBasedOnHeight(1, 2.4, 0, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); paintTileClassBasedOnHeight(-6, 0, 1, clWater); Engine.SetProgress(55); log("Creating stone mines..."); for (let i = 0; i < scaleByMapSize(12, 30); ++i) { let position = new Vector2D(randIntInclusive(1, mapSize - 1), randIntInclusive(1, mapSize - 1)); if (avoidClasses(clPlayer, 30, clRock, 25, clWater, 10).allows(position)) { createStoneMineFormation(position, oStoneSmall, tDirt4); addToClass(position.x, position.y, clRock); } } log("Creating metal mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal), 0, avoidClasses(clPlayer, 20, clMetal, 10, clRock, 8, clWater, 4), scaleByMapSize(2, 12), 100 ); Engine.SetProgress(65); log("Creating small decorative rocks..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(aRock, 1, 3, 0, 3)], true ), 0, avoidClasses(clPlayer, 7, clWater, 1), scaleByMapSize(200, 1200), 1 ); Engine.SetProgress(70); log("Creating boar..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oBoar, 1, 2, 0, 4)], true, clFood ), 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11), scaleByMapSize(4, 12), 50 ); log("Creating tigers..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oTiger, 2, 2, 0, 4)], true, clFood ), 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11), scaleByMapSize(4, 12), 50 ); log("Creating crocodiles..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oCrocodile, 2, 4, 0, 4)], true, clFood ), 0, stayClasses(clWater, 1), scaleByMapSize(4, 12), 50 ); log("Creating elephants..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(oElephant, 2, 4, 0, 4), new SimpleObject(oElephantInfant, 1, 2, 0, 4) ], true, clFood ), 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11), scaleByMapSize(4, 12), 50 ); log("Creating rabbits..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oRabbit, 5, 6, 0, 4)], true, clFood ), 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11), scaleByMapSize(4, 12), 50 ); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 25 * numPlayers ], [avoidClasses(clFood, 20), stayClasses(clWater, 2)], clFood); log("Creating berry bush..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oBerryBush, 5, 7, 0, 4)], true, clFood ), 0, avoidClasses(clWater, 3, clPlayer, 20, clFood, 12, clRock, 7, clMetal, 2), randIntInclusive(1, 4) * numPlayers + 2, 50 ); Engine.SetProgress(85); log("Creating trees..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(oTree, 1, 7, 0, 3)], true, clForest ), 0, avoidClasses(clForest, 1, clPlayer, 20, clMetal, 1, clRock, 7, clWater, 1), scaleByMapSize(70, 500) ); log("Creating large grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup( [new SimpleObject(aBush, 2, 4, 0, 1.8, -Math.PI/8, Math.PI/8)] ), 0, avoidClasses(clWater, 3, clPlayer, 2, clForest, 0), scaleByMapSize(100, 1200) ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setSunColor(0.87451, 0.847059, 0.647059); setWaterColor(0.741176, 0.592157, 0.27451); setWaterTint(0.741176, 0.592157, 0.27451); setWaterWaviness(2.0); setWaterType("clap"); setWaterMurkiness(0.835938); setUnitsAmbientColor(0.57, 0.58, 0.55); setTerrainAmbientColor(0.447059, 0.509804, 0.54902); setFogFactor(0.25); setFogThickness(0.15); setFogColor(0.847059, 0.737255, 0.482353); setPPEffect("hdr"); setPPContrast(0.57031); setPPBloom(0.34); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/islands.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/islands.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/islands.js (revision 21000) @@ -1,364 +1,364 @@ Engine.LoadLibrary("rmgen"); Engine.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 tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; 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 oWoodTreasure = "gaia/special_treasure_wood"; const oDock = "skirmish/structures/default_dock"; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; 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]; const heightSeaGround = -5; const heightLand = 3; const heightOffsetBump = 2; const heightHill = 18; var g_Map = new RandomMap(heightSeaGround, tWater); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -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 clLand = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clLand = g_Map.createTileClass(); var playerIslandRadius = scaleByMapSize(20, 29); var [playerIDs, playerPosition, playerAngle] = playerPlacementCircle(fractionToTiles(0.35)); if (!isNomad()) { log("Creating player islands and docks..."); for (let i = 0; i < numPlayers; i++) { createArea( new ClumpPlacer(diskArea(playerIslandRadius), 0.8, 0.1, 10, playerPosition[i]), [ new LayeredPainter([tMainTerrain , tMainTerrain, tMainTerrain], [1, 6]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 6), paintClass(clLand), paintClass(clPlayer) ]); let dockLocation = findLocationInDirectionBasedOnHeight(playerPosition[i], mapCenter, -3 , heightLand - 0.5, heightLand); placeObject(dockLocation.x, dockLocation.y, oDock, playerIDs[i], playerAngle[i] + Math.PI); } } log("Creating big islands..."); createAreas( new ChainPlacer( Math.floor(scaleByMapSize(4, 8)), Math.floor(scaleByMapSize(8, 14)), Math.floor(scaleByMapSize(25, 60)), 0.07), [ new LayeredPainter([tMainTerrain, tMainTerrain], [2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 6), paintClass(clLand) ], avoidClasses(clLand, scaleByMapSize(8, 12)), scaleByMapSize(4, 14)); log("Creating small islands..."); createAreas( new ChainPlacer( Math.floor(scaleByMapSize(4, 7)), Math.floor(scaleByMapSize(7, 10)), Math.floor(scaleByMapSize(16, 40)), 0.07), [ new LayeredPainter([tMainTerrain, tMainTerrain], [2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 6), paintClass(clLand) ], avoidClasses(clLand, scaleByMapSize(8, 12)), scaleByMapSize(6, 54)); paintTerrainBasedOnHeight(1, 3, 0, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], // PlayerTileClass marked above "BaseResourceClass": clBaseResource, "Walls": "towers", "CityPatch": { "radius": playerIslandRadius / 3, "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Treasures": { "types": [ { "template": oWoodTreasure, "count": 14 } ] }, "Trees": { "template": oTree1, "count": 5 }, "Decoratives": { "template": aGrassShort } }); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), [avoidClasses(clPlayer, 0), stayClasses(clLand, 3)], scaleByMapSize(20, 100)); log("Creating hills..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.5), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], [avoidClasses(clPlayer, 2, clHill, 15), stayClasses(clLand, 0)], scaleByMapSize(4, 13)); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); var types = [ [[tForestFloor2, tMainTerrain, pForest1], [tForestFloor2, pForest1]], [[tForestFloor1, tMainTerrain, pForest2], [tForestFloor1, pForest2]] ]; if (currentBiome() != "savanna") { var size = forestTrees / (scaleByMapSize(3,6) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), forestTrees / (num * Math.floor(scaleByMapSize(2, 5))), 0.5), [ new LayeredPainter(type, [2]), paintClass(clForest) ], [avoidClasses(clPlayer, 0, clForest, 10, clHill, 0), stayClasses(clLand, 6)], num); } Engine.SetProgress(50); log("Creating dirt patches..."); var numberOfPatches = scaleByMapSize(15, 45) * (currentBiome() == "savanna" ? 3 : 1); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]], [1, 1]), paintClass(clDirt) ], [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 6)], numberOfPatches); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), new TerrainPainter(tTier4Terrain), [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 6)], numberOfPatches); Engine.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, 0, clRock, 10, clHill, 1), stayClasses(clLand, 5)], 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, 0, clRock, 10, clHill, 1), stayClasses(clLand, 5)], 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, 0, clMetal, 10, clRock, 5, clHill, 1), stayClasses(clLand, 5)], scaleByMapSize(4,16), 100 ); Engine.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 5)], 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(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 5)], scaleByMapSize(8, 131), 50 ); Engine.SetProgress(70); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oMainHuntableAnimal, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 0, clPlayer, 0, clHill, 1, clFood, 20), stayClasses(clLand, 5)], 3 * numPlayers, 50 ); Engine.SetProgress(75); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oSecondaryHuntableAnimal, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 0, clPlayer, 0, clHill, 1, clFood, 20), stayClasses(clLand, 5)], 3 * numPlayers, 50 ); log("Creating fruit bush..."); group = new SimpleGroup( [new SimpleObject(oFruitBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 0, clPlayer, 8, clHill, 1, clFood, 20), stayClasses(clLand, 5)], randIntInclusive(1, 4) * numPlayers + 2, 50 ); log("Creating fish..."); group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clLand, 4, clForest, 2, clPlayer, 2, clHill, 2, clFood, 20), 25 * numPlayers, 60 ); Engine.SetProgress(85); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], [avoidClasses(clForest, 1, clHill, 1, clPlayer, 0, clMetal, 6, clRock, 6), stayClasses(clLand, 6)], clForest, stragglerTrees); var planetm = 1; if (currentBiome() == "tropic") planetm = 8; log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 6)], planetm * scaleByMapSize(13, 200) ); Engine.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 5)], planetm * scaleByMapSize(13, 200) ); Engine.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(clHill, 1, clPlayer, 1, clDirt, 1), stayClasses(clLand, 6)], planetm * scaleByMapSize(13, 200), 50 ); placePlayersNomad(clPlayer, [stayClasses(clLand, 4), avoidClasses(clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)]); setSkySet(pickRandom(["cirrus", "cumulus", "sunny"])); setSunRotation(randomAngle()); setSunElevation(randFloat(1/5, 1/3) * Math.PI); setWaterWaviness(2); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/lake.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/lake.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/lake.js (revision 21000) @@ -1,252 +1,252 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); 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 tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; 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 aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; 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]; const heightSeaGround = -3; const heightLand = 3; var g_Map = new RandomMap(heightLand, tMainTerrain); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); log("Preventing water in player territory..."); for (let i = 0; i < numPlayers; ++i) addCivicCenterAreaToClass(playerPosition[i], clPlayer); log("Creating the lake...") createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 16)), Math.floor(scaleByMapSize(35, 200)), 1, mapCenter, 0, [Math.floor(fractionToTiles(0.2))]), [ new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), paintClass(clWater) ], avoidClasses(clPlayer, 20)); log("Creating more shore jaggedness..."); createAreas( new ChainPlacer(2, Math.floor(scaleByMapSize(4, 6)), 3, 1), [ new LayeredPainter([tCliff, tHill], [2]), unPaintClass(clWater) ], borderClasses(clWater, 4, 7), scaleByMapSize(12, 130) * 2, 150); paintTerrainBasedOnHeight(2.4, 3.4, 3, tMainTerrain); paintTerrainBasedOnHeight(1, 2.4, 0, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); paintTileClassBasedOnHeight(-6, 0, 1, clWater); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], // PlayerTileClass marked above "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree1, "count": 5 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); createBumps(avoidClasses(clWater, 2, clPlayer, 20)); if (randBool()) createHills([tMainTerrain, tCliff, tHill], avoidClasses(clPlayer, 20, clHill, 15, clWater, 2), clHill, scaleByMapSize(1, 4) * numPlayers); else createMountains(tCliff, avoidClasses(clPlayer, 20, clHill, 15, clWater, 2), clHill, scaleByMapSize(1, 4) * numPlayers); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], avoidClasses(clPlayer, 20, clForest, 17, clHill, 0, clWater, 2), clForest, forestTrees); Engine.SetProgress(50); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], [1,1], avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tTier4Terrain, avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); Engine.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(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), clMetal ); Engine.SetProgress(65); var planetm = 1; if (currentBiome() == "tropic") planetm = 8; 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200) ], avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0)); Engine.SetProgress(70); createFood( [ [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), clFood); createFood( [ [new SimpleObject(oFruitBush, 5, 7, 0, 4)] ], [ 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 25 * numPlayers ], [avoidClasses(clFood, 20), stayClasses(clWater, 6)], clFood); Engine.SetProgress(85); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], avoidClasses(clWater, 5, clForest, 7, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setWaterWaviness(4.0); setWaterType("lake"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/mainland.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/mainland.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/mainland.js (revision 21000) @@ -1,196 +1,196 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); 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 tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; 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 oSecondaryHuntableAnimal = g_Gaia.secondaryHuntableAnimal; const oStoneLarge = g_Gaia.stoneLarge; const oStoneSmall = g_Gaia.stoneSmall; const oMetalLarge = g_Gaia.metalLarge; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; 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]; const heightLand = 3; var g_Map = new RandomMap(heightLand, tMainTerrain); const numPlayers = getNumPlayers(); -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 clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree1, "count": 5 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); createBumps(avoidClasses(clPlayer, 20)); if (randBool()) createHills([tCliff, tCliff, tHill], avoidClasses(clPlayer, 20, clHill, 15), clHill, scaleByMapSize(3, 15)); else createMountains(tCliff, avoidClasses(clPlayer, 20, clHill, 15), clHill, scaleByMapSize(3, 15)); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], avoidClasses(clPlayer, 20, clForest, 18, clHill, 0), clForest, forestTrees); Engine.SetProgress(50); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], [1, 1], avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tTier4Terrain, avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); Engine.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), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), clMetal ); Engine.SetProgress(65); var planetm = 1; if (currentBiome() == "tropic") planetm = 8; 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3,6, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200) ], avoidClasses(clForest, 0, clPlayer, 0, clHill, 0)); Engine.SetProgress(70); createFood( [ [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), clFood); Engine.SetProgress(75); createFood( [ [new SimpleObject(oFruitBush, 5, 7, 0, 4)] ], [ 3 * numPlayers ], avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); Engine.SetProgress(85); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], avoidClasses(clForest, 8, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/new_rms_test.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/new_rms_test.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/new_rms_test.js (revision 21000) @@ -1,11 +1,11 @@ Engine.LoadLibrary("rmgen"); var g_Map = new RandomMap(0, "grass1_spring"); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.39)) }); -placePlayersNomad(createTileClass()); +placePlayersNomad(g_Map.createTileClass()); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/persian_highlands.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/persian_highlands.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/persian_highlands.js (revision 21000) @@ -1,329 +1,329 @@ Engine.LoadLibrary("rmgen"); const tCity = "desert_city_tile_pers_dirt"; if (randBool()) { log("Summer biome..."); var tDirtMain = ["desert_dirt_persia_1", "desert_dirt_persia_2", "grass_field_dry"]; var tLakebed1 = ["desert_lakebed_dry_b", "desert_lakebed_dry"]; var tLakebed2 = ["desert_lakebed_dry_b", "desert_lakebed_dry", "desert_shore_stones", "desert_shore_stones"]; var tCliff = ["desert_cliff_persia_1", "desert_cliff_persia_crumbling"]; var tForestFloor = "medit_grass_field_dry"; var tRocky = "desert_dirt_persia_rocky"; var tRocks = "desert_dirt_persia_rocks"; var tGrass = "grass_field_dry"; } else { log("Spring biome..."); var tDirtMain = ["desert_grass_a", "desert_grass_a", "desert_grass_a", "desert_plants_a"]; var tLakebed1 = ["desert_lakebed_dry_b", "desert_lakebed_dry"]; var tLakebed2 = "desert_grass_a_sand"; var tCliff = ["desert_cliff_persia_1", "desert_cliff_persia_crumbling"]; var tForestFloor = "desert_plants_b_persia"; var tRocky = "desert_plants_b_persia"; var tRocks = "desert_plants_a"; var tGrass = "desert_dirt_persia_rocky"; setTerrainAmbientColor(0.329412, 0.419608, 0.501961); } const oGrapesBush = "gaia/flora_bush_grapes"; const oCamel = "gaia/fauna_camel"; const oSheep = "gaia/fauna_sheep"; const oGoat = "gaia/fauna_goat"; const oStoneLarge = "gaia/geology_stonemine_desert_badlands_quarry"; const oStoneSmall = "gaia/geology_stone_desert_small"; const oMetalLarge = "gaia/geology_metal_desert_slabs"; const oOak = "gaia/flora_tree_oak"; const aBush1 = "actor|props/flora/bush_desert_a.xml"; const aBush2 = "actor|props/flora/bush_desert_dry_a.xml"; const aBush3 = "actor|props/flora/bush_dry_a.xml"; const aBush4 = "actor|props/flora/plant_desert_a.xml"; const aBushes = [aBush1, aBush2, aBush3, aBush4]; const aDecorativeRock = "actor|geology/stone_desert_med.xml"; const pForestO = [tForestFloor + TERRAIN_SEPARATOR + oOak, tForestFloor + TERRAIN_SEPARATOR + oOak, tForestFloor, tDirtMain, tDirtMain]; const heightLand = 10; const heightOffsetValley = -10; var g_Map = new RandomMap(heightLand, tDirtMain); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clPatch = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clCP = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clPatch = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clCP = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tCity, "innerTerrain": tCity, "painters": [ paintClass(clPlayer) ] }, "Chicken": { }, "Berries": { "template": oGrapesBush, }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ], "groupElements": shuffleArray(aBushes).map(t => new SimpleObject(t, 1, 1, 3, 4)) }, "Trees": { "template": oOak, "count": 3 } // No decoratives }); Engine.SetProgress(10); log("Creating rock patches..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 6)), Math.floor(scaleByMapSize(20, 45)), 0), [ new TerrainPainter(tRocky), paintClass(clPatch) ], avoidClasses(clPatch, 2, clPlayer, 0), scaleByMapSize(5, 20)); Engine.SetProgress(15); log("Creating secondary rock patches..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), Math.floor(scaleByMapSize(15, 40)), 0), [ new TerrainPainter([tRocky, tRocks]), paintClass(clPatch) ], avoidClasses(clPatch, 2, clPlayer, 4), scaleByMapSize(15, 50)); Engine.SetProgress(20); log("Creating dirt patches..."); createAreas( new ChainPlacer( 1, Math.floor(scaleByMapSize(3, 5)), Math.floor(scaleByMapSize(15, 40)), 0), [ new TerrainPainter([tGrass]), paintClass(clPatch) ], avoidClasses(clPatch, 2, clPlayer, 4), scaleByMapSize(15, 50)); Engine.SetProgress(25); log("Creating centeral plateau..."); createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 13)), Math.floor(scaleByMapSize(35, 200)), 1, mapCenter, 0, [Math.floor(scaleByMapSize(18, 68))]), [ new LayeredPainter([tLakebed2, tLakebed1], [6]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetValley, 8), paintClass(clCP) ], avoidClasses(clPlayer, 18)); Engine.SetProgress(30); log("Creating hills..."); for (let i = 0; i < scaleByMapSize(20, 80); ++i) createMountain( Math.floor(scaleByMapSize(40, 60)), Math.floor(scaleByMapSize(3, 4)), Math.floor(scaleByMapSize(6, 12)), Math.floor(scaleByMapSize(4, 10)), avoidClasses(clPlayer, 7, clCP, 5, clHill, Math.floor(scaleByMapSize(18, 25))), randIntExclusive(0, mapSize), randIntExclusive(0, mapSize), tCliff, clHill, 14); Engine.SetProgress(35); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(500, 2500, 0.7); var types = [ [[tDirtMain, tForestFloor, pForestO], [tForestFloor, pForestO]], [[tDirtMain, tForestFloor, pForestO], [tForestFloor, pForestO]] ]; var size = forestTrees / (scaleByMapSize(3,6) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ChainPlacer( Math.floor(scaleByMapSize(1, 2)), Math.floor(scaleByMapSize(2, 5)), Math.floor(size / Math.floor(scaleByMapSize(8, 3))), 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses( clPlayer, 6, clForest, 10, clHill, 1, clCP, 1), num); Engine.SetProgress(50); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4), new RandomObject(aBushes, 2, 4, 0, 2)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill, 1, clCP, 1)], scaleByMapSize(2,8), 100 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3), new RandomObject(aBushes, 2,4, 0,2)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill, 1, clCP, 1)], scaleByMapSize(2,8), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4), new RandomObject(aBushes, 2,4, 0,2)], true, clMetal); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 10, clMetal, 10, clRock, 5, clHill, 1, clCP, 1)], scaleByMapSize(2,8), 100 ); log("Creating centeral stone mines..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4), new RandomObject(aBushes, 2,4, 0,2)], true, clRock); createObjectGroupsDeprecated(group, 0, stayClasses(clCP, 6), 5*scaleByMapSize(5,30), 50 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3), new RandomObject(aBushes, 2,4, 0,2)], true, clRock); createObjectGroupsDeprecated(group, 0, stayClasses(clCP, 6), 5*scaleByMapSize(5,30), 50 ); log("Creating centeral metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4), new RandomObject(aBushes, 2,4, 0,2)], true, clMetal); createObjectGroupsDeprecated(group, 0, stayClasses(clCP, 6), 5*scaleByMapSize(5,30), 50 ); Engine.SetProgress(60); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aDecorativeRock, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(16, 262), 50 ); Engine.SetProgress(65); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBush2, 1,2, 0,1), new SimpleObject(aBush1, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(8, 131), 50 ); Engine.SetProgress(70); log("Creating goat..."); group = new SimpleGroup( [new SimpleObject(oGoat, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 1, clHill, 1, clFood, 20, clCP, 2), 3 * numPlayers, 50 ); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oSheep, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 1, clHill, 1, clFood, 20, clCP, 2), 3 * numPlayers, 50 ); log("Creating grape bush..."); group = new SimpleGroup( [new SimpleObject(oGrapesBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 10, clCP, 2), randIntInclusive(1, 4) * numPlayers + 2, 50 ); log("Creating camels..."); group = new SimpleGroup( [new SimpleObject(oCamel, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, stayClasses(clCP, 2), 3 * numPlayers, 50 ); Engine.SetProgress(90); createStragglerTrees( [oOak], avoidClasses(clForest, 1, clHill, 1, clPlayer, 1, clBaseResource, 6, clMetal, 6, clRock, 6, clCP, 2), clForest, stragglerTrees); setSunColor(1.0, 0.796, 0.374); setSunElevation(Math.PI / 6); setSunRotation(-1.86532); setFogFactor(0.2); setFogThickness(0.0); setFogColor(0.852, 0.746, 0.493); setPPEffect("hdr"); setPPContrast(0.75); setPPSaturation(0.45); setPPBloom(0.3); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/lorraine_plain.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/lorraine_plain.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/lorraine_plain.js (revision 21000) @@ -1,321 +1,321 @@ Engine.LoadLibrary("rmgen"); const tPrimary = "temp_grass_long"; const tGrass = ["temp_grass", "temp_grass", "temp_grass_d"]; const tGrassPForest = "temp_plants_bog"; const tGrassDForest = "temp_plants_bog"; const tGrassA = "temp_grass_plants"; const tGrassB = "temp_plants_bog"; const tGrassC = "temp_mud_a"; const tRoad = "temp_road"; const tRoadWild = "temp_road_overgrown"; const tGrassPatchBlend = "temp_grass_long_b"; const tGrassPatch = ["temp_grass_d", "temp_grass_clovers"]; const tShore = "temp_plants_bog"; const tWater = "temp_mud_a"; const oBeech = "gaia/flora_tree_euro_beech"; const oOak = "gaia/flora_tree_oak"; const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; const oRabbit = "gaia/fauna_rabbit"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oStoneSmall = "gaia/geology_stone_temperate"; const oMetalLarge = "gaia/geology_metal_temperate_slabs"; const aGrass = "actor|props/flora/grass_soft_small_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aRockLarge = "actor|geology/stone_granite_med.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; const aLillies = "actor|props/flora/water_lillies.xml"; const aBushMedium = "actor|props/flora/bush_medit_me.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; const pForestB = [tGrassDForest + TERRAIN_SEPARATOR + oBeech, tGrassDForest]; const pForestO = [tGrassPForest + TERRAIN_SEPARATOR + oOak, tGrassPForest]; const pForestR = [tGrassDForest + TERRAIN_SEPARATOR + oBeech, tGrassDForest, tGrassDForest + TERRAIN_SEPARATOR + oOak, tGrassDForest, tGrassDForest, tGrassDForest]; const heightSeaGround = -4; const heightShallows = -2; const heightLand = 3; const heightOffsetBump = 2; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clShallow = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clShallow = g_Map.createTileClass(); var shallowWidth = scaleByMapSize(8, 12); var startAngle = randomAngle(); placePlayerBases({ "PlayerPlacement": playerPlacementRiver(startAngle + Math.PI / 2, fractionToTiles(0.5)), // PlayerTileClass marked below "BaseResourceClass": clBaseResource, "Walls": "towers", "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad, "painters": [ paintClass(clPlayer) ] }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oOak, "count": 3 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); var riverPositions = [ new Vector2D(mapBounds.left + 1, mapCenter.y), new Vector2D(mapBounds.right - 1, mapCenter.y) ].map(v => v.rotateAround(startAngle, mapCenter)); log("Creating the main river..."); createArea( new PathPlacer(riverPositions[0], riverPositions[1], scaleByMapSize(10, 20), 0.5, 3 * scaleByMapSize(1, 4), 0.1, 0.01), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), avoidClasses(clPlayer, 4)); Engine.SetProgress(25); log("Creating small puddles at the map border to ensure players being separated..."); for (let riverPosition of riverPositions) createArea( new ClumpPlacer(diskArea(scaleByMapSize(5, 10)), 0.95, 0.6, 10, riverPosition), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 2), avoidClasses(clPlayer, 8)); Engine.SetProgress(30); log("Creating the shallows of the main river..."); for (let i = 0; i <= randIntInclusive(3, scaleByMapSize(4, 6)); ++i) { let location = fractionToTiles(randFloat(0.15, 0.85)); createPassage({ "start": new Vector2D(location, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(location, mapBounds.bottom).rotateAround(startAngle, mapCenter), "startWidth": shallowWidth, "endWidth": shallowWidth, "smoothWidth": 2, "startHeight": heightShallows, "endHeight": heightShallows, "maxHeight": heightShallows, "tileClass": clShallow }); } Engine.SetProgress(35); createTributaryRivers( startAngle, randIntInclusive(9, scaleByMapSize(13, 21)), scaleByMapSize(10, 20), heightSeaGround, [-6, -1.5], Math.PI / 5, clWater, clShallow, avoidClasses(clPlayer, 3, clBaseResource, 4)); Engine.SetProgress(40); paintTerrainBasedOnHeight(-5, 1, 1, tWater); paintTerrainBasedOnHeight(1, 2, 1, pForestR); paintTileClassBasedOnHeight(-6, 0.5, 1, clWater); Engine.SetProgress(50); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), avoidClasses(clWater, 2, clPlayer, 15), scaleByMapSize(100, 200) ); Engine.SetProgress(55); var [forestTrees, stragglerTrees] = getTreeCounts(500, 2500, 0.7); createForests( [tGrass, tGrassDForest, tGrassPForest, pForestB, pForestO], avoidClasses(clPlayer, 15, clWater, 3, clForest, 16, clHill, 1), clForest, forestTrees); Engine.SetProgress(70); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([[tGrass,tGrassA], tGrassB, [tGrassB,tGrassC]], [1, 1]), paintClass(clDirt) ], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45) ); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), new LayeredPainter([tGrassPatchBlend, tGrassPatch], [1]), avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45) ); Engine.SetProgress(80); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 1, clPlayer, 15, clRock, 10, clHill, 1)], scaleByMapSize(4,16), 100 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 1, clPlayer, 15, clRock, 10, clHill, 1)], scaleByMapSize(4,16), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 1, clPlayer, 15, clMetal, 10, clRock, 5, clHill, 1)], scaleByMapSize(4,16), 100 ); Engine.SetProgress(86); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(8, 131), 50 ); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 15, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); log("Creating rabbits..."); group = new SimpleGroup( [new SimpleObject(oRabbit, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 15, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 15, clHill, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50 ); createStragglerTrees( [oOak, oBeech], avoidClasses(clWater, 1, clForest, 7, clHill, 1, clPlayer, 5, clMetal, 6, clRock, 6), clForest, stragglerTrees); log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), scaleByMapSize(13, 200) ); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), scaleByMapSize(13, 200) ); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1), scaleByMapSize(13, 200), 50 ); log("Creating shallow flora..."); group = new SimpleGroup( [new SimpleObject(aLillies, 1,2, 0,2), new SimpleObject(aReeds, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, stayClasses(clShallow, 1), 60 * scaleByMapSize(13, 200), 80 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("cirrus"); setWaterColor(0.1,0.212,0.422); setWaterTint(0.3,0.1,0.949); setWaterWaviness(3.0); setWaterType("lake"); setWaterMurkiness(0.80); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/neareastern_badlands.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/neareastern_badlands.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/neareastern_badlands.js (revision 21000) @@ -1,358 +1,358 @@ Engine.LoadLibrary("rmgen"); const tPrimary = ["desert_sand_smooth", "desert_sand_smooth_b"]; const tCity = "desert_city_tile"; const tCityPlaza = "desert_city_tile_plaza"; const tSand = "desert_dirt_rough"; const tDunes = "desert_sand_dunes_100"; const tFineSand = "desert_sand_smooth"; const tCliff = ["desert_cliff_badlands", "desert_cliff_badlands_2"]; const tForestFloor = "desert_forestfloor_palms"; const tGrass = "desert_grass_a"; const tGrassSand25 = "desert_grass_a_stones"; const tDirt = "desert_dirt_rough"; const tShore = "desert_shore_stones"; const tWaterDeep = "desert_shore_stones_wet"; const oBerryBush = "gaia/flora_bush_grapes"; const oCamel = "gaia/fauna_camel"; const oFish = "gaia/fauna_fish"; const oGazelle = "gaia/fauna_gazelle"; const oGiraffe = "gaia/fauna_giraffe"; const oGoat = "gaia/fauna_goat"; const oWildebeest = "gaia/fauna_wildebeest"; const oStoneLarge = "gaia/geology_stonemine_desert_badlands_quarry"; const oStoneSmall = "gaia/geology_stone_desert_small"; const oMetalLarge = "gaia/geology_metal_desert_slabs"; const oDatePalm = "gaia/flora_tree_date_palm"; const oSDatePalm = "gaia/flora_tree_senegal_date_palm"; const aBush1 = "actor|props/flora/bush_desert_a.xml"; const aBush2 = "actor|props/flora/bush_desert_dry_a.xml"; const aBush3 = "actor|props/flora/bush_dry_a.xml"; const aBush4 = "actor|props/flora/plant_desert_a.xml"; const aBushes = [aBush1, aBush2, aBush3, aBush4]; const aDecorativeRock = "actor|geology/stone_desert_med.xml"; const pForest = [tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERRAIN_SEPARATOR + oSDatePalm, tForestFloor]; const pForestOasis = [tGrass + TERRAIN_SEPARATOR + oDatePalm, tGrass + TERRAIN_SEPARATOR + oSDatePalm, tGrass]; const heightLand = 10; const heightOffsetOasis = -11; const heightOffsetHill1 = 16; const heightOffsetHill2 = 16; const heightOffsetHill3 = 16; const heightOffsetBump = 2; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill1 = createTileClass(); -var clOasis = createTileClass(); -var clForest = createTileClass(); -var clPatch = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill1 = g_Map.createTileClass(); +var clOasis = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clPatch = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var oasisRadius = scaleByMapSize(14, 40); var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); if (!isNomad()) for (let i = 0; i < numPlayers; ++i) createArea( new ClumpPlacer(diskArea(defaultPlayerBaseRadius()), 0.9, 0.5, 10, playerPosition[i]), paintClass(clPlayer)); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tCity, "innerTerrain": tCityPlaza, "width": 3, "radius": 10 }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oDatePalm } // No decoratives }); Engine.SetProgress(10); log("Creating dune patches..."); createAreas( new ClumpPlacer(scaleByMapSize(40, 150), 0.2, 0.1, 0), [ new TerrainPainter(tDunes), paintClass(clPatch) ], avoidClasses(clPatch, 2, clPlayer, 0), scaleByMapSize(5, 20)); Engine.SetProgress(15); log("Creating sand patches..."); createAreas( new ClumpPlacer(scaleByMapSize(25, 100), 0.2, 0.1, 0), [ new TerrainPainter([tSand, tFineSand]), paintClass(clPatch) ], avoidClasses(clPatch, 2, clPlayer, 0), scaleByMapSize(15, 50)); Engine.SetProgress(20); log("Creating dirt patches..."); createAreas( new ClumpPlacer(scaleByMapSize(25, 100), 0.2, 0.1, 0), [ new TerrainPainter([tDirt]), paintClass(clPatch) ], avoidClasses(clPatch, 2, clPlayer, 0), scaleByMapSize(15, 50)); Engine.SetProgress(25); log("Creating oasis..."); createArea( new ClumpPlacer(diskArea(oasisRadius), 0.6, 0.15, 0, mapCenter), [ new LayeredPainter([[tSand, pForest], [tGrassSand25, pForestOasis], tGrassSand25, tShore, tWaterDeep], [2, 3, 1, 1]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetOasis, 8), paintClass(clOasis) ]); Engine.SetProgress(30); log("Creating oasis wildlife..."); var num = Math.round(Math.PI * oasisRadius / 8); var constraint = new AndConstraint([borderClasses(clOasis, 0, 3), avoidClasses(clOasis, 0)]); for (var i = 0; i < num; ++i) { let animalPosition; let r = 0; let angle = 2 * Math.PI / num * i; do { // Work outward until constraint met animalPosition = Vector2D.add(mapCenter, new Vector2D(r, 0).rotate(-angle)).round(); ++r; } while (!constraint.allows(animalPosition) && r < mapSize / 2); createObjectGroup( new RandomGroup( [ new SimpleObject(oGiraffe, 2, 4, 0, 3), new SimpleObject(oWildebeest, 3,5, 0,3), new SimpleObject(oGazelle, 5,7, 0,3) ], true, clFood, animalPosition.x, animalPosition.y), 0); } log("Creating oasis fish..."); constraint = new AndConstraint([borderClasses(clOasis, 15, 0), avoidClasses(clFood, 5)]); num = Math.round(Math.PI * oasisRadius / 16); for (var i = 0; i < num; ++i) { let fishPosition; var r = 0; var angle = 2 * Math.PI / num * i; do { // Work outward until constraint met fishPosition = Vector2D.add(mapCenter, new Vector2D(r, 0).rotate(-angle)); ++r; } while (!constraint.allows(fishPosition) && r < mapSize / 2); createObjectGroup(new SimpleGroup([new SimpleObject(oFish, 1, 1, 0, 1)], true, clFood, fishPosition.x, fishPosition.y), 0); } Engine.SetProgress(35); log("Creating level 1 hills..."); var hillAreas = createAreas( new ClumpPlacer(scaleByMapSize(50,300), 0.25, 0.1, 0.5), [ new LayeredPainter([tCliff, tSand], [1]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHill1, 1), paintClass(clHill1) ], avoidClasses(clOasis, 3, clPlayer, 0, clHill1, 10), scaleByMapSize(10,20), 100 ); Engine.SetProgress(40); log("Creating small level 1 hills..."); hillAreas = hillAreas.concat( createAreas( new ClumpPlacer(scaleByMapSize(25,150), 0.25, 0.1, 0.5), [ new LayeredPainter([tCliff, tSand], [1]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHill2, 1), paintClass(clHill1) ], avoidClasses(clOasis, 3, clPlayer, 0, clHill1, 3), scaleByMapSize(15,25), 100)); Engine.SetProgress(45); log("Creating decorative rocks..."); createObjectGroupsByAreasDeprecated( new SimpleGroup( [new RandomObject([aDecorativeRock, aBush2, aBush3], 3, 8, 0, 2)], true), 0, borderClasses(clHill1, 0, 3), scaleByMapSize(40,200), 50, hillAreas); Engine.SetProgress(50); log("Creating level 2 hills..."); createAreasInAreas( new ClumpPlacer(scaleByMapSize(25, 150), 0.25, 0.1, 0), [ new LayeredPainter([tCliff, tSand], [1]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHill2, 1) ], [stayClasses(clHill1, 0)], scaleByMapSize(15, 25), 50, hillAreas); Engine.SetProgress(55); log("Creating level 3 hills..."); createAreas( new ClumpPlacer(scaleByMapSize(12, 75), 0.25, 0.1, 0), [ new LayeredPainter([tCliff, tSand], [1]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHill3, 1) ], [stayClasses(clHill1, 0)], scaleByMapSize(15,25), 50 ); Engine.SetProgress(60); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 0), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), avoidClasses(clOasis, 0, clPlayer, 0, clHill1, 2), scaleByMapSize(100, 200) ); Engine.SetProgress(65); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(500, 2500, 0.5); var num = scaleByMapSize(10,30); createAreas( new ClumpPlacer(forestTrees / num, 0.15, 0.1, 0.5), [ new TerrainPainter([tSand, pForest]), paintClass(clForest) ], avoidClasses(clPlayer, 1, clOasis, 10, clForest, 10, clHill1, 1), num, 50); Engine.SetProgress(70); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4), new RandomObject(aBushes, 2, 4, 0, 2)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clOasis, 1, clForest, 1, clPlayer, 10, clRock, 10, clHill1, 1)], scaleByMapSize(4,16), 100 ); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3), new RandomObject(aBushes, 2,4, 0,2)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clOasis, 1, clForest, 1, clPlayer, 10, clRock, 10, clHill1, 1)], scaleByMapSize(4,16), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4), new RandomObject(aBushes, 2,4, 0,2)], true, clMetal); createObjectGroupsDeprecated(group, 0, [avoidClasses(clOasis, 1, clForest, 1, clPlayer, 10, clMetal, 10, clRock, 5, clHill1, 1)], scaleByMapSize(4,16), 100 ); Engine.SetProgress(80); log("Creating gazelles..."); group = new SimpleGroup([new SimpleObject(oGazelle, 5,7, 0,4)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 1, clForest, 0, clPlayer, 5, clHill1, 1, clFood, 10), scaleByMapSize(5,20), 50 ); log("Creating goats..."); group = new SimpleGroup([new SimpleObject(oGoat, 2,4, 0,3)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 1, clForest, 0, clPlayer, 5, clHill1, 1, clFood, 10), scaleByMapSize(5,20), 50 ); log("Creating camels..."); group = new SimpleGroup([new SimpleObject(oCamel, 2,4, 0,2)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 1, clForest, 0, clPlayer, 5, clHill1, 1, clFood, 10), scaleByMapSize(5,20), 50 ); Engine.SetProgress(85); createStragglerTrees( [oDatePalm, oSDatePalm], avoidClasses(clOasis, 1, clForest, 0, clHill1, 1, clPlayer, 4, clMetal, 6, clRock, 6), clForest, stragglerTrees); Engine.SetProgress(90); log("Creating bushes..."); group = new SimpleGroup([new RandomObject(aBushes, 2,3, 0,2)]); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 1, clHill1, 1, clPlayer, 0, clForest, 0), scaleByMapSize(16, 262) ); log("Creating more decorative rocks..."); group = new SimpleGroup([new SimpleObject(aDecorativeRock, 1,2, 0,2)]); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 1, clHill1, 1, clPlayer, 0, clForest, 0), scaleByMapSize(16, 262) ); placePlayersNomad(clPlayer, avoidClasses(clOasis, 4, clForest, 1, clMetal, 4, clRock, 4, clHill1, 4, clFood, 2)); setWaterColor(0, 0.227, 0.843); setWaterTint(0, 0.545, 0.859); setWaterWaviness(1.0); setWaterType("clap"); setWaterMurkiness(0.75); setWaterHeight(20); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/oasis.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/oasis.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/oasis.js (revision 21000) @@ -1,341 +1,341 @@ Engine.LoadLibrary("rmgen"); const tSand = ["desert_sand_dunes_100", "desert_dirt_cracks","desert_sand_smooth", "desert_dirt_rough", "desert_dirt_rough_2", "desert_sand_smooth"]; const tDune = ["desert_sand_dunes_50"]; const tForestFloor = "desert_forestfloor_palms"; const tDirt = ["desert_dirt_rough","desert_dirt_rough","desert_dirt_rough", "desert_dirt_rough_2", "desert_dirt_rocks_2"]; const tRoad = "desert_city_tile";; const tRoadWild = "desert_city_tile";; const tShore = "dirta"; const tWater = "desert_sand_wet"; const ePalmShort = "gaia/flora_tree_cretan_date_palm_short"; const ePalmTall = "gaia/flora_tree_cretan_date_palm_tall"; const eBush = "gaia/flora_bush_grapes"; const eCamel = "gaia/fauna_camel"; const eGazelle = "gaia/fauna_gazelle"; const eLion = "gaia/fauna_lion"; const eLioness = "gaia/fauna_lioness"; const eStoneMine = "gaia/geology_stonemine_desert_quarry"; const eMetalMine = "gaia/geology_metal_desert_slabs"; const aFlower1 = "actor|props/flora/decals_flowers_daisies.xml"; const aWaterFlower = "actor|props/flora/water_lillies.xml"; const aReedsA = "actor|props/flora/reeds_pond_lush_a.xml"; const aReedsB = "actor|props/flora/reeds_pond_lush_b.xml"; const aRock = "actor|geology/stone_desert_med.xml"; const aBushA = "actor|props/flora/bush_desert_dry_a.xml"; const aBushB = "actor|props/flora/bush_desert_dry_a.xml"; const aSand = "actor|particle/blowing_sand.xml"; const pForestMain = [tForestFloor + TERRAIN_SEPARATOR + ePalmShort, tForestFloor + TERRAIN_SEPARATOR + ePalmTall, tForestFloor]; const pOasisForestLight = [tForestFloor + TERRAIN_SEPARATOR + ePalmShort, tForestFloor + TERRAIN_SEPARATOR + ePalmTall, tForestFloor,tForestFloor,tForestFloor ,tForestFloor,tForestFloor,tForestFloor,tForestFloor]; const heightSeaGround = -3; const heightFloraMin = -2.5 const heightFloraReedsMax = -1.9; const heightFloraMax = -1; const heightLand = 1; const heightSand = 3.4; const heightOasisPath = 4; const heightOffsetBump = 4; const heightOffsetDune = 18; var g_Map = new RandomMap(heightLand, tSand); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clOasis = createTileClass(); -var clPassage = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clOasis = g_Map.createTileClass(); +var clPassage = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var waterRadius = scaleByMapSize(7, 50) var shoreDistance = scaleByMapSize(4, 10); var forestDistance = scaleByMapSize(6, 20); var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); log("Creating small oasis near the players...") var forestDist = 1.2 * defaultPlayerBaseRadius(); for (let i = 0; i < numPlayers; ++i) { // Create starting batches of wood let forestPosition; let forestAngle; do { forestAngle = Math.PI / 3 * randFloat(1, 2); forestPosition = Vector2D.add(playerPosition[i], new Vector2D(forestDist, 0).rotate(-forestAngle)); } while ( !createArea( new ClumpPlacer(70, 1, 0.5, 10, forestPosition), [ new LayeredPainter([tForestFloor, pForestMain], [0]), paintClass(clBaseResource) ], avoidClasses(clBaseResource, 0))); log("Creating the water patch explaining the forest for player " + playerIDs[i] + "..."); let waterPosition; do { let waterAngle = forestAngle + randFloat(1, 5) / 3 * Math.PI; waterPosition = Vector2D.add(forestPosition, new Vector2D(6, 0).rotate(-waterAngle)).round(); let flowerPosition = Vector2D.add(forestPosition, new Vector2D(3, 0).rotate(-waterAngle)).round(); createObjectGroup( new SimpleGroup( [new SimpleObject(aFlower1, 1, 5, 0, 3)], true, undefined, flowerPosition.x, flowerPosition.y), 0); let reedsPosition = Vector2D.add(forestPosition, new Vector2D(5, 0).rotate(-waterAngle)).round(); createObjectGroup( new SimpleGroup( [new SimpleObject(aReedsA, 1, 3, 0, 0)], true, undefined, reedsPosition.x, reedsPosition.y), 0); } while ( !createArea( new ClumpPlacer(60, 0.9, 0.4, 5, waterPosition), [ new LayeredPainter([tShore, tWater], [1]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 3) ], avoidClasses(clBaseResource, 0))); } Engine.SetProgress(20); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad, "painters": [ paintClass(clPlayer) ] }, "Chicken": { }, "Berries": { "template": eBush }, "Mines": { "types": [ { "template": eMetalMine }, { "template": eStoneMine }, ], "distance": defaultPlayerBaseRadius(), "maxAngle": Math.PI / 2, "groupElements": shuffleArray([aBushA, aBushB, ePalmShort, ePalmTall]).map(t => new SimpleObject(t, 1, 1, 3, 4)) } // Starting trees were set above // No decoratives }); Engine.SetProgress(30); log("Creating central oasis..."); createArea( new ClumpPlacer(diskArea(forestDistance + shoreDistance + waterRadius), 0.8, 0.2, 10, mapCenter), [ new LayeredPainter([pOasisForestLight, tWater], [forestDistance]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, forestDistance + shoreDistance), paintClass(clOasis) ]); Engine.SetProgress(40); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 3), avoidClasses(clPlayer, 10, clBaseResource, 6, clOasis, 4), scaleByMapSize(30, 70)); log("Creating dirt patches..."); createAreas( new ClumpPlacer(80, 0.3, 0.06, 1), new TerrainPainter(tDirt), avoidClasses(clPlayer, 10, clBaseResource, 6, clOasis, 4, clForest, 4), scaleByMapSize(15, 50)); log("Creating dunes..."); createAreas( new ClumpPlacer(120, 0.3, 0.06, 1), [ new TerrainPainter(tDune), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetDune, 30) ], avoidClasses(clPlayer, 10, clBaseResource, 6, clOasis, 4, clForest, 4), scaleByMapSize(15, 50)); Engine.SetProgress(50); if (mapSize > 150 && randBool()) { log("Creating path though the oasis..."); let pathWidth = scaleByMapSize(7, 18); let points = distributePointsOnCircle(2, randomAngle(), waterRadius + shoreDistance + forestDistance + pathWidth, mapCenter)[0]; createArea( new PathPlacer(points[0], points[1], pathWidth, 0.4, 1, 0.2, 0), [ new TerrainPainter(tSand), new SmoothElevationPainter(ELEVATION_SET, heightOasisPath, 5), paintClass(clPassage) ]); } log("Creating some straggler trees around the passage..."); var group = new SimpleGroup([new SimpleObject(ePalmTall, 1,1, 0,0),new SimpleObject(ePalmShort, 1, 2, 1, 2), new SimpleObject(aBushA, 0,2, 1,3)], true, clForest); createObjectGroupsDeprecated(group, 0, stayClasses(clPassage, 3), scaleByMapSize(60, 250), 100); log("Creating stone mines..."); group = new SimpleGroup([new SimpleObject(eStoneMine, 1,1, 0,0),new SimpleObject(ePalmShort, 1,2, 3,3),new SimpleObject(ePalmTall, 0,1, 3,3) ,new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 10, clForest, 1, clPlayer, 30, clRock, 10,clBaseResource, 2, clHill, 1), scaleByMapSize(6,25), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(eMetalMine, 1,1, 0,0),new SimpleObject(ePalmShort, 1,2, 2,3),new SimpleObject(ePalmTall, 0,1, 2,2) ,new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3)], true, clMetal); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 10, clForest, 1, clPlayer, 30, clMetal, 10,clBaseResource, 2, clRock, 10, clHill, 1), scaleByMapSize(6,25), 100 ); Engine.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRock, 2,4, 0,2)], true, undefined ); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 30, scaleByMapSize(10, 50)); Engine.SetProgress(70); log("Creating camels..."); group = new SimpleGroup( [new SimpleObject(eCamel, 1,2, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 1 * numPlayers, 50 ); Engine.SetProgress(75); log("Creating gazelles..."); group = new SimpleGroup( [new SimpleObject(eGazelle, 2,4, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 1 * numPlayers, 50 ); Engine.SetProgress(85); log("Creating oasis animals..."); for (let i = 0; i < scaleByMapSize(5, 30); ++i) { let animalPos = Vector2D.add(mapCenter, new Vector2D(forestDistance + shoreDistance + waterRadius, 0).rotate(randomAngle())); createObjectGroup( new RandomGroup( [ new SimpleObject(eLion, 1, 2, 0, 4), new SimpleObject(eLioness, 1, 2, 2, 4), new SimpleObject(eGazelle, 4, 6, 1, 5), new SimpleObject(eCamel, 1, 2, 1, 5) ], true, clFood, animalPos.x, animalPos.y), 0); } Engine.SetProgress(90); log("Creating bushes..."); var group = new SimpleGroup( [new SimpleObject(aBushB, 1,2, 0,2), new SimpleObject(aBushA, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 2, clHill, 1, clPlayer, 1, clPassage, 1), scaleByMapSize(10, 40), 20 ); log("Creating sand blows and beautifications"); for (var sandx = 0; sandx < mapSize; sandx += 4) for (var sandz = 0; sandz < mapSize; sandz += 4) { let position = new Vector2D(sandx, sandz); let height = g_Map.getHeight(position); if (height > heightSand) { if (randBool((height - heightSand) / 1.4)) { group = new SimpleGroup( [new SimpleObject(aSand, 0,1, 0,2)], true, undefined, sandx,sandz ); createObjectGroup(group, 0); } } else if (height > heightFloraMin && height < heightFloraMax) { if (randBool(0.4)) { group = new SimpleGroup( [new SimpleObject(aWaterFlower, 1,4, 1,2)], true, undefined, sandx,sandz ); createObjectGroup(group, 0); } else if (randBool(0.7) && height < heightFloraReedsMax) { group = new SimpleGroup( [new SimpleObject(aReedsA, 5,12, 0,2),new SimpleObject(aReedsB, 5,12, 0,2)], true, undefined, sandx,sandz ); createObjectGroup(group, 0); } if (getTileClass(clPassage).countMembersInRadius(sandx, sandz, 2) > 0) { if (randBool(0.4)) { group = new SimpleGroup( [new SimpleObject(aWaterFlower, 1,4, 1,2)], true, undefined, sandx,sandz ); createObjectGroup(group, 0); } else if (randBool(0.7) && height < heightFloraReedsMax) { group = new SimpleGroup( [new SimpleObject(aReedsA, 5,12, 0,2),new SimpleObject(aReedsB, 5,12, 0,2)], true, undefined, sandx,sandz ); createObjectGroup(group, 0); } } } } placePlayersNomad(clPlayer, avoidClasses(clOasis, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("sunny"); setSunColor(0.914,0.827,0.639); setSunRotation(Math.PI/3); setSunElevation(0.5); setWaterColor(0, 0.227, 0.843); setWaterTint(0, 0.545, 0.859); setWaterWaviness(1.0); setWaterType("clap"); setWaterMurkiness(0.5); setTerrainAmbientColor(0.45, 0.5, 0.6); setUnitsAmbientColor(0.501961, 0.501961, 0.501961); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/polar_sea.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/polar_sea.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/polar_sea.js (revision 21000) @@ -1,289 +1,289 @@ Engine.LoadLibrary("rmgen"); var tPrimary = ["polar_snow_a"]; var tSecondary = "polar_snow_glacial"; var tHalfSnow = ["ice_01", "ice_dirt"]; var tSnowLimited = ["polar_snow_b", "polar_ice"]; var tDirt = "ice_dirt"; var tRoad = "polar_ice_b"; var tRoadWild = "polar_ice_cracked"; var tShore = "polar_ice_snow"; var tWater = "polar_ice_c"; var oArcticFox = "gaia/fauna_fox_arctic"; var oArcticWolf = "trigger/fauna_arctic_wolf_attack"; var oMuskox = "gaia/fauna_muskox"; var oWalrus = "gaia/fauna_walrus"; var oWhaleFin = "gaia/fauna_whale_fin"; var oWhaleHumpback = "gaia/fauna_whale_humpback"; var oFish = "gaia/fauna_fish"; var oStoneLarge = "gaia/geology_stonemine_medit_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_desert_badlands_slabs"; var oWoodTreasure = "gaia/special_treasure_wood"; var oMarket = "skirmish/structures/default_market"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; var aIceberg = "actor|props/special/eyecandy/iceberg.xml"; var heightSeaGround = -4; var heightLand = 2; var heightCliff = 3; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clHill = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clArcticWolf = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clArcticWolf = g_Map.createTileClass(); var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); var treasures = [{ "template": oWoodTreasure, "count": isNomad() ? 16 : 14 }]; log("Creating player markets..."); if (!isNomad()) for (let i = 0; i < numPlayers; ++i) { let marketPos = Vector2D.add(playerPosition[i], new Vector2D(12, 0).rotate(randomAngle())).round(); placeObject(marketPos.x, marketPos.y, oMarket, playerIDs[i], BUILDING_ORIENTATION); addCivicCenterAreaToClass(marketPos, clBaseResource); } placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "Walls": "towers", "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { "template": oMuskox }, // No berries, no trees, no decoratives "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Treasures": { "types": treasures }, }); Engine.SetProgress(30); log("Creating central lake..."); createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 16)), Math.floor(scaleByMapSize(35, 200)), 1, mapCenter, 0, [Math.floor(fractionToTiles(0.17))]), [ new LayeredPainter([tShore, tWater, tWater, tWater], [1, 4, 2]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), paintClass(clWater) ], avoidClasses(clPlayer, 20)); Engine.SetProgress(40); log("Creating small lakes..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(2, 4)), Math.floor(scaleByMapSize(20, 140)), 0.7), [ new LayeredPainter([tShore, tWater, tWater], [1, 3]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 5), paintClass(clWater) ], avoidClasses(clPlayer, 20), scaleByMapSize(10, 16), 1); Engine.SetProgress(50); createBumps(avoidClasses(clWater, 2, clPlayer, 20)); Engine.SetProgress(60); log("Creating hills..."); createHills( [tPrimary, tPrimary, tSecondary], avoidClasses(clPlayer, 20, clHill, 35), clHill, scaleByMapSize(20, 240)); Engine.SetProgress(65); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tDirt,tHalfSnow], [tHalfSnow,tSnowLimited]], [2], avoidClasses(clWater, 3, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating glacier patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tSecondary, avoidClasses(clWater, 3, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); Engine.SetProgress(70); 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, 3, clPlayer, 20, clRock, 18, clHill, 2), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 3, clPlayer, 20, clMetal, 18, clRock, 5, clHill, 2), clMetal); Engine.SetProgress(75); createDecoration( [ [ new SimpleObject(aRockMedium, 1, 3, 0, 1) ], [ new SimpleObject(aRockLarge, 1, 2, 0, 1), new SimpleObject(aRockMedium, 1, 3, 0, 2) ] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), ], avoidClasses(clWater, 0, clPlayer, 0)); createDecoration( [ [new SimpleObject(aIceberg, 1, 1, 1, 1)] ], [ scaleByMapSize(8, 131) ], [stayClasses(clWater, 4), avoidClasses(clHill, 2)]); Engine.SetProgress(80); createFood( [ [new SimpleObject(oArcticFox, 1, 2, 0, 3)], [new SimpleObject(isNomad() ? oArcticFox : oArcticWolf, 4, 6, 0, 4)], [new SimpleObject(oWalrus, 2, 3, 0, 2)], [new SimpleObject(oMuskox, 2, 3, 0, 2)] ], [ 3 * numPlayers, 5 * numPlayers, 5 * numPlayers, 12 * numPlayers ], avoidClasses(clPlayer, 35, clFood, 16, clWater, 2, clMetal, 4, clRock, 4, clHill, 2), clFood); createFood( [ [new SimpleObject(oWhaleFin, 1, 2, 0, 2)], [new SimpleObject(oWhaleHumpback, 1, 2, 0, 2)] ], [ scaleByMapSize(1, 6) * 3, scaleByMapSize(1, 6) * 3, ], [avoidClasses(clFood, 20, clHill, 5), stayClasses(clWater, 6)], clFood); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 100 ], [avoidClasses(clFood, 12, clHill, 5), stayClasses(clWater, 6)], clFood); Engine.SetProgress(85); // Create trigger points where wolves spawn createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject("trigger/trigger_point_A", 1, 1, 0, 0)], true, clArcticWolf), 0, avoidClasses(clWater, 2, clMetal, 4, clRock, 4, clPlayer, 15, clHill, 2, clArcticWolf, 20), 1000, 100); Engine.SetProgress(95); if (randBool(1/3)) { setSkySet("sunset 1"); setSunColor(0.8, 0.7, 0.6); setTerrainAmbientColor(0.7, 0.6, 0.7); setUnitsAmbientColor(0.6, 0.5, 0.6); setSunElevation(Math.PI * randFloat(1/24, 1/7)); } else { setSkySet(pickRandom(["cumulus", "rain", "mountainous", "overcast", "rain", "stratus"])); setSunElevation(Math.PI * randFloat(1/9, 1/7)); } if (isNomad()) { let constraint = avoidClasses(clWater, 4, clMetal, 4, clRock, 4, clHill, 4, clFood, 2); [playerIDs, playerPosition] = placePlayersNomad(clPlayer, constraint); for (let i = 0; i < numPlayers; ++i) placePlayerBaseTreasures({ "playerID": playerIDs[i], "playerPosition": playerPosition[i], "BaseResourceClass": clBaseResource, "baseResourceConstraint": constraint, "types": treasures }); } setSunRotation(randomAngle()); setWaterColor(0.3, 0.3, 0.4); setWaterTint(0.75, 0.75, 0.75); setWaterMurkiness(0.92); setWaterWaviness(0.5); setWaterType("clap"); setFogThickness(0.76); setFogFactor(0.7); setPPEffect("hdr"); setPPContrast(0.6); setPPSaturation(0.45); setPPBloom(0.4); g_Map.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 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/guadalquivir_river.js (revision 21000) @@ -1,285 +1,285 @@ Engine.LoadLibrary("rmgen"); const tGrass = ["medit_grass_field_a", "medit_grass_field_b"]; const tForestFloorC = "medit_plants_dirt"; const tForestFloorP = "medit_grass_shrubs"; const tGrassA = "medit_grass_field_b"; const tGrassB = "medit_grass_field_brown"; const tGrassC = "medit_grass_field_dry"; const tRoad = "medit_city_tile"; const tRoadWild = "medit_city_tile"; const tGrassPatch = "medit_grass_shrubs"; 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"; const pForestP = [tForestFloorP + TERRAIN_SEPARATOR + oPoplar, tForestFloorP]; const pForestC = [tForestFloorC + TERRAIN_SEPARATOR + oCarob, tForestFloorC]; var heightSeaGround = -3; var heightShallow = -1.5; var heightShore = 2; var heightLand = 3; var g_Map = new RandomMap(heightSeaGround, tWater); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -var clPlayer = createTileClass(); -var clForest = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clLand = createTileClass(); -var clRiver = createTileClass(); -var clShallow = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clLand = g_Map.createTileClass(); +var clRiver = g_Map.createTileClass(); +var clShallow = g_Map.createTileClass(); log("Create the continent body"); var startAngle = randomAngle(); var continentCenter = new Vector2D(fractionToTiles(0.5), fractionToTiles(0.7)); var continentCenterR = continentCenter.clone().rotateAround(startAngle, mapCenter).round() createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 12)), Math.floor(scaleByMapSize(60, 700)), 1, continentCenterR, 0, [Math.floor(fractionToTiles(0.49))]), [ new LayeredPainter([tGrass, tGrass, tGrass], [4, 2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 4), paintClass(clLand) ]); var playerPosition = playerPlacementCustomAngle( fractionToTiles(0.35), continentCenter, i => Math.PI * (-0.46 / numPlayers * (i + i % 2) - (i % 2) / 2))[0].map(pos => pos.rotateAround(startAngle, mapCenter)); placePlayerBases({ "PlayerPlacement": [primeSortAllPlayers(), playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "Walls": false, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oPoplar, "count": 2 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); paintRiver({ "parallel": true, "constraint": stayClasses(clLand, 0), "start": new Vector2D(mapCenter.x, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(mapCenter.x, mapBounds.bottom).rotateAround(startAngle, mapCenter), "width": fractionToTiles(0.07), "fadeDist": scaleByMapSize(3, 12), "deviation": 1, "heightRiverbed": heightSeaGround, "heightLand": heightShore, "meanderShort": 12, "meanderLong": 0, "waterFunc": (position, height, z) => { addToClass(position.x, position.y, clRiver); createTerrain(tWater).place(position); if (height < heightShallow && ( z > 0.3 && z < 0.4 || z > 0.5 && z < 0.6 || z > 0.7 && z < 0.8)) { g_Map.setHeight(position, heightShallow); addToClass(position.x, position.y, clShallow); } } }); paintTerrainBasedOnHeight(1, 3, 0, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); createBumps([avoidClasses(clPlayer, 20, clRiver, 1), stayClasses(clLand, 3)]); var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7); createForests( [tGrass, tForestFloorP, tForestFloorC, pForestC, pForestP], [avoidClasses(clPlayer, 20, clForest, 17, clRiver, 1), stayClasses(clLand, 7)], clForest, forestTrees); Engine.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, clDirt, 3, clPlayer, 8, clRiver, 1), stayClasses(clLand, 7)], scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tGrassPatch, [avoidClasses(clForest, 0, clDirt, 3, clPlayer, 8, clRiver, 1), stayClasses(clLand, 7)], scaleByMapSize(15, 45), clDirt); Engine.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, clRiver, 1), stayClasses(clLand, 5)], clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], [avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clRiver, 1), stayClasses(clLand, 5)], clMetal ); Engine.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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [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(clPlayer, 1, clDirt, 1, clRiver, 1), stayClasses(clLand, 6)]); 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)); Engine.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, clFood, 20, clRiver, 1), stayClasses(clLand, 3)], clFood); createFood( [ [new SimpleObject(oBerryBush, 5, 7, 0, 4)] ], [ randIntInclusive(1, 4) * numPlayers + 2 ], [avoidClasses(clForest, 0, clPlayer, 20, clFood, 10, clRiver, 1), stayClasses(clLand, 3)], clFood); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 25 * numPlayers ], avoidClasses(clLand, 2, clRiver, 1), clFood); Engine.SetProgress(85); createStragglerTrees( [oPoplar, oCarob, oApple], [avoidClasses(clForest, 1, clPlayer, 9, clMetal, 6, clRock, 6, clRiver, 1), stayClasses(clLand, 7)], clForest, stragglerTrees); placePlayersNomad( clPlayer, new AndConstraint([ stayClasses(clLand, 4), avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clFood, 2)])); 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); g_Map.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 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/hyrcanian_shores.js (revision 21000) @@ -1,343 +1,343 @@ Engine.LoadLibrary("rmgen"); const tPrimary = "temp_grass_long"; 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 tRoad = "temp_road"; const tRoadWild = "temp_road_overgrown"; const tGrassPatch = "temp_grass_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"; const pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oPoplar, tGrassDForest]; const pForestP = [tGrassPForest + TERRAIN_SEPARATOR + oOak, tGrassPForest]; const heightSeaGround1 = -3; const heightShore1 = -1.5; const heightShore2 = 0; const heightLand = 1; const heightOffsetBump = 4; const heightHill = 15; var g_Map = new RandomMap(heightLand, tPrimary); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); const numPlayers = getNumPlayers(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clHighlands = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clHighlands = g_Map.createTileClass(); var waterPosition = fractionToTiles(0.25) var highlandsPosition = fractionToTiles(0.75); var startAngle = randomAngle(); placePlayerBases({ "PlayerPlacement": [sortAllPlayers(), playerPlacementLine(startAngle, mapCenter, fractionToTiles(0.2))], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oOak, "count": 2 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(10); paintRiver({ "parallel": true, "start": new Vector2D(mapBounds.left, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(mapBounds.right, mapBounds.top).rotateAround(startAngle, mapCenter), "width": 2 * waterPosition, "fadeDist": scaleByMapSize(6, 25), "deviation": 0, "heightRiverbed": heightSeaGround1, "heightLand": heightLand, "meanderShort": 20, "meanderLong": 0, "landFunc": (position, shoreDist1, shoreDist2) => { if (waterPosition + shoreDist1 > highlandsPosition) addToClass(position.x, position.y, clHighlands); }, "waterFunc": (position, height, riverFraction) => { if (height < heightShore2) addToClass(position.x, position.y, clWater); createTerrain(height < heightShore1 ? tWater : tShore).place(position); } }); Engine.SetProgress(20); log("Creating fish..."); for (let i = 0; i < scaleByMapSize(10, 20); ++i) createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oFish, 2, 3, 0, 2)], true, clFood), 0, [stayClasses(clWater, 2), avoidClasses(clFood, 3)], numPlayers, 50); Engine.SetProgress(25); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(10, 60), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 3), stayClasses(clHighlands, 1), scaleByMapSize(300, 600)); Engine.SetProgress(30); log("Creating hills..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], avoidClasses(clPlayer, 20, clWater, 5, clHill, 15, clHighlands, 5), scaleByMapSize(1, 4) * numPlayers); Engine.SetProgress(35); log("Creating mainland forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(500, 2500, 0.7); var types = [ [[tGrassDForest, tGrass, pForestD], [tGrassDForest, pForestD]] ]; var size = forestTrees * 1.3 / (scaleByMapSize(2,8) * numPlayers); var num = Math.floor(0.7 * size / types.length); for (let type of types) createAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 20, clWater, 3, clForest, 10, clHill, 0, clBaseResource, 3), num); Engine.SetProgress(45); log("Creating highland forests..."); var types = [ [[tGrassDForest, tGrass, pForestP], [tGrassDForest, pForestP]] ]; var size = forestTrees / (scaleByMapSize(2,8) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 20, clWater, 3, clForest, 2, clHill, 0), num); Engine.SetProgress(70); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter([[tGrass, tGrassA], [tGrassA, tGrassB], [tGrassB, tGrassC]], [1, 1]), paintClass(clDirt) ], avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 4), scaleByMapSize(15, 45)); Engine.SetProgress(75); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new LayeredPainter([tGrassC, tGrassPatch], [2]), avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 6, clBaseResource, 6), scaleByMapSize(15, 45)); Engine.SetProgress(80); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 1, clPlayer, 20, clRock, 10, 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, 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, clHill, 2)], scaleByMapSize(4,16), 100 ); Engine.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), scaleByMapSize(16, 262), 50 ); Engine.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), 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), 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), 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), 2 * numPlayers, 50 ); createStragglerTrees( [oPoplar, oPalm, oApple], avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 10, clMetal, 6, clRock, 6), clForest, stragglerTrees); log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), scaleByMapSize(13, 200) ); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), scaleByMapSize(13, 200) ); Engine.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), scaleByMapSize(13, 200), 50 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("cirrus"); setWaterColor(0.114, 0.192, 0.463); setWaterTint(0.255, 0.361, 0.651); setWaterWaviness(2.0); setWaterType("ocean"); setWaterMurkiness(0.83); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/island_stronghold.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/island_stronghold.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/island_stronghold.js (revision 21000) @@ -1,409 +1,409 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmgen2"); Engine.LoadLibrary("rmbiome"); Engine.LoadLibrary("heightmap"); const g_InitialMineDistance = 14; const g_InitialTrees = 50; 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 tTier4Terrain = g_Terrains.tier4Terrain; 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 oWhale = "gaia/fauna_whale_humpback"; const oShipwreck = "other/special_treasure_shipwreck"; const oShipDebris = "other/special_treasure_shipwreck_debris"; const oObelisk = "other/obelisk"; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; const aRockLarge = g_Decoratives.rockLarge; const aRockMedium = g_Decoratives.rockMedium; const pForest1 = [tForestFloor2 + TERRAIN_SEPARATOR + oTree1, tForestFloor2 + TERRAIN_SEPARATOR + oTree2, tForestFloor2]; const pForest2 = [tForestFloor1 + TERRAIN_SEPARATOR + oTree4, tForestFloor1 + TERRAIN_SEPARATOR + oTree5, tForestFloor1]; const heightSeaGround = -10; const heightLand = 3; const heightHill = 18; var g_Map = new RandomMap(heightSeaGround, tWater); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -const clPlayer = createTileClass(); -const clHill = createTileClass(); -const clForest = createTileClass(); -const clDirt = createTileClass(); -const clRock = createTileClass(); -const clMetal = createTileClass(); -const clFood = createTileClass(); -const clBaseResource = createTileClass(); -const clLand = createTileClass(); +const clPlayer = g_Map.createTileClass(); +const clHill = g_Map.createTileClass(); +const clForest = g_Map.createTileClass(); +const clDirt = g_Map.createTileClass(); +const clRock = g_Map.createTileClass(); +const clMetal = g_Map.createTileClass(); +const clFood = g_Map.createTileClass(); +const clBaseResource = g_Map.createTileClass(); +const clLand = g_Map.createTileClass(); var startAngle = randomAngle(); var teams = getTeamsArray(); var numTeams = teams.filter(team => team).length; var teamPosition = distributePointsOnCircle(numTeams, startAngle, fractionToTiles(0.3), mapCenter)[0]; var teamRadius = fractionToTiles(0.05); var teamNo = 0; for (let i = 0; i < teams.length; ++i) { if (!teams[i] || isNomad()) continue; ++teamNo; let [playerPosition, playerAngle] = distributePointsOnCircle(teams[i].length, startAngle + 2 * Math.PI / teams[i].length, teamRadius, teamPosition[i]); playerPosition.forEach(position => position.round()); log("Creating island and starting entities for team " + i); for (let p = 0; p < teams[i].length; ++p) { addCivicCenterAreaToClass(playerPosition[p], clPlayer); createArea( new ChainPlacer(2, Math.floor(scaleByMapSize(5, 11)), Math.floor(scaleByMapSize(60, 250)), 1, playerPosition[p], 0, [Math.floor(fractionToTiles(0.01))]), [ new LayeredPainter([tMainTerrain, tMainTerrain, tMainTerrain], [1, 6]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 6), paintClass(clLand) ]); placeCivDefaultStartingEntities(playerPosition[p], teams[i][p], false); } let mineAngle = randFloat(-1, 1) * Math.PI / teams[i].length; let mines = [ { "template": oMetalLarge, "angle": mineAngle }, { "template": oStoneLarge, "angle": mineAngle + Math.PI / 4 } ]; log("Create starting resources for team " + i); for (let p = 0; p < teams[i].length; ++p) for (let mine of mines) { let position = Vector2D.add(playerPosition[p], new Vector2D(g_InitialMineDistance, 0).rotate(-playerAngle[p] - mine.angle)); createObjectGroup( new SimpleGroup([new SimpleObject(mine.template, 1, 1, 0, 4)], true, clBaseResource, position.x, position.y), 0, [avoidClasses(clBaseResource, 4, clPlayer, 4), stayClasses(clLand, 5)]); } log("Place initial trees for team " + i); for (let p = 0; p < teams[i].length; ++p) { let tries = 10; for (let x = 0; x < tries; ++x) { let tAngle = playerAngle[p] + randFloat(-1, 1) * 2 * Math.PI / teams[i].length; let treePosition = Vector2D.add(playerPosition[p], new Vector2D(16, 0).rotate(-tAngle)).round(); let group = new SimpleGroup( [new SimpleObject(oTree2, g_InitialTrees, g_InitialTrees, 0, 7)], true, clBaseResource, treePosition.x, treePosition.y ); if (createObjectGroup(group, 0, [avoidClasses(clBaseResource, 4, clPlayer, 4), stayClasses(clLand, 4)])) break; } } for (let p = 0; p < teams[i].length; ++p) placePlayerBaseBerries({ "template": oFruitBush, "playerID": teams[i][p], "playerPosition": playerPosition[p], "BaseResourceClass": clBaseResource, "baseResourceConstraint": new AndConstraint([avoidClasses(clPlayer, 4), stayClasses(clLand, 5)]) }); for (let p = 0; p < teams[i].length; ++p) placePlayerBaseChicken({ "playerID": teams[i][p], "playerPosition": playerPosition[p], "BaseResourceClass": clBaseResource, "baseResourceConstraint": new AndConstraint([avoidClasses(clPlayer, 4), stayClasses(clLand, 5)]) }); log("Creating huntable animals for team " + i + "..."); for (let p = 0; p < teams[i].length; ++p) { let group = new SimpleGroup( [new SimpleObject(oMainHuntableAnimal, 2 * numPlayers / numTeams, 2 * numPlayers / numTeams, 0, Math.floor(fractionToTiles(0.2)))], true, clBaseResource, teamPosition[i].x, teamPosition[i].y ); createObjectGroup(group, 0, [avoidClasses(clBaseResource, 2, clPlayer, 10), stayClasses(clLand, 5)]); group = new SimpleGroup( [new SimpleObject(oSecondaryHuntableAnimal, 4 * numPlayers / numTeams, 4 * numPlayers / numTeams, 0, Math.floor(fractionToTiles(0.2)))], true, clBaseResource, teamPosition[i].x, teamPosition[i].y ); createObjectGroup(group, 0, [avoidClasses(clBaseResource, 2, clPlayer, 10), stayClasses(clLand, 5)]); } } Engine.SetProgress(40); log("Creating big islands..."); createAreas( new ChainPlacer( Math.floor(scaleByMapSize(4, 8) * (isNomad() ? 2 : 1)), Math.floor(scaleByMapSize(8, 16) * (isNomad() ? 2 : 1)), Math.floor(scaleByMapSize(25, 60)), 0.07, undefined, scaleByMapSize(30, 70)), [ new LayeredPainter([tMainTerrain, tMainTerrain], [2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 6), paintClass(clLand) ], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(4, 14) * (isNomad() ? 2 : 1), 1); log("Creating small islands..."); createAreas( new ChainPlacer(Math.floor(scaleByMapSize(4, 7)), Math.floor(scaleByMapSize(7, 10)), Math.floor(scaleByMapSize(16, 40)), 0.07, undefined, scaleByMapSize(22, 40)), [ new LayeredPainter([tMainTerrain, tMainTerrain], [2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 6), paintClass(clLand) ], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(6, 55), 1); Engine.SetProgress(70); log("Smoothing heightmap..."); for (let i = 0; i < 5; ++i) globalSmoothHeightmap(); // repaint clLand to compensate for smoothing unPaintTileClassBasedOnHeight(-10, 10, 3, clLand); paintTileClassBasedOnHeight(0, 5, 3, clLand); Engine.SetProgress(85); createBumps(avoidClasses(clPlayer, 20)); createMines( [ [new SimpleObject(oMetalLarge, 1, 1, 3, (numPlayers * 2) + 1)] ], [avoidClasses(clForest, 1, clPlayer, 40, clRock, 20), stayClasses(clLand, 4)], clMetal ); createMines( [ [new SimpleObject(oStoneLarge, 1, 1, 3, (numPlayers * 2) + 1)], [new SimpleObject(oStoneSmall, 2, 2, 2, (numPlayers * 2) + 1)] ], [avoidClasses(clForest, 1, clPlayer, 40, clMetal, 20), stayClasses(clLand, 4)], clRock ); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], [avoidClasses(clPlayer, 10, clForest, 20, clBaseResource, 5, clRock, 6, clMetal, 6), stayClasses(clLand, 3)], clForest, forestTrees); log("Creating hills..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.5), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], [avoidClasses(clBaseResource, 20, clHill, 15, clRock, 6, clMetal, 6), stayClasses(clLand, 0)], scaleByMapSize(4, 13) ); for (let i = 0; i < 3; ++i) globalSmoothHeightmap(); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], [ avoidClasses(clForest, 10, clPlayer, 20, clMetal, 6, clRock, 6, clHill, 1), stayClasses(clLand, 4) ], clForest, stragglerTrees); createFood( [ [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)] ], [3 * numPlayers, 3 * numPlayers], [avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clRock, 6, clMetal, 6), stayClasses(clLand, 2)], clFood); createFood( [ [new SimpleObject(oFruitBush, 5, 7, 0, 4)] ], [3 * numPlayers], [avoidClasses(clForest, 0, clPlayer, 15, clHill, 1, clFood, 4, clRock, 6, clMetal, 6), stayClasses(clLand, 2)], clFood); if (currentBiome() == "desert") { log("Creating obelisks"); let group = new SimpleGroup( [new SimpleObject(oObelisk, 1, 1, 0, 1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clBaseResource, 0, clHill, 0, clRock, 0, clMetal, 0, clFood, 0), stayClasses(clLand, 1)], scaleByMapSize(3, 8), 1000 ); } log("Creating dirt patches..."); let numb = currentBiome() == "savanna" ? 3 : 1; for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]], [1, 1]), paintClass(clDirt) ], [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 4)], numb*scaleByMapSize(15, 45)); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), new TerrainPainter(tTier4Terrain), [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 4)], numb * scaleByMapSize(15, 45)); log("Creating small decorative rocks..."); let group = new SimpleGroup( [new SimpleObject(aRockMedium, 1, 3, 0, 1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clForest, 0, clHill, 0), stayClasses(clLand, 2)], 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(clForest, 0, clHill, 0), stayClasses(clLand, 2)], scaleByMapSize(8, 131), 50 ); log("Creating fish..."); group = new SimpleGroup( [new SimpleObject(oFish, 2, 3, 0, 2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clLand, 4, clFood, 20), 25 * numPlayers, 60 ); log("Creating Whales..."); group = new SimpleGroup( [new SimpleObject(oWhale, 1, 1, 0, 3)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clLand, 4),avoidClasses(clFood, 8)], scaleByMapSize(5, 20), 100 ); log("Creating shipwrecks..."); group = new SimpleGroup( [new SimpleObject(oShipwreck, 1, 1, 0, 1)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clLand, 4),avoidClasses(clFood, 8)], scaleByMapSize(12, 16), 100 ); log("Creating shipwreck debris..."); group = new SimpleGroup( [new SimpleObject(oShipDebris, 1, 1, 0, 1)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clLand, 4),avoidClasses(clFood, 8)], scaleByMapSize(10, 20), 100 ); log("Creating small grass tufts..."); let planetm = currentBiome() == "tropic" ? 8 : 1; group = new SimpleGroup( [new SimpleObject(aGrassShort, 1, 2, 0, 1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 3)], planetm * scaleByMapSize(13, 200) ); Engine.SetProgress(95); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2, 4, 0, 1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3, 6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 5)], planetm * scaleByMapSize(13, 200) ); paintTerrainBasedOnHeight(1, 2, 0, tShore); paintTerrainBasedOnHeight(heightSeaGround, 1, 3, tWater); placePlayersNomad(clPlayer, [stayClasses(clLand, 4), avoidClasses(clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)]); setSkySet(pickRandom(["cloudless", "cumulus", "overcast"])); setSunRotation(randomAngle()); setSunElevation(randFloat(1/5, 1/3) * Math.PI); setWaterWaviness(2); Engine.SetProgress(100); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/kerala.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/kerala.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/kerala.js (revision 21000) @@ -1,336 +1,336 @@ Engine.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]; const heightSeaGround = -5; const heightLand = 3; const heightHill = 25; var g_Map = new RandomMap(heightLand, tGrass); const numPlayers = getNumPlayers(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -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 clMountains = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clMountains = g_Map.createTileClass(); var waterPosition = fractionToTiles(0.31); var playerPosition = fractionToTiles(0.55); var mountainPosition = fractionToTiles(0.69); var startAngle = randomAngle(); placePlayerBases({ "PlayerPlacement": [ sortAllPlayers(), playerPlacementLine(0, new Vector2D(mapCenter.x, playerPosition), fractionToTiles(0.2)).map(pos => pos.rotateAround(startAngle, mapCenter)) ], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree, "count": scaleByMapSize(12, 30), "minDist": 12, "maxDist": 14, "minDistGroup": 1, "maxDistGroup": 3 } // No decoratives }); Engine.SetProgress(15); paintRiver({ "parallel": true, "start": new Vector2D(mapBounds.left, mapBounds.top).rotateAround(startAngle - Math.PI / 2, mapCenter), "end": new Vector2D(mapBounds.left, mapBounds.bottom).rotateAround(startAngle - Math.PI / 2, mapCenter), "width": 2 * waterPosition, "fadeDist": 8, "deviation": 0, "heightRiverbed": heightSeaGround, "heightLand": heightLand, "meanderShort": 20, "meanderLong": 0, "landFunc": (position, shoreDist1, shoreDist2) => { if (waterPosition + shoreDist1 > mountainPosition) addToClass(position.x, position.y, clMountains); }, "waterFunc": (position, height, riverFraction) => { addToClass(position.x, position.y, clWater); } }); log("Creating shores..."); for (let i = 0; i < scaleByMapSize(20, 120); ++i) { let position = new Vector2D(fractionToTiles(randFloat(0.28, 0.34)), fractionToTiles(randFloat(0.1, 0.9))).rotateAround(startAngle - Math.PI / 2, mapCenter).round(); createArea( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 30)), 1, position), [ new LayeredPainter([tGrass, tGrass], [2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 3), unPaintClass(clWater) ]); } paintTerrainBasedOnHeight(-6, 1, 1, tWater); paintTerrainBasedOnHeight(1, 2.8, 1, tShoreBlend); paintTerrainBasedOnHeight(0, 1, 1, tShore); paintTileClassBasedOnHeight(-6, 0.5, 1, clWater); Engine.SetProgress(45); log("Creating hills..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.1), [ new LayeredPainter([tCliff, tGrass], [3]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 3), paintClass(clHill) ], [avoidClasses(clPlayer, 20, clHill, 5, clWater, 2, clBaseResource, 2), stayClasses(clMountains, 0)], scaleByMapSize(5, 40) * numPlayers); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(1000, 6000, 0.7); var types = [ [[tGrass, tGrass, tGrass, tGrass, pForestD], [tGrass, tGrass, tGrass, pForestD]], [[tGrass, tGrass, tGrass, tGrass, pForestP], [tGrass, tGrass, tGrass, pForestP]] ]; var size = forestTrees / (scaleByMapSize(3,6) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ChainPlacer( 1, Math.floor(scaleByMapSize(3, 5)), forestTrees / (num * Math.floor(scaleByMapSize(2, 4))), 0.5), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 20, clForest, 10, clHill, 0, clWater, 8), num); Engine.SetProgress(70); log("Creating grass patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([tGrassC, tGrassA, tGrassB], [2, 1]), paintClass(clDirt) ], avoidClasses(clWater, 8, clForest, 0, clHill, 0, clPlayer, 12, clDirt, 16), scaleByMapSize(20, 80)); for (let size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([tPlants, tPlants], [1]), paintClass(clDirt) ], avoidClasses(clWater, 8, clForest, 0, clHill, 0, clPlayer, 12, clDirt, 16), scaleByMapSize(20, 80)); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 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, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), 8 * scaleByMapSize(13, 200) ); Engine.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aBush2, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aBush1, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), 8 * scaleByMapSize(13, 200) ); Engine.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 ); Engine.SetProgress(95); createStragglerTrees( [oTree, oPalm], avoidClasses(clWater, 5, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); 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 ); Engine.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 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setSunColor(0.6, 0.6, 0.6); setSunElevation(Math.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"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/latium.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/latium.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/latium.js (revision 21000) @@ -1,480 +1,480 @@ Engine.LoadLibrary("rmgen"); const tOceanDepths = "medit_sea_depths"; const tOceanRockDeep = "medit_sea_coral_deep"; const tOceanRockShallow = "medit_rocks_wet"; const tOceanCoral = "medit_sea_coral_plants"; const tBeachWet = "medit_sand_wet"; const tBeachDry = "medit_sand"; const tBeachGrass = "medit_rocks_grass"; const tBeachCliff = "medit_dirt"; const tCity = "medit_city_tile"; const tGrassDry = ["medit_grass_field_brown", "medit_grass_field_dry", "medit_grass_field_b"]; const tGrass = ["medit_grass_field_dry", "medit_grass_field_brown", "medit_grass_field_b"]; const tGrassShrubs = ["medit_grass_shrubs", "medit_grass_flowers"]; const tGrassRock = ["medit_rocks_grass"]; const tDirt = "medit_dirt"; const tDirtCliff = "medit_cliff_italia"; const tGrassCliff = "medit_cliff_italia_grass"; const tCliff = ["medit_cliff_italia", "medit_cliff_italia", "medit_cliff_italia_grass"]; const tForestFloor = "medit_grass_wild"; const oBeech = "gaia/flora_tree_euro_beech"; const oBerryBush = "gaia/flora_bush_berry"; const oCarob = "gaia/flora_tree_carob"; const oCypress1 = "gaia/flora_tree_cypress"; const oCypress2 = "gaia/flora_tree_cypress"; const oLombardyPoplar = "gaia/flora_tree_poplar_lombardy"; const oPalm = "gaia/flora_tree_medit_fan_palm"; const oPine = "gaia/flora_tree_aleppo_pine"; 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 aBushMedDry = "actor|props/flora/bush_medit_me_dry.xml"; const aBushMed = "actor|props/flora/bush_medit_me.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; const aBushSmallDry = "actor|props/flora/bush_medit_sm_dry.xml"; const aGrass = "actor|props/flora/grass_soft_large_tall.xml"; const aGrassDry = "actor|props/flora/grass_soft_dry_large_tall.xml"; const aRockLarge = "actor|geology/stone_granite_large.xml"; const aRockMed = "actor|geology/stone_granite_med.xml"; const aRockSmall = "actor|geology/stone_granite_small.xml"; const pPalmForest = [tForestFloor+TERRAIN_SEPARATOR+oPalm, tGrass]; const pPineForest = [tForestFloor+TERRAIN_SEPARATOR+oPine, tGrass]; const pPoplarForest = [tForestFloor+TERRAIN_SEPARATOR+oLombardyPoplar, tGrass]; const pMainForest = [tForestFloor+TERRAIN_SEPARATOR+oCarob, tForestFloor+TERRAIN_SEPARATOR+oBeech, tGrass, tGrass]; const heightSeaGround = -16; const heightLand = 0; const heightPlayer = 5; const heightHill = 12; var g_Map = new RandomMap(heightLand, tGrass); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -var clWater = createTileClass(); -var clCliff = createTileClass(); -var clForest = createTileClass(); -var clMetal = createTileClass(); -var clRock = createTileClass(); -var clFood = createTileClass(); -var clPlayer = createTileClass(); -var clBaseResource = createTileClass(); +var clWater = g_Map.createTileClass(); +var clCliff = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var WATER_WIDTH = 0.1; var horizontal = randBool(); log("Creating players..."); var startAngle = randBool() ? 0 : Math.PI / 2; var playerPosition = playerPlacementLine(startAngle + Math.PI / 2, mapCenter, fractionToTiles(randFloat(0.42, 0.46))); function distanceToPlayers(x, z) { let r = Infinity; for (let i = 0; i < numPlayers; ++i) { var dx = x - playerPosition[i].x; var dz = z - playerPosition[i].y; r = Math.min(r, Math.square(dx) + Math.square(dz)); } return Math.sqrt(r); } function playerNearness(x, z) { var d = fractionToTiles(distanceToPlayers(x,z)); if (d < 13) return 0; if (d < 19) return (d-13)/(19-13); return 1; } for (let x of [mapBounds.left, mapBounds.right]) paintRiver({ "parallel": true, "start": new Vector2D(x, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(x, mapBounds.bottom).rotateAround(startAngle, mapCenter), "width": 2 * fractionToTiles(WATER_WIDTH), "fadeDist": 16, "deviation": 0, "heightRiverbed": heightSeaGround, "heightLand": heightLand, "meanderShort": 0, "meanderLong": 0, "waterFunc": (position, height, z) => { addToClass(position.x, position.y, clWater); } }); Engine.SetProgress(10); log("Painting elevation..."); var noise0 = new Noise2D(scaleByMapSize(4, 16)); var noise1 = new Noise2D(scaleByMapSize(8, 32)); var noise2 = new Noise2D(scaleByMapSize(15, 60)); var noise2a = new Noise2D(scaleByMapSize(20, 80)); var noise2b = new Noise2D(scaleByMapSize(35, 140)); var noise3 = new Noise2D(scaleByMapSize(4, 16)); var noise4 = new Noise2D(scaleByMapSize(6, 24)); var noise5 = new Noise2D(scaleByMapSize(11, 44)); for (var ix = 0; ix <= mapSize; ix++) for (var iz = 0; iz <= mapSize; iz++) { let position = new Vector2D(ix, iz); var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); var pn = playerNearness(x, z); let c = startAngle ? z : x; let distToWater = stayClasses(clWater, 1).allows(position) ? 0 : (0.5 - WATER_WIDTH - Math.abs(c - 0.5)); let h = distToWater ? heightHill * (1 - Math.abs(c - 0.5) / (0.5 - WATER_WIDTH)) : g_Map.getHeight(position); // add some base noise var baseNoise = 16*noise0.get(x,z) + 8*noise1.get(x,z) + 4*noise2.get(x,z) - (16+8+4)/2; if ( baseNoise < 0 ) { baseNoise *= pn; baseNoise *= Math.max(0.1, distToWater / (0.5 - WATER_WIDTH)); } var oldH = h; h += baseNoise; // add some higher-frequency noise on land if ( oldH > 0 ) h += (0.4 * noise2a.get(x,z) + 0.2 * noise2b.get(x,z)) * Math.min(oldH / 10, 1); // create cliff noise if ( h > -10 ) { var cliffNoise = (noise3.get(x,z) + 0.5*noise4.get(x,z)) / 1.5; if (h < 1) { var u = 1 - 0.3*((h-1)/-10); cliffNoise *= u; } cliffNoise += 0.05 * distToWater / (0.5 - WATER_WIDTH); if (cliffNoise > 0.6) { var u = 0.8 * (cliffNoise - 0.6); cliffNoise += u * noise5.get(x,z); cliffNoise /= (1 + u); } cliffNoise -= 0.59; cliffNoise *= pn; if (cliffNoise > 0) h += 19 * Math.min(cliffNoise, 0.045) / 0.045; } g_Map.setHeight(position, h); } Engine.SetProgress(20); log("Painting terrain..."); var noise6 = new Noise2D(scaleByMapSize(10, 40)); var noise7 = new Noise2D(scaleByMapSize(20, 80)); var noise8 = new Noise2D(scaleByMapSize(13, 52)); var noise9 = new Noise2D(scaleByMapSize(26, 104)); var noise10 = new Noise2D(scaleByMapSize(50, 200)); for (var ix = 0; ix < mapSize; ix++) for (var iz = 0; iz < mapSize; iz++) { let position = new Vector2D(ix, iz); var x = ix / (mapSize + 1.0); var z = iz / (mapSize + 1.0); var pn = playerNearness(x, z); // get heights of surrounding vertices var h00 = g_Map.getHeight(Vector2D.add(position, new Vector2D(0, 0)); var h01 = g_Map.getHeight(Vector2D.add(position, new Vector2D(0, 1)); var h10 = g_Map.getHeight(Vector2D.add(position, new Vector2D(1, 0)); var h11 = g_Map.getHeight(Vector2D.add(position, new Vector2D(1, 1)); // find min and max height var maxH = Math.max(h00, h01, h10, h11); var minH = Math.min(h00, h01, h10, h11); var diffH = maxH - minH; // figure out if we're at the top of a cliff using min adjacent height var minAdjHeight = minH; if (maxH > 15) { var maxNx = Math.min(ix + 2, mapSize); var maxNz = Math.min(iz + 2, mapSize); for (let nx = Math.max(ix - 1, 0); nx <= maxNx; ++nx) for (let nz = Math.max(iz - 1, 0); nz <= maxNz; ++nz) minAdjHeight = Math.min(minAdjHeight, getHeight(new Vector2D(nx, nz))); } // choose a terrain based on elevation var t = tGrass; // water if (maxH < -12) t = tOceanDepths; else if (maxH < -8.8) t = tOceanRockDeep; else if (maxH < -4.7) t = tOceanCoral; else if (maxH < -2.8) t = tOceanRockShallow; else if (maxH < 0.9 && minH < 0.35) t = tBeachWet; else if (maxH < 1.5 && minH < 0.9) t = tBeachDry; else if (maxH < 2.3 && minH < 1.3) t = tBeachGrass; if (minH < 0) addToClass(ix, iz, clWater); // cliffs if (diffH > 2.9 && minH > -7) { t = tCliff; addToClass(ix, iz, clCliff); } else if (diffH > 2.5 && minH > -5 || maxH - minAdjHeight > 2.9 && minH > 0) { if (minH < -1) t = tCliff; else if (minH < 0.5) t = tBeachCliff; else t = [tDirtCliff, tGrassCliff, tGrassCliff, tGrassRock, tCliff]; addToClass(ix, iz, clCliff); } // Don't place resources onto potentially impassable mountains if (minH >= 20) addToClass(ix, iz, clCliff); // forests if (g_Map.getHeight(position) < 11 && diffH < 2 && minH > 1) { var forestNoise = (noise6.get(x,z) + 0.5*noise7.get(x,z)) / 1.5 * pn - 0.59; // Thin out trees a bit if (forestNoise > 0 && randBool()) { if (minH < 11 && minH >= 4) { var typeNoise = noise10.get(x,z); if (typeNoise < 0.43 && forestNoise < 0.05) t = pPoplarForest; else if (typeNoise < 0.63) t = pMainForest; else t = pPineForest; addToClass(ix, iz, clForest); } else if (minH < 4) { t = pPalmForest; addToClass(ix, iz, clForest); } } } // grass variations if (t == tGrass) { var grassNoise = (noise8.get(x,z) + 0.6*noise9.get(x,z)) / 1.6; if (grassNoise < 0.3) t = (diffH > 1.2) ? tDirtCliff : tDirt; else if (grassNoise < 0.34) { t = (diffH > 1.2) ? tGrassCliff : tGrassDry; if (diffH < 0.5 && randBool(0.02)) placeObject(randFloat(ix, ix + 1), randFloat(iz, iz + 1), aGrassDry, 0, randomAngle()); } else if (grassNoise > 0.61) { t = (diffH > 1.2 ? tGrassRock : tGrassShrubs); } else if (diffH < 0.5 && randBool(0.02)) placeObject(randFloat(ix, ix + 1), randFloat(iz, iz + 1), aGrass, 0, randomAngle()); } createTerrain(t).place(position); } Engine.SetProgress(30); placePlayerBases({ "PlayerPlacement": [sortAllPlayers(), playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "baseResourceConstraint": avoidClasses(clCliff, 4), "CityPatch": { "radius": 11, "outerTerrain": tGrass, "innerTerrain": tCity, "width": 4, "painters": [ new SmoothElevationPainter(ELEVATION_SET, heightPlayer, 2) ] }, "Chicken": { }, "Berries": { "template": oBerryBush, "distance": 9 }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oPalm, "count": 5, "minDist": 10, "maxDist": 11 } // No decoratives }); Engine.SetProgress(40); log("Creating bushes..."); var group = new SimpleGroup( [new SimpleObject(aBushSmall, 0,2, 0,2), new SimpleObject(aBushSmallDry, 0,2, 0,2), new SimpleObject(aBushMed, 0,1, 0,2), new SimpleObject(aBushMedDry, 0,1, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 4, clCliff, 2), scaleByMapSize(9, 146), 50 ); Engine.SetProgress(45); log("Creating rocks..."); group = new SimpleGroup( [new SimpleObject(aRockSmall, 0,3, 0,2), new SimpleObject(aRockMed, 0,2, 0,2), new SimpleObject(aRockLarge, 0,1, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clCliff, 1), scaleByMapSize(9, 146), 50 ); Engine.SetProgress(50); log("Creating large 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, 1, clForest, 4, clPlayer, 40, clRock, 60, clMetal, 10, clCliff, 3), scaleByMapSize(4,16), 100 ); log("Creating small stone mines..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroups(group, 0, avoidClasses(clForest, 4, clWater, 1, clPlayer, 40, clRock, 30, clMetal, 10, clCliff, 3), scaleByMapSize(4,16), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,2)], true, clMetal); createObjectGroups(group, 0, avoidClasses(clForest, 4, clWater, 1, clPlayer, 40, clMetal, 50, clCliff, 3), scaleByMapSize(4,16), 100 ); Engine.SetProgress(60); createStragglerTrees( [oCarob, oBeech, oLombardyPoplar, oLombardyPoplar, oPine], avoidClasses(clWater, 5, clCliff, 4, clForest, 2, clPlayer, 15, clMetal, 6, clRock, 6), clForest, scaleByMapSize(10, 190)); Engine.SetProgress(70); log("Creating straggler cypresses..."); group = new SimpleGroup( [new SimpleObject(oCypress2, 1,3, 0,3), new SimpleObject(oCypress1, 0,2, 0,2)], true ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 5, clCliff, 4, clForest, 2, clPlayer, 15, clMetal, 6, clRock, 6), scaleByMapSize(5, 75), 50 ); Engine.SetProgress(80); log("Creating sheep..."); group = new SimpleGroup([new SimpleObject(oSheep, 2,4, 0,2)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 5, clForest, 2, clCliff, 1, clPlayer, 20, clMetal, 6, clRock, 6, clFood, 8), 3 * numPlayers, 50 ); Engine.SetProgress(85); log("Creating fish..."); var num = scaleByMapSize(4, 16); var offsetX = mapSize * WATER_WIDTH/2; for (let i = 0; i < num; ++i) createObjectGroup( new SimpleGroup( [new SimpleObject(oFish, 1, 1, 0, 1)], true, clFood, randIntInclusive(offsetX / 2, offsetX * 3/2), Math.round((i + 0.5) * mapSize / num)), 0); for (let i = 0; i < num; ++i) createObjectGroup( new SimpleGroup( [new SimpleObject(oFish, 1, 1, 0, 1)], true, clFood, randIntInclusive(mapSize - offsetX * 3/2, mapSize - offsetX / 2), Math.round((i + 0.5) * mapSize / num)), 0); Engine.SetProgress(90); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 5, clForest, 2, clCliff, 1, clPlayer, 20, clMetal, 6, clRock, 6, clFood, 8), 3 * numPlayers, 50 ); Engine.SetProgress(95); log("Creating berry bushes..."); group = new SimpleGroup([new SimpleObject(oBerryBush, 5,7, 0,3)], true, clFood); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 5, clForest, 2, clCliff, 1, clPlayer, 20, clMetal, 6, clRock, 6, clFood, 8), 1.5 * numPlayers, 100 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clCliff, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setSkySet("sunny"); setWaterColor(0.024,0.262,0.224); setWaterTint(0.133, 0.325,0.255); setWaterWaviness(2.5); setWaterType("ocean"); setWaterMurkiness(0.8); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/migration.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/migration.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/migration.js (revision 21000) @@ -1,372 +1,372 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); 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 tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; 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 oWoodTreasure = "gaia/special_treasure_wood"; const oDock = "skirmish/structures/default_dock"; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; 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]; const heightSeaGround = -5; const heightLand = 3; const heightHill = 18; const heightOffsetBump = 2; var g_Map = new RandomMap(heightSeaGround, tWater); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -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 clLand = createTileClass(); -var clIsland = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clLand = g_Map.createTileClass(); +var clIsland = g_Map.createTileClass(); var startAngle = randomAngle(); var playerIDs = sortAllPlayers(); var [playerPosition, playerAngle] = playerPlacementCustomAngle( fractionToTiles(0.35), mapCenter, i => startAngle - Math.PI * (i + 1) / (numPlayers + 1)); log("Creating player islands and docks..."); for (let i = 0; i < numPlayers; ++i) { createArea( new ClumpPlacer(diskArea(defaultPlayerBaseRadius()), 0.8, 0.1, 10, playerPosition[i]), [ new LayeredPainter([tWater, tShore, tMainTerrain], [1, 4]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 4), paintClass(clIsland), paintClass(isNomad() ? clLand : clPlayer) ]); if (isNomad()) continue; let dockLocation = findLocationInDirectionBasedOnHeight(playerPosition[i], mapCenter, -3 , 2.6, 3); placeObject(dockLocation.x, dockLocation.y, oDock, playerIDs[i], playerAngle[i] + Math.PI); } Engine.SetProgress(10); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "Walls": false, // No city patch "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Treasures": { "types": [ { "template": oWoodTreasure, "count": 14 } ] }, "Trees": { "template": oTree1, "count": scaleByMapSize(12, 30) }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(15); log("Create the continent body..."); var continentPosition = Vector2D.add(mapCenter, new Vector2D(0, fractionToTiles(0.38)).rotate(-startAngle)).round() createArea( new ClumpPlacer(diskArea(fractionToTiles(0.4)), 0.8, 0.08, 10, continentPosition), [ new LayeredPainter([tWater, tShore, tMainTerrain], [4, 2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 4), paintClass(clLand) ], avoidClasses(clIsland, 8)); Engine.SetProgress(20); log("Creating shore jaggedness..."); createAreas( new ClumpPlacer(scaleByMapSize(15, 80), 0.2, 0.1, 1), [ new LayeredPainter([tMainTerrain, tMainTerrain], [2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 4), paintClass(clLand) ], [ borderClasses(clLand, 6, 3), avoidClasses(clIsland, 8) ], scaleByMapSize(2, 15) * 20, 150); paintTerrainBasedOnHeight(1, 3, 0, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); Engine.SetProgress(25); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), [avoidClasses(clIsland, 10), stayClasses(clLand, 3)], scaleByMapSize(100, 200) ); Engine.SetProgress(30); log("Creating hills..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], [avoidClasses(clIsland, 10, clHill, 15), stayClasses(clLand, 7)], scaleByMapSize(1, 4) * numPlayers ); Engine.SetProgress(34); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); var types = [ [[tForestFloor2, tMainTerrain, pForest1], [tForestFloor2, pForest1]], [[tForestFloor1, tMainTerrain, pForest2], [tForestFloor1, pForest2]] ]; var size = forestTrees / (scaleByMapSize(2,8) * numPlayers) * (currentBiome() == "savanna" ? 2 : 1); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], [avoidClasses(clPlayer, 6, clForest, 10, clHill, 0), stayClasses(clLand, 7)], num); Engine.SetProgress(38); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter( [[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]], [1, 1]), paintClass(clDirt) ], [ avoidClasses( clForest, 0, clHill, 0, clDirt, 5, clIsland, 0), stayClasses(clLand, 7) ], scaleByMapSize(15, 45)); Engine.SetProgress(42); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new TerrainPainter(tTier4Terrain), [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clIsland, 0), stayClasses(clLand, 7)], scaleByMapSize(15, 45)); Engine.SetProgress(46); 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, 7)], scaleByMapSize(4,16), 100 ); Engine.SetProgress(50); 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, 7)], scaleByMapSize(4,16), 100 ); Engine.SetProgress(54); 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, 7)], scaleByMapSize(4,16), 100 ); Engine.SetProgress(58); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 6)], scaleByMapSize(16, 262), 50 ); Engine.SetProgress(62); 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(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 6)], scaleByMapSize(8, 131), 50 ); Engine.SetProgress(66); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oMainHuntableAnimal, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), stayClasses(clLand, 7)], 3 * numPlayers, 50 ); Engine.SetProgress(70); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oSecondaryHuntableAnimal, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), stayClasses(clLand, 7)], 3 * numPlayers, 50 ); Engine.SetProgress(74); log("Creating fruit bush..."); group = new SimpleGroup( [new SimpleObject(oFruitBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 0, clPlayer, 8, clHill, 1, clFood, 20), stayClasses(clLand, 7)], randIntInclusive(1, 4) * numPlayers + 2, 50 ); Engine.SetProgress(78); log("Creating fish..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oFish, 2,3, 0,2)], true, clFood), 0, avoidClasses(clLand, 2, clPlayer, 2, clHill, 0, clFood, 20), 25 * numPlayers, 60 ); Engine.SetProgress(82); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], [avoidClasses(clForest, 1, clHill, 1, clPlayer, 9, clMetal, 6, clRock, 6), stayClasses(clLand, 9)], clForest, stragglerTrees); Engine.SetProgress(86); var planetm = currentBiome() == "tropic" ? 8 : 1; log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 6)], planetm * scaleByMapSize(13, 200) ); Engine.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 6)], planetm * scaleByMapSize(13, 200) ); Engine.SetProgress(94); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clHill, 1, clPlayer, 1, clDirt, 1), stayClasses(clLand, 6)], planetm * scaleByMapSize(13, 200), 50 ); Engine.SetProgress(98); setSkySet(pickRandom(["cirrus", "cumulus", "sunny"])); setSunRotation(randomAngle()); setSunElevation(randFloat(1/5, 1/3) * Math.PI); setWaterWaviness(2); placePlayersNomad(clPlayer, [stayClasses(clIsland, 4), avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)]); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/northern_lights.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/northern_lights.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/northern_lights.js (revision 21000) @@ -1,288 +1,288 @@ Engine.LoadLibrary("rmgen"); const tSnowA = ["polar_snow_b"]; const tSnowB = "polar_ice_snow"; const tSnowC = "polar_ice"; const tSnowD = "polar_snow_a"; const tForestFloor = "polar_tundra_snow"; const tCliff = "polar_snow_rocks"; const tSnowE = ["polar_snow_glacial"]; const tRoad = "new_alpine_citytile"; const tRoadWild = "new_alpine_citytile"; const tShoreBlend = "alpine_shore_rocks_icy"; const tShore = "alpine_shore_rocks"; const tWater = "alpine_shore_rocks"; const oPine = "gaia/flora_tree_pine_w"; const oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; const oStoneSmall = "gaia/geology_stone_alpine_a"; const oMetalLarge = "gaia/geology_metal_alpine_slabs"; const oFish = "gaia/fauna_fish"; const oWalrus = "gaia/fauna_walrus"; const oArcticWolf = "gaia/fauna_arctic_wolf"; const aIceberg = "actor|props/special/eyecandy/iceberg.xml"; const pForestD = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor, tForestFloor]; const pForestS = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor, tForestFloor, tForestFloor]; const heightSeaGround = -5; const heightLake = -4; const heightLand = 3; const heightHill = 25; var g_Map = new RandomMap(heightLand, tSnowA); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clIsland = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clIsland = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); var startAngle = randomAngle(); placePlayerBases({ "PlayerPlacement": [ sortAllPlayers(), playerPlacementLine(0, new Vector2D(mapCenter.x, fractionToTiles(0.45)), fractionToTiles(0.2)).map( pos => pos.rotateAround(startAngle, mapCenter)) ], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, // No chicken, no berries "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oPine, "count": scaleByMapSize(12, 30), } // No decoratives }); Engine.SetProgress(15); paintRiver({ "parallel": true, "start": new Vector2D(mapBounds.left, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(mapBounds.right, mapBounds.top).rotateAround(startAngle, mapCenter), "width": 2 * fractionToTiles(0.31), "fadeDist": 8, "deviation": 0, "heightRiverbed": heightSeaGround, "heightLand": heightLand, "meanderShort": 0, "meanderLong": 0 }); paintTileClassBasedOnHeight(-Infinity, 0.5, Elevation_ExcludeMin_ExcludeMax, clWater); log("Creating shores..."); for (let i = 0; i < scaleByMapSize(20, 120); ++i) { let position = new Vector2D(fractionToTiles(randFloat(0.1, 0.9)), fractionToTiles(randFloat(0.67, 0.74))).rotateAround(startAngle, mapCenter).round(); createArea( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 30)), 1, position), [ new LayeredPainter([tSnowA, tSnowA], [2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 3), unPaintClass(clWater) ]); } log("Creating islands..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.1), [ new LayeredPainter([tSnowA, tSnowA], [3]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 3), paintClass(clIsland), unPaintClass(clWater) ], stayClasses(clWater, 7), scaleByMapSize(10, 80)); paintTerrainBasedOnHeight(-6, 1, 1, tWater); log("Creating lakes..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(5, 7)), Math.floor(scaleByMapSize(20, 50)), 0.1), [ new LayeredPainter([tShoreBlend, tShore, tWater], [1, 1]), new SmoothElevationPainter(ELEVATION_SET, heightLake, 3), paintClass(clWater) ], avoidClasses(clPlayer, 20, clWater, 20), Math.round(scaleByMapSize(1, 4) * numPlayers)); paintTerrainBasedOnHeight(1, 2.8, 1, tShoreBlend); paintTileClassBasedOnHeight(-6, 0.5, 1, clWater); Engine.SetProgress(45); log("Creating hills..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.1), [ new LayeredPainter([tCliff, tSnowA], [3]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 3), paintClass(clHill) ], avoidClasses(clPlayer, 20, clHill, 15, clWater, 2, clBaseResource, 2), scaleByMapSize(1, 4) * numPlayers ); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(100, 625, 0.7); var types = [ [[tSnowA, tSnowA, tSnowA, tSnowA, pForestD], [tSnowA, tSnowA, tSnowA, pForestD]], [[tSnowA, tSnowA, tSnowA, tSnowA, pForestS], [tSnowA, tSnowA, tSnowA, pForestS]] ]; var size = forestTrees / (scaleByMapSize(3,6) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), forestTrees / (num * Math.floor(scaleByMapSize(2, 4))), 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 20, clForest, 20, clHill, 0, clWater, 8), num); log("Creating iceberg..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aIceberg, 0, 2, 0, 4)], true, clRock), 0, [avoidClasses(clRock, 6), stayClasses(clWater, 4)], scaleByMapSize(4, 16), 100); Engine.SetProgress(70); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([tSnowD, tSnowB, tSnowC], [2, 1]), paintClass(clDirt) ], avoidClasses( clWater, 8, clForest, 0, clHill, 0, clPlayer, 20, clDirt, 16), scaleByMapSize(20, 80)); for (let size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([tSnowE, tSnowE], [1]), paintClass(clDirt) ], avoidClasses( clWater, 8, clForest, 0, clHill, 0, clPlayer, 20, clDirt, 16), scaleByMapSize(20, 80)); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), scaleByMapSize(8,32), 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(8,32), 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(8,32), 100 ); Engine.SetProgress(95); createStragglerTrees( [oPine], avoidClasses(clWater, 5, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oWalrus, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), 3 * numPlayers, 50 ); Engine.SetProgress(75); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oArcticWolf, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, 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 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2, clIsland, 4)); setSunColor(0.6, 0.6, 0.6); setSunElevation(Math.PI/ 6); setWaterColor(0.02, 0.17, 0.52); setWaterTint(0.494, 0.682, 0.808); setWaterMurkiness(0.82); setWaterWaviness(0.5); setWaterType("ocean"); setFogFactor(0.95); setFogThickness(0.09); setPPSaturation(0.28); setPPEffect("hdr"); setSkySet("fog"); g_Map.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 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/phoenician_levant.js (revision 21000) @@ -1,332 +1,332 @@ Engine.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 aDecorativeRock = "actor|geology/stone_granite_med.xml"; const pForest = [tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERRAIN_SEPARATOR + oSDatePalm, tForestFloor + TERRAIN_SEPARATOR + oCarob, tForestFloor, tForestFloor]; const heightSeaGround = -3; const heightShore = -1.5; const heightLand = 1; const heightIsland = 6; const heightHill = 15; const heightOffsetBump = 2; var g_Map = new RandomMap(heightLand, tHill); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -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 clGrass = createTileClass(); -var clHill = createTileClass(); -var clIsland = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clGrass = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clIsland = g_Map.createTileClass(); var startAngle = randIntInclusive(0, 3) * Math.PI / 2; placePlayerBases({ "PlayerPlacement": [ sortAllPlayers(), playerPlacementLine(Math.PI / 2, new Vector2D(fractionToTiles(0.76), mapCenter.y), fractionToTiles(0.2)).map(pos => pos.rotateAround(startAngle, mapCenter)) ], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tCityPlaza, "innerTerrain": tCity }, "Chicken": { }, "Berries": { "template": oGrapeBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oCarob, "count": 2 }, "Decoratives": { "template": aBush1 } }); Engine.SetProgress(30); paintRiver({ "parallel": true, "start": new Vector2D(mapBounds.left, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(mapBounds.left, mapBounds.bottom).rotateAround(startAngle, mapCenter), "width": mapSize, "fadeDist": scaleByMapSize(6, 25), "deviation": 0, "heightRiverbed": heightSeaGround, "heightLand": heightLand, "meanderShort": 20, "meanderLong": 0 }); Engine.SetProgress(40); paintTileClassBasedOnHeight(-Infinity, heightLand, Elevation_ExcludeMin_ExcludeMax, clWater); paintTerrainBasedOnHeight(-Infinity, heightShore, Elevation_ExcludeMin_ExcludeMax, tWater); paintTerrainBasedOnHeight(heightShore, heightLand, Elevation_ExcludeMin_ExcludeMax, tShore); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), avoidClasses(clWater, 2, clPlayer, 20), scaleByMapSize(100, 200)); log("Creating hills..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.5), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], avoidClasses(clPlayer, 20, clForest, 1, clHill, 15, clWater, 0), scaleByMapSize(1, 4) * numPlayers * 3); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(500, 2500, 0.5); var num = scaleByMapSize(10,42); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), forestTrees / (num * Math.floor(scaleByMapSize(2, 5))), 0.5), [ new TerrainPainter([tForestFloor, pForest]), paintClass(clForest) ], avoidClasses(clPlayer, 20, clForest, 10, clWater, 1, clHill, 1, clBaseResource, 3), num, 50); Engine.SetProgress(50); log("Creating grass patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter( [[tGrass, tRocksShrubs], [tRocksShrubs, tRocksGrass], [tRocksGrass, tGrass]], [1, 1]), paintClass(clDirt) ], avoidClasses(clForest, 0, clGrass, 5, clPlayer, 10, clWater, 4, clDirt, 5, clHill, 1), scaleByMapSize(15, 45)); Engine.SetProgress(55); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter( [[tDirt, tDirtB], [tDirt, tMainDirt], [tDirtB, tMainDirt]], [1, 1]), paintClass(clDirt) ], avoidClasses(clForest, 0, clDirt, 5, clPlayer, 10, clWater, 4, clGrass, 5, clHill, 1), scaleByMapSize(15, 45)); Engine.SetProgress(60); log("Creating cyprus..."); createAreas( new ClumpPlacer(diskArea(fractionToTiles(0.08)), 0.2, 0.1, 0.01), [ new LayeredPainter([tShore, tHill], [12]), new SmoothElevationPainter(ELEVATION_SET, heightIsland, 8), paintClass(clIsland), unPaintClass(clWater) ], [stayClasses (clWater, 8)], 1, 100); log("Creating cyprus mines..."); var mines = [ new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock), new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal), new SimpleGroup([new SimpleObject(oStoneSmall, 2, 5, 1, 3)], true, clRock) ]; for (let mine of mines) createObjectGroups( mine, 0, [ stayClasses(clIsland, 9), avoidClasses(clForest, 1, clRock, 8, clMetal, 8) ], scaleByMapSize(4, 16)); 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, 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 ); Engine.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 ); Engine.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 ); Engine.SetProgress(90); var stragglerTreeConfig = [ [1, avoidClasses(clForest, 0, clWater, 4, clPlayer, 8, clMetal, 6, clHill, 1)], [3, [stayClasses(clIsland, 9), avoidClasses(clRock, 4, clMetal, 4)]] ]; for (let [amount, constraint] of stragglerTreeConfig) createStragglerTrees( [oDatePalm, oSDatePalm, oCarob, oFanPalm, oPoplar, oCypress], constraint, clForest, amount * stragglerTrees); 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); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/river_archipelago.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/river_archipelago.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/river_archipelago.js (revision 21000) @@ -1,500 +1,500 @@ Engine.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 oPalm1 = "gaia/flora_tree_palm_tropic"; const oPalm2 = "gaia/flora_tree_palm_tropical"; 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 oTiger = "gaia/fauna_tiger"; const oBoar = "gaia/fauna_boar"; const oPeacock = "gaia/fauna_peacock"; const oBush = "gaia/flora_bush_berry"; const oSpearman = "units/maur_infantry_spearman_b"; const oArcher = "units/maur_infantry_archer_b"; const oArcherElephant = "units/maur_elephant_archer_b"; 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 pForestP1 = [tForestFloor + TERRAIN_SEPARATOR + oPalm1, tForestFloor]; const pForestP2 = [tForestFloor + TERRAIN_SEPARATOR + oPalm2, tForestFloor]; const heightSeaGround = -8; const heightLand = 3; const heightHill = 25; var g_Map = new RandomMap(heightSeaGround, tGrass); const numPlayers = getNumPlayers(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -var clPlayer = createTileClass(); -var clPlayerTerritory = 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 clGaia = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clPlayerTerritory = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clGaia = g_Map.createTileClass(); var clStrip = []; var startAngle = randomAngle(); var connectPlayers = randBool(); // Map layout var stripWidthsLeft = connectPlayers ? [[0.03, 0.09], [0.14, 0.25], [0.36, 0.46]] : [[0, 0.06], [0.12, 0.23], [0.33, 0.43]]; // Mirror var stripWidthsRight = clone(stripWidthsLeft); stripWidthsRight.reverse(); stripWidthsRight = stripWidthsRight.map(strip => [1 - strip[1], 1 - strip[0]]); var stripWidths = stripWidthsLeft.concat(stripWidthsRight); log("Creating strips..."); for (let i = 0; i < stripWidths.length; ++i) { - clStrip[i] = createTileClass(); + clStrip[i] = g_Map.createTileClass(); let isPlayerStrip = i == 2 || i == 3; for (let j = 0; j < scaleByMapSize(20, 100); ++j) { let position = new Vector2D( randFloat(mapBounds.bottom, mapBounds.top), fractionToTiles(randFloat(...stripWidths[i]))).rotateAround(startAngle, mapCenter).round(); createArea( new ChainPlacer( 1, Math.floor(scaleByMapSize(3, connectPlayers && isPlayerStrip ? 8 : 7)), Math.floor(scaleByMapSize(30, 60)), 1, position), [ new LayeredPainter([tGrass, tGrass], [2]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 3), paintClass(clStrip[i]) ]); } } Engine.SetProgress(20); var playerPosition = playerPlacementLine(startAngle, mapCenter, fractionToTiles(1 - stripWidthsLeft[2][0] - stripWidthsLeft[2][1])); // Either left vs right or top vs bottom var playerIDs = randBool() ? sortAllPlayers() : primeSortAllPlayers(); log("Ensuring player territory..."); var playerRadius = scaleByMapSize(12, 20); for (let i = 0; i < numPlayers; ++i) createArea( new ChainPlacer(1, 6, 40, 1, playerPosition[i], 0, [Math.floor(playerRadius)]), [ new LayeredPainter([tGrass, tGrass, tGrass], [1, 4]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 4), paintClass(clPlayerTerritory) ]); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "baseResourceConstraint": stayClasses(clPlayerTerritory, 4), "Walls": "towers", "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad, "radius": playerRadius / 3 }, "Chicken": { "template": oPeacock }, "Berries": { "template": oBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree, "count": 40 } // No decoratives }); Engine.SetProgress(35); paintTerrainBasedOnHeight(-10, 0, 1, tWater); paintTileClassBasedOnHeight(-10, 0, 1, clWater); paintTerrainBasedOnHeight(1, 2.8, 1, tShoreBlend); paintTerrainBasedOnHeight(0, 1, 1, tShore); Engine.SetProgress(40); if (!isNomad()) { log("Creating gaia..."); for (let i = 0; i < 2; ++i) for (let j = 0; j < scaleByMapSize(1, 8); ++j) createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(oSpearman, 8, 12, 2, 3), new SimpleObject(oArcher, 8, 12, 2, 3), new SimpleObject(oArcherElephant, 2, 3, 4, 5) ], true, clGaia), 0, [ avoidClasses( clWater, 2, clForest, 1, clPlayerTerritory, 0, clHill, 1, clGaia, 15), stayClasses(clStrip[i == 0 ? 0 : stripWidths.length - 1], 1) ], scaleByMapSize(5, 10), 50); } log("Creating hills..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.1), [ new LayeredPainter([tCliff, tGrass], [3]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 3), paintClass(clHill) ], [ avoidClasses( clPlayerTerritory, 0, clHill, 5, clGaia, 1, clWater, 2) ], scaleByMapSize(1, 5)); log("Creating bumps..."); createBumps(avoidClasses(clPlayer, 8, clWater, 2), scaleByMapSize(20, 150), 2, 8, 4, 1, 4); Engine.SetProgress(50); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(1000, 4000, 0.7); var types = [ [[tGrass, tGrass, tGrass, tGrass, pForestD], [tGrass, tGrass, tGrass, pForestD]], [[tGrass, tGrass, tGrass, tGrass, pForestP1], [tGrass, tGrass, tGrass, pForestP1]], [[tGrass, tGrass, tGrass, tGrass, pForestP2], [tGrass, tGrass, tGrass, pForestP2]] ]; var size = forestTrees / (scaleByMapSize(3, 6) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ChainPlacer( 1, Math.floor(scaleByMapSize(3, 5)), forestTrees / (num * Math.floor(scaleByMapSize(2, 4))), 0.5), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses( clPlayer, 12, clForest, 6, clHill, 0, clGaia, 1, clWater, 2), num); createStragglerTrees( [oTree, oPalm1, oPalm2], avoidClasses( clWater, 5, clForest, 1, clHill, 1, clPlayer, 8, clBaseResource, 4, clGaia, 1, clMetal, 4, clRock, 4), clForest, stragglerTrees); Engine.SetProgress(60); log("Creating grass patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([tGrassC, tGrassA, tGrassB], [2, 1]), paintClass(clDirt) ], avoidClasses( clWater, 8, clForest, 0, clHill, 0, clGaia, 1, clPlayerTerritory, 0, clDirt, 16), scaleByMapSize(20, 80)); log("Creating dirt patches..."); for (let size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), [ new LayeredPainter([tPlants, tPlants], [1]), paintClass(clDirt) ], avoidClasses( clWater, 8, clForest, 0, clHill, 0, clGaia, 1, clPlayerTerritory, 0, clDirt, 16), scaleByMapSize(20, 80)); log("Creating stone mines..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4) ], true, clRock), 0, avoidClasses( clWater, 3, clForest, 1, clPlayerTerritory, 0, clGaia, 1, clRock, 10, clHill, 1), 9 * scaleByMapSize(1, 4), 100); log("Creating small stone mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oStoneSmall, 2, 5, 1, 3)], true, clRock), 0, avoidClasses( clWater, 4, clForest, 1, clPlayerTerritory, 0, clGaia, 1, clRock, 10, clHill, 1), 9 * scaleByMapSize(1, 4), 100); log("Creating metal mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal), 0, avoidClasses( clWater, 4, clForest, 1, clPlayerTerritory, 0, clGaia, 1, clMetal, 10, clRock, 5, clHill, 1), 9 * scaleByMapSize(1, 4), 100); log("Creating small decorative rocks..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aRockMedium, 1, 3, 0, 1)], true), 0, avoidClasses( clWater, 2, clForest, 1, clGaia, 1, clPlayer, 8, clBaseResource, 4, clHill, 0), 3 * scaleByMapSize(16, 262), 50); log("Creating large decorative rocks..."); createObjectGroupsDeprecated( new SimpleGroup([ new SimpleObject(aRockLarge, 1, 2, 0, 1), new SimpleObject(aRockMedium, 1, 3, 0, 2) ], true), 0, avoidClasses( clWater, 2, clForest, 1, clGaia, 1, clPlayer, 8, clBaseResource, 4, clHill, 0), 3 * scaleByMapSize(8, 131), 50); log("Creating small grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aBush1, 1, 2, 0, 1, -Math.PI / 8, Math.PI / 8)]), 0, avoidClasses( clWater, 4, clHill, 2, clPlayer, 8, clGaia, 1, clBaseResource, 4, clDirt, 0), 8 * scaleByMapSize(13, 200)); Engine.SetProgress(70); log("Creating large grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup([ new SimpleObject(aBush2, 2, 4, 0, 1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aBush1, 3, 6, 1.2, 2.5, -Math.PI / 8, Math.PI / 8) ]), 0, avoidClasses( clWater, 4, clHill, 2, clGaia, 1, clPlayer, 8, clBaseResource, 4, clDirt, 1, clForest, 0), 8 * scaleByMapSize(13, 200)); Engine.SetProgress(85); log("Creating bushes..."); createObjectGroupsDeprecated( new SimpleGroup([ new SimpleObject(aBush3, 1, 2, 0, 2), new SimpleObject(aBush2, 2, 4, 0, 2) ]), 0, avoidClasses( clWater, 4, clHill, 1, clPlayerTerritory, 0, clGaia, 1, clDirt, 1), 8 * scaleByMapSize(13, 200), 50); log("Creating deer..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oDeer, 5, 7, 0, 4)], true, clFood), 0, avoidClasses( clWater, 4, clForest, 0, clPlayerTerritory, 0, clGaia, 1, clHill, 1, clFood, 20), 3 * numPlayers, 50); log("Creating boar..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oBoar, 2, 4, 0, 4)], true, clFood), 0, avoidClasses( clWater, 4, clForest, 0, clPlayerTerritory, 0, clGaia, 1, clHill, 1, clFood, 20), 3 * numPlayers, 50); log("Creating tigers..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oTiger, 1, 1, 0, 4)], true, clFood), 0, avoidClasses( clWater, 4, clForest, 0, clPlayerTerritory, 0, clGaia, 1, clHill, 1, clFood, 20), 3 * numPlayers, 50); Engine.SetProgress(95); log("Creating berry bush..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oBush, 5, 7, 0, 4)], true, clFood), 0, avoidClasses( clWater, 4, clForest, 0, clPlayerTerritory, 0, clGaia, 1, clHill, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50); log("Creating fish..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oFish, 2, 3, 0, 2)], true, clFood), 0, [avoidClasses(clFood, 15), stayClasses(clWater, 4)], 200, 100); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setSunColor(0.6, 0.6, 0.6); setSunElevation(Math.PI/ 3); setWaterColor(0.424, 0.534, 0.639); setWaterTint(0.369, 0.765, 0.745); setWaterWaviness(1.0); setWaterType("default"); setWaterMurkiness(0.35); setFogFactor(0.03); setFogThickness(0.2); setPPEffect("hdr"); setPPContrast(0.7); setPPSaturation(0.65); setPPBloom(0.6); setSkySet("stratus"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/rmgen2/setup.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/rmgen2/setup.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/rmgen2/setup.js (revision 21000) @@ -1,470 +1,470 @@ var g_Amounts = { "scarce": 0.2, "few": 0.5, "normal": 1, "many": 1.75, "tons": 3 }; var g_Mixes = { "same": 0, "similar": 0.1, "normal": 0.25, "varied": 0.5, "unique": 0.75 }; var g_Sizes = { "tiny": 0.5, "small": 0.75, "normal": 1, "big": 1.25, "huge": 1.5, }; var g_AllAmounts = Object.keys(g_Amounts); var g_AllMixes = Object.keys(g_Mixes); var g_AllSizes = Object.keys(g_Sizes); var g_DefaultTileClasses = [ "animals", "baseResource", "berries", "bluff", "bluffSlope", "dirt", "fish", "food", "forest", "hill", "land", "map", "metal", "mountain", "plateau", "player", "prop", "ramp", "rock", "settlement", "spine", "valley", "water" ]; var g_TileClasses; /** * Adds an array of elements to the map. */ function addElements(elements) { for (let element of elements) element.func( [ avoidClasses.apply(null, element.avoid), stayClasses.apply(null, element.stay || null) ], pickSize(element.sizes), pickMix(element.mixes), pickAmount(element.amounts), element.baseHeight || 0); } /** * Converts "amount" terms to numbers. */ function pickAmount(amounts) { let amount = pickRandom(amounts); if (amount in g_Amounts) return g_Amounts[amount]; return g_Amounts.normal; } /** * Converts "mix" terms to numbers. */ function pickMix(mixes) { let mix = pickRandom(mixes); if (mix in g_Mixes) return g_Mixes[mix]; return g_Mixes.normal; } /** * Converts "size" terms to numbers. */ function pickSize(sizes) { let size = pickRandom(sizes); if (size in g_Sizes) return g_Sizes[size]; return g_Sizes.normal; } /** * Choose starting locations for all players. * * @param {string} type - "radial", "line", "stronghold", "random" * @param {number} distance - radial distance from the center of the map * @param {number} groupedDistance - space between players within a team * @param {number} startAngle - determined by the map that might want to place something between players * @returns {Array|undefined} - If successful, each element is an object that contains id, angle, x, z for each player */ function addBases(type, distance, groupedDistance, startAngle) { let playerIDs = sortAllPlayers(); let teamsArray = getTeamsArray(); switch(type) { case "line": return placeLine(teamsArray, distance, groupedDistance, startAngle); case "radial": return placeRadial(playerIDs, distance, startAngle); case "random": return placeRandom(playerIDs) || placeRadial(playerIDs, distance, startAngle); case "stronghold": return placeStronghold(teamsArray, distance, groupedDistance, startAngle); default: warn("Unknown base placement type:" + type); return undefined; } } /** * Create the base for a single player. * * @param {Object} player - contains id, angle, x, z * @param {boolean} walls - Whether or not iberian gets starting walls */ function createBase(player, walls = true) { placePlayerBase({ "playerID": player.id, "playerPosition": player.position, "PlayerTileClass": g_TileClasses.player, "BaseResourceClass": g_TileClasses.baseResource, "Walls": g_Map.getSize() > 192 && walls, "CityPatch": { "outerTerrain": g_Terrains.roadWild, "innerTerrain": g_Terrains.road, "painters": [ paintClass(g_TileClasses.player) ] }, "Chicken": { "template": g_Gaia.chicken }, "Berries": { "template": g_Gaia.fruitBush }, "Mines": { "types": [ { "template": g_Gaia.metalLarge }, { "template": g_Gaia.stoneLarge } ] }, "Trees": { "template": g_Gaia.tree1, "count": currentBiome() == "savanna" ? 5 : 15 }, "Decoratives": { "template": g_Decoratives.grassShort } }); } /** * Return an array where each element is an array of playerIndices of a team. */ function getTeamsArray() { var playerIDs = sortAllPlayers(); var numPlayers = getNumPlayers(); // Group players by team var teams = []; for (let i = 0; i < numPlayers; ++i) { let team = getPlayerTeam(playerIDs[i]); if (team == -1) continue; if (!teams[team]) teams[team] = []; teams[team].push(playerIDs[i]); } // Players without a team get a custom index for (let i = 0; i < numPlayers; ++i) if (getPlayerTeam(playerIDs[i]) == -1) teams.push([playerIDs[i]]); // Remove unused indices return teams.filter(team => true); } /** * Choose a random pattern for placing the bases of the players. */ function randomStartingPositionPattern(teamsArray) { var formats = ["radial"]; var mapSize = g_Map.getSize(); var numPlayers = getNumPlayers(); // Enable stronghold if we have a few teams and a big enough map if (teamsArray.length >= 2 && numPlayers >= 4 && mapSize >= 256) formats.push("stronghold"); // Enable random if we have enough teams or enough players on a big enough map if (mapSize >= 256 && (teamsArray.length >= 3 || numPlayers > 4)) formats.push("random"); // Enable line if we have enough teams and players on a big enough map if (teamsArray.length >= 2 && numPlayers >= 4 && mapSize >= 384) formats.push("line"); return { "setup": pickRandom(formats), "distance": fractionToTiles(randFloat(0.2, 0.35)), "separation": fractionToTiles(randFloat(0.05, 0.1)) }; } /** * Place teams in a line-pattern. * * @param {Array} playerIDs - typically randomized indices of players of a single team * @param {number} distance - radial distance from the center of the map * @param {number} groupedDistance - distance between players * @param {number} startAngle - determined by the map that might want to place something between players. * * @returns {Array} - contains id, angle, x, z for every player */ function placeLine(teamsArray, distance, groupedDistance, startAngle) { let players = []; let mapCenter = g_Map.getCenter(); let dist = fractionToTiles(0.45); for (let i = 0; i < teamsArray.length; ++i) { var safeDist = distance; if (distance + teamsArray[i].length * groupedDistance > dist) safeDist = dist - teamsArray[i].length * groupedDistance; var teamAngle = startAngle + (i + 1) * 2 * Math.PI / teamsArray.length; // Create player base for (let p = 0; p < teamsArray[i].length; ++p) { players[teamsArray[i][p]] = { "id": teamsArray[i][p], "position": Vector2D.add(mapCenter, new Vector2D(safeDist + p * groupedDistance, 0).rotate(-teamAngle)).round() }; createBase(players[teamsArray[i][p]], false); } } return players; } /** * Place players in a circle-pattern. * * @param {Array} playerIDs - order of playerIDs to be placed * @param {number} distance - radial distance from the center of the map * @param {number} startAngle - determined by the map that might want to place something between players */ function placeRadial(playerIDs, distance, startAngle) { let mapCenter = g_Map.getCenter(); let players = []; let numPlayers = getNumPlayers(); for (let i = 0; i < numPlayers; ++i) { let angle = startAngle + i * 2 * Math.PI / numPlayers; players[i] = { "id": playerIDs[i], "position": Vector2D.add(mapCenter, new Vector2D(distance, 0).rotate(-angle)).round() }; createBase(players[i]); } return players; } /** * Choose arbitrary starting locations. */ function placeRandom(playerIDs) { var locations = []; var attempts = 0; var resets = 0; var mapCenter = g_Map.getCenter(); for (let i = 0; i < getNumPlayers(); ++i) { let position = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(randFloat(0, 0.42)), 0).rotate(randomAngle())).round(); // Minimum distance between initial bases must be a quarter of the map diameter if (locations.some(loc => loc.distanceTo(position) < fractionToTiles(0.25))) { --i; ++attempts; // Reset if we're in what looks like an infinite loop if (attempts > 100) { locations = []; i = -1; attempts = 0; ++resets; // If we only pick bad locations, stop trying to place randomly if (resets == 100) return undefined; } continue; } locations[i] = position; } let players = groupPlayersByLocations(playerIDs, locations); for (let player of players) createBase(player); return players; } /** * Pick locations from the given set so that teams end up grouped. * * @param {Array} playerIDs - sorted by teams. * @param {Array} locations - array of Vector2D of possible starting locations. */ function groupPlayersByLocations(playerIDs, locations) { playerIDs = sortPlayers(playerIDs); let minDist = Infinity; let minLocations; // Of all permutations of starting locations, find the one where // the sum of the distances between allies is minimal, weighted by teamsize. heapsPermute(shuffleArray(locations).slice(0, playerIDs.length), v => v.clone(), permutation => { let dist = 0; let teamDist = 0; let teamSize = 0; for (let i = 1; i < playerIDs.length; ++i) { let team1 = getPlayerTeam(playerIDs[i - 1]); let team2 = getPlayerTeam(playerIDs[i]); ++teamSize; if (team1 != -1 && team1 == team2) teamDist += permutation[i - 1].distanceTo(permutation[i]); else { dist += teamDist / teamSize; teamDist = 0; teamSize = 0; } } if (teamSize) dist += teamDist / teamSize; if (dist < minDist) { minDist = dist; minLocations = permutation; } }); let players = []; for (let i = 0; i < playerIDs.length; ++i) players[i] = { "id": playerIDs[i], "position": minLocations[i] }; return players; } /** * Place given players in a stronghold-pattern. * * @param teamsArray - each item is an array of playerIDs placed per stronghold * @param distance - radial distance from the center of the map * @param groupedDistance - distance between neighboring players * @param {number} startAngle - determined by the map that might want to place something between players */ function placeStronghold(teamsArray, distance, groupedDistance, startAngle) { var players = []; var mapCenter = g_Map.getCenter(); for (let i = 0; i < teamsArray.length; ++i) { var teamAngle = startAngle + (i + 1) * 2 * Math.PI / teamsArray.length; var teamPosition = Vector2D.add(mapCenter, new Vector2D(distance, 0).rotate(-teamAngle)); var teamGroupDistance = groupedDistance; // If we have a team of above average size, make sure they're spread out if (teamsArray[i].length > 4) teamGroupDistance = Math.max(fractionToTiles(0.08), groupedDistance); // If we have a solo player, place them on the center of the team's location if (teamsArray[i].length == 1) teamGroupDistance = fractionToTiles(0); // TODO: Ensure players are not placed outside of the map area, similar to placeLine // Create player base for (var p = 0; p < teamsArray[i].length; ++p) { var angle = startAngle + (p + 1) * 2 * Math.PI / teamsArray[i].length; players[teamsArray[i][p]] = { "id": teamsArray[i][p], "position": Vector2D.add(teamPosition, new Vector2D(teamGroupDistance, 0).rotate(-angle)).round() }; createBase(players[teamsArray[i][p]], false); } } return players; } /** * Creates tileClass for the default classes and every class given. * * @param {Array} newClasses * @returns {Object} - maps from classname to ID */ function initTileClasses(newClasses) { var classNames = g_DefaultTileClasses; if (newClasses !== undefined) classNames = classNames.concat(newClasses); g_TileClasses = {}; for (var className of classNames) - g_TileClasses[className] = createTileClass(); + g_TileClasses[className] = g_Map.createTileClass(); } Index: ps/trunk/binaries/data/mods/public/maps/random/schwarzwald.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/schwarzwald.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/schwarzwald.js (revision 21000) @@ -1,320 +1,320 @@ Engine.LoadLibrary('rmgen'); Engine.LoadLibrary("heightmap"); setSkySet("fog"); setFogFactor(0.35); setFogThickness(0.19); setWaterColor(0.501961, 0.501961, 0.501961); setWaterTint(0.25098, 0.501961, 0.501961); setWaterWaviness(0.5); setWaterType("clap"); setWaterMurkiness(0.75); setPPSaturation(0.37); setPPContrast(0.4); setPPBrightness(0.4); setPPEffect("hdr"); setPPBloom(0.4); var oStoneLarge = 'gaia/geology_stonemine_alpine_quarry'; var oMetalLarge = 'gaia/geology_metal_alpine_slabs'; var oFish = "gaia/fauna_fish"; var aGrass = 'actor|props/flora/grass_soft_small_tall.xml'; var aGrassShort = 'actor|props/flora/grass_soft_large.xml'; var aRockLarge = 'actor|geology/stone_granite_med.xml'; var aRockMedium = 'actor|geology/stone_granite_med.xml'; var aBushMedium = 'actor|props/flora/bush_medit_me.xml'; var aBushSmall = 'actor|props/flora/bush_medit_sm.xml'; var aReeds = 'actor|props/flora/reeds_pond_lush_b.xml'; var terrainPrimary = ["temp_grass_plants", "temp_plants_bog"]; var terrainWood = ['alpine_forrestfloor|gaia/flora_tree_oak', 'alpine_forrestfloor|gaia/flora_tree_pine']; var terrainWoodBorder = ['new_alpine_grass_mossy|gaia/flora_tree_oak', 'alpine_forrestfloor|gaia/flora_tree_pine', 'temp_grass_long|gaia/flora_bush_temperate', 'temp_grass_clovers|gaia/flora_bush_berry', 'temp_grass_clovers_2|gaia/flora_bush_grapes', 'temp_grass_plants|gaia/fauna_deer', 'temp_grass_plants|gaia/fauna_rabbit', 'new_alpine_grass_dirt_a']; var terrainBase = ['temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_grass_plants|gaia/fauna_sheep']; var terrainBaseBorder = ['temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_d', 'temp_grass_plants', 'temp_plants_bog', 'temp_grass_plants', 'temp_grass_plants']; var baseTex = ['temp_road', 'temp_road_overgrown']; var terrainPath = ['temp_road', 'temp_road_overgrown']; var tWater = ['dirt_brown_d']; var tWaterBorder = ['dirt_brown_d']; const heightLand = 1; const heightOffsetPath = -0.1; var g_Map = new RandomMap(heightLand, terrainPrimary); -var clPlayer = createTileClass(); -var clPath = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clMetal = createTileClass(); -var clRock = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clOpen = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clPath = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clOpen = g_Map.createTileClass(); var mapSize = g_Map.getSize(); var mapCenter = g_Map.getCenter(); var mapRadius = mapSize/2; var numPlayers = getNumPlayers(); var baseRadius = 15; var minPlayerRadius = Math.min(mapRadius - 1.5 * baseRadius, 5/8 * mapRadius); var maxPlayerRadius = Math.min(mapRadius - baseRadius, 3/4 * mapRadius); var playerPosition = []; var playerAngleStart = randomAngle(); var playerAngleAddAvrg = 2 * Math.PI / numPlayers; var playerAngleMaxOff = playerAngleAddAvrg/4; var resourceRadius = fractionToTiles(1/3); // Setup woods // For large maps there are memory errors with too many trees. A density of 256*192/mapArea works with 0 players. // Around each player there is an area without trees so with more players the max density can increase a bit. var maxTreeDensity = Math.min(256 * (192 + 8 * numPlayers) / Math.square(mapSize), 1); // Has to be tweeked but works ok var bushChance = 1/3; // 1 means 50% chance in deepest wood, 0.5 means 25% chance in deepest wood // Set height limits and water level by map size // Set target min and max height depending on map size to make average steepness about the same on all map sizes var heightRange = {'min': MIN_HEIGHT * (g_Map.size + 512) / 8192, 'max': MAX_HEIGHT * (g_Map.size + 512) / 8192, 'avg': (MIN_HEIGHT * (g_Map.size + 512) +MAX_HEIGHT * (g_Map.size + 512))/16384}; // Set average water coverage var averageWaterCoverage = 1/5; // NOTE: Since erosion is not predictable actual water coverage might vary much with the same values var heightSeaGround = -MIN_HEIGHT + heightRange.min + averageWaterCoverage * (heightRange.max - heightRange.min); var heightSeaGroundAdjusted = heightSeaGround + MIN_HEIGHT; setWaterHeight(heightSeaGround); // Setting a 3x3 Grid as initial heightmap var initialReliefmap = [[heightRange.max, heightRange.max, heightRange.max], [heightRange.max, heightRange.min, heightRange.max], [heightRange.max, heightRange.max, heightRange.max]]; setBaseTerrainDiamondSquare(heightRange.min, heightRange.max, initialReliefmap); for (var i = 0; i < 5; i++) globalSmoothHeightmap(); rescaleHeightmap(heightRange.min, heightRange.max); var heighLimits = [ heightRange.min + 1/3 * (heightSeaGroundAdjusted - heightRange.min), // 0 Deep water heightRange.min + 2/3 * (heightSeaGroundAdjusted - heightRange.min), // 1 Medium Water heightRange.min + (heightSeaGroundAdjusted - heightRange.min), // 2 Shallow water heightSeaGroundAdjusted + 1/8 * (heightRange.max - heightSeaGroundAdjusted), // 3 Shore heightSeaGroundAdjusted + 2/8 * (heightRange.max - heightSeaGroundAdjusted), // 4 Low ground heightSeaGroundAdjusted + 3/8 * (heightRange.max - heightSeaGroundAdjusted), // 5 Player and path height heightSeaGroundAdjusted + 4/8 * (heightRange.max - heightSeaGroundAdjusted), // 6 High ground heightSeaGroundAdjusted + 5/8 * (heightRange.max - heightSeaGroundAdjusted), // 7 Lower forest border heightSeaGroundAdjusted + 6/8 * (heightRange.max - heightSeaGroundAdjusted), // 8 Forest heightSeaGroundAdjusted + 7/8 * (heightRange.max - heightSeaGroundAdjusted), // 9 Upper forest border heightSeaGroundAdjusted + (heightRange.max - heightSeaGroundAdjusted)]; // 10 Hilltop var startLocations = getStartLocationsByHeightmap({'min': heighLimits[4], 'max': heighLimits[5]}); var playerHeight = (heighLimits[4] + heighLimits[5]) / 2; for (let i = 0; i < numPlayers; ++i) { playerPosition[i] = Vector2D.add( mapCenter, new Vector2D(randFloat(minPlayerRadius, maxPlayerRadius), 0).rotate( -((playerAngleStart + i * playerAngleAddAvrg + randFloat(0, playerAngleMaxOff)) % (2 * Math.PI)))).round(); rectangularSmoothToHeight(playerPosition[i], 20, 20, playerHeight, 0.8); } placePlayerBases({ "PlayerPlacement": [sortAllPlayers(), playerPosition], "BaseResourceClass": clBaseResource, "Walls": false, // player class painted below "CityPatch": { "radius": 0.8 * baseRadius, "smoothness": 1/8, "painters": [ new TerrainPainter([baseTex], [baseRadius/4, baseRadius/4]), paintClass(clPlayer) ] }, // No chicken "Berries": { "template": "gaia/flora_bush_berry", "minCount": 2, "maxCount": 2, "minDist": 10, "maxDist": 10 }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ], "distance": 15, "minAngle": Math.PI / 2, "maxAngle": Math.PI }, "Trees": { "template": "gaia/flora_tree_oak_large", "count": 2 } }); log("Creating mines..."); for (let [minHeight, maxHeight] of [[heighLimits[3], (heighLimits[4] + heighLimits[3]) / 2], [(heighLimits[5] + heighLimits[6]) / 2, heighLimits[7]]]) for (let [template, tileClass] of [[oStoneLarge, clRock], [oMetalLarge, clMetal]]) createObjectGroups( new SimpleGroup([new SimpleObject(template, 1, 1, 0, 4)], true, tileClass), 0, [ new HeightConstraint(minHeight, maxHeight), avoidClasses(clForest, 4, clPlayer, 20, clMetal, 40, clRock, 40) ], scaleByMapSize(2, 8), 100, false); Engine.SetProgress(50); log("Painting textures..."); var betweenShallowAndShore = (heighLimits[3] + heighLimits[2]) / 2; createArea( new HeightPlacer(Elevation_IncludeMin_IncludeMax, heighLimits[2], betweenShallowAndShore), new LayeredPainter([terrainBase, terrainBaseBorder], [5])); paintTileClassBasedOnHeight(heighLimits[2], betweenShallowAndShore, 1, clOpen); createArea( new HeightPlacer(Elevation_IncludeMin_IncludeMax, heightRange.min, heighLimits[2]), new LayeredPainter([tWaterBorder, tWater], [2])); paintTileClassBasedOnHeight(heightRange.min, heighLimits[2], 1, clWater); Engine.SetProgress(60); log("Painting paths..."); var pathBlending = numPlayers <= 4; for (let i = 0; i < numPlayers + (pathBlending ? 1 : 0); ++i) for (let j = pathBlending ? 0 : i + 1; j < numPlayers + 1; ++j) { let pathStart = i < numPlayers ? playerPosition[i] : mapCenter; let pathEnd = j < numPlayers ? playerPosition[j] : mapCenter; createArea( new RandomPathPlacer(pathStart, pathEnd, 1.75, baseRadius / 2, pathBlending), [ new TerrainPainter(terrainPath), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetPath, 1), paintClass(clPath) ], avoidClasses(clPath, 0, clOpen, 0 ,clWater, 4, clBaseResource, 4)); } Engine.SetProgress(75); log("Creating decoration..."); 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [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(clForest, 1, clPlayer, 0, clPath, 3, clWater, 3)); Engine.SetProgress(80); log("Growing fish..."); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 100 * numPlayers ], [avoidClasses(clFood, 5), stayClasses(clWater, 4)], clFood); Engine.SetProgress(85); log("Planting reeds..."); var types = [aReeds]; for (let type of types) createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(type, 1, 1, 0, 0)], true), 0, borderClasses(clWater, 0, 6), scaleByMapSize(1, 2) * 1000, 1000); Engine.SetProgress(90); log("Planting trees..."); for (var x = 0; x < mapSize; x++) for (var z = 0;z < mapSize;z++) { let position = new Vector2D(x, z); if (!g_Map.validTile(position)) continue; // The 0.5 is a correction for the entities placed on the center of tiles let radius = Vector2D.add(position, new Vector2D(0.5, 0.5)).distanceTo(mapCenter); var minDistToSL = mapSize; for (let i = 0; i < numPlayers; ++i) minDistToSL = Math.min(minDistToSL, position.distanceTo(playerPosition[i])); // Woods tile based var tDensFactSL = Math.max(Math.min((minDistToSL - baseRadius) / baseRadius, 1), 0); var tDensFactRad = Math.abs((resourceRadius - radius) / resourceRadius); var tDensActual = (maxTreeDensity * tDensFactSL * tDensFactRad)*0.75; if (!randBool(tDensActual)) continue; let border = tDensActual < randFloat(0, bushChance * maxTreeDensity); createArea( new RectPlacer(x, z, x, z), [ new TerrainPainter(border ? terrainWoodBorder : terrainWood), paintClass(clForest) ], border ? avoidClasses(clPath, 1, clOpen, 2, clWater, 3, clMetal, 4, clRock, 4) : avoidClasses(clPath, 2, clOpen, 3, clWater, 4, clMetal, 4, clRock, 4)); } placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clFood, 2, clMetal, 4, clRock, 4)); Engine.SetProgress(100); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/the_nile.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/the_nile.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/the_nile.js (revision 21000) @@ -1,411 +1,411 @@ Engine.LoadLibrary("rmgen"); var tPrimary = "desert_sand_dunes_100"; var tCity = "desert_city_tile"; var tCityPlaza = "desert_city_tile_plaza"; var tFineSand = "desert_sand_smooth"; 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 oGazelle = "gaia/fauna_gazelle"; var oGoat = "gaia/fauna_goat"; 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 oWoodTreasure = "gaia/special_treasure_wood"; var oFoodTreasure = "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 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"; var pForest = [tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERRAIN_SEPARATOR + oSDatePalm, tForestFloor]; const heightLand = 1; const heightShore = 2; const heightPonds = -7; const heightSeaGround = -3; const heightOffsetBump = 2; var g_Map = new RandomMap(heightLand, tPrimary); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); var aPlants = mapSize < 256 ? "actor|props/flora/grass_tropical.xml" : "actor|props/flora/grass_tropic_field_tall.xml"; var numPlayers = getNumPlayers(); -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 clGrass = createTileClass(); -var clDesert = createTileClass(); -var clPond = createTileClass(); -var clShore = createTileClass(); -var clTreasure = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clGrass = g_Map.createTileClass(); +var clDesert = g_Map.createTileClass(); +var clPond = g_Map.createTileClass(); +var clShore = g_Map.createTileClass(); +var clTreasure = g_Map.createTileClass(); var desertWidth = fractionToTiles(0.25); var startAngle = randomAngle(); placePlayerBases({ "PlayerPlacement": playerPlacementRiver(startAngle, fractionToTiles(0.4)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tCityPlaza, "innerTerrain": tCity }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oDatePalm, "count": 2 }, "Decoratives": { "template": aBush1 } }); Engine.SetProgress(30); const riverTextures = [ { "left": fractionToTiles(0), "right": fractionToTiles(0.04), "terrain": tLush, "tileClass": clShore }, { "left": fractionToTiles(0.04), "right": fractionToTiles(0.06), "terrain": tSLush, "tileClass": clShore }, { "left": fractionToTiles(0.06), "right": fractionToTiles(0.09), "terrain": tSDry, "tileClass": clShore }, { "left": fractionToTiles(0.25), "right": fractionToTiles(0.5), "tileClass": clDesert } ]; const plantFrequency = 2; var plantID = 0; paintRiver({ "parallel": true, "start": new Vector2D(mapCenter.x, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(mapCenter.x, mapBounds.bottom).rotateAround(startAngle, mapCenter), "width": fractionToTiles(0.1), "fadeDist": scaleByMapSize(3, 12), "deviation": 0.5, "heightRiverbed": heightSeaGround, "heightLand": heightShore, "meanderShort": 12, "meanderLong": 50, "waterFunc": (position, height, riverFraction) => { addToClass(position.x, position.y, clWater); createTerrain(tShore).place(position); // Place river bushes if (height <= -0.2 || height >= 0.1) return; if (plantID % plantFrequency == 0) { plantID = 0; placeObject(position.x, position.y, aPlants, 0, randomAngle()); } ++plantID; }, "landFunc": (position, shoreDist1, shoreDist2) => { for (let riv of riverTextures) if (riv.left < +shoreDist1 && +shoreDist1 < riv.right || riv.left < -shoreDist2 && -shoreDist2 < riv.right) { addToClass(position.x, position.y, riv.tileClass); if (riv.terrain) createTerrain(riv.terrain).place(position); } } }); Engine.SetProgress(40); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), avoidClasses(clWater, 2, clPlayer, 6), scaleByMapSize(100, 200)); log("Creating ponds..."); var numLakes = Math.round(scaleByMapSize(1, 4) * numPlayers / 2); var waterAreas = createAreas( new ClumpPlacer(scaleByMapSize(2, 5) * 50, 0.8, 0.1, 10), [ new LayeredPainter([tShore, tShore, tShore], [1, 1]), new SmoothElevationPainter(ELEVATION_SET, heightPonds, 4), paintClass(clPond) ], avoidClasses(clPlayer, 25, clWater, 20, clPond, 10), numLakes); log("Creating reeds..."); createObjectGroupsByAreasDeprecated( new SimpleGroup([new SimpleObject(aReeds, 1, 3, 0, 1)], true), 0, stayClasses(clPond, 1), numLakes, 100, waterAreas); log("Creating lillies..."); createObjectGroupsByAreasDeprecated( new SimpleGroup([new SimpleObject(aLillies, 1, 3, 0, 1)], true), 0, stayClasses(clPond, 1), numLakes, 100, waterAreas); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(700, 3500, 0.5); var num = scaleByMapSize(10,30); createAreas( new ClumpPlacer(forestTrees / num, 0.15, 0.1, 0.5), [ new TerrainPainter([pForest, tForestFloor]), paintClass(clForest) ], avoidClasses(clPlayer, 19, clForest, 4, clWater, 1, clDesert, 5, clPond, 2, clBaseResource, 3), num, 50); Engine.SetProgress(50); log("Creating grass patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter( [[tGrass, tGrassSand50], [tGrassSand50, tGrassSand25], [tGrassSand25, tGrass]], [1, 1]), paintClass(clDirt) ], avoidClasses(clForest, 0, clGrass, 5, clPlayer, 10, clWater, 1, clDirt, 5, clShore, 1, clPond, 1), scaleByMapSize(15, 45)); Engine.SetProgress(55); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter( [[tDirt, tDirtCracks], [tDirt, tFineSand], [tDirtCracks, tFineSand]], [1, 1]), paintClass(clDirt) ], avoidClasses(clForest, 0, clDirt, 5, clPlayer, 10, clWater, 1, clGrass, 5, clShore, 1, clPond, 1), scaleByMapSize(15, 45)); Engine.SetProgress(60); 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, 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 ); Engine.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 ); Engine.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(oFoodTreasure, 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(oWoodTreasure, 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 ); Engine.SetProgress(90); createStragglerTrees( [oDatePalm, oSDatePalm], avoidClasses(clForest, 0, clWater, 1, clPlayer, 20, clMetal, 6, clDesert, 1, clTreasure, 2, clPond, 1), clForest, stragglerTrees / 2); createStragglerTrees( [oDatePalm, oSDatePalm], avoidClasses(clForest, 0, clWater, 1, clPlayer, 20, clMetal, 6, clTreasure, 2), clForest, stragglerTrees / 10); createStragglerTrees( [oDatePalm, oSDatePalm], borderClasses(clPond, 1, 4), clForest, stragglerTrees); 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 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); 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"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/rivers.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/rivers.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/rivers.js (revision 21000) @@ -1,289 +1,289 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); 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 tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; var tShore = g_Terrains.shore; var tWater = g_Terrains.water; if (currentBiome() == "tropic") { tShore = "tropic_dirt_b_plants"; tWater = "tropic_dirt_b"; } 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 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]; const heightSeaGround = -3; const heightShallows = -1; const heightLand = 1; var g_Map = new RandomMap(heightLand, tMainTerrain); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clShallow = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clShallow = g_Map.createTileClass(); var [playerIDs, playerPosition, playerAngle, startAngle] = playerPlacementCircle(fractionToTiles(0.35)); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree1, "count": 2 }, "Decoratives": { "template": aGrassShort } }); log("Creating central lake..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.075)), 0.7, 0.1, 10, mapCenter), [ new LayeredPainter([tShore, tWater, tWater, tWater], [1, 4, 2]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), paintClass(clWater) ]); log("Creating rivers between opponents..."); let numRivers = isNomad() ? randIntInclusive(4, 8) : numPlayers; let rivers = distributePointsOnCircle(numRivers, startAngle + Math.PI / numRivers, fractionToTiles(0.5), mapCenter)[0]; for (let i = 0; i < numRivers; ++i) { if (isNomad() ? randBool() : areAllies(playerIDs[i], playerIDs[(i + 1) % numPlayers])) continue; let shallowLocation = randFloat(0.2, 0.7); let shallowWidth = randFloat(0.12, 0.21); paintRiver({ "parallel": true, "start": rivers[i], "end": mapCenter, "width": scaleByMapSize(10, 30), "fadeDist": 5, "deviation": 0, "heightLand": heightLand, "heightRiverbed": heightSeaGround, "minHeight": heightSeaGround, "meanderShort": 10, "meanderLong": 0, "waterFunc": (position, height, riverFraction) => { addToClass(position.x, position.y, clWater); let isShallow = height < heightShallows && riverFraction > shallowLocation && riverFraction < shallowLocation + shallowWidth; let newHeight = isShallow ? heightShallows : Math.max(height, heightSeaGround); if (g_Map.getHeight(position) < newHeight) return; g_Map.setHeight(position, newHeight); createTerrain(height >= 0 ? tShore : tWater).place(position); if (isShallow) addToClass(position.x, position.y, clShallow); } }); } Engine.SetProgress(40); createBumps(avoidClasses(clWater, 2, clPlayer, 20)); if (randBool()) createHills([tMainTerrain, tCliff, tHill], avoidClasses(clPlayer, 20, clHill, 15, clWater, 2), clHill, scaleByMapSize(3, 15)); else createMountains(tCliff, avoidClasses(clPlayer, 20, clHill, 15, clWater, 2), clHill, scaleByMapSize(3, 15)); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], avoidClasses(clPlayer, 20, clForest, 17, clHill, 0, clWater, 2), clForest, forestTrees); Engine.SetProgress(50); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], [1,1], avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tTier4Terrain, avoidClasses(clWater, 3, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12), scaleByMapSize(15, 45), clDirt); Engine.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(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), clRock); log("Creating metal mines..."); createMines( [ [new SimpleObject(oMetalLarge, 1,1, 0,4)] ], avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), clMetal ); Engine.SetProgress(65); var planetm = 1; if (currentBiome() == "tropic") planetm = 8; 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)], [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200) ], avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0)); createDecoration( [ [new SimpleObject(aReeds, 1, 3, 0, 1)], [new SimpleObject(aLillies, 1, 2, 0, 1)] ], [ scaleByMapSize(800, 12800), scaleByMapSize(800, 12800) ], stayClasses(clShallow, 0)); Engine.SetProgress(70); createFood( [ [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)] ], [ 3 * numPlayers, 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), clFood); createFood( [ [new SimpleObject(oFruitBush, 5, 7, 0, 4)] ], [ 3 * numPlayers ], avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), clFood); createFood( [ [new SimpleObject(oFish, 2, 3, 0, 2)] ], [ 25 * numPlayers ], [avoidClasses(clFood, 20), stayClasses(clWater, 6)], clFood); Engine.SetProgress(85); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], avoidClasses(clWater, 5, clForest, 7, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setWaterWaviness(3.0); setWaterType("lake"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/saharan_oases.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/saharan_oases.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/saharan_oases.js (revision 21000) @@ -1,240 +1,240 @@ Engine.LoadLibrary("rmgen"); const tPrimary = "desert_sand_dunes_100"; const tCity = "desert_city_tile"; const tCityPlaza = "desert_city_tile_plaza"; const tFineSand = "desert_sand_smooth"; const tDirt1 = "desert_dirt_rough_2"; const tSandDunes = "desert_sand_dunes_50"; const tDirt2 = "desert_dirt_rough"; const tDirtCracks = "desert_dirt_cracks"; const tShore = "desert_shore_stones"; const tWaterDeep = "desert_shore_stones_wet"; const tLush = "desert_grass_a"; const tSLush = "desert_grass_a_sand"; const oGrapeBush = "gaia/flora_bush_grapes"; const oCamel = "gaia/fauna_camel"; const oGazelle = "gaia/fauna_gazelle"; const oGoat = "gaia/fauna_goat"; const oStoneLarge = "gaia/geology_stonemine_desert_badlands_quarry"; const oStoneSmall = "gaia/geology_stone_desert_small"; const oMetalLarge = "gaia/geology_metal_desert_slabs"; const oDatePalm = "gaia/flora_tree_date_palm"; const oSDatePalm = "gaia/flora_tree_cretan_date_palm_short"; const oWoodTreasure = "gaia/special_treasure_wood"; const oFoodTreasure = "gaia/special_treasure_food_bin"; const aBush1 = "actor|props/flora/bush_desert_a.xml"; const aBush2 = "actor|props/flora/bush_desert_dry_a.xml"; const aBush3 = "actor|props/flora/bush_medit_sm_dry.xml"; const aBush4 = "actor|props/flora/plant_desert_a.xml"; const aDecorativeRock = "actor|geology/stone_desert_med.xml"; const pForest = [tLush + TERRAIN_SEPARATOR + oDatePalm, tLush + TERRAIN_SEPARATOR + oSDatePalm, tLush]; const heightLand = 1; const heightOffsetOasis = -3; var g_Map = new RandomMap(heightLand, tPrimary); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -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 clTreasure = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clTreasure = g_Map.createTileClass(); var [playerIDs, playerPosition, playerAngle] = playerPlacementCircle(fractionToTiles(0.35)); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tCityPlaza, "innerTerrain": tCity }, "Chicken": { }, "Berries": { "template": oGrapeBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oSDatePalm }, "Decoratives": { "template": aBush1 } }); Engine.SetProgress(30); log("Creating oases..."); var oasisRadius = fractionToTiles(scaleByMapSize(0.19, 0.22)); for (let i = 0; i < numPlayers; ++i) { let position = Vector2D.add(mapCenter, new Vector2D(oasisRadius, 0).rotate(-playerAngle[i])); createArea( new ClumpPlacer(diskArea(scaleByMapSize(16, 60)) * 0.185, 0.6, 0.15, 0, position), [ new LayeredPainter( [tSLush ,[tLush, pForest], [tLush, pForest], tShore, tShore, tWaterDeep], [2, 2, 1, 3, 1]), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetOasis, 10), paintClass(clWater) ]); } Engine.SetProgress(50); log("Creating grass patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter( [[tDirt1, tSandDunes], [tSandDunes, tDirt2], [tDirt2, tDirt1]], [1, 1] ), paintClass(clDirt) ], avoidClasses(clForest, 0, clPlayer, 0, clWater, 1, clDirt, 5), scaleByMapSize(15, 45)); Engine.SetProgress(55); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter( [[tDirt2, tDirtCracks], [tDirt2, tFineSand], [tDirtCracks, tFineSand]], [1, 1] ), paintClass(clDirt) ], avoidClasses(clForest, 0, clDirt, 5, clPlayer, 0, clWater, 1), scaleByMapSize(15, 45)); Engine.SetProgress(60); 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, 26, clRock, 10, clWater, 1), 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(clForest, 1, clPlayer, 26, clRock, 10, clWater, 1), 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(clForest, 1, clPlayer, 26, clMetal, 10, clRock, 5, clWater, 1), 2*scaleByMapSize(4,16), 100 ); 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), 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), scaleByMapSize(10, 100), 50 ); log("Creating small decorative rocks on mines..."); group = new SimpleGroup( [new SimpleObject(aDecorativeRock, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, stayClasses(clRock, 0), 5*scaleByMapSize(16, 262), 50 ); group = new SimpleGroup( [new SimpleObject(aDecorativeRock, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, stayClasses(clMetal, 0), 5*scaleByMapSize(16, 262), 50 ); log("Creating gazelles..."); group = new SimpleGroup([new SimpleObject(oGazelle, 5,7, 0,4)], true, clFood); createObjectGroupsDeprecated(group, 0, borderClasses(clWater, 8, 5), 6*scaleByMapSize(5,20), 50 ); log("Creating goats..."); group = new SimpleGroup([new SimpleObject(oGoat, 2,4, 0,3)], true, clFood); createObjectGroupsDeprecated(group, 0, borderClasses(clWater, 8, 5), 5*scaleByMapSize(5,20), 50 ); log("Creating treasures..."); group = new SimpleGroup([new SimpleObject(oFoodTreasure, 1,1, 0,2)], true, clTreasure); createObjectGroupsDeprecated(group, 0, borderClasses(clWater, 8, 5), 3*scaleByMapSize(5,20), 50 ); group = new SimpleGroup([new SimpleObject(oWoodTreasure, 1,1, 0,2)], true, clTreasure); createObjectGroupsDeprecated(group, 0, borderClasses(clWater, 8, 5), 3*scaleByMapSize(5,20), 50 ); log("Creating camels..."); group = new SimpleGroup([new SimpleObject(oCamel, 2,4, 0,2)], true, clFood); createObjectGroupsDeprecated(group, 0, borderClasses(clWater, 14, 5), 5*scaleByMapSize(5,20), 50 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2, clTreasure, 2)); setSkySet("sunny"); setSunColor(0.746, 0.718, 0.539); setWaterColor(0, 0.227, 0.843); setWaterTint(0, 0.545, 0.859); setWaterWaviness(1.0); setWaterType("clap"); setWaterMurkiness(0.5); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/snowflake_searocks.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/snowflake_searocks.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/snowflake_searocks.js (revision 21000) @@ -1,440 +1,440 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); 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.mainTerrain; const tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; 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 oSecondaryHuntableAnimal = g_Gaia.secondaryHuntableAnimal; const oStoneLarge = g_Gaia.stoneLarge; const oStoneSmall = g_Gaia.stoneSmall; const oMetalLarge = g_Gaia.metalLarge; const aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; 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]; const heightIsland = 20; const heightSeaGround = -5; var g_Map = new RandomMap(heightSeaGround, tWater); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clForest = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clLand = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clLand = g_Map.createTileClass(); const playerIslandRadius = scaleByMapSize(15, 30); const islandBetweenPlayerAndCenterDist = 0.16; const islandBetweenPlayerAndCenterRadius = 0.81; const centralIslandRadius = 0.36; var [playerIDs, playerPosition, playerAngle, startAngle] = playerPlacementCircle(fractionToTiles(0.35)); var numIslands = 0; var isConnected = []; var islandPos = []; function initIsConnected() { for (let m = 0; m < numIslands; ++m) { isConnected[m] = []; for (let n = 0; n < numIslands; ++n) isConnected[m][n] = 0; } } function createIsland(islandID, size, tileClass) { createArea( new ClumpPlacer(size * diskArea(playerIslandRadius), 0.95, 0.6, 10, islandPos[islandID]), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightIsland, 2), paintClass(tileClass) ]); } function createIslandAtRadialLocation(playerID, islandID, playerIDOffset, distFromCenter, islandRadius) { let angle = startAngle + (playerID * 2 + playerIDOffset) * Math.PI / numPlayers; islandPos[islandID] = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(distFromCenter), 0).rotate(-angle)).round(); createIsland(islandID, islandRadius, clLand); } function createSnowflakeSearockWithCenter(sizeID) { let [tertiaryIslandDist, tertiaryIslandRadius, islandBetweenPlayersDist, islandBetweenPlayersRadius] = islandSizes[sizeID]; let islandID_center = 4 * numPlayers; numIslands = islandID_center + 1; initIsConnected(); log("Creating central island..."); islandPos[islandID_center] = mapCenter; createIsland(islandID_center, centralIslandRadius, clLand); for (let playerID = 0; playerID < numPlayers; ++playerID) { let playerID_neighbor = playerID + 1 < numPlayers ? playerID + 1 : 0; let islandID_player = playerID; let islandID_playerNeighbor = playerID_neighbor; let islandID_betweenPlayers = playerID + numPlayers; let islandID_betweenPlayerAndCenter = playerID + 2 * numPlayers; let islandID_betweenPlayerAndCenterNeighbor = playerID_neighbor + 2 * numPlayers; let islandID_tertiary = playerID + 3 * numPlayers; log("Creating island between the player and their neighbor..."); isConnected[islandID_betweenPlayers][islandID_player] = 1; isConnected[islandID_betweenPlayers][islandID_playerNeighbor] = 1; createIslandAtRadialLocation(playerID, islandID_betweenPlayers, 1, islandBetweenPlayersDist, islandBetweenPlayersRadius); log("Creating an island between the player and the center..."); isConnected[islandID_betweenPlayerAndCenter][islandID_player] = 1; isConnected[islandID_betweenPlayerAndCenter][islandID_center] = 1; isConnected[islandID_betweenPlayerAndCenter][islandID_betweenPlayerAndCenterNeighbor] = 1; createIslandAtRadialLocation(playerID, islandID_betweenPlayerAndCenter, 0, islandBetweenPlayerAndCenterDist, islandBetweenPlayerAndCenterRadius); log("Creating tertiary island, at the map border..."); isConnected[islandID_tertiary][islandID_betweenPlayers] = 1; createIslandAtRadialLocation(playerID, islandID_tertiary, 1, tertiaryIslandDist, tertiaryIslandRadius); } } /** * Creates one island in front of every player and connects it with the neighbors. */ function createSnowflakeSearockWithoutCenter() { numIslands = 2 * numPlayers; initIsConnected(); for (let playerID = 0; playerID < numPlayers; ++playerID) { let playerID_neighbor = playerID + 1 < numPlayers ? playerID + 1 : 0; let islandID_player = playerID; let islandID_playerNeighbor = playerID_neighbor; let islandID_inFrontOfPlayer = playerID + numPlayers; let islandID_inFrontOfPlayerNeighbor = playerID_neighbor + numPlayers; isConnected[islandID_player][islandID_playerNeighbor] = 1; isConnected[islandID_player][islandID_inFrontOfPlayer] = 1; isConnected[islandID_inFrontOfPlayer][islandID_inFrontOfPlayerNeighbor] = 1; createIslandAtRadialLocation(playerID, islandID_inFrontOfPlayer, 0, islandBetweenPlayerAndCenterDist, islandBetweenPlayerAndCenterRadius); } } function createSnowflakeSearockTiny() { numIslands = numPlayers + 1; initIsConnected(); let islandID_center = numPlayers; log("Creating central island..."); islandPos[islandID_center] = mapCenter; createIsland(numPlayers, 1, clLand); for (let playerID = 0; playerID < numPlayers; ++playerID) { let islandID_player = playerID; isConnected[islandID_player][islandID_center] = 1; } } const islandSizes = { "medium": [0.41, 0.49, 0.26, 1], "large1": [0.41, 0.49, 0.24, 1], "large2": [0.41, 0.36, 0.28, 0.81] }; if (mapSize <= 128) { createSnowflakeSearockTiny(); } else if (mapSize <= 192) { createSnowflakeSearockWithoutCenter(); } else if (mapSize <= 256) { if (numPlayers < 6) createSnowflakeSearockWithCenter("medium"); else createSnowflakeSearockWithoutCenter(); } else if (mapSize <= 320) { if (numPlayers < 8) createSnowflakeSearockWithCenter("medium"); else createSnowflakeSearockWithoutCenter(); } else createSnowflakeSearockWithCenter(numPlayers < 6 ? "large1" : "large2"); log("Creating player islands..."); for (let i = 0; i < numPlayers; ++i) { islandPos[i] = playerPosition[i]; createIsland(i, 1, isNomad() ? clLand : clPlayer); } placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], // PlayerTileClass already marked above "BaseResourceClass": clBaseResource, "baseResourceConstraint": stayClasses(clPlayer, 4), "Walls": "towers", "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oFruitBush, "distance": playerIslandRadius - 4 }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ], "distance": playerIslandRadius - 4 }, "Trees": { "template": oTree1, "count": scaleByMapSize(10, 50), "minDist": 11, "maxDist": 11 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(30); log("Creating connectors..."); for (let i = 0; i < numIslands; ++i) for (let j = 0; j < numIslands; ++j) if (isConnected[i][j]) createPassage({ "start": islandPos[i], "end": islandPos[j], "startWidth": 11, "endWidth": 11, "smoothWidth": 3, "maxHeight": heightIsland - 1, "tileClass": clLand, "terrain": tHill, "edgeTerrain": tCliff }); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); var types = [ [[tForestFloor2, tMainTerrain, pForest1], [tForestFloor2, pForest1]], [[tForestFloor1, tMainTerrain, pForest2], [tForestFloor1, pForest2]] ]; var size = forestTrees / (scaleByMapSize(2, 8) * numPlayers) * (currentBiome() == "savanna" ? 2 : 1); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], [avoidClasses(clPlayer, 6, clForest, 10), stayClasses(clLand, 4)], num); Engine.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), stayClasses(clLand, 5)], 5*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, 10, clRock, 10), stayClasses(clLand, 5)], 5*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, 10, clMetal, 10, clRock, 5), stayClasses(clLand, 5)], 5*scaleByMapSize(4,16), 100 ); Engine.SetProgress(65); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter([[tMainTerrain, tTier1Terrain],[tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]], [1, 1]), paintClass(clDirt) ], [avoidClasses(clForest, 0, clDirt, 5, clPlayer, 12), stayClasses(clLand, 5)], scaleByMapSize(15, 45)); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new TerrainPainter(tTier4Terrain), [avoidClasses(clForest, 0, clDirt, 5, clPlayer, 12), stayClasses(clLand, 5)], scaleByMapSize(15, 45)); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, [avoidClasses(clForest, 0, clPlayer, 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(clForest, 0, clPlayer, 0), stayClasses(clLand, 4)], scaleByMapSize(8, 131), 50 ); Engine.SetProgress(70); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oMainHuntableAnimal, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 0, clPlayer, 10, clFood, 20), stayClasses(clLand, 4)], 3 * numPlayers, 50 ); Engine.SetProgress(75); log("Creating sheep..."); group = new SimpleGroup( [new SimpleObject(oSecondaryHuntableAnimal, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 0, clPlayer, 10, clFood, 20), stayClasses(clLand, 4)], 3 * numPlayers, 50 ); log("Creating fruits..."); group = new SimpleGroup( [new SimpleObject(oFruitBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 0, clPlayer, 10, clFood, 20), stayClasses(clLand, 4)], 3 * numPlayers, 50 ); Engine.SetProgress(85); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], [avoidClasses(clForest, 1, clPlayer, 9, clMetal, 6, clRock, 6), stayClasses(clLand, 4)], clForest, stragglerTrees); var planetm = 1; if (currentBiome() == "tropic") planetm = 8; log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clPlayer, 2, clDirt, 0), stayClasses(clLand, 4)], planetm * scaleByMapSize(13, 200) ); Engine.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 4)], planetm * scaleByMapSize(13, 200) ); Engine.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(clPlayer, 1, clDirt, 1), stayClasses(clLand, 4)], planetm * scaleByMapSize(13, 200), 50 ); placePlayersNomad( clPlayer, [ stayClasses(clLand, 8), avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clFood, 2) ]); setSkySet(pickRandom(["cirrus", "cumulus", "sunny"])); setSunRotation(randomAngle()); setSunElevation(Math.PI * randFloat(1/5, 1/3)); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/the_unknown/unknown_common.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/the_unknown/unknown_common.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/the_unknown/unknown_common.js (revision 21000) @@ -1,1060 +1,1060 @@ /** * @file This library is used to generate different map variations on the map Unknown, Unknown Land and Unknown Nomad. */ /** * True if all players should be connected via land and false if river or islands can split some if not all the players. */ var g_AllowNaval; 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 tRoad = g_Terrains.road; const tRoadWild = g_Terrains.roadWild; const tTier4Terrain = g_Terrains.tier4Terrain; const tShore = g_Terrains.shore; const tWater = g_Terrains.water; const oTree1 = g_Gaia.tree1; const oTree2 = g_Gaia.tree2; const oTree4 = g_Gaia.tree4; const oTree5 = g_Gaia.tree5; const oFruitBush = g_Gaia.fruitBush; const oMainHuntableAnimal = g_Gaia.mainHuntableAnimal; const oSecondaryHuntableAnimal = g_Gaia.secondaryHuntableAnimal; const oFish = g_Gaia.fish; const oStoneLarge = g_Gaia.stoneLarge; const oStoneSmall = g_Gaia.stoneSmall; const oMetalLarge = g_Gaia.metalLarge; const oWoodTreasure = "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]; const heightSeaGround = -5; const heightLand = 3; const heightCliff = 3.12; const heightHill = 18; const heightOffsetBump = 2; var g_Map = new RandomMap(heightSeaGround, tWater); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); const mapBounds = g_Map.getBounds(); -var clPlayer = createTileClass(); -var clPlayerTerritory = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clPeninsulaSteam = createTileClass(); -var clBaseResource = createTileClass(); -var clLand = createTileClass(); -var clShallow = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clPlayerTerritory = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clPeninsulaSteam = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clLand = g_Map.createTileClass(); +var clShallow = g_Map.createTileClass(); var landElevationPainter = new SmoothElevationPainter(ELEVATION_SET, heightLand, 4); var unknownMapFunctions = { "land": [ "Continent", "CentralSea", "CentralRiver", "EdgeSeas", "Gulf", "Lakes", "Passes", "Lowlands", "Mainland" ], "naval": [ "Archipelago", "RiversAndLake" ] }; /** * The player IDs and locations shall only be determined by the landscape functions if it's not a nomad game, * because nomad maps randomize the locations after the terrain generation. * The locations should only determined by the landscape functions to avoid placing bodies of water and resources into civic centers and the starting resources. */ var playerIDs = sortAllPlayers(); var playerPosition = []; var g_StartingTreasures = false; var g_StartingWalls = true; function createUnknownMap() { let funcs = unknownMapFunctions.land; if (g_AllowNaval) funcs = funcs.concat(unknownMapFunctions.naval); global["unknown" + pickRandom(funcs)](); paintUnknownMapBasedOnHeight(); createUnknownPlayerBases(); createUnknownObjects(); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2, clWater, 10)); } /** * Chain of islands or many disconnected islands. */ function unknownArchipelago() { g_StartingWalls = "towers"; g_StartingTreasures = true; let [pIDs, islandPosition] = playerPlacementCircle(fractionToTiles(0.35)); if (!isNomad()) { [playerIDs, playerPosition] = [pIDs, islandPosition]; markPlayerArea("large"); } log("Creating islands..."); let islandSize = diskArea(scaleByMapSize(17, 29)); for (let i = 0; i < numPlayers; ++i) createArea( new ClumpPlacer(islandSize, 0.8, 0.1, 10, islandPosition[i]), landElevationPainter); let type = isNomad() ? randIntInclusive(1, 2) : randIntInclusive(1, 3); if (type == 1) { log("Creating archipelago..."); createAreas( new ClumpPlacer(islandSize * randFloat(0.8, 1.2), 0.8, 0.1, 10), [ landElevationPainter, paintClass(clLand) ], null, scaleByMapSize(2, 5) * randIntInclusive(8, 14)); log("Creating shore jaggedness with small puddles..."); createAreas( new ClumpPlacer(scaleByMapSize(15, 80), 0.2, 0.1, 1), [ new SmoothElevationPainter(ELEVATION_SET, heightLand, 4), paintClass(clLand) ], borderClasses(clLand, 6, 3), scaleByMapSize(12, 130) * 2, 150); } else if (type == 2) { log("Creating islands..."); createAreas( new ClumpPlacer(islandSize * randFloat(0.6, 1.4), 0.8, 0.1, randFloat(0.0, 0.2)), [ landElevationPainter, paintClass(clLand) ], avoidClasses(clLand, 3, clPlayerTerritory, 3), scaleByMapSize(6, 10) * randIntInclusive(8, 14)); log("Creating small islands..."); createAreas( new ClumpPlacer(islandSize * randFloat(0.3, 0.7), 0.8, 0.1, 0.07), [ new SmoothElevationPainter(ELEVATION_SET, heightLand, 6), paintClass(clLand) ], avoidClasses(clLand, 3, clPlayerTerritory, 3), scaleByMapSize(2, 6) * randIntInclusive(6, 15), 25); } else if (type == 3) { log("Creating tight islands..."); createAreas( new ClumpPlacer(islandSize * randFloat(0.8, 1.2), 0.8, 0.1, 10), [ landElevationPainter, paintClass(clLand) ], avoidClasses(clLand, randIntInclusive(8, 16), clPlayerTerritory, 3), scaleByMapSize(2, 5) * randIntInclusive(8, 14)); } } /** * Disk shaped mainland with water on the edge. */ function unknownContinent() { let waterHeight = -5; if (!isNomad()) { log("Ensuring player area..."); [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.25)); markPlayerArea("small"); for (let i = 0; i < numPlayers; ++i) createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 9)), Math.floor(scaleByMapSize(5, 20)), 1, playerPosition[i], 0, [Math.floor(scaleByMapSize(23, 50))]), [ landElevationPainter, paintClass(clLand) ]); } log("Creating continent..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.38)), 0.9, 0.09, 10, mapCenter), [ landElevationPainter, paintClass(clLand) ]); if (randBool(1/3)) { log("Creating peninsula (i.e. half the map not being surrounded by water)..."); let angle = randomAngle(); let peninsulaPosition1 = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.25), 0).rotate(-angle)); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.38)), 0.9, 0.09, 10, peninsulaPosition1), [ landElevationPainter, paintClass(clLand) ]); log("Remembering to not paint shorelines into the peninsula..."); let peninsulaPosition2 = Vector2D.add(mapCenter, new Vector2D(fractionToTiles(0.35), 0).rotate(-angle)); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.33)), 0.9, 0.01, 10, peninsulaPosition2), paintClass(clPeninsulaSteam)); } createShoreJaggedness(waterHeight, clLand, 7); } /** * Creates a huge central river, possibly connecting the riversides with a narrow piece of land. */ function unknownCentralSea() { let waterHeight = -3; let startAngle = randomAngle(); let [riverStart, riverEnd] = centralRiverCoordinates(startAngle); paintRiver({ "parallel": false, "start": riverStart, "end": riverEnd, "width": fractionToTiles(scaleByMapSize(0.27, 0.42) + randFloat(0, 0.08)), "fadeDist": scaleByMapSize(3, 12), "deviation": 0, "heightRiverbed": waterHeight, "heightLand": heightLand, "meanderShort": 20, "meanderLong": 0, "waterFunc": (position, height, riverFraction) => { if (height < 0) addToClass(position.x, position.y, clWater); }, "landFunc": (position, shoreDist1, shoreDist2) => { g_Map.setHeight(position, 3.1); addToClass(position.x, position.y, clLand); } }); if (!isNomad()) { [playerIDs, playerPosition] = playerPlacementRiver(startAngle + Math.PI / 2, fractionToTiles(0.6)); markPlayerArea("small"); } if (!g_AllowNaval || randBool()) { log("Creating isthmus (i.e. connecting the two riversides with a big land passage)..."); let [isthmusStart, isthmusEnd] = centralRiverCoordinates(startAngle + Math.PI / 2); createArea( new PathPlacer( isthmusStart, isthmusEnd, scaleByMapSize(randIntInclusive(16, 24), randIntInclusive(100, 140)), 0.5, 3 * scaleByMapSize(1, 4), 0.1, 0.01), [ landElevationPainter, paintClass(clLand), unPaintClass(clWater) ]); } createExtensionsOrIslands(); // Don't createShoreJaggedness since it doesn't fit artistically here } /** * Creates a very small central river. */ function unknownCentralRiver() { let waterHeight = -4; let heightShallow = -2; createArea( new MapBoundsPlacer(), new ElevationPainter(heightLand)); let startAngle = randomAngle(); if (!isNomad()) { [playerIDs, playerPosition] = playerPlacementRiver(startAngle + Math.PI / 2, fractionToTiles(0.5)); markPlayerArea("large"); } log("Creating the main river..."); let [coord1, coord2] = centralRiverCoordinates(startAngle); createArea( new PathPlacer(coord1, coord2, scaleByMapSize(14, 24), 0.5, scaleByMapSize(3, 12), 0.1, 0.01), new SmoothElevationPainter(ELEVATION_SET, waterHeight, 4), avoidClasses(clPlayerTerritory, 4)); log("Creating small water spots at the map border to ensure separation of players..."); for (let coord of [coord1, coord2]) createArea( new ClumpPlacer(diskArea(scaleByMapSize(5, 10)), 0.95, 0.6, 10, coord), new SmoothElevationPainter(ELEVATION_SET, waterHeight, 2), avoidClasses(clPlayerTerritory, 8)); if (!g_AllowNaval || randBool()) { log("Creating the shallows of the main river..."); for (let i = 0; i <= randIntInclusive(1, scaleByMapSize(4, 8)); ++i) { let location = fractionToTiles(randFloat(0.15, 0.85)); createPassage({ "start": new Vector2D(location, mapBounds.top).rotateAround(startAngle, mapCenter), "end": new Vector2D(location, mapBounds.bottom).rotateAround(startAngle, mapCenter), "startWidth": scaleByMapSize(8, 12), "endWidth": scaleByMapSize(8, 12), "smoothWidth": 2, "startHeight": heightShallow, "endHeight": heightShallow, "maxHeight": heightShallow, "tileClass": clShallow }); } } if (randBool(2/3)) createTributaryRivers( startAngle, randIntInclusive(8, scaleByMapSize(12, 16)), scaleByMapSize(10, 20), -4, [-6, -1.5], Math.PI / 5, clWater, clShallow, avoidClasses(clPlayerTerritory, 3)); } /** * Creates a circular lake in the middle and possibly a river between each player ("pizza slices"). */ function unknownRiversAndLake() { let waterHeight = -4; createArea( new MapBoundsPlacer(), new ElevationPainter(heightLand)); let startAngle; if (!isNomad()) { let playerAngle; [playerIDs, playerPosition, playerAngle, startAngle] = playerPlacementCircle(fractionToTiles(0.35)); markPlayerArea("small"); } let lake = randBool(3/4); if (lake) { log("Creating lake..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.17)), 0.7, 0.1, 10, mapCenter), [ new SmoothElevationPainter(ELEVATION_SET, waterHeight, 4), paintClass(clWater) ]); createShoreJaggedness(waterHeight, clWater, 3); } // Don't do this on nomad because the imbalances on the different islands are too drastic if (!isNomad() && (!lake || randBool(1/3))) { log("Creating small rivers separating players..."); for (let river of distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers, fractionToTiles(0.5), mapCenter)[0]) { createArea( new PathPlacer(mapCenter, river, scaleByMapSize(14, 24), 0.4, 3 * scaleByMapSize(1, 3), 0.2, 0.05), [ new SmoothElevationPainter(ELEVATION_SET, waterHeight, 4), paintClass(clWater) ], avoidClasses(clPlayer, 5)); createArea( new ClumpPlacer(diskArea(scaleByMapSize(4, 22)), 0.95, 0.6, 10, river), [ new SmoothElevationPainter(ELEVATION_SET, waterHeight, 0), paintClass(clWater) ], avoidClasses(clPlayer, 5)); } log("Creating lake..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.04)), 0.7, 0.1, 10, mapCenter), [ new SmoothElevationPainter(ELEVATION_SET, waterHeight, 4), paintClass(clWater) ]); } if (!isNomad && lake && randBool()) { log("Creating small central island..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.05)), 0.7, 0.1, 10, mapCenter), [ landElevationPainter, paintClass(clWater) ]); } } /** * Align players on a land strip with seas bordering on one or both sides that can hold islands. */ function unknownEdgeSeas() { let waterHeight = -4; createArea( new MapBoundsPlacer(), new ElevationPainter(heightLand)); let startAngle = randomAngle(); if (!isNomad()) { playerIDs = sortAllPlayers(); playerPosition = playerPlacementLine(startAngle + Math.PI / 2, mapCenter, fractionToTiles(0.2)); // Don't place the shoreline inside the CC, but possibly into the players territory markPlayerArea("small"); } for (let side of pickRandom([[0], [Math.PI], [0, Math.PI]])) paintRiver({ "parallel": true, "start": new Vector2D(mapBounds.left, mapBounds.top).rotateAround(side + startAngle, mapCenter), "end": new Vector2D(mapBounds.left, mapBounds.bottom).rotateAround(side + startAngle, mapCenter), "width": scaleByMapSize(80, randFloat(270, 320)), "fadeDist": scaleByMapSize(2, 8), "deviation": 0, "heightRiverbed": waterHeight, "heightLand": heightLand, "meanderShort": 20, "meanderLong": 0 }); createExtensionsOrIslands(); paintTileClassBasedOnHeight(0, heightCliff, 1, clLand); createShoreJaggedness(waterHeight, clLand, 7, false); } /** * Land shaped like a concrescent moon around a central lake. */ function unknownGulf() { let waterHeight = -3; createArea( new MapBoundsPlacer(), new ElevationPainter(heightLand)); let startAngle = randomAngle(); if (!isNomad()) { log("Determining player locations..."); playerPosition = playerPlacementCustomAngle( fractionToTiles(0.35), mapCenter, i => startAngle + 2/3 * Math.PI * (-1 + (numPlayers == 1 ? 1 : 2 * i / (numPlayers - 1))))[0]; markPlayerArea("large"); } let gulfParts = [ { "radius": fractionToTiles(0.16), "distance": fractionToTiles(0) }, { "radius": fractionToTiles(0.2), "distance": fractionToTiles(0.2) }, { "radius": fractionToTiles(0.22), "distance": fractionToTiles(0.49) } ]; for (let gulfPart of gulfParts) { let position = Vector2D.sub(mapCenter, new Vector2D(gulfPart.distance, 0).rotate(-startAngle)).round(); createArea( new ClumpPlacer(diskArea(gulfPart.radius), 0.7, 0.05, 10, position), [ new SmoothElevationPainter(ELEVATION_SET, waterHeight, 4), paintClass(clWater) ], avoidClasses(clPlayerTerritory, defaultPlayerBaseRadius())); } } /** * Mainland style with some small random lakes. */ function unknownLakes() { let waterHeight = -5; createArea( new MapBoundsPlacer(), new ElevationPainter(heightLand)); if (!isNomad()) { [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); markPlayerArea("large"); } log("Creating lakes..."); createAreas( new ClumpPlacer(scaleByMapSize(160, 700), 0.2, 0.1, 1), [ new SmoothElevationPainter(ELEVATION_SET, waterHeight, 5), paintClass(clWater) ], [avoidClasses(clPlayerTerritory, 12), randBool() ? avoidClasses(clWater, 8) : new NullConstraint()], scaleByMapSize(5, 16)); } /** * A large hill leaving players only a small passage to each of the the two neighboring players. */ function unknownPasses() { let heightMountain = 24; let waterHeight = -4; createArea( new MapBoundsPlacer(), new ElevationPainter(heightLand)); let playerAngle; let startAngle; if (!isNomad()) { [playerIDs, playerPosition, playerAngle, startAngle] = playerPlacementCircle(fractionToTiles(0.35)); markPlayerArea("small"); } else startAngle = randomAngle(); for (let mountain of distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers, fractionToTiles(0.5), mapCenter)[0]) { log("Creating a mountain range between neighboring players..."); createArea( new PathPlacer(mapCenter, mountain, scaleByMapSize(14, 24), 0.4, 3 * scaleByMapSize(1, 3), 0.2, 0.05), [ // More smoothing than this often results in the mountainrange becoming passable to one player. new SmoothElevationPainter(ELEVATION_SET, heightMountain, 1), paintClass(clWater) ], avoidClasses(clPlayer, 5)); log("Creating small mountain at the map border between the players to ensure separation of players..."); createArea( new ClumpPlacer(diskArea(scaleByMapSize(4, 22)), 0.95, 0.6, 10, mountain), new SmoothElevationPainter(ELEVATION_SET, heightMountain, 0), avoidClasses(clPlayer, 5)); } let passes = distributePointsOnCircle(numPlayers * 2, startAngle, fractionToTiles(0.35), mapCenter)[0]; for (let i = 0; i < numPlayers; ++i) { log("Create passages between neighboring players..."); createArea( new PathPlacer( passes[2 * i], passes[2 * ((i + 1) % numPlayers)], scaleByMapSize(14, 24), 0.4, 3 * scaleByMapSize(1, 3), 0.2, 0.05), new SmoothElevationPainter(ELEVATION_SET, heightLand, 2)); } if (randBool(2/5)) { log("Create central lake..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.1)), 0.7, 0.1, 10, mapCenter), [ new SmoothElevationPainter(ELEVATION_SET, waterHeight, 3), paintClass(clWater) ]); } else { log("Fill area between the paths..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.05)), 0.7, 0.1, 10, mapCenter), [ new SmoothElevationPainter(ELEVATION_SET, heightMountain, 4), paintClass(clWater) ]); } } /** * Land enclosed by a hill that leaves small areas for civic centers and large central place. */ function unknownLowlands() { let heightMountain = 30; log("Creating mountain that is going to separate players..."); createArea( new MapBoundsPlacer(), new ElevationPainter(heightMountain)); let playerAngle; let startAngle; if (!isNomad()) { [playerIDs, playerPosition, playerAngle, startAngle] = playerPlacementCircle(fractionToTiles(0.35)); markPlayerArea("small"); } else startAngle = randomAngle(); log("Creating valleys enclosed by the mountain..."); let valleys = numPlayers; if (mapSize >= 128 && numPlayers <= 2 || mapSize >= 192 && numPlayers <= 3 || mapSize >= 320 && numPlayers <= 4 || mapSize >= 384 && numPlayers <= 5 || mapSize >= 448 && numPlayers <= 6) valleys *= 2; for (let valley of distributePointsOnCircle(valleys, startAngle, fractionToTiles(0.35), mapCenter)[0]) { log("Creating player valley..."); createArea( new ClumpPlacer(diskArea(scaleByMapSize(18, 32)), 0.65, 0.1, 10, valley), [ new SmoothElevationPainter(ELEVATION_SET, heightLand, 2), paintClass(clLand) ]); log("Creating passes from player areas to the center..."); createArea( new PathPlacer(mapCenter, valley, scaleByMapSize(14, 24), 0.4, 3 * scaleByMapSize(1, 3), 0.2, 0.05), [ landElevationPainter, paintClass(clWater) ]); } log("Creating the big central area..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.18)), 0.7, 0.1, 10, mapCenter), [ landElevationPainter, paintClass(clWater) ]); } /** * No water, no hills. */ function unknownMainland() { createArea( new MapBoundsPlacer(), new ElevationPainter(3)); if (!isNomad()) { [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); markPlayerArea("small"); } } function centralRiverCoordinates(angle) { return [ new Vector2D(mapBounds.left + 1, mapCenter.y), new Vector2D(mapBounds.right - 1, mapCenter.y) ].map(v => v.rotateAround(angle, mapCenter)); } function createShoreJaggedness(waterHeight, borderClass, shoreDist, inwards = true) { log("Creating shore jaggedness..."); for (let i = 0; i < 2; ++i) if (i || inwards) createAreas( new ChainPlacer(2, Math.floor(scaleByMapSize(4, 6)), 15, 1), [ new SmoothElevationPainter(ELEVATION_SET, i ? heightLand : waterHeight, 4), i ? paintClass(clLand) : unPaintClass(clLand) ], [ avoidClasses(clPlayer, 20, clPeninsulaSteam, 20), borderClasses(borderClass, shoreDist, shoreDist) ], scaleByMapSize(7, 130) * 2, 150); } function createExtensionsOrIslands() { let rnd = randIntInclusive(1, 3); if (rnd == 1) { log("Creating islands..."); createAreas( new ClumpPlacer(Math.square(randIntInclusive(scaleByMapSize(8, 15), scaleByMapSize(15, 23))), 0.8, 0.1, randFloat(0, 0.2)), [ landElevationPainter, paintClass(clLand) ], avoidClasses(clLand, 3, clPlayer, 3), scaleByMapSize(2, 5) * randIntInclusive(8, 14)); } else if (rnd == 2) { log("Creating extentions..."); createAreas( new ChainPlacer(Math.floor(scaleByMapSize(4, 7)), Math.floor(scaleByMapSize(7, 10)), Math.floor(scaleByMapSize(16, 40)), 0.07), [ landElevationPainter, paintClass(clLand) ], null, scaleByMapSize(2, 5) * randIntInclusive(8, 14)); } } /** * Prevent impassable terrain and resource collisions at the the civic center and starting resources. */ function markPlayerArea(size) { for (let i = 0; i < numPlayers; ++i) { addCivicCenterAreaToClass(playerPosition[i], clPlayer); if (size == "large") createArea( new ClumpPlacer(diskArea(scaleByMapSize(17, 29) / 3), 0.6, 0.3, 10, playerPosition[i]), paintClass(clPlayerTerritory)); } } function paintUnknownMapBasedOnHeight() { paintTerrainBasedOnHeight(heightCliff, 40, 1, tCliff); paintTerrainBasedOnHeight(3, heightCliff, 1, tMainTerrain); paintTerrainBasedOnHeight(1, 3, 1, tShore); paintTerrainBasedOnHeight(-8, 1, 2, tWater); unPaintTileClassBasedOnHeight(0, heightCliff, 1, clWater); unPaintTileClassBasedOnHeight(-6, 0, 1, clLand); paintTileClassBasedOnHeight(-6, 0, 1, clWater); paintTileClassBasedOnHeight(0, heightCliff, 1, clLand); paintTileClassBasedOnHeight(heightCliff, 40, 1, clHill); } /** * Place resources and decoratives after the player territory was marked. */ function createUnknownObjects() { log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), [avoidClasses(clWater, 2, clPlayer, 10), stayClasses(clLand, 3)], randIntInclusive(0, scaleByMapSize(1, 2) * 200)); log("Creating hills..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], [avoidClasses(clPlayer, 15, clHill, randIntInclusive(6, 18)), stayClasses(clLand, 0)], randIntInclusive(0, scaleByMapSize(4, 8))*randIntInclusive(1, scaleByMapSize(4, 9)) ); Engine.SetProgress(50); log("Creating forests..."); let [numForest, numStragglers] = getTreeCounts(...rBiomeTreeCount(1)); let types = [ [[tForestFloor2, tMainTerrain, pForest1], [tForestFloor2, pForest1]], [[tForestFloor1, tMainTerrain, pForest2], [tForestFloor1, pForest2]] ]; let size = numForest / (scaleByMapSize(2, 8) * numPlayers); let num = Math.floor(size / types.length); for (let type of types) createAreas( new ClumpPlacer(numForest / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], [avoidClasses(clPlayer, 20, clForest, randIntInclusive(5, 15), clHill, 2), stayClasses(clLand, 4)], num); Engine.SetProgress(50); log("Creating dirt patches..."); let patchCount = (currentBiome() == "savanna" ? 3 : 1) * scaleByMapSize(15, 45); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter([[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]], [1, 1]), paintClass(clDirt) ], [avoidClasses(clForest, 0, clHill, 2, clDirt, 5, clPlayer, 7), stayClasses(clLand, 4)], patchCount); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new TerrainPainter(tTier4Terrain), [avoidClasses(clForest, 0, clHill, 2, clDirt, 5, clPlayer, 7), stayClasses(clLand, 4)], patchCount); Engine.SetProgress(55); log("Creating stone mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock), 0, [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill, 2), stayClasses(clLand, 3)], randIntInclusive(scaleByMapSize(2, 9), scaleByMapSize(9, 40)), 100); log("Creating small stone quarries..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oStoneSmall, 2, 5, 1, 3)], true, clRock), 0, [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill, 2), stayClasses(clLand, 3)], randIntInclusive(scaleByMapSize(2, 9),scaleByMapSize(9, 40)), 100); log("Creating metal mines..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal), 0, [avoidClasses(clForest, 1, clPlayer, 10, clMetal, 10, clRock, 5, clHill, 2), stayClasses(clLand, 3)], randIntInclusive(scaleByMapSize(2, 9), scaleByMapSize(9, 40)), 100); Engine.SetProgress(65); log("Creating small decorative rocks..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aRockMedium, 1, 3, 0, 1)], true), 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 2), stayClasses(clLand, 3)], scaleByMapSize(16, 262), 50); log("Creating large decorative rocks..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aRockLarge, 1, 2, 0, 1), new SimpleObject(aRockMedium, 1, 3, 0, 2)], true), 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 2), stayClasses(clLand, 3)], scaleByMapSize(8, 131), 50); Engine.SetProgress(70); log("Creating deer..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)], true, clFood), 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 8, clHill, 2, clFood, 20), stayClasses(clLand, 2)], randIntInclusive(numPlayers + 3, 5 * numPlayers + 4), 50); log("Creating berry bush..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oFruitBush, 5, 7, 0, 4)], true, clFood), 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 8, clHill, 2, clFood, 20), stayClasses(clLand, 2)], randIntInclusive(1, 4) * numPlayers + 2, 50); Engine.SetProgress(75); log("Creating sheep..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)], true, clFood), 0, [avoidClasses(clWater, 0, clForest, 0, clPlayer, 8, clHill, 2, clFood, 20), stayClasses(clLand, 2)], randIntInclusive(numPlayers + 3, 5 * numPlayers + 4), 50); log("Creating fish..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(oFish, 2, 3, 0, 2)], true, clFood), 0, avoidClasses(clLand, 4, clForest, 0, clPlayer, 0, clHill, 2, clFood, 20), randIntInclusive(15, 40) * numPlayers, 60); Engine.SetProgress(85); log("Creating straggler trees..."); types = [g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree3, g_Gaia.tree4]; num = Math.floor(numStragglers / types.length); for (let type of types) createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(type, 1, 1, 0, 3)], true, clForest), 0, [avoidClasses(clWater, 1, clForest, 1, clHill, 2, clPlayer, 0, clMetal, 6, clRock, 6, clBaseResource, 6), stayClasses(clLand, 4)], num); let planetm = currentBiome() == "tropic" ? 8 : 1; log("Creating small grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aGrassShort, 1, 2, 0, 1, -Math.PI / 8, Math.PI / 8)]), 0, [avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 3)], planetm * scaleByMapSize(13, 200)); Engine.SetProgress(90); log("Creating large grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aGrass, 2, 4, 0, 1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5, -Math.PI / 8, Math.PI / 8)]), 0, [avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 3)], planetm * scaleByMapSize(13, 200)); Engine.SetProgress(95); log("Creating shallow flora..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aLillies, 1, 2, 0, 2), new SimpleObject(aReeds, 2, 4, 0, 2)]), 0, stayClasses(clShallow, 1), 60 * scaleByMapSize(13, 200), 80); log("Creating bushes..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)]), 0, [avoidClasses(clWater, 1, clHill, 2, clPlayer, 1, clDirt, 1), stayClasses(clLand, 3)], planetm * scaleByMapSize(13, 200), 50); setSkySet(pickRandom(["cirrus", "cumulus", "sunny", "sunny 1", "mountainous", "stratus"])); setSunRotation(randomAngle()); setSunElevation(Math.PI * randFloat(1/5, 1/3)); } function createUnknownPlayerBases() { placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "BaseResourceClass": clBaseResource, "Walls": g_StartingWalls, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad, "painters": [ paintClass(clPlayer) ] }, "Chicken": { }, "Berries": { "template": oFruitBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Treasures": { "types": [ { "template": oWoodTreasure, "count": g_StartingTreasures ? 14 : 0 } ] }, "Trees": { "template": oTree1 }, "Decoratives": { "template": aGrassShort } }); } Index: ps/trunk/binaries/data/mods/public/maps/random/rhine_marshlands.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/rhine_marshlands.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/rhine_marshlands.js (revision 21000) @@ -1,308 +1,308 @@ Engine.LoadLibrary("rmgen"); const tGrass = ["temp_grass", "temp_grass", "temp_grass_d"]; const tForestFloor = "temp_plants_bog"; const tGrassA = "temp_grass_plants"; const tGrassB = "temp_plants_bog"; const tMud = "temp_mud_a"; const tRoad = "temp_road"; const tRoadWild = "temp_road_overgrown"; const tShoreBlend = "temp_grass_plants"; const tShore = "temp_plants_bog"; const tWater = "temp_mud_a"; const oBeech = "gaia/flora_tree_euro_beech"; const oOak = "gaia/flora_tree_oak"; const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; const oHorse = "gaia/fauna_horse"; const oWolf = "gaia/fauna_wolf"; const oRabbit = "gaia/fauna_rabbit"; const oStoneLarge = "gaia/geology_stonemine_temperate_quarry"; const oStoneSmall = "gaia/geology_stone_temperate"; const oMetalLarge = "gaia/geology_metal_temperate_slabs"; const aGrass = "actor|props/flora/grass_soft_small_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aRockLarge = "actor|geology/stone_granite_med.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aReeds = "actor|props/flora/reeds_pond_lush_a.xml"; const aLillies = "actor|props/flora/water_lillies.xml"; const aBushMedium = "actor|props/flora/bush_medit_me.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; const pForestD = [tForestFloor + TERRAIN_SEPARATOR + oBeech, tForestFloor]; const pForestP = [tForestFloor + TERRAIN_SEPARATOR + oOak, tForestFloor]; const heightMarsh = -2 const heightLand = 1; const heightOffsetBumpWater = 1; const heightOffsetBumpLand = 2; var g_Map = new RandomMap(heightLand, tGrass); const numPlayers = getNumPlayers(); -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 clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oBeech }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(15); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBumpLand, 2), avoidClasses(clPlayer, 13), scaleByMapSize(300, 800)); log("Creating marshes..."); for (let i = 0; i < 7; ++i) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(6, 12)), Math.floor(scaleByMapSize(15, 60)), 0.8), [ new LayeredPainter([tShoreBlend, tShore, tWater], [1, 1]), new SmoothElevationPainter(ELEVATION_SET, heightMarsh, 3), paintClass(clWater) ], avoidClasses(clPlayer, 20, clWater, Math.round(scaleByMapSize(7,16)*randFloat(0.8,1.35))), scaleByMapSize(4,20)); log("Creating reeds..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aReeds, 5, 10, 0, 4), new SimpleObject(aLillies, 5, 10, 0, 4)], true), 0, stayClasses(clWater, 1), scaleByMapSize(400,2000), 100); Engine.SetProgress(40); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBumpWater, 2), stayClasses(clWater, 2), scaleByMapSize(50, 100)); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(500, 2500, 0.7); var types = [ [[tForestFloor, tGrass, pForestD], [tForestFloor, pForestD]], [[tForestFloor, tGrass, pForestP], [tForestFloor, pForestP]] ]; var size = forestTrees / (scaleByMapSize(3,6) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), forestTrees / (num * Math.floor(scaleByMapSize(2, 4))), 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 20, clWater, 0, clForest, 10), num); Engine.SetProgress(50); log("Creating mud patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 1), [ new LayeredPainter([tGrassA, tGrassB, tMud], [1, 1]), paintClass(clDirt) ], avoidClasses(clWater, 1, clForest, 0, clDirt, 5, clPlayer, 8), scaleByMapSize(15, 45)); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clWater, 0, clForest, 1, clPlayer, 20, clRock, 10)], 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)], 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)], scaleByMapSize(4,16), 100 ); Engine.SetProgress(60); 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), scaleByMapSize(16, 262), 50 ); Engine.SetProgress(65); 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), scaleByMapSize(8, 131), 50 ); Engine.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, 20, clFood, 13), 6 * numPlayers, 50 ); log("Creating horse..."); group = new SimpleGroup( [new SimpleObject(oHorse, 1,3, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clFood, 13), 3 * numPlayers, 50 ); Engine.SetProgress(75); log("Creating rabbit..."); group = new SimpleGroup( [new SimpleObject(oRabbit, 5,7, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clFood, 13), 6 * numPlayers, 50 ); log("Creating wolf..."); group = new SimpleGroup( [new SimpleObject(oWolf, 1,3, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clFood, 13), 3 * numPlayers, 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50 ); Engine.SetProgress(80); createStragglerTrees( [oOak, oBeech], avoidClasses(clForest, 1, clPlayer, 13, clMetal, 6, clRock, 6, clWater, 0), clForest, stragglerTrees); Engine.SetProgress(85); log("Creating small grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(aGrassShort, 1, 2, 0, 1)]), 0, avoidClasses(clWater, 2, clPlayer, 13, clDirt, 0), scaleByMapSize(13, 200)); Engine.SetProgress(90); log("Creating large grass tufts..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5) ]), 0, avoidClasses(clWater, 3, clPlayer, 13, clDirt, 1, clForest, 0), scaleByMapSize(13, 200)); Engine.SetProgress(95); log("Creating bushes..."); createObjectGroupsDeprecated( new SimpleGroup( [ new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2) ]), 0, avoidClasses(clWater, 1, clPlayer, 13, clDirt, 1), scaleByMapSize(13, 200), 50); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setSkySet("cirrus"); setWaterColor(0.753,0.635,0.345); // muddy brown setWaterTint(0.161,0.514,0.635); // clear blue for blueness setWaterMurkiness(0.8); setWaterWaviness(1.0); setWaterType("clap"); setFogThickness(0.25); setFogFactor(0.6); setPPEffect("hdr"); setPPSaturation(0.44); setPPBloom(0.3); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/rmgen/library.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/rmgen/library.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/rmgen/library.js (revision 21000) @@ -1,343 +1,338 @@ const TERRAIN_SEPARATOR = "|"; const SEA_LEVEL = 20.0; const HEIGHT_UNITS_PER_METRE = 92; const MAP_BORDER_WIDTH = 3; const g_DamageTypes = new DamageTypes(); /** * Constants needed for heightmap_manipulation.js */ const MAX_HEIGHT_RANGE = 0xFFFF / HEIGHT_UNITS_PER_METRE; // Engine limit, Roughly 700 meters const MIN_HEIGHT = - SEA_LEVEL; /** * Length of one tile of the terrain grid in metres. * Useful to transform footprint sizes of templates to the coordinate system used by getMapSize. */ const TERRAIN_TILE_SIZE = Engine.GetTerrainTileSize(); const MAX_HEIGHT = MAX_HEIGHT_RANGE - SEA_LEVEL; /** * Default angle for buildings. */ const BUILDING_ORIENTATION = -1/4 * Math.PI; const g_CivData = deepfreeze(loadCivFiles(false)); /** * Sets whether setHeight operates on the center of a tile or on the vertices. */ var TILE_CENTERED_HEIGHT_MAP = false; function fractionToTiles(f) { return g_MapSettings.Size * f; } function tilesToFraction(t) { return t / g_MapSettings.Size; } function scaleByMapSize(min, max, minMapSize = 128, maxMapSize = 512) { return min + (max - min) * (g_MapSettings.Size - minMapSize) / (maxMapSize - minMapSize); } /** * Retries the given function with those arguments as often as specified. */ function retryPlacing(placeFunc, retryFactor, amount, getResult, behaveDeprecated = false) { let maxFail = amount * retryFactor; let results = []; let good = 0; let bad = 0; while (good < amount && bad <= maxFail) { let result = placeFunc(); if (result !== undefined || behaveDeprecated) { ++good; if (getResult) results.push(result); } else ++bad; } return getResult ? results : good; } /** * Sets the x and z property of the given object (typically a Placer or Group) to a random point on the map. * @param passableOnly - Should be true for entity placement and false for terrain or elevation operations. */ function randomizeCoordinates(obj, passableOnly) { let border = passableOnly ? MAP_BORDER_WIDTH : 0; if (g_Map.isCircularMap()) { // Polar coordinates // Uniformly distributed on the disk let halfMapSize = g_Map.size / 2 - border; let r = halfMapSize * Math.sqrt(randFloat(0, 1)); let theta = randomAngle(); obj.x = Math.floor(r * Math.cos(theta)) + halfMapSize; obj.z = Math.floor(r * Math.sin(theta)) + halfMapSize; } else { // Rectangular coordinates obj.x = randIntExclusive(border, g_Map.size - border); obj.z = randIntExclusive(border, g_Map.size - border); } } /** * Sets the x and z property of the given JS object (typically a Placer or Group) to a random point of the area. */ function randomizeCoordinatesFromAreas(obj, areas) { let pt = pickRandom(pickRandom(areas).points); obj.x = pt.x; obj.z = pt.y; } // TODO this is a hack to simulate the old behaviour of those functions // until all old maps are changed to use the correct version of these functions function createObjectGroupsDeprecated(group, player, constraint, amount, retryFactor = 10) { return createObjectGroups(group, player, constraint, amount, retryFactor, true); } function createObjectGroupsByAreasDeprecated(group, player, constraint, amount, retryFactor, areas) { return createObjectGroupsByAreas(group, player, constraint, amount, retryFactor, areas, true); } /** * Attempts to place the given number of areas in random places of the map. * Returns actually placed areas. */ function createAreas(centeredPlacer, painter, constraint, amount, retryFactor = 10) { let placeFunc = function() { randomizeCoordinates(centeredPlacer, false); return createArea(centeredPlacer, painter, constraint); }; return retryPlacing(placeFunc, retryFactor, amount, true, false); } /** * Attempts to place the given number of areas in random places of the given areas. * Returns actually placed areas. */ function createAreasInAreas(centeredPlacer, painter, constraint, amount, retryFactor, areas) { let placeFunc = function() { randomizeCoordinatesFromAreas(centeredPlacer, areas); return createArea(centeredPlacer, painter, constraint); }; return retryPlacing(placeFunc, retryFactor, amount, true, false); } /** * Attempts to place the given number of groups in random places of the map. * Returns the number of actually placed groups. */ function createObjectGroups(group, player, constraint, amount, retryFactor = 10, behaveDeprecated = false) { let placeFunc = function() { randomizeCoordinates(group, true); return createObjectGroup(group, player, constraint); }; return retryPlacing(placeFunc, retryFactor, amount, false, behaveDeprecated); } /** * Attempts to place the given number of groups in random places of the given areas. * Returns the number of actually placed groups. */ function createObjectGroupsByAreas(group, player, constraint, amount, retryFactor, areas, behaveDeprecated = false) { let placeFunc = function() { randomizeCoordinatesFromAreas(group, areas); return createObjectGroup(group, player, constraint); }; return retryPlacing(placeFunc, retryFactor, amount, false, behaveDeprecated); } function createTerrain(terrain) { return typeof terrain == "string" ? new SimpleTerrain(...terrain.split(TERRAIN_SEPARATOR)) : new RandomTerrain(terrain.map(t => createTerrain(t))); } function placeObject(x, z, type, player, angle) { let position = new Vector2D(x, z); if (g_Map.validTile(position)) g_Map.addObject(new Entity(type, player, x, z, angle)); } -function createTileClass() -{ - return g_Map.createTileClass(); -} - function getTileClass(id) { if (!g_Map.validClass(id)) return undefined; return g_Map.tileClasses[id]; } /** * Constructs a new Area shaped by the Placer meeting the Constraints and calls the Painters there. * Supports both Centered and Non-Centered Placers. */ function createArea(placer, painter, constraints) { let points = placer.place(new AndConstraint(constraints)); if (!points) return undefined; let area = g_Map.createArea(points); if (painter instanceof Array) painter = new MultiPainter(painter); painter.paint(area); return area; } /** * @param mode is one of the HeightPlacer constants determining whether to exclude the min/max elevation. */ function paintTerrainBasedOnHeight(minHeight, maxHeight, mode, terrain) { createArea( new HeightPlacer(mode, minHeight, maxHeight), new TerrainPainter(terrain)); } function paintTileClassBasedOnHeight(minHeight, maxHeight, mode, tileClass) { createArea( new HeightPlacer(mode, minHeight, maxHeight), new TileClassPainter(getTileClass(tileClass))); } function unPaintTileClassBasedOnHeight(minHeight, maxHeight, mode, tileClass) { createArea( new HeightPlacer(mode, minHeight, maxHeight), new TileClassUnPainter(getTileClass(tileClass))); } /** * Places the Entities of the given Group if they meet the Constraints * and sets the given player as the owner. */ function createObjectGroup(group, player, constraints) { return group.place(player, new AndConstraint(constraints)); } /** * Add point to given class by id */ function addToClass(x, z, id) { let tileClass = getTileClass(id); if (tileClass !== null) tileClass.add(x, z); } /** * Remove point from the given class by id */ function removeFromClass(x, z, id) { let tileClass = getTileClass(id); if (tileClass !== null) tileClass.remove(x, z); } /** * Create a painter for the given class */ function paintClass(id) { return new TileClassPainter(getTileClass(id)); } /** * Create a painter for the given class */ function unPaintClass(id) { return new TileClassUnPainter(getTileClass(id)); } /** * Create an avoid constraint for the given classes by the given distances */ function avoidClasses(/*class1, dist1, class2, dist2, etc*/) { let ar = []; for (let i = 0; i < arguments.length/2; ++i) ar.push(new AvoidTileClassConstraint(arguments[2*i], arguments[2*i+1])); // Return single constraint if (ar.length == 1) return ar[0]; return new AndConstraint(ar); } /** * Create a stay constraint for the given classes by the given distances */ function stayClasses(/*class1, dist1, class2, dist2, etc*/) { let ar = []; for (let i = 0; i < arguments.length/2; ++i) ar.push(new StayInTileClassConstraint(arguments[2*i], arguments[2*i+1])); // Return single constraint if (ar.length == 1) return ar[0]; return new AndConstraint(ar); } /** * Create a border constraint for the given classes by the given distances */ function borderClasses(/*class1, idist1, odist1, class2, idist2, odist2, etc*/) { let ar = []; for (let i = 0; i < arguments.length/3; ++i) ar.push(new BorderTileClassConstraint(arguments[3*i], arguments[3*i+1], arguments[3*i+2])); // Return single constraint if (ar.length == 1) return ar[0]; return new AndConstraint(ar); } Index: ps/trunk/binaries/data/mods/public/maps/random/sahel_watering_holes.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/sahel_watering_holes.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/sahel_watering_holes.js (revision 21000) @@ -1,391 +1,391 @@ Engine.LoadLibrary("rmgen"); const tGrass = "savanna_grass_a"; const tForestFloor = "savanna_forestfloor_a"; const tCliff = "savanna_cliff_b"; const tDirtRocksA = "savanna_dirt_rocks_c"; const tDirtRocksB = "savanna_dirt_rocks_a"; const tDirtRocksC = "savanna_dirt_rocks_b"; const tHill = "savanna_cliff_a"; const tRoad = "savanna_tile_a_red"; const tRoadWild = "savanna_tile_a_red"; const tGrassPatch = "savanna_grass_b"; const tShore = "savanna_riparian_bank"; const tWater = "savanna_riparian_wet"; const oBaobab = "gaia/flora_tree_baobab"; const oFig = "gaia/flora_tree_fig"; const oBerryBush = "gaia/flora_bush_berry"; const oWildebeest = "gaia/fauna_wildebeest"; const oFish = "gaia/fauna_fish"; const oGazelle = "gaia/fauna_gazelle"; const oElephant = "gaia/fauna_elephant_african_bush"; const oGiraffe = "gaia/fauna_giraffe"; const oZebra = "gaia/fauna_zebra"; const oStoneLarge = "gaia/geology_stonemine_desert_quarry"; const oStoneSmall = "gaia/geology_stone_savanna_small"; const oMetalLarge = "gaia/geology_metal_savanna_slabs"; const aGrass = "actor|props/flora/grass_savanna.xml"; const aGrassShort = "actor|props/flora/grass_medit_field.xml"; const aRockLarge = "actor|geology/stone_savanna_med.xml"; const aRockMedium = "actor|geology/stone_savanna_med.xml"; const aBushMedium = "actor|props/flora/bush_desert_dry_a.xml"; const aBushSmall = "actor|props/flora/bush_dry_a.xml"; const pForest = [tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor]; const heightSeaGround = -4; const heightShallows = -2; const heightLand = 3; const heightHill = 35; const heightOffsetBump = 2; var g_Map = new RandomMap(heightLand, tGrass); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clShallows = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clShallows = g_Map.createTileClass(); var [playerIDs, playerPosition, playerAngle, startAngle] = playerPlacementCircle(fractionToTiles(0.35)); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oBaobab, "count": 5 }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(20); log("Creating rivers..."); var riverStart = distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers, fractionToTiles(0.15), mapCenter)[0]; var riverEnd = distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers, fractionToTiles(0.49), mapCenter)[0]; for (let i = 0; i < numPlayers; ++i) { let neighborID = (i + 1) % numPlayers; log("Creating lake near the center..."); createArea( new ClumpPlacer(diskArea(scaleByMapSize(5, 30)), 0.95, 0.6, 10, riverStart[i]), [ new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), paintClass(clWater) ], avoidClasses(clPlayer, 5)); log("Creating the river between the players..."); createArea( new PathPlacer(riverStart[i], riverEnd[i], scaleByMapSize(10, 50), 0.2, 3 * scaleByMapSize(1, 4), 0.2, 0.05), [ new LayeredPainter([tShore, tWater, tWater], [1, 3]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), paintClass(clWater) ], avoidClasses(clPlayer, 5)); log("Creating lake near the map border..."); createArea( new ClumpPlacer(diskArea(scaleByMapSize(5, 22)), 0.95, 0.6, 10, riverEnd[i]), [ new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4), paintClass(clWater) ], avoidClasses(clPlayer, 5)); log("Creating shallows between neighbors..."); createPassage({ "start": playerPosition[i], "end": playerPosition[neighborID], "startWidth": 10, "endWidth": 10, "smoothWidth": 4, "startHeight": heightShallows, "endHeight": heightShallows, "maxHeight": heightShallows, "tileClass": clShallows }); log("Creating animals in shallows..."); let shallowPosition = Vector2D.average([playerPosition[i], playerPosition[neighborID]]).round(); let objects = [ new SimpleObject(oWildebeest, 5, 6, 0, 4), new SimpleObject(oElephant, 2, 3, 0, 4) ]; for (let object of objects) createObjectGroup( new SimpleGroup( [object], true, clFood, shallowPosition.x, shallowPosition.y), 0); } paintTerrainBasedOnHeight(-6, 2, 1, tWater); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), avoidClasses(clWater, 2, clPlayer, 20), scaleByMapSize(100, 200)); log("Creating hills..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1), [ new LayeredPainter([tGrass, tCliff, tHill], [1, 2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 3), paintClass(clHill) ], avoidClasses(clPlayer, 20, clHill, 15, clWater, 3), scaleByMapSize(1, 4) * numPlayers); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(160, 900, 0.02); var types = [ [[tForestFloor, tGrass, pForest], [tForestFloor, pForest]] ]; var size = forestTrees / (0.5 * scaleByMapSize(2,8) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 20, clForest, 10, clHill, 0, clWater, 2), num ); Engine.SetProgress(50); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter( [[tGrass, tDirtRocksA], [tDirtRocksA, tDirtRocksB], [tDirtRocksB, tDirtRocksC]], [1, 1]), paintClass(clDirt) ], avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20), scaleByMapSize(15, 45)); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new TerrainPainter(tGrassPatch), avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20), scaleByMapSize(15, 45)); Engine.SetProgress(55); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), scaleByMapSize(4,16), 100 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), scaleByMapSize(4,16), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), scaleByMapSize(4,16), 100 ); Engine.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(8, 131), 50 ); Engine.SetProgress(70); log("Creating wildebeest..."); group = new SimpleGroup( [new SimpleObject(oWildebeest, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); Engine.SetProgress(75); log("Creating gazelle..."); group = new SimpleGroup( [new SimpleObject(oGazelle, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); log("Creating elephant..."); group = new SimpleGroup( [new SimpleObject(oElephant, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); log("Creating giraffe..."); group = new SimpleGroup( [new SimpleObject(oGiraffe, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); log("Creating zebra..."); group = new SimpleGroup( [new SimpleObject(oZebra, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5), 3 * numPlayers, 50 ); log("Creating fish..."); group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clFood, 20), stayClasses(clWater, 6)], 25 * numPlayers, 60 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50 ); Engine.SetProgress(85); createStragglerTrees( [oBaobab, oBaobab, oBaobab, oFig], avoidClasses(clWater, 5, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6), clForest, stragglerTrees); var planetm = 4; log("Creating small grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 2), planetm * scaleByMapSize(13, 200) ); Engine.SetProgress(90); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clForest, 0), planetm * scaleByMapSize(13, 200) ); Engine.SetProgress(95); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 1, clPlayer, 1), planetm * scaleByMapSize(13, 200), 50 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clHill, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setSkySet("sunny"); setSunRotation(randomAngle()); setSunElevation(Math.PI * randFloat(1/5, 1/4)); setWaterColor(0.478,0.42,0.384); // greyish setWaterTint(0.58,0.22,0.067); // reddish setWaterMurkiness(0.87); setWaterWaviness(0.5); setWaterType("clap"); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/syria.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/syria.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/syria.js (revision 21000) @@ -1,277 +1,277 @@ Engine.LoadLibrary("rmgen"); const tMainDirt = ["desert_dirt_rocks_1", "desert_dirt_cracks"]; const tForestFloor1 = "forestfloor_dirty"; const tForestFloor2 = "desert_forestfloor_palms"; const tGrassSands = "desert_grass_a_sand"; const tGrass = "desert_grass_a"; const tSecondaryDirt = "medit_dirt_dry"; const tCliff = ["desert_cliff_persia_1", "desert_cliff_persia_2"]; const tHill = ["desert_dirt_rocks_1", "desert_dirt_rocks_2", "desert_dirt_rocks_3"]; const tDirt = ["desert_dirt_rough", "desert_dirt_rough_2"]; const tRoad = "desert_shore_stones";; const tRoadWild = "desert_grass_a_stones";; const oTamarix = "gaia/flora_tree_tamarix"; const oPalm = "gaia/flora_tree_date_palm"; const oPine = "gaia/flora_tree_aleppo_pine"; const oBush = "gaia/flora_bush_grapes"; const oCamel = "gaia/fauna_camel"; const oGazelle = "gaia/fauna_gazelle"; const oLion = "gaia/fauna_lion"; const oStoneLarge = "gaia/geology_stonemine_desert_quarry"; const oStoneSmall = "gaia/geology_stone_desert_small"; const oMetalLarge = "gaia/geology_metal_desert_slabs"; const aRock = "actor|geology/stone_desert_med.xml"; const aBushA = "actor|props/flora/bush_desert_dry_a.xml"; const aBushB = "actor|props/flora/bush_desert_dry_a.xml"; const aBushes = [aBushA, aBushB]; const pForestP = [tForestFloor2 + TERRAIN_SEPARATOR + oPalm, tForestFloor2]; const pForestT = [tForestFloor1 + TERRAIN_SEPARATOR + oTamarix,tForestFloor2]; const heightLand = 1; const heightHill = 22; const heightOffsetBump = 2; var g_Map = new RandomMap(heightLand, tMainDirt); const mapCenter = g_Map.getCenter(); const numPlayers = getNumPlayers(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clGrass = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clGrass = g_Map.createTileClass(); var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35)); for (let i = 0; i < numPlayers; ++i) { log("Marking player territory larger than the city patch..."); if (!isNomad()) createArea( new ClumpPlacer(diskArea(defaultPlayerBaseRadius()), 0.9, 0.5, 10, playerPosition[i]), paintClass(clPlayer)); log("Creating big grass patches surrounding the city patches..."); createArea( new ChainPlacer( 2, Math.floor(scaleByMapSize(5, 12)), Math.floor(scaleByMapSize(25, 60)) / (isNomad() ? 2 : 1), 1, playerPosition[i], 0, [Math.floor(scaleByMapSize(16, 30))]), [ new LayeredPainter([tGrassSands, tGrass], [3]), paintClass(clGrass) ]); } Engine.SetProgress(10); placePlayerBases({ "PlayerPlacement": [playerIDs, playerPosition], // PlayerTileClass marked above "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad, "radius": 10, "width": 3 }, "Chicken": { }, "Berries": { "template": oBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ], "groupElements": [new RandomObject(aBushes, 2, 4, 2, 3)] }, "Trees": { "template": pickRandom([oPalm, oTamarix]), "count": 3 } // No decoratives }); Engine.SetProgress(20); log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2), avoidClasses(clPlayer, 13), scaleByMapSize(300, 800)); log("Creating hills..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.5), [ new LayeredPainter([tCliff, tHill], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], avoidClasses(clPlayer, 3, clGrass, 1, clHill, 10), scaleByMapSize(1, 3) * numPlayers * 3); Engine.SetProgress(25); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(400, 2000, 0.7); var types = [ [[tMainDirt, tForestFloor2, pForestP], [tForestFloor2, pForestP]], [[tMainDirt, tForestFloor1, pForestT], [tForestFloor1, pForestT]] ]; var size = forestTrees / (scaleByMapSize(3,6) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ChainPlacer( 1, Math.floor(scaleByMapSize(3, 5)), forestTrees / (num * Math.floor(scaleByMapSize(2, 4))), 0.5), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 1, clGrass, 1, clForest, 10, clHill, 1), num); Engine.SetProgress(40); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), new LayeredPainter([tSecondaryDirt, tDirt], [1]), avoidClasses(clHill, 0, clForest, 0, clPlayer, 8, clGrass, 1), scaleByMapSize(50, 90)); Engine.SetProgress(60); log("Creating big patches..."); for (let size of [scaleByMapSize(6, 30), scaleByMapSize(10, 50), scaleByMapSize(16, 70)]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5), new LayeredPainter([tSecondaryDirt, tDirt], [1]), avoidClasses(clHill, 0, clForest, 0, clPlayer, 8, clGrass, 1), scaleByMapSize(30, 90)); Engine.SetProgress(70); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0,4), new RandomObject(aBushes, 2, 4, 0, 2)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill, 1, clGrass, 1)], scaleByMapSize(2,8), 100 ); log("Creating small stone quarries..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3), new RandomObject(aBushes, 2,4, 0,2)], true, clRock); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill, 1, clGrass, 1)], scaleByMapSize(2,8), 100 ); log("Creating metal mines..."); group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4), new RandomObject(aBushes, 2,4, 0,2)], true, clMetal); createObjectGroupsDeprecated(group, 0, [avoidClasses(clForest, 1, clPlayer, 10, clMetal, 10, clRock, 5, clHill, 1, clGrass, 1)], scaleByMapSize(2,8), 100 ); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRock, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(16, 262), 50 ); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushB, 1,2, 0,1), new SimpleObject(aBushA, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(50, 500), 50 ); Engine.SetProgress(80); log("Creating gazelle..."); group = new SimpleGroup( [new SimpleObject(oGazelle, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 1, clHill, 1, clFood, 20, clGrass, 2), 3 * numPlayers, 50 ); log("Creating lions..."); group = new SimpleGroup( [new SimpleObject(oLion, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 1, clHill, 1, clFood, 20, clGrass, 2), 3 * numPlayers, 50 ); log("Creating camels..."); group = new SimpleGroup( [new SimpleObject(oCamel, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 0, clPlayer, 1, clHill, 1, clFood, 20, clGrass, 2), 3 * numPlayers, 50 ); Engine.SetProgress(85); createStragglerTrees( [oPalm, oTamarix, oPine], avoidClasses(clForest, 1, clHill, 1, clPlayer, 1, clMetal, 6, clRock, 6), clForest, stragglerTrees); createStragglerTrees( [oPalm, oTamarix, oPine], [avoidClasses(clForest, 1, clHill, 1, clPlayer, 1, clMetal, 6, clRock, 6), stayClasses(clGrass, 3)], clForest, stragglerTrees * (isNomad() ? 3 : 1)); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("sunny"); setSunElevation(Math.PI / 8); setSunRotation(randomAngle()); setSunColor(0.746, 0.718, 0.539); setWaterColor(0.292, 0.347, 0.691); setWaterTint(0.550, 0.543, 0.437); setWaterMurkiness(0.83); setFogColor(0.8, 0.76, 0.61); setFogThickness(0.2); setFogFactor(0.4); setPPEffect("hdr"); setPPContrast(0.65); setPPSaturation(0.42); setPPBloom(0.6); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/wild_lake.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/wild_lake.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/wild_lake.js (revision 21000) @@ -1,637 +1,637 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); Engine.LoadLibrary("heightmap"); var g_Map = new RandomMap(0, "whiteness"); /** * getArray - To ensure a terrain texture is contained within an array */ function getArray(stringOrArrayOfStrings) { if (typeof stringOrArrayOfStrings == "string") return [stringOrArrayOfStrings]; return stringOrArrayOfStrings; } setSelectedBiome(); // Terrain, entities and actors let wildLakeBiome = [ // 0 Deep water { "texture": getArray(g_Terrains.water), "actor": [[g_Gaia.fish], 0.01], "textureHS": getArray(g_Terrains.water), "actorHS": [[g_Gaia.fish], 0.03] }, // 1 Shallow water { "texture": getArray(g_Terrains.water), "actor": [[g_Decoratives.lillies, g_Decoratives.reeds], 0.3], "textureHS": getArray(g_Terrains.water), "actorHS": [[g_Decoratives.lillies], 0.1] }, // 2 Shore { "texture": getArray(g_Terrains.shore), "actor": [ [ g_Gaia.tree1, g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree2, g_Gaia.mainHuntableAnimal, g_Decoratives.grass, g_Decoratives.grass, g_Decoratives.rockMedium, g_Decoratives.rockMedium, g_Decoratives.bushMedium, g_Decoratives.bushMedium ], 0.3 ], "textureHS": getArray(g_Terrains.cliff), "actorHS": [[g_Decoratives.grassShort, g_Decoratives.rockMedium, g_Decoratives.bushSmall], 0.1] }, // 3 Low ground { "texture": getArray(g_Terrains.tier1Terrain), "actor": [ [ g_Decoratives.grass, g_Decoratives.grassShort, g_Decoratives.rockLarge, g_Decoratives.rockMedium, g_Decoratives.bushMedium, g_Decoratives.bushSmall ], 0.2 ], "textureHS": getArray(g_Terrains.cliff), "actorHS": [[g_Decoratives.grassShort, g_Decoratives.rockMedium, g_Decoratives.bushSmall], 0.1] }, // 4 Mid ground. Player and path height { "texture": getArray(g_Terrains.mainTerrain), "actor": [ [ g_Decoratives.grass, g_Decoratives.grassShort, g_Decoratives.rockLarge, g_Decoratives.rockMedium, g_Decoratives.bushMedium, g_Decoratives.bushSmall ], 0.2 ], "textureHS": getArray(g_Terrains.cliff), "actorHS": [[g_Decoratives.grassShort, g_Decoratives.rockMedium, g_Decoratives.bushSmall], 0.1] }, // 5 High ground { "texture": getArray(g_Terrains.tier2Terrain), "actor": [ [ g_Decoratives.grass, g_Decoratives.grassShort, g_Decoratives.rockLarge, g_Decoratives.rockMedium, g_Decoratives.bushMedium, g_Decoratives.bushSmall ], 0.2 ], "textureHS": getArray(g_Terrains.cliff), "actorHS": [[g_Decoratives.grassShort, g_Decoratives.rockMedium, g_Decoratives.bushSmall], 0.1] }, // 6 Lower hilltop forest border { "texture": getArray(g_Terrains.dirt), "actor": [ [ g_Gaia.tree1, g_Gaia.tree3, g_Gaia.fruitBush, g_Gaia.secondaryHuntableAnimal, g_Decoratives.grass, g_Decoratives.rockMedium, g_Decoratives.bushMedium ], 0.3 ], "textureHS": getArray(g_Terrains.cliff), "actorHS": [[g_Decoratives.grassShort, g_Decoratives.rockMedium, g_Decoratives.bushSmall], 0.1] }, // 7 Hilltop forest { "texture": getArray(g_Terrains.forestFloor1), "actor": [ [ g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree3, g_Gaia.tree4, g_Gaia.tree5, g_Decoratives.tree, g_Decoratives.grass, g_Decoratives.rockMedium, g_Decoratives.bushMedium ], 0.5 ], "textureHS": getArray(g_Terrains.cliff), "actorHS": [[g_Decoratives.grassShort, g_Decoratives.rockMedium, g_Decoratives.bushSmall], 0.1] } ]; var mercenaryCampGuards = { "temperate": [ { "Template" : "structures/merc_camp_egyptian" }, { "Template" : "units/mace_infantry_javelinist_b", "Count" : 4 }, { "Template" : "units/mace_cavalry_spearman_e", "Count" : 3 }, { "Template" : "units/mace_infantry_archer_a", "Count" : 4 }, { "Template" : "units/mace_champion_infantry_a", "Count" : 3 } ], "snowy": [ { "Template" : "structures/ptol_mercenary_camp" }, { "Template" : "units/brit_infantry_javelinist_b", "Count" : 4 }, { "Template" : "units/brit_cavalry_swordsman_e", "Count" : 3 }, { "Template" : "units/brit_infantry_slinger_a", "Count" : 4 }, { "Template" : "units/brit_champion_infantry", "Count" : 3 } ], "desert": [ { "Template" : "structures/ptol_mercenary_camp" }, { "Template" : "units/pers_infantry_javelinist_b", "Count" : 4 }, { "Template" : "units/pers_cavalry_swordsman_e", "Count" : 3 }, { "Template" : "units/pers_infantry_archer_a", "Count" : 4 }, { "Template" : "units/pers_champion_infantry", "Count" : 3 } ], "alpine": [ { "Template" : "structures/ptol_mercenary_camp" }, { "Template" : "units/rome_infantry_swordsman_b", "Count" : 4 }, { "Template" : "units/rome_cavalry_spearman_e", "Count" : 3 }, { "Template" : "units/rome_infantry_javelinist_a", "Count" : 4 }, { "Template" : "units/rome_champion_infantry", "Count" : 3 } ], "mediterranean": [ { "Template" : "structures/merc_camp_egyptian" }, { "Template" : "units/iber_infantry_javelinist_b", "Count" : 4 }, { "Template" : "units/iber_cavalry_spearman_e", "Count" : 3 }, { "Template" : "units/iber_infantry_slinger_a", "Count" : 4 }, { "Template" : "units/iber_champion_infantry", "Count" : 3 } ], "savanna": [ { "Template" : "structures/merc_camp_egyptian" }, { "Template" : "units/sele_infantry_javelinist_b", "Count" : 4 }, { "Template" : "units/sele_cavalry_spearman_merc_e", "Count" : 3 }, { "Template" : "units/sele_infantry_spearman_a", "Count" : 4 }, { "Template" : "units/sele_champion_infantry_swordsman", "Count" : 3 } ], "tropic": [ { "Template" : "structures/merc_camp_egyptian" }, { "Template" : "units/ptol_infantry_javelinist_b", "Count" : 4 }, { "Template" : "units/ptol_cavalry_archer_e", "Count" : 3 }, { "Template" : "units/ptol_infantry_slinger_a", "Count" : 4 }, { "Template" : "units/ptol_champion_infantry_pikeman", "Count" : 3 } ], "autumn": [ { "Template" : "structures/ptol_mercenary_camp" }, { "Template" : "units/gaul_infantry_javelinist_b", "Count" : 4 }, { "Template" : "units/gaul_cavalry_swordsman_e", "Count" : 3 }, { "Template" : "units/gaul_infantry_slinger_a", "Count" : 4 }, { "Template" : "units/gaul_champion_infantry", "Count" : 3 } ] }; /** * Resource spots and other points of interest */ // Mines function placeMine(point, centerEntity, decorativeActors = [ g_Decoratives.grass, g_Decoratives.grassShort, g_Decoratives.rockLarge, g_Decoratives.rockMedium, g_Decoratives.bushMedium, g_Decoratives.bushSmall ] ) { placeObject(point.x, point.y, centerEntity, 0, randomAngle()); let quantity = randIntInclusive(11, 23); let dAngle = 2 * Math.PI / quantity; for (let i = 0; i < quantity; ++i) { let angle = dAngle * randFloat(i, i + 1); let dist = randFloat(2, 5); placeObject(point.x + dist * Math.cos(angle), point.y + dist * Math.sin(angle), pickRandom(decorativeActors), 0, randomAngle()); } } // Groves, only Wood let groveActors = [g_Decoratives.grass, g_Decoratives.rockMedium, g_Decoratives.bushMedium]; -let clGrove = createTileClass(); +let clGrove = g_Map.createTileClass(); function placeGrove(point, groveEntities = [ g_Gaia.tree1, g_Gaia.tree1, g_Gaia.tree1, g_Gaia.tree1, g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree2, g_Gaia.tree2, g_Gaia.tree2, g_Gaia.tree3, g_Gaia.tree3, g_Gaia.tree3, g_Gaia.tree4, g_Gaia.tree4, g_Gaia.tree5 ], groveActors = [g_Decoratives.grass, g_Decoratives.rockMedium, g_Decoratives.bushMedium], groveTileClass = undefined, groveTerrainTexture = getArray(g_Terrains.forestFloor1) ) { placeObject(point.x, point.y, pickRandom(["structures/gaul_outpost", "gaia/flora_tree_oak_new"]), 0, randomAngle()); let quantity = randIntInclusive(20, 30); let dAngle = 2 * Math.PI / quantity; for (let i = 0; i < quantity; ++i) { let angle = dAngle * randFloat(i, i + 1); let dist = randFloat(2, 5); let objectList = groveEntities; if (i % 3 == 0) objectList = groveActors; let position = Vector2D.add(point, new Vector2D(dist, 0).rotate(-angle)); placeObject(position.x, position.y, pickRandom(objectList), 0, randomAngle()); let painters = [new TerrainPainter(groveTerrainTexture)]; if (groveTileClass) painters.push(paintClass(groveTileClass)); createArea( new ClumpPlacer(5, 1, 1, 1, position), painters); } } var farmEntities = { "temperate": { "building": "structures/mace_farmstead", "animal": "gaia/fauna_pig" }, "snowy": { "building": "structures/brit_farmstead", "animal": "gaia/fauna_sheep" }, "desert": { "building": "structures/pers_farmstead", "animal": "gaia/fauna_camel" }, "alpine": { "building": "structures/rome_farmstead", "animal": "gaia/fauna_sheep" }, "mediterranean": { "building": "structures/iber_farmstead", "animal": "gaia/fauna_pig" }, "savanna": { "building": "structures/sele_farmstead", "animal": "gaia/fauna_horse" }, "tropic": { "building": "structures/ptol_farmstead", "animal": "gaia/fauna_camel" }, "autumn": { "building": "structures/gaul_farmstead", "animal": "gaia/fauna_horse" } }; g_WallStyles.other = { "overlap": 0, "fence": readyWallElement("other/fence_long", "gaia"), "fence_short": readyWallElement("other/fence_short", "gaia"), "bench": { "angle": Math.PI / 2, "length": 1.5, "indent": 0, "bend": 0, "templateName": "other/bench" }, "foodBin": { "angle": Math.PI / 2, "length": 1.5, "indent": 0, "bend": 0, "templateName": "gaia/special_treasure_food_bin" }, "animal": { "angle": 0, "length": 0, "indent": 0.75, "bend": 0, "templateName": farmEntities[currentBiome()].animal }, "farmstead": { "angle": Math.PI, "length": 0, "indent": -3, "bend": 0, "templateName": farmEntities[currentBiome()].building } }; let fences = [ new Fortress("fence", [ "foodBin", "farmstead", "bench", "turn_0.25", "animal", "turn_0.25", "fence", "turn_0.25", "animal", "turn_0.25", "fence", "turn_0.25", "animal", "turn_0.25", "fence" ]), new Fortress("fence", [ "foodBin", "farmstead", "fence", "turn_0.25", "animal", "turn_0.25", "fence", "turn_0.25", "animal", "turn_0.25", "bench", "animal", "fence", "turn_0.25", "animal", "turn_0.25", "fence" ]), new Fortress("fence", [ "foodBin", "farmstead", "turn_0.5", "bench", "turn_-0.5", "fence_short", "turn_0.25", "animal", "turn_0.25", "fence", "turn_0.25", "animal", "turn_0.25", "fence", "turn_0.25", "animal", "turn_0.25", "fence_short", "animal", "fence" ]), new Fortress("fence", [ "foodBin", "farmstead", "turn_0.5", "fence_short", "turn_-0.5", "bench", "turn_0.25", "animal", "turn_0.25", "fence", "turn_0.25", "animal", "turn_0.25", "fence", "turn_0.25", "animal", "turn_0.25", "fence_short", "animal", "fence" ]), new Fortress("fence", [ "foodBin", "farmstead", "fence", "turn_0.25", "animal", "turn_0.25", "bench", "animal", "fence", "turn_0.25", "animal", "turn_0.25", "fence_short", "animal", "fence", "turn_0.25", "animal", "turn_0.25", "fence_short", "animal", "fence" ]) ]; let num = fences.length; for (let i = 0; i < num; ++i) fences.push(new Fortress("fence", clone(fences[i].wall).reverse())); // Camps with fire and gold treasure function placeCamp(point, centerEntity = "actor|props/special/eyecandy/campfire.xml", otherEntities = ["gaia/special_treasure_metal", "gaia/special_treasure_standing_stone", "units/brit_infantry_slinger_b", "units/brit_infantry_javelinist_b", "units/gaul_infantry_slinger_b", "units/gaul_infantry_javelinist_b", "units/gaul_champion_fanatic", "actor|props/special/common/waypoint_flag.xml", "actor|props/special/eyecandy/barrel_a.xml", "actor|props/special/eyecandy/basket_celt_a.xml", "actor|props/special/eyecandy/crate_a.xml", "actor|props/special/eyecandy/dummy_a.xml", "actor|props/special/eyecandy/handcart_1.xml", "actor|props/special/eyecandy/handcart_1_broken.xml", "actor|props/special/eyecandy/sack_1.xml", "actor|props/special/eyecandy/sack_1_rough.xml" ] ) { placeObject(point.x, point.y, centerEntity, 0, randomAngle()); let quantity = randIntInclusive(5, 11); let dAngle = 2 * Math.PI / quantity; for (let i = 0; i < quantity; ++i) { let angle = dAngle * randFloat(i, i + 1); let dist = randFloat(1, 3); placeObject(point.x + dist * Math.cos(angle), point.y + dist * Math.sin(angle), pickRandom(otherEntities), 0, randomAngle()); } } function placeStartLocationResources( point, foodEntities = [g_Gaia.fruitBush, g_Gaia.chicken], groveEntities = [ g_Gaia.tree1, g_Gaia.tree1, g_Gaia.tree1, g_Gaia.tree1, g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree2, g_Gaia.tree2, g_Gaia.tree2, g_Gaia.tree3, g_Gaia.tree3, g_Gaia.tree3, g_Gaia.tree4, g_Gaia.tree4, g_Gaia.tree5 ], groveTerrainTexture = getArray(g_Terrains.forestFloor1), averageDistToCC = 10, dAverageDistToCC = 2 ) { function getRandDist() { return averageDistToCC + randFloat(-dAverageDistToCC, dAverageDistToCC); } let currentAngle = randomAngle(); // Stone let dAngle = 4/9 * Math.PI; let angle = currentAngle + randFloat(dAngle / 4, 3 * dAngle / 4); placeMine({ "x": point.x + averageDistToCC * Math.cos(angle), "y": point.y + averageDistToCC * Math.sin(angle) }, g_Gaia.stoneLarge); currentAngle += dAngle; // Wood let quantity = 80; dAngle = 2/3 * Math.PI / quantity; for (let i = 0; i < quantity; ++i) { angle = currentAngle + randFloat(0, dAngle); let dist = getRandDist(); let objectList = groveEntities; if (i % 2 == 0) objectList = groveActors; let position = Vector2D.add(point, new Vector2D(dist, 0).rotate(-angle)); placeObject(position.x, position.y, pickRandom(objectList), 0, randomAngle()); createArea( new ClumpPlacer(5, 1, 1, 1, position), [ new TerrainPainter(groveTerrainTexture), paintClass(clGrove) ]); currentAngle += dAngle; } // Metal dAngle = 4/9 * Math.PI; angle = currentAngle + randFloat(dAngle / 4, 3 * dAngle / 4); placeMine({ "x": point.x + averageDistToCC * Math.cos(angle), "y": point.y + averageDistToCC * Math.sin(angle) }, g_Gaia.metalLarge); currentAngle += dAngle; // Berries and domestic animals quantity = 15; dAngle = 4/9 * Math.PI / quantity; for (let i = 0; i < quantity; ++i) { angle = currentAngle + randFloat(0, dAngle); let dist = getRandDist(); placeObject(point.x + dist * Math.cos(angle), point.y + dist * Math.sin(angle), pickRandom(foodEntities), 0, randomAngle()); currentAngle += dAngle; } } /** * Base terrain shape generation and settings */ // Height range by map size let heightScale = (g_Map.size + 256) / 768 / 4; let heightRange = { "min": MIN_HEIGHT * heightScale, "max": MAX_HEIGHT * heightScale }; // Water coverage let averageWaterCoverage = 1/5; // NOTE: Since terrain generation is quite unpredictable actual water coverage might vary much with the same value let heightSeaGround = -MIN_HEIGHT + heightRange.min + averageWaterCoverage * (heightRange.max - heightRange.min); // Water height in environment and the engine let heightSeaGroundAdjusted = heightSeaGround + MIN_HEIGHT; // Water height as terrain height setWaterHeight(heightSeaGround); // Generate base terrain shape let lowH = heightRange.min; let medH = (heightRange.min + heightRange.max) / 2; // Lake let initialHeightmap = [ [medH, medH, medH, medH, medH, medH], [medH, medH, medH, medH, medH, medH], [medH, medH, lowH, lowH, medH, medH], [medH, medH, lowH, lowH, medH, medH], [medH, medH, medH, medH, medH, medH], [medH, medH, medH, medH, medH, medH], ]; if (g_Map.size < 256) { initialHeightmap = [ [medH, medH, medH, medH, medH], [medH, medH, medH, medH, medH], [medH, medH, lowH, medH, medH], [medH, medH, medH, medH, medH], [medH, medH, medH, medH, medH] ]; } if (g_Map.size >= 384) { initialHeightmap = [ [medH, medH, medH, medH, medH, medH, medH, medH], [medH, medH, medH, medH, medH, medH, medH, medH], [medH, medH, medH, medH, medH, medH, medH, medH], [medH, medH, medH, lowH, lowH, medH, medH, medH], [medH, medH, medH, lowH, lowH, medH, medH, medH], [medH, medH, medH, medH, medH, medH, medH, medH], [medH, medH, medH, medH, medH, medH, medH, medH], [medH, medH, medH, medH, medH, medH, medH, medH], ]; } setBaseTerrainDiamondSquare(heightRange.min, heightRange.max, initialHeightmap, 0.8); // Apply simple erosion for (let i = 0; i < 5; ++i) splashErodeMap(0.1); globalSmoothHeightmap(); // Final rescale rescaleHeightmap(heightRange.min, heightRange.max); Engine.SetProgress(25); /** * Prepare terrain texture placement */ let heighLimits = [ heightRange.min + 3/4 * (heightSeaGroundAdjusted - heightRange.min), // 0 Deep water heightSeaGroundAdjusted, // 1 Shallow water heightSeaGroundAdjusted + 2/8 * (heightRange.max - heightSeaGroundAdjusted), // 2 Shore heightSeaGroundAdjusted + 3/8 * (heightRange.max - heightSeaGroundAdjusted), // 3 Low ground heightSeaGroundAdjusted + 4/8 * (heightRange.max - heightSeaGroundAdjusted), // 4 Player and path height heightSeaGroundAdjusted + 6/8 * (heightRange.max - heightSeaGroundAdjusted), // 5 High ground heightSeaGroundAdjusted + 7/8 * (heightRange.max - heightSeaGroundAdjusted), // 6 Lower forest border heightRange.max // 7 Forest ]; let playerHeightRange = { "min" : heighLimits[3], "max" : heighLimits[4] }; let resourceSpotHeightRange = { "min" : (heighLimits[2] + heighLimits[3]) / 2, "max" : (heighLimits[4] + heighLimits[5]) / 2 }; let playerHeight = (playerHeightRange.min + playerHeightRange.max) / 2; // Average player height log("Chosing starting locations..."); let [playerIDs, startLocations] = sortPlayersByLocation(getStartLocationsByHeightmap(playerHeightRange, 1000, 30)); Engine.SetProgress(30); /** * Smooth Start Locations before height region calculation */ let playerBaseRadius = 35; if (g_Map.size < 256) playerBaseRadius = 25; for (let p = 0; p < playerIDs.length; ++p) rectangularSmoothToHeight(startLocations[p], playerBaseRadius, playerBaseRadius, playerHeight, 0.7); /** * Calculate tile centered height map after start position smoothing but before placing paths * This has nothing to to with TILE_CENTERED_HEIGHT_MAP which should be false! */ let tchm = getTileCenteredHeightmap(); /** * Add paths (If any) */ -let clPath = createTileClass(); +let clPath = g_Map.createTileClass(); /** * Divide tiles in areas by height and avoid paths */ let areas = heighLimits.map(heightLimit => []); for (let x = 0; x < tchm.length; ++x) for (let y = 0; y < tchm[0].length; ++y) { if (g_Map.tileClasses[clPath].inclusionCount[x][y] > 0) // Avoid paths continue; let minHeight = heightRange.min; for (let h = 0; h < heighLimits.length; ++h) { if (tchm[x][y] >= minHeight && tchm[x][y] <= heighLimits[h]) { areas[h].push(new Vector2D(x, y)); break; } else minHeight = heighLimits[h]; } } /** * Get max slope of each area */ let slopeMap = getSlopeMap(); let minSlope = []; let maxSlope = []; for (let h = 0; h < heighLimits.length; ++h) { minSlope[h] = Infinity; maxSlope[h] = 0; for (let point of areas[h]) { let slope = slopeMap[point.x][point.y]; if (slope > maxSlope[h]) maxSlope[h] = slope; if (slope < minSlope[h]) minSlope[h] = slope; } } /** * Paint areas by height and slope */ for (let h = 0; h < heighLimits.length; ++h) for (let point of areas[h]) { let actor; let texture = pickRandom(wildLakeBiome[h].texture); if (slopeMap[point.x][point.y] < (minSlope[h] + maxSlope[h]) / 2) { if (randBool(wildLakeBiome[h].actor[1])) actor = pickRandom(wildLakeBiome[h].actor[0]); } else { texture = pickRandom(wildLakeBiome[h].textureHS); if (randBool(wildLakeBiome[h].actorHS[1])) actor = pickRandom(wildLakeBiome[h].actorHS[0]); } g_Map.setTexture(point, texture); if (actor) placeObject(point.x + randFloat(0, 1), point.y + randFloat(0, 1), actor, 0, randomAngle()); } Engine.SetProgress(80); log("Placing resources..."); let avoidPoints = clone(startLocations); for (let i = 0; i < avoidPoints.length; ++i) avoidPoints[i].dist = 30; let resourceSpots = getPointsByHeight(resourceSpotHeightRange, avoidPoints, clPath); Engine.SetProgress(55); log("Placing players..."); if (isNomad()) - placePlayersNomad(createTileClass(), new HeightConstraint(playerHeightRange.min, playerHeightRange.max)); + placePlayersNomad(g_Map.createTileClass(), new HeightConstraint(playerHeightRange.min, playerHeightRange.max)); else for (let p = 0; p < playerIDs.length; ++p) { let point = startLocations[p]; placeCivDefaultStartingEntities(point, playerIDs[p], g_Map.size > 192); placeStartLocationResources(point); } let mercenaryCamps = isNomad() ? 0 : Math.ceil(g_Map.size / 256); log("Maximum number of mercenary camps: " + mercenaryCamps); for (let i = 0; i < resourceSpots.length; ++i) { let choice = i % 5; if (choice == 0) placeMine(resourceSpots[i], g_Gaia.stoneLarge); if (choice == 1) placeMine(resourceSpots[i], g_Gaia.metalLarge); if (choice == 2) placeGrove(resourceSpots[i]); if (choice == 3) { placeCamp(resourceSpots[i]); rectangularSmoothToHeight(resourceSpots[i], 5, 5, g_Map.getHeight(resourceSpots[i]) - 10, 0.5); } if (choice == 4) { if (mercenaryCamps) { placeStartingEntities(resourceSpots[i], 0, mercenaryCampGuards[currentBiome()]); rectangularSmoothToHeight(resourceSpots[i], 15, 15, g_Map.getHeight(resourceSpots[i]), 0.5); --mercenaryCamps; } else { placeCustomFortress(resourceSpots[i].x, resourceSpots[i].y, pickRandom(fences), "other", 0, randomAngle()); rectangularSmoothToHeight(resourceSpots[i], 10, 10, g_Map.getHeight(resourceSpots[i]), 0.5); } } } g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/pyrenean_sierra.js (revision 21000) @@ -1,483 +1,483 @@ Engine.LoadLibrary("rmgen"); TILE_CENTERED_HEIGHT_MAP = true; const tGrassSpecific = ["new_alpine_grass_d","new_alpine_grass_d", "new_alpine_grass_e"]; const tGrass = ["new_alpine_grass_d", "new_alpine_grass_b", "new_alpine_grass_e"]; const tGrassMidRange = ["new_alpine_grass_b", "alpine_grass_a"]; const tGrassHighRange = ["new_alpine_grass_a", "alpine_grass_a", "alpine_grass_rocky"]; const tHighRocks = ["alpine_cliff_b", "alpine_cliff_c","alpine_cliff_c", "alpine_grass_rocky"]; const tSnowedRocks = ["alpine_cliff_b", "alpine_cliff_snow"]; const tTopSnow = ["alpine_snow_rocky","alpine_snow_a"]; const tTopSnowOnly = ["alpine_snow_a"]; const tDirtyGrass = ["new_alpine_grass_d","alpine_grass_d","alpine_grass_c", "alpine_grass_b"]; const tLushGrass = ["new_alpine_grass_a","new_alpine_grass_d"]; const tMidRangeCliffs = ["alpine_cliff_b","alpine_cliff_c"]; const tHighRangeCliffs = ["alpine_mountainside","alpine_cliff_snow" ]; const tSand = ["beach_c", "beach_d"]; const tSandTransition = ["beach_scrub_50_"]; const tWater = ["sand_wet_a","sand_wet_b","sand_wet_b","sand_wet_b"]; const tGrassLandForest = "alpine_forrestfloor"; const tGrassLandForest2 = "alpine_grass_d"; const tForestTransition = ["new_alpine_grass_d", "new_alpine_grass_b","alpine_grass_d"]; const tRoad = "new_alpine_citytile"; const tRoadWild = "new_alpine_citytile"; const oBeech = "gaia/flora_tree_euro_beech"; const oPine = "gaia/flora_tree_aleppo_pine"; const oBerryBush = "gaia/flora_bush_berry"; const oDeer = "gaia/fauna_deer"; const oFish = "gaia/fauna_fish"; const oRabbit = "gaia/fauna_rabbit"; const oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; const oStoneSmall = "gaia/geology_stone_alpine_a"; const oMetalLarge = "gaia/geology_metal_alpine_slabs"; const aGrass = "actor|props/flora/grass_soft_small_tall.xml"; const aGrassShort = "actor|props/flora/grass_soft_large.xml"; const aRockLarge = "actor|geology/stone_granite_med.xml"; const aRockMedium = "actor|geology/stone_granite_med.xml"; const aBushMedium = "actor|props/flora/bush_medit_me.xml"; const aBushSmall = "actor|props/flora/bush_medit_sm.xml"; const pForestLand = [tGrassLandForest + TERRAIN_SEPARATOR + oPine,tGrassLandForest + TERRAIN_SEPARATOR + oBeech, tGrassLandForest2 + TERRAIN_SEPARATOR + oPine,tGrassLandForest2 + TERRAIN_SEPARATOR + oBeech, tGrassLandForest,tGrassLandForest2,tGrassLandForest2,tGrassLandForest2]; const pForestLandLight = [tGrassLandForest + TERRAIN_SEPARATOR + oPine,tGrassLandForest + TERRAIN_SEPARATOR + oBeech, tGrassLandForest2 + TERRAIN_SEPARATOR + oPine,tGrassLandForest2 + TERRAIN_SEPARATOR + oBeech, tGrassLandForest,tGrassLandForest2,tForestTransition,tGrassLandForest2, tGrassLandForest,tForestTransition,tGrassLandForest2,tForestTransition, tGrassLandForest2,tGrassLandForest2,tGrassLandForest2,tGrassLandForest2]; const pForestLandVeryLight = [ tGrassLandForest2 + TERRAIN_SEPARATOR + oPine,tGrassLandForest2 + TERRAIN_SEPARATOR + oBeech, tForestTransition,tGrassLandForest2,tForestTransition,tForestTransition,tForestTransition, tGrassLandForest,tForestTransition,tGrassLandForest2,tForestTransition, tGrassLandForest2,tGrassLandForest2,tGrassLandForest2,tGrassLandForest2]; const heightInit = -100; const heightOcean = -22; const heightBase = -6; const heightWaterLevel = 8; const heightPyreneans = 15; const heightGrass = 6; const heightGrassMidRange = 18; const heightGrassHighRange = 30; const heightPassage = scaleByMapSize(25, 40); const heightHighRocks = heightPassage + 5; const heightSnowedRocks = heightHighRocks + 10; const heightMountain = heightHighRocks + 20; const heightOffsetHill = 7; const heightOffsetHillRandom = 2; var g_Map = new RandomMap(heightInit, tGrass); const numPlayers = getNumPlayers(); const mapSize = g_Map.getSize(); const mapCenter = g_Map.getCenter(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); -var clPass = createTileClass(); -var clPyrenneans = createTileClass(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clPass = g_Map.createTileClass(); +var clPyrenneans = g_Map.createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); var startAngle = randomAngle(); var oceanAngle = startAngle + randFloat(-1, 1) * Math.PI / 12; var mountainLength = fractionToTiles(0.68); var mountainWidth = scaleByMapSize(15, 55); var mountainPeaks = 100 * scaleByMapSize(1, 10); var mountainOffset = randFloat(-1, 1) * scaleByMapSize(1, 12); var passageLength = scaleByMapSize(8, 50); var terrainPerHeight = [ { "maxHeight": heightGrass, "steepness": 5, "terrainGround": tGrass, "terrainSteep": tMidRangeCliffs }, { "maxHeight": heightGrassMidRange, "steepness": 8, "terrainGround": tGrassMidRange, "terrainSteep": tMidRangeCliffs }, { "maxHeight": heightGrassHighRange, "steepness": 8, "terrainGround": tGrassHighRange, "terrainSteep": tMidRangeCliffs }, { "maxHeight": heightHighRocks, "steepness": 8, "terrainGround": tHighRocks, "terrainSteep": tHighRangeCliffs }, { "maxHeight": heightSnowedRocks, "steepness": 7, "terrainGround": tSnowedRocks, "terrainSteep": tHighRangeCliffs }, { "maxHeight": Infinity, "steepness": 6, "terrainGround": tTopSnowOnly, "terrainSteep": tTopSnow } ]; log("Creating initial sinusoidal noise..."); var baseHeights = []; for (var ix = 0; ix < mapSize; ix++) { baseHeights.push([]); for (var iz = 0; iz < mapSize; iz++) { let position = new Vector2D(ix, iz); if (g_Map.inMapBounds(position)) { let height = heightBase + randFloat(-1, 1) + scaleByMapSize(1, 3) * (Math.cos(ix / scaleByMapSize(5, 30)) + Math.sin(iz / scaleByMapSize(5, 30))); g_Map.setHeight(position, height); baseHeights[ix].push(height); } else baseHeights[ix].push(heightInit); } } placePlayerBases({ "PlayerPlacement": [primeSortAllPlayers(), ...playerPlacementCustomAngle( fractionToTiles(0.35), mapCenter, i => oceanAngle + Math.PI * (i % 2 ? 1 : -1) * ((1/2 + 1/3 * (2/numPlayers * (i + 1 - i % 2) - 1))))], "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oPine }, "Decoratives": { "template": aGrassShort } }); Engine.SetProgress(30); log("Creating the pyreneans..."); var mountainVec = new Vector2D(mountainLength, 0).rotate(-startAngle); var mountainStart = Vector2D.sub(mapCenter, Vector2D.div(mountainVec, 2)); var mountainDirection = mountainVec.clone().normalize(); createPyreneans(); paintTileClassBasedOnHeight(heightPyreneans, Infinity, Elevation_ExcludeMin_ExcludeMax, clPyrenneans); Engine.SetProgress(40); /** * Generates the mountain peak noise. * * @param {number} x - between 0 and 1 * @returns {number} between 0 and 1 */ function sigmoid(x, peakPosition) { return 1 / (1 + Math.exp(x)) * // If we're too far from the border, we flatten (0.2 - Math.max(0, Math.abs(0.5 - peakPosition) - 0.3)) * 5; } function createPyreneans() { for (let peak = 0; peak < mountainPeaks; ++peak) { let peakPosition = peak / mountainPeaks; let peakHeight = randFloat(0, 10); for (let distance = 0; distance < mountainWidth; distance += 1/3) { let rest = 2 * (1 - distance / mountainWidth); let sigmoidX = - 1 * (rest - 1.9) + - 4 * (rest - randFloat(0.9, 1.1)) * (rest - randFloat(0.9, 1.1)) * (rest - randFloat(0.9, 1.1)); for (let direction of [-1, 1]) { let pos = Vector2D.sum([ Vector2D.add(mountainStart, Vector2D.mult(mountainDirection, peakPosition * mountainLength)), new Vector2D(mountainOffset, 0).rotate(-peakPosition * Math.PI * 4), new Vector2D(distance, 0).rotate(-startAngle - direction * Math.PI / 2) ]).round(); g_Map.setHeight(pos, baseHeights[pos.x][pos.y] + (heightMountain + peakHeight + randFloat(-9, 9)) * sigmoid(sigmoidX, peakPosition)); } } } } log("Smoothing pyreneans..."); for (let ix = 1; ix < mapSize - 1; ++ix) for (let iz = 1; iz < mapSize - 1; ++iz) { let position = new Vector2D(ix, iz); if (g_Map.validHeight(position) && getTileClass(clPyrenneans).countMembersInRadius(ix, iz, 1)) { let height = g_Map.getHeight(position); let index = 1 / (1 + Math.max(0, height / 7)); g_Map.setHeight(position, height * (1 - index) + g_Map.getAverageHeight(position) * index); } } Engine.SetProgress(48); log("Creating passages..."); var passageLocation = 0.35; var passageVec = mountainDirection.perpendicular().mult(passageLength); for (let passLoc of [passageLocation, 1 - passageLocation]) for (let direction of [1, -1]) { let passageStart = Vector2D.add(mountainStart, Vector2D.mult(mountainVec, passLoc)); let passageEnd = Vector2D.add(passageStart, Vector2D.mult(passageVec, direction)); createPassage({ "start": passageStart, "end": passageEnd, "startHeight": heightPassage, "startWidth": 7, "endWidth": 7, "smoothWidth": 2, "tileClass": clPass }); } Engine.SetProgress(50); log("Smoothing the mountains..."); for (let ix = 1; ix < mapSize - 1; ++ix) for (let iz = 1; iz < mapSize - 1; ++iz) { let position = new Vector2D(ix, iz); if (g_Map.inMapBounds(position) && getTileClass(clPyrenneans).countMembersInRadius(ix, iz, 1)) { let heightNeighbor = g_Map.getAverageHeight(position); let index = 1 / (1 + Math.max(0, (g_Map.getHeight(position) - 10) / 7)); g_Map.setHeight(position, g_Map.getHeight(position) * (1 - index) + heightNeighbor * index); } } log("Creating oceans..."); for (let ocean of distributePointsOnCircle(2, oceanAngle, fractionToTiles(0.48), mapCenter)[0]) createArea( new ClumpPlacer(diskArea(fractionToTiles(0.18)), 0.9, 0.05, 10, ocean), [ new ElevationPainter(heightOcean), paintClass(clWater) ]); log("Smoothing around the water..."); var smoothDist = 5; for (let ix = 1; ix < mapSize - 1; ++ix) for (let iz = 1; iz < mapSize - 1; ++iz) { let position = new Vector2D(ix, iz); if (!g_Map.inMapBounds(position) || !getTileClass(clWater).countMembersInRadius(ix, iz, smoothDist)) continue; let averageHeight = 0; let todivide = 0; for (let xx = -smoothDist; xx <= smoothDist; ++xx) for (let yy = -smoothDist; yy <= smoothDist; ++yy) { let smoothPos = Vector2D.add(position, new Vector2D(xx, yy)); if (g_Map.inMapBounds(smoothPos) && (xx != 0 || yy != 0)) { averageHeight += g_Map.getHeight(smoothPos) / (Math.abs(xx) + Math.abs(yy)); todivide += 1 / (Math.abs(xx) + Math.abs(yy)); } } g_Map.setHeight(position, (averageHeight + 2 * g_Map.getHeight(position)) / (todivide + 2)); } Engine.SetProgress(55); log("Creating hills..."); createAreas( new ClumpPlacer(scaleByMapSize(60, 120), 0.3, 0.06, 5), [ new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHill, 4, heightOffsetHillRandom), new TerrainPainter(tGrassSpecific), paintClass(clHill) ], avoidClasses(clWater, 5, clPlayer, 20, clBaseResource, 6, clPyrenneans, 2), scaleByMapSize(5, 35)); log("Creating forests..."); var types = [[tForestTransition, pForestLandVeryLight, pForestLandLight, pForestLand]]; var size = scaleByMapSize(40, 115) * Math.PI; var num = Math.floor(scaleByMapSize(8,40) / types.length); for (let type of types) createAreas( new ClumpPlacer(size, 0.2, 0.1, 1), [ new LayeredPainter(type, [scaleByMapSize(1, 2), scaleByMapSize(3, 6), scaleByMapSize(3, 6)]), paintClass(clForest) ], avoidClasses(clPlayer, 20, clPyrenneans,0, clForest, 7, clWater, 2), num); Engine.SetProgress(60); log("Creating lone trees..."); var num = scaleByMapSize(80,400); var group = new SimpleGroup([new SimpleObject(oPine, 1,2, 1,3),new SimpleObject(oBeech, 1,2, 1,3)], true, clForest); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 1, clPlayer, 8,clPyrenneans, 1), num, 20 ); log("Painting the map..."); for (let x = 0; x < mapSize; ++x) for (let z = 0; z < mapSize; ++z) { let position = new Vector2D(x, z); let height = g_Map.getHeight(position); let heightDiff = g_Map.getSlope(position); if (getTileClass(clPyrenneans).countMembersInRadius(x, z, 2)) { let layer = terrainPerHeight.find(layer => height < layer.maxHeight); createTerrain(heightDiff > layer.steepness ? layer.terrainSteep : layer.terrainGround).place(position); } let terrainShore = getShoreTerrain(height, heightDiff, x, z); if (terrainShore) createTerrain(terrainShore).place(position); } function getShoreTerrain(height, heightDiff, x, z) { if (height <= -14) return tWater; if (height <= -2 && getTileClass(clWater).countMembersInRadius(x, z, 2)) return heightDiff < 2.5 ? tSand : tMidRangeCliffs; if (height <= 0 && getTileClass(clWater).countMembersInRadius(x, z, 3)) return heightDiff < 2.5 ? tSandTransition : tMidRangeCliffs; return undefined; } log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 20), scaleByMapSize(5, 40), scaleByMapSize(8, 60)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new TerrainPainter(tDirtyGrass), paintClass(clDirt) ], avoidClasses(clWater, 3, clForest, 0, clPyrenneans,5, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45)); log("Creating grass patches..."); for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new TerrainPainter(tLushGrass), avoidClasses(clWater, 3, clForest, 0, clPyrenneans,5, clHill, 0, clDirt, 5, clPlayer, 6), scaleByMapSize(15, 45)); Engine.SetProgress(70); // making more in dirt areas so as to appear different log("Creating small grass tufts..."); var group = new SimpleGroup( [new SimpleObject(aGrassShort, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clHill, 2, clPlayer, 5, clDirt, 0, clPyrenneans,2), scaleByMapSize(13, 200) ); createObjectGroupsDeprecated(group, 0, stayClasses(clDirt,1), scaleByMapSize(13, 200),10); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aGrass, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clHill, 2, clPlayer, 5, clDirt, 1, clForest, 0, clPyrenneans,2), scaleByMapSize(13, 200) ); createObjectGroupsDeprecated(group, 0, stayClasses(clDirt,1), scaleByMapSize(13, 200),10); Engine.SetProgress(75); log("Creating bushes..."); group = new SimpleGroup( [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 2, clPlayer, 1, clPyrenneans, 1), scaleByMapSize(13, 200), 50 ); Engine.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, 3, clForest, 1, clPlayer, 20, clRock, 8, clPyrenneans, 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, 8, clPyrenneans, 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, 8, clRock, 5, clPyrenneans, 1), scaleByMapSize(4,16), 100 ); Engine.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), 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), scaleByMapSize(8, 131), 50 ); Engine.SetProgress(90); log("Creating deer..."); group = new SimpleGroup( [new SimpleObject(oDeer, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clPyrenneans, 1, clFood, 15), 3 * numPlayers, 50 ); log("Creating rabbit..."); group = new SimpleGroup( [new SimpleObject(oRabbit, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clPyrenneans, 1, clFood,15), 3 * numPlayers, 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)],true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clPyrenneans, 1, clFood, 10), randIntInclusive(1, 4) * numPlayers + 2, 50); log("Creating fish..."); group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clFood, 15), stayClasses(clWater, 6)], 20 * numPlayers, 60 ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clPyrenneans, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setSunElevation(Math.PI * randFloat(1/5, 1/3)); setSunRotation(randomAngle()); setSkySet("cumulus"); setSunColor(0.73,0.73,0.65); setTerrainAmbientColor(0.45,0.45,0.50); setUnitsAmbientColor(0.4,0.4,0.4); setWaterColor(0.263, 0.353, 0.616); setWaterTint(0.104, 0.172, 0.563); setWaterWaviness(5.0); setWaterType("ocean"); setWaterMurkiness(0.83); setWaterHeight(heightWaterLevel); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/rmgen/gaia_terrain.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/rmgen/gaia_terrain.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/rmgen/gaia_terrain.js (revision 21000) @@ -1,600 +1,600 @@ /** * @file These functions are often used to create a landscape, for instance shaping mountains, hills, rivers or grass and dirt patches. */ /** * Bumps add slight, diverse elevation differences to otherwise completely level terrain. */ function createBumps(constraint, count, minSize, maxSize, spread, failFraction = 0, elevation = 2) { log("Creating bumps..."); createAreas( new ChainPlacer( minSize || 1, maxSize || Math.floor(scaleByMapSize(4, 6)), spread || Math.floor(scaleByMapSize(2, 5)), failFraction), new SmoothElevationPainter(ELEVATION_MODIFY, elevation, 2), constraint, count || scaleByMapSize(100, 200)); } /** * Hills are elevated, planar, impassable terrain areas. */ function createHills(terrainset, constraint, tileClass, count, minSize, maxSize, spread, failFraction = 0.5, elevation = 18, elevationSmoothing = 2) { log("Creating hills..."); createAreas( new ChainPlacer( minSize || 1, maxSize || Math.floor(scaleByMapSize(4, 6)), spread || Math.floor(scaleByMapSize(16, 40)), failFraction), [ new LayeredPainter(terrainset, [1, elevationSmoothing]), new SmoothElevationPainter(ELEVATION_SET, elevation, elevationSmoothing), paintClass(tileClass) ], constraint, count || scaleByMapSize(1, 4) * getNumPlayers()); } /** * Mountains are impassable smoothened cones. */ function createMountains(terrain, constraint, tileClass, count, maxHeight, minRadius, maxRadius, numCircles) { log("Creating mountains..."); let mapSize = g_Map.getSize(); for (let i = 0; i < (count || scaleByMapSize(1, 4) * getNumPlayers()); ++i) createMountain( maxHeight !== undefined ? maxHeight : Math.floor(scaleByMapSize(30, 50)), minRadius || Math.floor(scaleByMapSize(3, 4)), maxRadius || Math.floor(scaleByMapSize(6, 12)), numCircles || Math.floor(scaleByMapSize(4, 10)), constraint, randIntExclusive(0, mapSize), randIntExclusive(0, mapSize), terrain, tileClass, 14); } /** * Create a mountain using a technique very similar to ChainPlacer. */ function createMountain(maxHeight, minRadius, maxRadius, numCircles, constraints, x, z, terrain, tileClass, fcc = 0, q = []) { let position = new Vector2D(x, z); let constraint = new AndConstraint(constraints); if (!g_Map.inMapBounds(position) || !constraint.allows(position)) return; let mapSize = g_Map.getSize(); let queueEmpty = !q.length; let gotRet = []; for (let i = 0; i < mapSize; ++i) { gotRet[i] = []; for (let j = 0; j < mapSize; ++j) gotRet[i][j] = -1; } --mapSize; minRadius = Math.max(1, Math.min(minRadius, maxRadius)); let edges = [[x, z]]; let circles = []; for (let i = 0; i < numCircles; ++i) { let badPoint = false; let [cx, cz] = pickRandom(edges); let radius; if (queueEmpty) radius = randIntInclusive(minRadius, maxRadius); else { radius = q.pop(); queueEmpty = !q.length; } let sx = Math.max(0, cx - radius); let sz = Math.max(0, cz - radius); let lx = Math.min(cx + radius, mapSize); let lz = Math.min(cz + radius, mapSize); let radius2 = Math.square(radius); for (let ix = sx; ix <= lx; ++ix) { for (let iz = sz; iz <= lz; ++iz) { let pos = new Vector2D(ix, iz); if (Math.euclidDistance2D(ix, iz, cx, cz) > radius2 || !g_Map.inMapBounds(pos)) continue; if (!constraint.allows(pos)) { badPoint = true; break; } let state = gotRet[ix][iz]; if (state == -1) { gotRet[ix][iz] = -2; } else if (state >= 0) { edges.splice(state, 1); gotRet[ix][iz] = -2; for (let k = state; k < edges.length; ++k) --gotRet[edges[k][0]][edges[k][1]]; } } if (badPoint) break; } if (badPoint) continue; circles.push([cx, cz, radius]); for (let ix = sx; ix <= lx; ++ix) for (let iz = sz; iz <= lz; ++iz) { if (gotRet[ix][iz] != -2 || fcc && (x - ix > fcc || ix - x > fcc || z - iz > fcc || iz - z > fcc) || ix > 0 && gotRet[ix-1][iz] == -1 || iz > 0 && gotRet[ix][iz-1] == -1 || ix < mapSize && gotRet[ix+1][iz] == -1 || iz < mapSize && gotRet[ix][iz+1] == -1) continue; edges.push([ix, iz]); gotRet[ix][iz] = edges.length - 1; } } for (let [cx, cz, radius] of circles) { let circlePosition = new Vector2D(cx, cz); let sx = Math.max(0, cx - radius); let sz = Math.max(0, cz - radius); let lx = Math.min(cx + radius, mapSize); let lz = Math.min(cz + radius, mapSize); let clumpHeight = radius / maxRadius * maxHeight * randFloat(0.8, 1.2); for (let ix = sx; ix <= lx; ++ix) for (let iz = sz; iz <= lz; ++iz) { let position = new Vector2D(ix, iz); let distance = position.distanceTo(circlePosition); let newHeight = randIntInclusive(0, 2) + Math.round(2/3 * clumpHeight * (Math.sin(Math.PI * 2/3 * (3/4 - distance / radius)) + 0.5)); if (distance > radius) continue; if (g_Map.getHeight(position) < newHeight) g_Map.setHeight(position, newHeight); else if (g_Map.getHeight(position) >= newHeight && g_Map.getHeight(position) < newHeight + 4) g_Map.setHeight(position, newHeight + 4); if (terrain !== undefined) createTerrain(terrain).place(position); if (tileClass !== undefined) addToClass(ix, iz, tileClass); } } } /** * Generates a volcano mountain. Smoke and lava are optional. * * @param {number} center - Vector2D location on the tilemap. * @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(position, tileClass, terrainTexture, lavaTextures, smoke, elevationType) { log("Creating volcano..."); - let clLava = createTileClass(); + let clLava = g_Map.createTileClass(); let layers = [ { "clumps": diskArea(scaleByMapSize(18, 25)), "elevation": 15, "tileClass": tileClass, "steepness": 3 }, { "clumps": diskArea(scaleByMapSize(16, 23)), "elevation": 25, - "tileClass": createTileClass(), + "tileClass": g_Map.createTileClass(), "steepness": 3 }, { "clumps": diskArea(scaleByMapSize(10, 15)), "elevation": 45, - "tileClass": createTileClass(), + "tileClass": g_Map.createTileClass(), "steepness": 3 }, { "clumps": diskArea(scaleByMapSize(8, 11)), "elevation": 62, - "tileClass": createTileClass(), + "tileClass": g_Map.createTileClass(), "steepness": 3 }, { "clumps": diskArea(scaleByMapSize(4, 6)), "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(layers[i].clumps, 0.7, 0.05, 100, position), [ layers[i].painter || new LayeredPainter([terrainTexture, terrainTexture], [3]), new SmoothElevationPainter(elevationType, layers[i].elevation, layers[i].steepness), paintClass(layers[i].tileClass) ], i == 0 ? null : stayClasses(layers[i - 1].tileClass, 1)); if (smoke) { let num = Math.floor(diskArea(scaleByMapSize(3, 5))); createObjectGroup( new SimpleGroup( [new SimpleObject("actor|particle/smoke.xml", num, num, 0, 7)], false, clLava, position.x, position.y), 0, stayClasses(tileClass, 1)); } } /** * Paint the given terrain texture in the given sizes at random places of the map to diversify monotone land texturing. */ function createPatches(sizes, terrain, constraint, count, tileClass, failFraction = 0.5) { for (let size of sizes) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, failFraction), [ new TerrainPainter(terrain), paintClass(tileClass) ], constraint, count); } /** * Same as createPatches, but each patch consists of a set of textures drawn depending to the distance of the patch border. */ function createLayeredPatches(sizes, terrains, terrainWidths, constraint, count, tileClass, failFraction = 0.5) { for (let size of sizes) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, failFraction), [ new LayeredPainter(terrains, terrainWidths), paintClass(tileClass) ], constraint, count); } /** * Creates a meandering river at the given location and width. * Optionally calls a function on the affected tiles. * * @property start - A Vector2D in tile coordinates stating where the river starts. * @property end - A Vector2D in tile coordinates stating where the river ends. * @property parallel - Whether the shorelines should be parallel or meander separately. * @property width - Size between the two shorelines. * @property fadeDist - Size of the shoreline. * @property deviation - Fuzz effect on the shoreline if greater than 0. * @property heightRiverbed - Ground height of the riverbed. * @proeprty heightLand - Ground height of the end of the shoreline. * @property meanderShort - Strength of frequent meanders. * @property meanderLong - Strength of less frequent meanders. * @property [constraint] - If given, ignores any tiles that don't satisfy the given Constraint. * @property [waterFunc] - Optional function called on tiles within the river. * Provides location on the tilegrid, new elevation and * the location on the axis parallel to the river as a fraction of the river length. * @property [landFunc] - Optional function called on land tiles, providing ix, iz, shoreDist1, shoreDist2. * @property [minHeight] - If given, only changes the elevation below this height while still calling the given functions. */ function paintRiver(args) { log("Creating river..."); // Model the river meandering as the sum of two sine curves. let meanderShort = fractionToTiles(args.meanderShort / scaleByMapSize(35, 160)); let meanderLong = fractionToTiles(args.meanderLong / scaleByMapSize(35, 100)); // Unless the river is parallel, each riverside will receive an own random seed and starting angle. let seed1 = randFloat(2, 3); let seed2 = randFloat(2, 3); let startingAngle1 = randFloat(0, 1); let startingAngle2 = randFloat(0, 1); // Computes the deflection of the river at a given point. let riverCurve = (riverFraction, startAngle, seed) => meanderShort * rndRiver(startAngle + fractionToTiles(riverFraction) / 128, seed) + meanderLong * rndRiver(startAngle + fractionToTiles(riverFraction) / 256, seed); // Describe river location in vectors. let riverLength = args.start.distanceTo(args.end); let unitVecRiver = Vector2D.sub(args.start, args.end).normalize(); // Describe river boundaries. let riverMinX = Math.min(args.start.x, args.end.x); let riverMinZ = Math.min(args.start.y, args.end.y); let riverMaxX = Math.max(args.start.x, args.end.x); let riverMaxZ = Math.max(args.start.y, args.end.y); let mapSize = g_Map.getSize(); for (let ix = 0; ix < mapSize; ++ix) for (let iz = 0; iz < mapSize; ++iz) { let vecPoint = new Vector2D(ix, iz); if (args.constraint && !args.constraint.allows(vecPoint)) continue; // Compute the shortest distance to the river. let distanceToRiver = distanceOfPointFromLine(args.start, args.end, vecPoint); // Closest point on the river (i.e the foot of the perpendicular). let river = Vector2D.sub(vecPoint, unitVecRiver.perpendicular().mult(distanceToRiver)); // Only process points that actually are perpendicular with the river. if (river.x < riverMinX || river.x > riverMaxX || river.y < riverMinZ || river.y > riverMaxZ) continue; // Coordinate between 0 and 1 on the axis parallel to the river. let riverFraction = river.distanceTo(args.start) / riverLength; // Amplitude of the river at this location. let riverCurve1 = riverCurve(riverFraction, startingAngle1, seed1); let riverCurve2 = args.parallel ? riverCurve1 : riverCurve(riverFraction, startingAngle2, seed2); // Add noise. let deviation = args.deviation * randFloat(-1, 1); // Compute the distance to the shoreline. let sign = Math.sign(distanceToRiver || 1); let shoreDist1 = sign * riverCurve1 + Math.abs(distanceToRiver) - deviation - args.width / 2; let shoreDist2 = sign * riverCurve2 + Math.abs(distanceToRiver) - deviation + args.width / 2; // Create the elevation for the water and the slopy shoreline and call the user functions. if (shoreDist1 < 0 && shoreDist2 > 0) { let height = args.heightRiverbed; if (shoreDist1 > -args.fadeDist) height += (args.heightLand - args.heightRiverbed) * (1 + shoreDist1 / args.fadeDist); else if (shoreDist2 < args.fadeDist) height += (args.heightLand - args.heightRiverbed) * (1 - shoreDist2 / args.fadeDist); if (args.minHeight === undefined || height < args.minHeight) g_Map.setHeight(vecPoint, height); if (args.waterFunc) args.waterFunc(vecPoint, height, riverFraction); } else if (args.landFunc) args.landFunc(vecPoint, shoreDist1, shoreDist2); } } /** * Helper function to create a meandering river. * It works the same as sin or cos function with the difference that it's period is 1 instead of 2 pi. */ function rndRiver(f, seed) { let rndRw = seed; for (let i = 0; i <= f; ++i) rndRw = 10 * (rndRw % 1); let rndRr = f % 1; let retVal = (Math.floor(f) % 2 ? -1 : 1) * rndRr * (rndRr - 1); let rndRe = Math.floor(rndRw) % 5; if (rndRe == 0) retVal *= 2.3 * (rndRr - 0.5) * (rndRr - 0.5); else if (rndRe == 1) retVal *= 2.6 * (rndRr - 0.3) * (rndRr - 0.7); else if (rndRe == 2) retVal *= 22 * (rndRr - 0.2) * (rndRr - 0.3) * (rndRr - 0.3) * (rndRr - 0.8); else if (rndRe == 3) retVal *= 180 * (rndRr - 0.2) * (rndRr - 0.2) * (rndRr - 0.4) * (rndRr - 0.6) * (rndRr - 0.6) * (rndRr - 0.8); else if (rndRe == 4) retVal *= 2.6 * (rndRr - 0.5) * (rndRr - 0.7); return retVal; } /** * Add small rivers with shallows starting at a central river ending at the map border, if the given Constraint is met. */ function createTributaryRivers(riverAngle, riverCount, riverWidth, heightRiverbed, heightRange, maxAngle, tributaryRiverTileClass, shallowTileClass, constraint) { log("Creating tributary rivers..."); let waviness = 0.4; let smoothness = scaleByMapSize(3, 12); let offset = 0.1; let tapering = 0.05; let heightShallow = -2; let mapSize = g_Map.getSize(); let mapCenter = g_Map.getCenter(); let mapBounds = g_Map.getBounds(); let riverConstraint = avoidClasses(tributaryRiverTileClass, 3); if (shallowTileClass) riverConstraint = new AndConstraint([riverConstraint, avoidClasses(shallowTileClass, 2)]); for (let i = 0; i < riverCount; ++i) { // Determining tributary river location let searchCenter = new Vector2D(fractionToTiles(randFloat(tapering, 1 - tapering)), mapCenter.y); let sign = randBool() ? 1 : -1; let distanceVec = new Vector2D(0, sign * tapering); let searchStart = Vector2D.add(searchCenter, distanceVec).rotateAround(riverAngle, mapCenter); let searchEnd = Vector2D.sub(searchCenter, distanceVec).rotateAround(riverAngle, mapCenter); let start = findLocationInDirectionBasedOnHeight(searchStart, searchEnd, heightRange[0], heightRange[1], 4); if (!start) continue; start.round(); let end = Vector2D.add(mapCenter, new Vector2D(mapSize, 0).rotate(riverAngle - sign * randFloat(maxAngle, 2 * Math.PI - maxAngle))).round(); // Create river if (!createArea( new PathPlacer(start, end, riverWidth, waviness, smoothness, offset, tapering), [ new SmoothElevationPainter(ELEVATION_SET, heightRiverbed, 4), paintClass(tributaryRiverTileClass) ], new AndConstraint([constraint, riverConstraint]))) continue; // Create small puddles at the map border to ensure players being separated createArea( new ClumpPlacer(diskArea(riverWidth / 2), 0.95, 0.6, 10, end), new SmoothElevationPainter(ELEVATION_SET, heightRiverbed, 3), constraint); } // Create shallows if (shallowTileClass) for (let z of [0.25, 0.75]) createPassage({ "start": new Vector2D(mapBounds.left, fractionToTiles(z)).rotateAround(riverAngle, mapCenter), "end": new Vector2D(mapBounds.right, fractionToTiles(z)).rotateAround(riverAngle, mapCenter), "startWidth": scaleByMapSize(8, 12), "endWidth": scaleByMapSize(8, 12), "smoothWidth": 2, "startHeight": heightShallow, "endHeight": heightShallow, "maxHeight": heightShallow, "tileClass": shallowTileClass }); } /** * Creates a smooth, passable path between between start and end with the given startWidth and endWidth. * Paints the given tileclass and terrain. * * @property {Vector2D} start - Location of the passage. * @property {Vector2D} end * @property {number} startWidth - Size of the passage (perpendicular to the direction of the passage). * @property {number} endWidth * @property {number} [startHeight] - Fixed height to be used if the height at the location shouldn't be used. * @property {number} [endHeight] * @property {number} [maxHeight] - If given, do not touch any terrain above this height. * @property {number} smoothWidth - Number of tiles at the passage border to apply height interpolation. * @property {number} [tileClass] - Marks the passage with this tile class. * @property {string} [terrain] - Texture to be painted on the passage area. * @property {string} [edgeTerrain] - Texture to be painted on the borders of the passage. */ function createPassage(args) { let bound = x => Math.max(0, Math.min(Math.round(x), g_Map.getSize())); let startHeight = args.startHeight !== undefined ? args.startHeight : g_Map.getHeight(new Vector2D(bound(args.start.x), bound(args.start.y))); let endHeight = args.endHeight !== undefined ? args.endHeight : g_Map.getHeight(new Vector2D(bound(args.end.x), bound(args.end.y))); let passageVec = Vector2D.sub(args.end, args.start); let widthDirection = passageVec.perpendicular().normalize(); let lengthStep = 1 / (2 * passageVec.length()); for (let lengthFraction = 0; lengthFraction <= 1; lengthFraction += lengthStep) { let locationLength = Vector2D.add(args.start, Vector2D.mult(passageVec, lengthFraction)); let halfPassageWidth = (args.startWidth + (args.endWidth - args.startWidth) * lengthFraction) / 2; let passageHeight = startHeight + (endHeight - startHeight) * lengthFraction; for (let stepWidth = -halfPassageWidth; stepWidth <= halfPassageWidth; stepWidth += 0.5) { let location = Vector2D.add(locationLength, Vector2D.mult(widthDirection, stepWidth)).round(); if (!g_Map.inMapBounds(location) || args.maxHeight !== undefined && g_Map.getHeight(location) > args.maxHeight) continue; let smoothDistance = args.smoothWidth + Math.abs(stepWidth) - halfPassageWidth; g_Map.setHeight( location, smoothDistance > 0 ? (g_Map.getHeight(location) * smoothDistance + passageHeight / smoothDistance) / (smoothDistance + 1 / smoothDistance) : passageHeight); if (args.tileClass !== undefined) addToClass(location.x, location.y, args.tileClass); if (args.edgeTerrain && smoothDistance > 0) createTerrain(args.edgeTerrain).place(location); else if (args.terrain) createTerrain(args.terrain).place(location); } } } /** * Returns the first location between startPoint and endPoint that lies within the given heightrange. */ function findLocationInDirectionBasedOnHeight(startPoint, endPoint, minHeight, maxHeight, offset = 0) { let stepVec = Vector2D.sub(endPoint, startPoint); let distance = Math.ceil(stepVec.length()); stepVec.normalize(); for (let i = 0; i < distance; ++i) { let pos = Vector2D.add(startPoint, Vector2D.mult(stepVec, i)); let ipos = pos.clone().round(); if (g_Map.validHeight(ipos) && g_Map.getHeight(ipos) >= minHeight && g_Map.getHeight(ipos) <= maxHeight) return pos.add(stepVec.mult(offset)); } return undefined; } Index: ps/trunk/binaries/data/mods/public/maps/random/sahel.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/sahel.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/sahel.js (revision 21000) @@ -1,241 +1,241 @@ Engine.LoadLibrary("rmgen"); const tPrimary = "savanna_grass_a"; const tGrass2 = "savanna_grass_b"; const tGrass3 = "savanna_shrubs_a"; const tDirt1 = "savanna_dirt_rocks_a"; const tDirt2 = "savanna_dirt_rocks_b"; const tDirt3 = "savanna_dirt_rocks_c"; const tDirt4 = "savanna_dirt_b"; const tCityTiles = "savanna_tile_a"; const tShore = "savanna_riparian_bank"; const tWater = "savanna_riparian_wet"; const oBaobab = "gaia/flora_tree_baobab"; const oBerryBush = "gaia/flora_bush_berry"; const oGazelle = "gaia/fauna_gazelle"; const oGiraffe = "gaia/fauna_giraffe"; const oGiraffeInfant = "gaia/fauna_giraffe_infant"; const oElephant = "gaia/fauna_elephant_african_bush"; const oElephantInfant = "gaia/fauna_elephant_african_infant"; const oLion = "gaia/fauna_lion"; const oLioness = "gaia/fauna_lioness"; const oZebra = "gaia/fauna_zebra"; const oStoneSmall = "gaia/geology_stone_savanna_small"; const oMetalLarge = "gaia/geology_metal_savanna_slabs"; const aBush = "actor|props/flora/bush_medit_sm_dry.xml"; const aRock = "actor|geology/stone_savanna_med.xml"; const heightSeaGround = -5; const heightLand = 1; var g_Map = new RandomMap(heightLand, tPrimary); var numPlayers = getNumPlayers(); var mapSize = g_Map.getSize(); -var clPlayer = createTileClass(); -var clForest = createTileClass(); -var clWater = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clFood = createTileClass(); -var clBaseResource = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clWater = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clFood = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tCityTiles, "innerTerrain": tCityTiles }, "Chicken": { }, "Berries": { "template": oBerryBush }, "Mines": { "types": [ { "template": oMetalLarge }, { "type": "stone_formation", "template": oStoneSmall, "terrain": tDirt4 } ] }, "Trees": { "template": oBaobab, "count": scaleByMapSize(2, 7), "minDistGroup": 2, "maxDistGroup": 7 } // No decoratives }); Engine.SetProgress(20); log("Creating big patches..."); var patches = [tGrass2, tGrass3]; for (var i = 0; i < patches.length; i++) createAreas( new ChainPlacer(Math.floor(scaleByMapSize(3, 6)), Math.floor(scaleByMapSize(10, 20)), Math.floor(scaleByMapSize(15, 60)), 1), new TerrainPainter(patches[i]), avoidClasses(clPlayer, 10), scaleByMapSize(5, 20)); log("Creating small patches..."); for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)]) for (let patch of [tDirt1, tDirt2, tDirt3]) createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 1), new TerrainPainter(patch), avoidClasses(clPlayer, 12), scaleByMapSize(4, 15)); log("Creating water holes..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), Math.floor(scaleByMapSize(20, 60)), 1), [ new LayeredPainter([tShore, tWater], [1]), new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 7), paintClass(clWater) ], avoidClasses(clPlayer, 24), scaleByMapSize(1, 3)); Engine.SetProgress(55); log("Creating stone mines..."); for (var i = 0; i < scaleByMapSize(12,30); ++i) { let position = new Vector2D(randIntExclusive(0, mapSize), randIntExclusive(0, mapSize)); if (avoidClasses(clPlayer, 30, clRock, 25, clWater, 10).allows(position)) { createStoneMineFormation(position, oStoneSmall, tDirt4); addToClass(position.x, position.y, clRock); } } log("Creating metal mines..."); var group = new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal); createObjectGroupsDeprecated(group, 0, avoidClasses(clPlayer, 20, clMetal, 10, clRock, 8, clWater, 4), scaleByMapSize(2,8), 100 ); Engine.SetProgress(65); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRock, 1,3, 0,3)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clPlayer, 7, clWater, 1), scaleByMapSize(200, 1200), 1 ); Engine.SetProgress(70); log("Creating gazelle..."); group = new SimpleGroup( [new SimpleObject(oGazelle, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11), scaleByMapSize(4,12), 50 ); log("Creating zebra..."); group = new SimpleGroup( [new SimpleObject(oZebra, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11), scaleByMapSize(4,12), 50 ); log("Creating giraffe..."); group = new SimpleGroup( [new SimpleObject(oGiraffe, 2,4, 0,4), new SimpleObject(oGiraffeInfant, 0,2, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11), scaleByMapSize(4,12), 50 ); log("Creating elephants..."); group = new SimpleGroup( [new SimpleObject(oElephant, 2,4, 0,4), new SimpleObject(oElephantInfant, 0,2, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11), scaleByMapSize(4,12), 50 ); log("Creating lions..."); group = new SimpleGroup( [new SimpleObject(oLion, 0,1, 0,4), new SimpleObject(oLioness, 2,3, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 1, clPlayer, 20, clFood, 11), scaleByMapSize(4,12), 50 ); log("Creating berry bush..."); group = new SimpleGroup( [new SimpleObject(oBerryBush, 5,7, 0,4)], true, clFood ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clPlayer, 20, clFood, 12, clRock, 7, clMetal, 6), randIntInclusive(1, 4) * numPlayers + 2, 50 ); Engine.SetProgress(85); createStragglerTrees( [oBaobab], avoidClasses(clForest, 1, clPlayer, 20, clMetal, 6, clRock, 7, clWater, 1), clForest, scaleByMapSize(70, 500)); log("Creating large grass tufts..."); group = new SimpleGroup( [new SimpleObject(aBush, 2,4, 0,1.8, -Math.PI / 8, Math.PI / 8)] ); createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clPlayer, 2, clForest, 0), scaleByMapSize(100, 1200) ); placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); setSunColor(0.87451, 0.847059, 0.647059); setWaterColor(0.741176, 0.592157, 0.27451); setWaterTint(0.741176, 0.592157, 0.27451); setWaterWaviness(2.0); setWaterType("clap"); setWaterMurkiness(0.835938); setUnitsAmbientColor(0.57, 0.58, 0.55); setTerrainAmbientColor(0.447059, 0.509804, 0.54902); setFogFactor(0.25); setFogThickness(0.15); setFogColor(0.847059, 0.737255, 0.482353); setPPEffect("hdr"); setPPContrast(0.57031); setPPBloom(0.34); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/survivalofthefittest.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/survivalofthefittest.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/survivalofthefittest.js (revision 21000) @@ -1,203 +1,203 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); setSelectedBiome(); const tMainTerrain = g_Terrains.mainTerrain; const tForestFloor1 = g_Terrains.forestFloor1; const tForestFloor2 = g_Terrains.forestFloor2; const tCliff = g_Terrains.cliff; const tHill = g_Terrains.hill; const tTier1Terrain = g_Terrains.tier1Terrain; const tTier2Terrain = g_Terrains.tier2Terrain; const tTier3Terrain = g_Terrains.tier3Terrain; const tTier4Terrain = g_Terrains.tier4Terrain; 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 aGrass = g_Decoratives.grass; const aGrassShort = g_Decoratives.grassShort; const aRockLarge = g_Decoratives.rockLarge; const aRockMedium = g_Decoratives.rockMedium; const aBushMedium = g_Decoratives.bushMedium; const aBushSmall = g_Decoratives.bushSmall; const aWaypointFlag = "actor|props/special/common/waypoint_flag.xml"; const pForest1 = [tForestFloor2 + TERRAIN_SEPARATOR + oTree1, tForestFloor2 + TERRAIN_SEPARATOR + oTree2, tForestFloor2]; const pForest2 = [tForestFloor1 + TERRAIN_SEPARATOR + oTree4, tForestFloor1 + TERRAIN_SEPARATOR + oTree5, tForestFloor1]; const oTreasureSeeker = "undeletable|skirmish/units/default_support_female_citizen"; const triggerPointAttacker = "trigger/trigger_point_A"; const triggerPointTreasures = [ "trigger/trigger_point_B", "trigger/trigger_point_C", "trigger/trigger_point_D" ]; const heightLand = 3; const heightHill = 30; var g_Map = new RandomMap(heightHill, tMainTerrain); var numPlayers = getNumPlayers(); var mapSize = g_Map.getSize(); var mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clDirt = createTileClass(); -var clBaseResource = createTileClass(); -var clLand = createTileClass(); -var clWomen = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); +var clLand = g_Map.createTileClass(); +var clWomen = g_Map.createTileClass(); log("Creating central area..."); createArea( new ClumpPlacer(diskArea(fractionToTiles(0.15)), 0.7, 0.1, 10, mapCenter), [ new LayeredPainter([tMainTerrain, tMainTerrain], [3]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 3), paintClass(clLand) ]); Engine.SetProgress(10); var [playerIDs, playerPosition, playerAngle, startAngle] = playerPlacementCircle(fractionToTiles(0.3)); var halfway = distributePointsOnCircle(numPlayers, startAngle, fractionToTiles(0.375), mapCenter)[0].map(v => v.round()); var attacker = distributePointsOnCircle(numPlayers, startAngle, fractionToTiles(0.45), mapCenter)[0].map(v => v.round()); var passage = distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers, fractionToTiles(0.5), mapCenter)[0]; log("Creating player bases and attacker points..."); for (let i = 0; i < numPlayers; ++i) { placeStartingEntities(playerPosition[i], playerIDs[i], getStartingEntities(playerIDs[i]).filter(ent => ent.Template.indexOf("civil_centre") != -1 || ent.Template.indexOf("infantry") != -1)); placePlayerBaseDecoratives({ "playerPosition": playerPosition[i], "template": aGrassShort, "BaseResourceClass": clBaseResource }); log("Creating passage separating players..."); createArea( new PathPlacer(mapCenter, passage[i], scaleByMapSize(14, 24), 0.4, scaleByMapSize(3, 9), 0.2, 0.05), [ new LayeredPainter([tMainTerrain, tMainTerrain], [1]), new SmoothElevationPainter(ELEVATION_SET, heightLand, 4) ]); log("Placing treasure seeker woman..."); let femaleLocation = findLocationInDirectionBasedOnHeight(playerPosition[i], mapCenter, -3 , 3.5, 3).round(); addToClass(femaleLocation.x, femaleLocation.y, clWomen); placeObject(femaleLocation.x, femaleLocation.y, oTreasureSeeker, playerIDs[i], playerAngle[i] + Math.PI); log("Placing attacker spawn point...."); placeObject(attacker[i].x, attacker[i].y, aWaypointFlag, 0, Math.PI / 2); placeObject(attacker[i].x, attacker[i].y, triggerPointAttacker, playerIDs[i], Math.PI / 2); log("Preventing mountains in the area between player and attackers..."); addCivicCenterAreaToClass(playerPosition[i], clPlayer); addToClass(attacker[i].x, attacker[i].y, clPlayer); addToClass(halfway[i].x, halfway[i].y, clPlayer); } Engine.SetProgress(20); paintTerrainBasedOnHeight(3.12, 29, 1, tCliff); paintTileClassBasedOnHeight(3.12, 29, 1, clHill); for (let triggerPointTreasure of triggerPointTreasures) createObjectGroupsDeprecated( new SimpleGroup([new SimpleObject(triggerPointTreasure, 1, 1, 0, 0)], true, clWomen), 0, [avoidClasses(clForest, 5, clPlayer, 5, clHill, 5), stayClasses(clLand, 5)], scaleByMapSize(40, 140), 100 ); Engine.SetProgress(25); createBumps(stayClasses(clLand, 5)); var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1)); createForests( [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2], [avoidClasses(clPlayer, 20, clForest, 5, clHill, 0, clBaseResource,2, clWomen, 5), stayClasses(clLand, 4)], clForest, forestTrees); Engine.SetProgress(30); if (randBool()) createHills( [tMainTerrain, tCliff, tHill], [avoidClasses(clPlayer, 20, clHill, 5, clBaseResource, 3, clWomen, 5), stayClasses(clLand, 5)], clHill, scaleByMapSize(10, 60) * numPlayers); else createMountains( tCliff, [avoidClasses(clPlayer, 20, clHill, 5, clBaseResource, 3, clWomen, 5), stayClasses(clLand, 5)], clHill, scaleByMapSize(10, 60) * numPlayers); Engine.SetProgress(40); createHills( [tCliff, tCliff, tHill], avoidClasses(clPlayer, 20, clHill, 5, clBaseResource, 3, clWomen, 5, clLand, 5), clHill, scaleByMapSize(15, 90) * numPlayers, undefined, undefined, undefined, undefined, 55); Engine.SetProgress(50); log("Creating dirt patches..."); createLayeredPatches( [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)], [[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]], [1, 1], [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12, clWomen, 5), stayClasses(clLand, 5)], scaleByMapSize(15, 45), clDirt); log("Creating grass patches..."); createPatches( [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)], tTier4Terrain, [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12, clWomen, 5), stayClasses(clLand, 5)], scaleByMapSize(15, 45), clDirt); var planetm = 1; if (currentBiome() == "tropic") planetm = 8; 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)], [new SimpleObject(aGrass, 2,4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)], [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)] ], [ scaleByMapSize(16, 262), scaleByMapSize(8, 131), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200), planetm * scaleByMapSize(13, 200) ], [avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 5)]); createStragglerTrees( [oTree1, oTree2, oTree4, oTree3], [avoidClasses(clForest, 7, clHill, 1, clPlayer, 9), stayClasses(clLand, 7)], clForest, stragglerTrees); g_Map.ExportMap(); Index: ps/trunk/binaries/data/mods/public/maps/random/volcanic_lands.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/volcanic_lands.js (revision 20999) +++ ps/trunk/binaries/data/mods/public/maps/random/volcanic_lands.js (revision 21000) @@ -1,185 +1,185 @@ Engine.LoadLibrary("rmgen"); var tGrass = ["cliff volcanic light", "ocean_rock_a", "ocean_rock_b"]; var tGrassA = "cliff volcanic light"; var tGrassB = "ocean_rock_a"; var tGrassC = "ocean_rock_b"; var tCliff = ["cliff volcanic coarse", "cave_walls"]; var tRoad = "road1"; var tRoadWild = "road1"; var tLava1 = "LavaTest05"; var tLava2 = "LavaTest04"; var tLava3 = "LavaTest03"; var oTree = "gaia/flora_tree_dead"; var oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; var oStoneSmall = "gaia/geology_stone_alpine_a"; var oMetalLarge = "gaia/geology_metal_alpine_slabs"; var aRockLarge = "actor|geology/stone_granite_med.xml"; var aRockMedium = "actor|geology/stone_granite_med.xml"; var pForestD = [tGrassC + TERRAIN_SEPARATOR + oTree, tGrassC]; var pForestP = [tGrassB + TERRAIN_SEPARATOR + oTree, tGrassB]; const heightLand = 1; const heightHill = 18; var g_Map = new RandomMap(heightLand, tGrassB); var numPlayers = getNumPlayers(); var mapCenter = g_Map.getCenter(); -var clPlayer = createTileClass(); -var clHill = createTileClass(); -var clForest = createTileClass(); -var clDirt = createTileClass(); -var clRock = createTileClass(); -var clMetal = createTileClass(); -var clBaseResource = createTileClass(); +var clPlayer = g_Map.createTileClass(); +var clHill = g_Map.createTileClass(); +var clForest = g_Map.createTileClass(); +var clDirt = g_Map.createTileClass(); +var clRock = g_Map.createTileClass(); +var clMetal = g_Map.createTileClass(); +var clBaseResource = g_Map.createTileClass(); placePlayerBases({ "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.35)), "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "CityPatch": { "outerTerrain": tRoadWild, "innerTerrain": tRoad }, // No berries, no chicken, no decoratives "Mines": { "types": [ { "template": oMetalLarge }, { "template": oStoneLarge } ] }, "Trees": { "template": oTree, "count": scaleByMapSize(12, 30) } }); Engine.SetProgress(15); createVolcano(mapCenter, clHill, tCliff, [tLava1, tLava2, tLava3], true, ELEVATION_SET); Engine.SetProgress(45); log("Creating hills..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1), [ new LayeredPainter([tCliff, tGrass], [2]), new SmoothElevationPainter(ELEVATION_SET, heightHill, 2), paintClass(clHill) ], avoidClasses(clPlayer, 12, clHill, 15, clBaseResource, 2), scaleByMapSize(2, 8) * numPlayers ); log("Creating forests..."); var [forestTrees, stragglerTrees] = getTreeCounts(200, 1250, 0.7); var types = [ [[tGrassB, tGrassA, pForestD], [tGrassB, pForestD]], [[tGrassB, tGrassA, pForestP], [tGrassB, pForestP]] ]; var size = forestTrees / (scaleByMapSize(2,8) * numPlayers); var num = Math.floor(size / types.length); for (let type of types) createAreas( new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1), [ new LayeredPainter(type, [2]), paintClass(clForest) ], avoidClasses(clPlayer, 12, clForest, 10, clHill, 0, clBaseResource, 6), num); Engine.SetProgress(70); log("Creating dirt patches..."); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter([tGrassA, tGrassA], [1]), paintClass(clDirt) ], avoidClasses(clForest, 0, clHill, 0, clPlayer, 12), scaleByMapSize(20, 80)); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter([tGrassB, tGrassB], [1]), paintClass(clDirt) ], avoidClasses(clForest, 0, clHill, 0, clPlayer, 12), scaleByMapSize(20, 80)); for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)]) createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), [ new LayeredPainter([tGrassC, tGrassC], [1]), paintClass(clDirt) ], avoidClasses(clForest, 0, clHill, 0, clPlayer, 12), scaleByMapSize(20, 80) ); log("Creating stone mines..."); var group = new SimpleGroup([new SimpleObject(oStoneSmall, 0, 2, 0, 4), new SimpleObject(oStoneLarge, 1, 1, 0, 4)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill, 1), scaleByMapSize(4,16), 100 ); log("Creating small stone mines..."); group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock); createObjectGroupsDeprecated(group, 0, avoidClasses(clForest, 1, clPlayer, 10, 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(clForest, 1, clPlayer, 10, clMetal, 10, clRock, 5, clHill, 1), scaleByMapSize(4,16), 100 ); Engine.SetProgress(90); log("Creating small decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockMedium, 1,3, 0,1)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(16, 262), 50 ); log("Creating large decorative rocks..."); group = new SimpleGroup( [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)], true ); createObjectGroupsDeprecated( group, 0, avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), scaleByMapSize(8, 131), 50 ); Engine.SetProgress(95); createStragglerTrees( [oTree], avoidClasses(clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6, clBaseResource, 6), clForest, stragglerTrees); placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4)); g_Map.ExportMap();