Index: binaries/data/mods/public/art/textures/ui/session/icons/mappreview/belgian_uplands.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: binaries/data/mods/public/art/textures/ui/session/icons/mappreview/belgian_uplands.png
===================================================================
--- binaries/data/mods/public/art/textures/ui/session/icons/mappreview/belgian_uplands.png	(revision 0)
+++ binaries/data/mods/public/art/textures/ui/session/icons/mappreview/belgian_uplands.png	(working copy)

Property changes on: binaries/data/mods/public/art/textures/ui/session/icons/mappreview/belgian_uplands.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: binaries/data/mods/public/maps/random/belgian_uplands.js
===================================================================
--- binaries/data/mods/public/maps/random/belgian_uplands.js	(revision 0)
+++ binaries/data/mods/public/maps/random/belgian_uplands.js	(working copy)
@@ -0,0 +1,355 @@
+RMS.LoadLibrary("rmgen");
+
+const BUILDING_ANGlE = -PI/4;
+
+// initialize map
+
+log("Initializing map...");
+
+InitMap();
+
+var numPlayers = getNumPlayers();
+var mapSize = getMapSize();
+
+
+//////////
+// Heightmap functionality
+//////////
+
+// Some heightmap variables
+const MIN_HEIGHT = - SEA_LEVEL; // 20
+const MAX_HEIGHT = 0xFFFF/HEIGHT_UNITS_PER_METRE - SEA_LEVEL; // A bit smaler than 90
+
+// Random heightmap generation
+function getRandomReliefmap(minHeight, maxHeight)
+{
+	minHeight = (minHeight || MIN_HEIGHT);
+	maxHeight = (maxHeight || MAX_HEIGHT);
+	if (minHeight < MIN_HEIGHT)
+		warn("getRandomReliefmap: Argument minHeight is smaler then the supported minimum height of " + MIN_HEIGHT + " (const MIN_HEIGHT): " + minHeight)
+	if (maxHeight > MAX_HEIGHT)
+		warn("getRandomReliefmap: Argument maxHeight is smaler then the supported maximum height of " + MAX_HEIGHT + " (const MAX_HEIGHT): " + maxHeight)
+	var reliefmap = [];
+	for (var x = 0; x <= mapSize; x++)
+	{
+		reliefmap.push([]);
+		for (var y = 0; y <= mapSize; y++)
+		{
+			reliefmap[x].push(randFloat(minHeight, maxHeight));
+		}
+	}
+	return reliefmap;
+}
+
+// Apply a heightmap
+function setReliefmap(reliefmap)
+{
+	// g_Map.height = reliefmap;
+	for (var x = 0; x <= mapSize; x++)
+	{
+		for (var y = 0; y <= mapSize; y++)
+		{
+			setHeight(x, y, reliefmap[x][y]);
+		}
+	}
+}
+
+// Get the diferrence between minimum and maxumum height
+function getMinAndMaxHeight(reliefmap)
+{
+	var height = {};
+	height.min = Infinity;
+	height.max = -Infinity;
+	for (var x = 0; x <= mapSize; x++)
+	{
+		for (var y = 0; y <= mapSize; y++)
+		{
+			if (reliefmap[x][y] < height.min)
+				height.min = reliefmap[x][y];
+			else if (reliefmap[x][y] > height.max)
+				height.max = reliefmap[x][y];
+		}
+	}
+	return height;
+}
+
+// Normalizing the heightmap
+function getRescaledReliefmap(reliefmap, minHeight, maxHeight)
+{
+	var newReliefmap = deepcopy(reliefmap);
+	minHeight = (minHeight || MIN_HEIGHT);
+	maxHeight = (maxHeight || MAX_HEIGHT);
+	if (minHeight < MIN_HEIGHT)
+		warn("getRescaledReliefmap: Argument minHeight is smaler then the supported minimum height of " + MIN_HEIGHT + " (const MIN_HEIGHT): " + minHeight)
+	if (maxHeight > MAX_HEIGHT)
+		warn("getRescaledReliefmap: Argument maxHeight is smaler then the supported maximum height of " + MAX_HEIGHT + " (const MAX_HEIGHT): " + maxHeight)
+	var oldHeightRange = getMinAndMaxHeight(reliefmap);
+	for (var x = 0; x <= mapSize; x++)
+	{
+		for (var y = 0; y <= mapSize; y++)
+		{
+			newReliefmap[x][y] = minHeight + (reliefmap[x][y] - oldHeightRange.min) / (oldHeightRange.max - oldHeightRange.min) * (maxHeight - minHeight);
+		}
+	}
+	return newReliefmap
+}
+
+// Applying decay errosion (terrain independent)
+function getHeightErrosionedReliefmap(reliefmap, strength)
+{
+	var newReliefmap = deepcopy(reliefmap);
+	strength = (strength || 1.0); // Values much higher then 1 (1.32+ for an 8 tile map, 1.45+ for a 12 tile map, 1.62+ @ 20 tile map, 0.99 @ 4 tiles) will result in a resonance disaster/self interference
+	var map = [[1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1]]; // Default
+	for (var x = 0; x <= mapSize; x++)
+	{
+		for (var y = 0; y <= mapSize; y++)
+		{
+			var div = 0;
+			for (var i = 0; i < map.length; i++)
+				newReliefmap[x][y] += strength / map.length * (reliefmap[(x + map[i][0] + mapSize + 1) % (mapSize + 1)][(y + map[i][1] + mapSize + 1) % (mapSize + 1)] - reliefmap[x][y]); // Not entirely sure if scaling with map.length is perfect but tested values seam to indicate it is
+		}
+	}
+	return newReliefmap;
+}
+
+//////////
+// Apply hightmap munipulation
+//////////
+
+// 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 / 512, "max": MAX_HEIGHT * mapSize / 512};
+
+// Set average water coverage
+var averageWaterCoverage = 1/3; // NOTE: Since errosion is not pedictable actual water coverage might vary much with the same values
+if (mapSize < 200)
+	averageWaterCoverage = 2/3 * averageWaterCoverage;
+var waterHeight = -MIN_HEIGHT + heightRange.min + averageWaterCoverage * (heightRange.max - heightRange.min);
+var waterHeightAdjusted = waterHeight + MIN_HEIGHT;
+setWaterHeight(waterHeight);
+
+// Generate reliefmap
+var myReliefmap = getRandomReliefmap(heightRange.min, heightRange.max);
+for (var i = 0; i < 50 + mapSize/4; i++) // Cycles depend on used getHeightErrosionedReliefmap.map and mapSize so should be put inside getHeightErrosionedReliefmap
+	myReliefmap = getHeightErrosionedReliefmap(myReliefmap, 1);
+myReliefmap = getRescaledReliefmap(myReliefmap, heightRange.min, heightRange.max);
+setReliefmap(myReliefmap);
+
+
+//////////
+// Apply terrain texture by height
+//////////
+
+var textueByHeight = [];
+textueByHeight.push({"upperHeightLimit": heightRange.min + 1/3 * (waterHeightAdjusted - heightRange.min), "terrein": "temp_sea_rocks"});
+var terreins = ["temp_sea_weed"];
+terreins = terreins.concat(terreins, terreins, terreins, terreins);
+terreins = terreins.concat(terreins, terreins, terreins, terreins);
+terreins.push("temp_sea_weed|gaia/fauna_fish");
+textueByHeight.push({"upperHeightLimit": heightRange.min + 2/3 * (waterHeightAdjusted - heightRange.min), "terrein": terreins});
+textueByHeight.push({"upperHeightLimit": heightRange.min + 3/3 * (waterHeightAdjusted - heightRange.min), "terrein": "temp_mud_a"});
+var terreins = ["temp_plants_bog", "temp_plants_bog_aut", "temp_dirt_gravel_plants", "temp_grass_d"];
+terreins = terreins.concat(terreins, terreins, terreins, terreins, terreins);
+terreins = ["temp_plants_bog|gaia/flora_bush_temperate"].concat(terreins, terreins);
+terreins = ["temp_dirt_gravel_plants|gaia/geology_metal_temperate", "temp_dirt_gravel_plants|gaia/geology_stone_temperate", "temp_plants_bog|gaia/fauna_rabbit"].concat(terreins, terreins);
+terreins = ["temp_plants_bog_aut|gaia/flora_tree_dead"].concat(terreins, terreins);
+textueByHeight.push({"upperHeightLimit": waterHeightAdjusted + 1/6 * (heightRange.max - waterHeightAdjusted), "terrein": terreins});
+textueByHeight.push({"upperHeightLimit": waterHeightAdjusted + 2/6 * (heightRange.max - waterHeightAdjusted),
+	"terrein": ["temp_grass", "temp_grass_d", "temp_grass_long_b", "temp_grass_plants"]});
+textueByHeight.push({"upperHeightLimit": waterHeightAdjusted + 3/6 * (heightRange.max - waterHeightAdjusted),
+	"terrein": ["temp_grass", "temp_grass_b", "temp_grass_c", "temp_grass_mossy"]});
+textueByHeight.push({"upperHeightLimit": waterHeightAdjusted + 4/6 * (heightRange.max - waterHeightAdjusted),
+	"terrein": ["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 terreins = ["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 numTerreins = terreins.length;
+for (var i = 0; i < numTerreins; i++)
+	terreins.push("temp_grass_plants");
+textueByHeight.push({"upperHeightLimit": waterHeightAdjusted + 5/6 * (heightRange.max - waterHeightAdjusted), "terrein": terreins});
+textueByHeight.push({"upperHeightLimit": waterHeightAdjusted + 6/6 * (heightRange.max - waterHeightAdjusted),
+	"terrein": ["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;
+for(var x = minTerrainDistToBorder; x < mapSize - minTerrainDistToBorder; x++)
+{
+	for (var y = minTerrainDistToBorder; y < mapSize - minTerrainDistToBorder; y++)
+	{
+		var textureMinHeight = heightRange.min;
+		for (var i = 0; i < textueByHeight.length; i++)
+		{
+			if (getHeight(x, y) >= textureMinHeight && getHeight(x, y) <= textueByHeight[i].upperHeightLimit)
+			{
+				placeTerrain(x, y, textueByHeight[i].terrein);
+				break;
+			}
+			else
+			{
+				textureMinHeight = textueByHeight[i].upperHeightLimit;
+			}
+		}
+	}
+}
+
+//////////
+// Find good start positions
+//////////
+
+var startPositions = [];
+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...
+var lowerHeightLimit = textueByHeight[3].upperHeightLimit;
+var upperHeightLimit = textueByHeight[6].upperHeightLimit;
+// 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++)
+	{
+		var actualHeight = getHeight(x, y);
+		if (actualHeight > lowerHeightLimit && actualHeight < upperHeightLimit)
+		{
+			// Check for points within a valid area by height (rectangular so not optimal fast)
+			var isPossible = true;
+			for (var offX = - neededDistance; offX <= neededDistance; offX++)
+			{
+				for (var offY = - neededDistance; offY <= neededDistance; offY++)
+				{
+					var testHeight = getHeight(x + offX, y + offY);
+					if (testHeight <= lowerHeightLimit || testHeight >= upperHeightLimit)
+					{
+						isPossible = false;
+						break;
+					}
+				}
+			}
+			if (isPossible)
+			{
+				possibleStartPositions.push([x, y]);
+				// placeTerrain(x, y, "blue");
+			}
+		}
+	}
+}
+
+// Trying to reduce the number of possible start locations...
+
+// ...by beeing in a circle of mapSize / 2 distance to the center
+var possibleStartPositionsTemp = [];
+var maxDistToCenter = mapSize / 2;
+for (var i = 0; i < possibleStartPositions.length; i++)
+{
+	var deltaX = possibleStartPositions[i][0] - mapSize / 2;
+	var deltaY = possibleStartPositions[i][1] - mapSize / 2;
+	var distToCenter = Math.pow(Math.pow(deltaX, 2) + Math.pow(deltaY, 2), 1/2);
+	if (distToCenter < maxDistToCenter)
+	{
+		possibleStartPositionsTemp.push(deepcopy(possibleStartPositions[i]));
+		// placeTerrain(possibleStartPositions[i][0], possibleStartPositions[i][1], "purple");
+	}
+}
+possibleStartPositions = deepcopy(possibleStartPositionsTemp);
+
+// ...by checking if low and high ground is near. Rectangular check since faster...
+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 = getHeight(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(deepcopy(possibleStartPositions[i]));
+		// placeTerrain(possibleStartPositions[i][0], possibleStartPositions[i][1], "red");
+	}
+}
+possibleStartPositions = deepcopy(possibleStartPositionsTemp);
+
+// Get some random start location derivations. NOTE: Itterating over all possible derivations is just to much (valid points ** numPlayers)
+var maxTries = 100000; // floor(800000 / (Math.pow(numPlayers, 2) / 2));
+
+var possibleDerivations = [];
+for (var i = 0; i < maxTries; i++)
+{
+	var vector = [];
+	for (var p = 0; p < numPlayers; p++)
+		vector.push(randInt(possibleStartPositions.length));
+	possibleDerivations.push(vector);
+}
+
+// Maximise minimum distance between start locations
+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)
+			{
+				var StartPositionP1 = deepcopy(possibleStartPositions[possibleDerivations[d][p1]]);
+				var StartPositionP2 = deepcopy(possibleStartPositions[possibleDerivations[d][p2]]);
+				var actualDist = Math.pow(Math.pow(StartPositionP1[0] - StartPositionP2[0], 2) + Math.pow(StartPositionP1[1] - StartPositionP2[1], 2), 1/2);
+				if (actualDist < minDist)
+					minDist = deepcopy(actualDist);
+				if (minDist < maxMinDist)
+					break;
+			}
+		}
+		if (minDist < maxMinDist)
+			break;
+	}
+	if (minDist > maxMinDist)
+	{
+		maxMinDist = deepcopy(minDist);
+		var bestDerivation = deepcopy(possibleDerivations[d]);
+	}
+}
+
+// Place players
+for (var p = 0; p < numPlayers; p++)
+{
+	var actualX = possibleStartPositions[bestDerivation[p]][0];
+	var actualY = possibleStartPositions[bestDerivation[p]][1];
+	placeCivDefaultEntities(actualX, actualY, p + 1, BUILDING_ANGlE, {"iberWall" : false});
+	var uDist = 8;
+	var uSpace = 1;
+	for (var j = 1; j <= 4; ++j)
+	{
+		var uAngle = BUILDING_ANGlE - PI * (2-j) / 2;
+		var count = 4;
+		for (var numberofentities = 0; numberofentities < count; numberofentities++)
+		{
+			var ux = actualX + uDist * cos(uAngle) + numberofentities * uSpace * cos(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * cos(uAngle + PI/2));
+			var uz = actualY + uDist * sin(uAngle) + numberofentities * uSpace * sin(uAngle + PI/2) - (0.75 * uSpace * floor(count / 2) * sin(uAngle + PI/2));
+			if (j % 2 == 0)
+				placeObject(ux, uz, "gaia/flora_bush_berry", 0, randFloat(0, 2*PI)); 
+			else
+				placeObject(ux, uz, "gaia/flora_tree_cypress", 0, randFloat(0, 2*PI)); 
+		}
+	}
+}
+
+
+// Export map data
+ExportMap();
Index: binaries/data/mods/public/maps/random/belgian_uplands.json
===================================================================
--- binaries/data/mods/public/maps/random/belgian_uplands.json	(revision 0)
+++ binaries/data/mods/public/maps/random/belgian_uplands.json	(working copy)
@@ -0,0 +1,12 @@
+{
+	"settings" : {
+		"Name" : "Belgian Uplands",
+		"Script" : "belgian_uplands.js",
+		"Description" : "An experimental map generated with erosion functionality. Players will seldomly be placed equally fair!",
+		"CircularMap" : false,
+		"BaseTerrain" : ["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"],
+		"BaseHeight" : 0,
+		"Preview" : "belgian_uplands.png",
+		"XXXXXX" : "Optionally define other things here, like we would for a scenario"
+	}
+}
