RMS.LoadLibrary("rmgen");
// initialize map
log("Initializing map...");
InitMap();
// Setup tile classes
var clPlayer = createTileClass();
var clPath = createTileClass();
var clHill = createTileClass();
var clForest = createTileClass();
// var clWater = createTileClass();
// var clRock = createTileClass();
// var clFood = createTileClass();
// var clBaseResource = createTileClass();
// Setup Templates
var templateStone = "gaia/geology_stone_temperate"
var templateStoneMine = "gaia/geology_stonemine_temperate_quarry";
var templateMetal = "gaia/geology_metal_temperate";
var templateMetalMine = "gaia/geology_metal_temperate_slabs";
var startingResourcees = ["gaia/flora_tree_oak_large", "gaia/flora_bush_temperate", templateStoneMine,
"gaia/flora_bush_grapes", "gaia/flora_tree_apple", "gaia/flora_bush_berry", templateMetalMine, "gaia/flora_bush_temperate"];
// Setup terrain
var terrainWood = ['temp_forestfloor_a|gaia/flora_tree_oak', 'temp_forestfloor_autumn|gaia/flora_tree_carob', 'temp_forestfloor_pine|gaia/flora_tree_pine'];
var terrainWoodBorder = ['temp_grass_plants|gaia/flora_bush_berry', 'temp_grass_clovers_2|gaia/flora_bush_grapes', 'temp_grass_long_b|gaia/flora_tree_apple',
'temp_grass_long|gaia/flora_bush_temperate', 'temp_highlands|gaia/flora_bush_temperate', 'temp_grass_mossy|gaia/flora_bush_temperate',
'temp_grass_plants|gaia/fauna_deer', "temp_mud_plants|gaia/fauna_boar", "temp_grass_long_b|gaia/fauna_rabbit"];
var terrainBase = ['temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b', 'temp_dirt_gravel', 'temp_grass_b',
'temp_grass_b|gaia/fauna_pig', 'temp_dirt_gravel|gaia/fauna_chicken'];
var terrainBaseBorder = ['temp_grass_b', 'temp_grass_b', 'temp_grass_c'];
var terrainPath = ['temp_road', 'temp_grass_b', "temp_road_overgrown"];
var terrainHill = ["temp_highlands", "temp_highlands", "temp_dirt_gravel_b"];
var terrainHillBorder = ["temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants",
"temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants", "temp_highlands", "temp_mud_plants",
"temp_grass_clovers_2|gaia/fauna_goat"];
// Setup map
var mapSize = getMapSize();
var mapRadius = mapSize/2;
var playableMapRadius = mapRadius - 5;
var mapCenterX = mapRadius;
var mapCenterZ = mapRadius;
// Setup players and bases
var fortresses = false;
var numPlayers = getNumPlayers();
var baseRadius = 20;
if (fortresses == true)
baseRadius = 30;
var minPlayerRadius = min(mapRadius-1.5*baseRadius, 5*mapRadius/8);
var maxPlayerRadius = min(mapRadius-baseRadius, 3*mapRadius/4);
const BUILDING_ANlE = 3*PI/4;
var buildAngle = 3*PI/4;
var playerStartLocX = new Array(numPlayers);
var playerStartLocZ = new Array(numPlayers);
var playerAngle = new Array(numPlayers);
var playerAngleStart = randFloat(0, 2*PI);
var playerAngleAddAvrg = 2*PI / numPlayers;
var playerAngleMaxOff = playerAngleAddAvrg/4;
// Setup eyecandy
var templateEC = "other/unfinished_greek_temple";
var radiusEC = max(mapRadius/8, baseRadius/2);
// Setup paths
var pathSucsessRadius = baseRadius/2;
var pathAngleOff = PI/2;
var pathWidth = 5; // This is not really the path's sickness in tiles but the number of tiles in the clumbs of the path
if (fortresses == true)
pathSucsessRadius = baseRadius;;
// Setup additional resources
var resourceRadius = 2*mapRadius/3; // 3*mapRadius/8;
var recourcePerPlayer = [];
var resourcePerPlayer = 2;
// Setup woods
var maxTreeDensity = min(256*256/mapSize/mapSize, 1); // Has to be tweeked but works ok
var bushChance = 0.5; // 1 means 50% chance in deepest wood, 0.5 means 25% chance in deepest wood
// Place bases
for (var i=0; i < numPlayers; i++)
{
var civ = g_MapSettings.PlayerData[i].Civ;
var startEntities = getStartingEntities(i);
playerAngle[i] = (playerAngleStart + i*playerAngleAddAvrg + randFloat(0, playerAngleMaxOff))%(2*PI);
var x = round(mapCenterX + randFloat(minPlayerRadius, maxPlayerRadius)*cos(playerAngle[i]));
var z = round(mapCenterZ + randFloat(minPlayerRadius, maxPlayerRadius)*sin(playerAngle[i]));
playerStartLocX[i] = x;
playerStartLocZ[i] = z;
// Place starting entities
createStartingPlayerEntities(x, z, i+1, startEntities, buildAngle)
// Place base texture
var placer = new ClumpPlacer(baseRadius*baseRadius, 1/2, 1/8, 1, x, z);
var painter = [new LayeredPainter([terrainBaseBorder, terrainBase], [2+randFloat()])];
createArea(placer, painter);
addToClass(x, z, clPlayer);
// Place fortresses
if (fortresses == true)
{
// Place fortresses
new wallTool(civ, "small").place(x, z, i+1, buildAngle);
// if (civ == "iber")
// new wallTool("iber").setGenericFortress(x, z, i+1, 20, PI/6);
};
// Place starting resources
var distToSL = 10;
var resStartAngle = playerAngle[i] + PI;
var resAddAngle = 2*PI / startingResourcees.length;
for (var rIndex = 0; rIndex < startingResourcees.length; rIndex++)
{
var angleOff = randFloat(-resAddAngle/2, resAddAngle/2);
var placeX = x + distToSL*cos(resStartAngle + rIndex*resAddAngle + angleOff);
var placeZ = z + distToSL*sin(resStartAngle + rIndex*resAddAngle + angleOff);
placeObject(placeX, placeZ, startingResourcees[rIndex], 0, randFloat(0, 2*PI));
};
};
// Place paths (2 path between each 2 players and each player and the eyecandy in the middle)
for (var i = 0; i < numPlayers+1; i++)
{
for (var j = 0; j < numPlayers+1; j++)
{
if (i < numPlayers)
{
var x = playerStartLocX[i];
var z = playerStartLocZ[i];
}
else
{
var x = mapCenterX;
var z = mapCenterZ;
};
if (j < numPlayers)
{
var targetX = playerStartLocX[j];
var targetZ = playerStartLocZ[j];
}
else
{
var targetX = mapCenterX;
var targetZ = mapCenterZ;
};
var angle = getAngle(x, z, targetX, targetZ);
x += round(pathSucsessRadius*cos(angle));
z += round(pathSucsessRadius*sin(angle));
var targetReached = false;
var tries = 0;
while (targetReached == false && tries < 2*mapSize)
{
var placer = new ClumpPlacer(pathWidth, 1, 1, 1, x, z);
var painter = [new TerrainPainter(terrainPath), new ElevationPainter(-randFloat())];
createArea(placer, painter, avoidClasses(clHill, 20)); // DOES NOT WORK!!! Because of centred placer???
addToClass(x, z, clPath);
// Set vars for next loop
angle = getAngle(x, z, targetX, targetZ);
x += round(cos(angle + randFloat(-pathAngleOff/2, 3*pathAngleOff/2)));
z += round(sin(angle + randFloat(-pathAngleOff/2, 3*pathAngleOff/2)));
if (getDistance(x, z, targetX, targetZ) < pathSucsessRadius)
targetReached = true;
tries++;
};
};
};
// Place expansion resources
for (var i=0; i < numPlayers; i++)
{
for (var rIndex = 0; rIndex < resourcePerPlayer; rIndex++)
{
if (numPlayers > 1)
var angleDist = (playerAngle[(i+1)%numPlayers] - playerAngle[i] + 2*PI)%(2*PI);
else
var angleDist = 2*PI;
var placeX = round(mapCenterX + resourceRadius*cos(playerAngle[i] + (rIndex+1)*angleDist/(resourcePerPlayer+1)));
var placeZ = round(mapCenterX + resourceRadius*sin(playerAngle[i] + (rIndex+1)*angleDist/(resourcePerPlayer+1)));
if (rIndex%2 == 0)
placeObject(placeX, placeZ, templateStone, 0, randFloat(0, 2*PI));
else
placeObject(placeX, placeZ, templateMetalMine, 0, randFloat(0, 2*PI));
var placer = new ClumpPlacer(40, 1/2, 1/8, 1, placeX, placeZ);
var painter = [new LayeredPainter([terrainHillBorder, terrainHill], [1]), new ElevationPainter(1+randFloat())];
createArea(placer, painter);
// addToClass(placeX, placeX, clHill);
};
};
// Place eyecandy
placeObject(mapCenterX, mapCenterZ, templateEC, 0, randFloat(0, 2*PI));
var placer = new ClumpPlacer(radiusEC*radiusEC, 1/2, 1/8, 1, mapCenterX, mapCenterZ);
var painter = [new LayeredPainter([terrainHillBorder, terrainHill], [radiusEC/4]), new ElevationPainter(1+randFloat())];
createArea(placer, painter);
addToClass(mapCenterX, mapCenterZ, clHill);
// Woods and hills
for (var x = 0; x < mapSize; x++)
{
for (var z = 0;z < mapSize;z++)
{
// Some variables
var radius = Math.pow(Math.pow(mapCenterX - x, 2) + Math.pow(mapCenterZ - z, 2), 1/2);
var minDistToSL = mapSize;
for (var i=0; i < numPlayers; i++)
minDistToSL = min(minDistToSL, getDistance(playerStartLocX[i], playerStartLocZ[i], x, z))
// Woods tile based
var tDensFactSL = max(min((minDistToSL - baseRadius) / baseRadius, 1), 0);
var tDensFactRad = abs((resourceRadius - radius) / resourceRadius);
var tDensFactEC = max(min((radius - radiusEC) / radiusEC, 1), 0);
var tDensActual = maxTreeDensity * tDensFactSL * tDensFactRad * tDensFactEC;
if (randFloat() < tDensActual && radius < playableMapRadius)
{
if (tDensActual < bushChance*randFloat()*maxTreeDensity)
{
var placer = new ClumpPlacer(1, 1, 1, 1, x, z);
var painter = [new TerrainPainter(terrainWoodBorder), new ElevationPainter(randFloat())];
createArea(placer, painter, avoidClasses(clPath, 1));
}
else
{
var placer = new ClumpPlacer(1, 1, 1, 1, x, z);
var painter = [new TerrainPainter(terrainWood), new ElevationPainter(randFloat())]; // new TileClassPainter(clForest)
createArea(placer, painter, avoidClasses(clPath, 2));
};
addToClass(x, z, clForest);
};
// Hills
var hVarMiddleHill = mapSize/64 * (1+cos(3*PI/2 * radius/mapRadius));
var hVarHills = 5*(1+sin(x/10)*sin(z/10));
setHeight(x, z, getHeight(x, z) + hVarMiddleHill + hVarHills + 1);
};
};
// Export map data
ExportMap();