Engine.LoadLibrary("rmgen");
Engine.LoadLibrary("rmgen-common");

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/treasure/food_bin";
const oWoodTreasure = "gaia/treasure/wood";
const oStoneTreasure = "gaia/treasure/stone";
const oMetalTreasure = "gaia/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];

const oPalisadeTallSpikes = "uncapturable|other/palisades_tall_spikes";
const oPalisadeAngleSpikes = "uncapturable|other/palisades_angle_spike";
const oPalisadeCurve = "uncapturable|other/palisades_rocks_curve";
const oPalisadeShort = "uncapturable|other/palisades_rocks_short";
const oPalisadeMedium = "uncapturable|other/palisades_rocks_medium";
const oPalisadeLong = "uncapturable|other/palisades_rocks_long";
const oPalisadeGate = "uncapturable|other/palisades_rocks_gate";
const oPalisadePillar = "uncapturable|other/palisades_rocks_tower";


var heightSeaGround = -4;
var heightLand = 3;

var g_Map = new RandomMap(heightLand, tGrass);
g_WallStyles.danubius_spikes = {
	"spikes_tall": readyWallElement(oPalisadeLong, "gaia"),
	"spike_single": readyWallElement(oPalisadeAngleSpikes, "gaia"),
	"gate2": readyWallElement(oPalisadeGate, "gaia"),
	"overlap": 0
};

g_WallStyles.danubius_village = {
	"pillar": readyWallElement(oPalisadePillar),
	"gate": readyWallElement(oPalisadeGate),
	"long": readyWallElement(oPalisadeLong),
	"medium": readyWallElement(oPalisadeMedium),
	"short": readyWallElement(oPalisadeShort),
	"cornerIn": readyWallElement(oPalisadeCurve),
	"overlap": 0.05
};
var palisadeCorner = ["turn_0.25", "spikes_tall", "turn_0.25"];
var palisadeGate = ["spikes_tall", "gate2", "spikes_tall"];
var palisadeWallShort = new Array(3).fill("spikes_tall");
var palisadeWallLong = new Array(5).fill("spikes_tall");
var palisadeSideShort = [...palisadeGate, ...palisadeWallShort, ...palisadeCorner, ...palisadeWallShort];
var palisadeSideLong = [...palisadeGate, ...palisadeWallShort, ...palisadeCorner, ...palisadeWallLong];
var fortressDanubiusSpikes = new Fortress(
	"Spikes Of The Geto-Dacian Tribal Confederation",
	[...palisadeSideLong, ...palisadeSideShort, ...palisadeSideLong, ...palisadeSideShort]);


var fortressDanubiusVillage = new Fortress(
	"Geto-Dacian Tribal Confederation",
	new Array(2).fill([
		"gate", "pillar",  "long", "long",
		"cornerIn",  "long",  "temple", "long",
		"pillar",  "long", "short", "pillar", "gate", "pillar", "long", "long",
		"cornerIn", "long",  "long", "pillar"
	]).reduce((result, items) => result.concat(items), []));
const numPlayers = getNumPlayers();

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": oStoneTreasure, "distance": 2 }
];

var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35));

g_Map.log("Creating playerbases");
var playerAngle = BUILDING_ORIENTATION;





var Dic={0:"A",1:"B",2:"C",3:"D",4:"E",5:"F",6:"G",7:"H",8:"I",9:"J"};
for (let i = 0; i < numPlayers; ++i)
{	

	
	//g_Map.placeEntityPassable("trigger/trigger_point_"+Dic[playerIDs[i]], playerIDs[i], pos, playerAngle);
	if (isNomad())
		break;

	// CC and units
	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);
	}

	// Ground texture
	var civ = getCivCode(playerIDs[i]);
	var tilesSize = civ == "cart" ? 30 : 29;
	createArea(
		new ConvexPolygonPlacer(
			new Array(4).fill(0).map((zero, j) => new Vector2D(tilesSize, 0).rotate(j * Math.PI / 2 - playerAngle - Math.PI/4).add(playerPosition[i])),
			Infinity),
		[
			new TerrainPainter(tRoad),
			new TileClassPainter(clPlayer)
		]);
    createObjectGroup(
			new SimpleGroup(
				[new SimpleObject(oMetalLarge, 1, 1, 0, 1)],
				false,
				clBaseResource,
				Vector2D.add(playerPosition[i], new Vector2D(7, 7))),
			0);
	createObjectGroup(
	    new SimpleGroup(
				[new SimpleObject(oStoneLarge, 1, 1, 0, 1)],
				false,
				clBaseResource,
				Vector2D.add(playerPosition[i], new Vector2D(10, 0))),
			0);
	
	placeCustomFortress(playerPosition[i], fortressDanubiusSpikes, "danubius_spikes", playerIDs[i], playerAngle);
	
}

g_Map.log("Creating lakes");
var numLakes = Math.round(scaleByMapSize(1,4) * numPlayers);



createBumps(avoidClasses(clWater, 2, clPlayer, 5));
Engine.SetProgress(35);

createHills([tCliff, tCliff, tHill], avoidClasses(clPlayer, 5, clWater, 5, clHill, 15), clHill, scaleByMapSize(1, 4) * numPlayers);
Engine.SetProgress(40);

g_Map.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]),
			new TileClassPainter(clForest)
		],
		avoidClasses(clPlayer, 5, clWater, 3, clForest, 15, clHill, 1),
		num);
Engine.SetProgress(50);

g_Map.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);

g_Map.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);

g_Map.log("Creating stone mines");
createMines(
 [
  [new SimpleObject(oStoneSmall, 0, 2, 0, 4, 0, 2 * Math.PI, 1), new SimpleObject(oStoneLarge, 1, 1, 0, 4, 0, 2 * Math.PI, 4)],
  [new SimpleObject(oStoneSmall, 2,5, 1,3)]
 ],
 avoidClasses(clWater, 0, clForest, 1, clPlayer, 5, clRock, 10, clHill, 1),
 clRock);
Engine.SetProgress(65);

g_Map.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");

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();
