1 Engine.LoadLibrary("rmgen");
2 Engine.LoadLibrary("rmgen-common");
4 const tPrimary = ["temp_forestfloor_pine", "temp_forestfloor_pine", "alpine_cliff_c", "alpine_grass_rocky"];
5 const tGrass = ["new_alpine_grass_b", "new_alpine_grass_c", "new_alpine_grass_d"];
6 const tPineForestFloor = "temp_forestfloor_pine";
7 const tForestFloor = [tPineForestFloor, tPineForestFloor, "alpine_dirt_grass_50"];
8 const tCliff = ["alpine_cliff_c", "alpine_cliff_c", "alpine_grass_rocky"];
9 const tCity = ["new_alpine_citytile", "new_alpine_grass_dirt_a"];
10 const tGrassPatch = ["alpine_grass_a", "alpine_grass_b"];
12 const oBoar = "gaia/fauna_boar";
13 const oDeer = "gaia/fauna_deer";
14 const oBear = "gaia/fauna_bear";
15 const oPig = "gaia/fauna_pig";
16 const oBerryBush = "gaia/flora_bush_berry";
17 const oMetalSmall = "gaia/geology_metal_alpine";
18 const oMetalLarge = "gaia/geology_metal_temperate_slabs";
19 const oStoneSmall = "gaia/geology_stone_alpine_a";
20 const oStoneLarge = "gaia/geology_stonemine_temperate_quarry";
22 const oOak = "gaia/flora_tree_oak";
23 const oOakLarge = "gaia/flora_tree_oak_large";
24 const oPine = "gaia/flora_tree_pine";
25 const oAleppoPine = "gaia/flora_tree_aleppo_pine";
27 const aTreeA = "actor|flora/trees/oak.xml";
28 const aTreeB = "actor|flora/trees/oak_large.xml";
29 const aTreeC = "actor|flora/trees/pine.xml";
30 const aTreeD = "actor|flora/trees/aleppo_pine.xml";
32 const aTrees = [aTreeA, aTreeB, aTreeC, aTreeD];
34 const aGrassLarge = "actor|props/flora/grass_soft_large.xml";
35 const aWoodLarge = "actor|props/special/eyecandy/wood_pile_1_b.xml";
36 const aWoodA = "actor|props/special/eyecandy/wood_sm_pile_a.xml";
37 const aWoodB = "actor|props/special/eyecandy/wood_sm_pile_b.xml";
38 const aBarrel = "actor|props/special/eyecandy/barrel_a.xml";
39 const aWheel = "actor|props/special/eyecandy/wheel_laying.xml";
40 const aCeltHomestead = "actor|structures/celts/homestead.xml";
41 const aCeltHouse = "actor|structures/celts/house.xml";
42 const aCeltLongHouse = "actor|structures/celts/longhouse.xml";
45 tPineForestFloor+TERRAIN_SEPARATOR+oOak, tForestFloor,
46 tPineForestFloor+TERRAIN_SEPARATOR+oPine, tForestFloor,
47 tPineForestFloor+TERRAIN_SEPARATOR+oAleppoPine, tForestFloor,
51 const heightRavineValley = 2;
52 const heightLand = 30;
53 const heightRavineHill = 40;
54 const heightHill = 50;
55 const heightOffsetRavine = 10;
57 var g_Map = new RandomMap(heightHill, tPrimary);
59 const numPlayers = getNumPlayers();
60 const mapSize = g_Map.getSize();
61 const mapCenter = g_Map.getCenter();
63 var clPlayer = g_Map.createTileClass();
64 var clHill = g_Map.createTileClass();
65 var clForest = g_Map.createTileClass();
66 var clForestJoin = g_Map.createTileClass();
67 var clRock = g_Map.createTileClass();
68 var clMetal = g_Map.createTileClass();
69 var clFood = g_Map.createTileClass();
70 var clBaseResource = g_Map.createTileClass();
71 var clHillDeco = g_Map.createTileClass();
73 g_Map.log("Creating the central dip");
75 new ClumpPlacer(diskArea(fractionToTiles(0.42)), 0.94, 0.05, 0.1, mapCenter),
77 new LayeredPainter([tCliff, tGrass], [3]),
78 new SmoothElevationPainter(ELEVATION_SET, heightLand, 3)
80 Engine.SetProgress(5);
82 g_Map.log("Finding hills");
83 var noise0 = new Noise2D(20);
84 for (var ix = 0; ix < mapSize; ix++)
85 for (var iz = 0; iz < mapSize; iz++)
87 let position = new Vector2D(ix, iz);
88 let h = g_Map.getHeight(position);
89 if (h > heightRavineHill)
94 var x = ix / (mapSize + 1.0);
95 var z = iz / (mapSize + 1.0);
96 var n = (noise0.get(x, z) - 0.5) * heightRavineHill;
97 g_Map.setHeight(position, h + n);
101 var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.3));
103 function distanceToPlayers(x, z)
106 for (var i = 0; i < numPlayers; i++)
108 var dx = x - playerPosition[i].x;
109 var dz = z - playerPosition[i].y;
110 r = Math.min(r, Math.square(dx) + Math.square(dz));
115 function playerNearness(x, z)
117 var d = fractionToTiles(distanceToPlayers(x,z));
123 return (d-13)/(19-13);
128 Engine.SetProgress(10);
131 "PlayerPlacement": [playerIDs, playerPosition],
132 "BaseResourceClass": clBaseResource,
133 // Playerclass marked below
135 "outerTerrain": tCity,
136 "innerTerrain": tCity,
137 "radius": scaleByMapSize(5, 6),
144 "template": oBerryBush,
150 { "template": oMetalLarge },
151 { "template": oStoneLarge }
162 g_Map.log("Marking player territory");
163 for (let i = 0; i < numPlayers; ++i)
165 new ClumpPlacer(250, 0.95, 0.3, 0.1, playerPosition[i]),
166 new TileClassPainter(clPlayer));
168 Engine.SetProgress(30);
170 g_Map.log("Creating hills");
171 for (let size of [scaleByMapSize(50, 800), scaleByMapSize(50, 400), scaleByMapSize(10, 30), scaleByMapSize(10, 30)])
173 let mountains = createAreas(
174 new ClumpPlacer(size, 0.1, 0.2, 0.1),
176 new LayeredPainter([tCliff, [tForestFloor, tForestFloor, tCliff]], [2]),
177 new SmoothElevationPainter(ELEVATION_SET, heightHill, size < 50 ? 2 : 4),
178 new TileClassPainter(clHill)
180 avoidClasses(clPlayer, 8, clBaseResource, 2, clHill, 5),
181 scaleByMapSize(1, 4));
183 if (size > 100 && mountains.length)
185 new ClumpPlacer(size * 0.3, 0.94, 0.05, 0.1),
187 new LayeredPainter([tCliff, tForestFloor], [2]),
188 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetRavine, 3)
190 stayClasses(clHill, 4),
191 mountains.length * 2,
195 let ravine = createAreas(
196 new ClumpPlacer(size, 0.1, 0.2, 0.1),
198 new LayeredPainter([tCliff, tForestFloor], [2]),
199 new SmoothElevationPainter(ELEVATION_SET, heightRavineValley, 2),
200 new TileClassPainter(clHill)
202 avoidClasses(clPlayer, 6, clBaseResource, 2, clHill, 5),
203 scaleByMapSize(1, 3));
205 if (size > 150 && ravine.length)
207 g_Map.log("Placing huts in ravines");
208 createObjectGroupsByAreasDeprecated(
211 new SimpleObject(aCeltHouse, 0, 1, 4, 5),
212 new SimpleObject(aCeltLongHouse, 1, 1, 4, 5)
217 [avoidClasses(clHillDeco, 3), stayClasses(clHill, 3)],
218 ravine.length * 5, 20,
221 createObjectGroupsByAreasDeprecated(
222 new RandomGroup([new SimpleObject(aCeltHomestead, 1, 1, 1, 1)], true, clHillDeco),
224 [avoidClasses(clHillDeco, 5), stayClasses(clHill, 4)],
225 ravine.length * 2, 100,
230 new ClumpPlacer(size * 0.3, 0.94, 0.05, 0.1),
232 new LayeredPainter([tCliff, tForestFloor], [2]),
233 new SmoothElevationPainter(ELEVATION_SET, heightRavineValley, 2)
235 [avoidClasses(clHillDeco, 2), stayClasses(clHill, 0)],
241 new ClumpPlacer(size * 0.1, 0.3, 0.05, 0.1),
243 new LayeredPainter([tCliff, tForestFloor], [2]),
244 new SmoothElevationPainter(ELEVATION_SET, heightRavineHill, 2),
245 new TileClassPainter(clHill)
247 [avoidClasses(clHillDeco, 2), borderClasses(clHill, 15, 1)],
254 Engine.SetProgress(50);
256 for (var ix = 0; ix < mapSize; ix++)
257 for (var iz = 0; iz < mapSize; iz++)
259 let position = new Vector2D(ix, iz);
260 let h = g_Map.getHeight(position);
262 if (h > 35 && randBool(0.1) ||
263 h < 15 && randBool(0.05) && clHillDeco.countMembersInRadius(position, 1) == 0)
264 g_Map.placeEntityAnywhere(
267 randomPositionOnTile(position),
271 var explorableArea = createArea(
272 new MapBoundsPlacer(),
275 new HeightConstraint(15, 45),
276 avoidClasses(clPlayer, 1)
279 Engine.SetProgress(55);
281 // Add some general noise - after placing height dependant trees
282 for (var ix = 0; ix < mapSize; ix++)
284 var x = ix / (mapSize + 1.0);
285 for (var iz = 0; iz < mapSize; iz++)
287 let position = new Vector2D(ix, iz);
288 var z = iz / (mapSize + 1.0);
289 var h = g_Map.getHeight(position);
290 var pn = playerNearness(x,z);
291 var n = (noise0.get(x,z) - 0.5) * 10;
292 g_Map.setHeight(position, h + (n * pn));
296 Engine.SetProgress(60);
298 g_Map.log("Creating forests");
299 var [forestTrees, stragglerTrees] = getTreeCounts(400, 6000, 0.8);
300 var [forestTreesJoin, forestTrees] = getTreeCounts(forestTrees, forestTrees, 0.25);
302 var num = forestTrees / (scaleByMapSize(6, 16) * numPlayers);
304 new ClumpPlacer(forestTrees / num, 0.1, 0.1, Infinity),
306 new TerrainPainter(pForest),
307 new TileClassPainter(clForest)
309 avoidClasses(clPlayer, 5, clBaseResource, 4, clForest, 6, clHill, 4),
315 var num = forestTreesJoin / (scaleByMapSize(4,6) * numPlayers);
317 new ClumpPlacer(forestTreesJoin / num, 0.1, 0.1, Infinity),
319 new TerrainPainter(pForest),
320 new TileClassPainter(clForest),
321 new TileClassPainter(clForestJoin)
323 [avoidClasses(clPlayer, 5, clBaseResource, 4, clForestJoin, 5, clHill, 4), borderClasses(clForest, 1, 4)],
329 Engine.SetProgress(70);
331 g_Map.log("Creating grass patches");
332 for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)])
334 new ClumpPlacer(size, 0.3, 0.06, 0.5),
335 new TerrainPainter([tGrass, tGrassPatch]),
336 avoidClasses(clForest, 0, clHill, 2, clPlayer, 5),
337 scaleByMapSize(15, 45));
339 g_Map.log("Creating chopped forest patches");
340 for (let size of [scaleByMapSize(20, 120)])
342 new ClumpPlacer(size, 0.3, 0.06, 0.5),
343 new TerrainPainter(tForestFloor),
344 avoidClasses(clForest, 1, clHill, 2, clPlayer, 5),
345 scaleByMapSize(4, 12));
347 Engine.SetProgress(75);
349 g_Map.log("Creating stone mines");
350 createObjectGroupsByAreasDeprecated(
353 new SimpleObject(oStoneSmall, 1, 2, 0, 4, 0, 2 * Math.PI, 1),
354 new SimpleObject(oStoneLarge, 0, 1, 0, 4, 0, 2 * Math.PI, 4)
359 [avoidClasses(clHill, 4, clForest, 2, clPlayer, 20, clRock, 10)],
360 scaleByMapSize(6,20), 100,
363 g_Map.log("Creating small stone mines");
364 var group = new SimpleGroup([new SimpleObject(oStoneSmall, 2, 5, 1, 3)], true, clRock);
365 createObjectGroupsByAreasDeprecated(group, 0,
366 [avoidClasses(clHill, 4, clForest, 2, clPlayer, 20, clRock, 10)],
367 scaleByMapSize(6,20), 100,
371 g_Map.log("Creating metal mines");
372 group = new SimpleGroup([new SimpleObject(oMetalSmall, 1,2, 0,4), new SimpleObject(oMetalLarge, 0,1, 0,4)], true, clMetal);
373 createObjectGroupsByAreasDeprecated(group, 0,
374 [avoidClasses(clHill, 4, clForest, 2, clPlayer, 20, clMetal, 10, clRock, 5)],
375 scaleByMapSize(6,20), 100,
379 Engine.SetProgress(80);
381 g_Map.log("Creating wildlife");
382 group = new SimpleGroup(
383 [new SimpleObject(oDeer, 5,7, 0,4)],
386 createObjectGroupsByAreasDeprecated(group, 0,
387 avoidClasses(clHill, 4, clForest, 0, clPlayer, 0, clBaseResource, 20),
392 group = new SimpleGroup(
393 [new SimpleObject(oBoar, 2,3, 0,5)],
396 createObjectGroupsByAreasDeprecated(group, 0,
397 avoidClasses(clHill, 4, clForest, 0, clPlayer, 0, clBaseResource, 15),
402 group = new SimpleGroup(
403 [new SimpleObject(oBear, 1,1, 0,4)],
406 createObjectGroupsByAreasDeprecated(group, 0,
407 avoidClasses(clHill, 4, clForest, 0, clPlayer, 20),
408 scaleByMapSize(3, 12), 200,
412 Engine.SetProgress(85);
414 g_Map.log("Creating berry bush");
415 group = new SimpleGroup(
416 [new SimpleObject(oBerryBush, 5,7, 0,4)],
419 createObjectGroupsDeprecated(group, 0,
420 avoidClasses(clForest, 0, clPlayer, 20, clHill, 4, clFood, 20),
421 randIntInclusive(3, 12) * numPlayers + 2, 50
424 g_Map.log("Creating decorative props");
425 group = new SimpleGroup(
427 new SimpleObject(aWoodA, 1,2, 0,1),
428 new SimpleObject(aWoodB, 1,3, 0,1),
429 new SimpleObject(aWheel, 0,2, 0,1),
430 new SimpleObject(aWoodLarge, 0,1, 0,1),
431 new SimpleObject(aBarrel, 0,2, 0,1)
435 createObjectGroupsByAreasDeprecated(
437 avoidClasses(clForest, 0),
438 scaleByMapSize(5, 50), 50,
442 Engine.SetProgress(90);
444 g_Map.log("Creating straggler trees");
445 var types = [oOak, oOakLarge, oPine, oAleppoPine];
446 var num = Math.floor(stragglerTrees / types.length);
447 for (let type of types)
448 createObjectGroupsByAreasDeprecated(
449 new SimpleGroup([new SimpleObject(type, 1, 1, 0, 3)], true, clForest),
451 avoidClasses(clForest, 4, clHill, 5, clPlayer, 10, clBaseResource, 2, clMetal, 5, clRock, 5),
455 Engine.SetProgress(95);
457 g_Map.log("Creating grass tufts");
458 group = new SimpleGroup(
459 [new SimpleObject(aGrassLarge, 1,2, 0,1, -Math.PI / 8, Math.PI / 8)]
461 createObjectGroupsByAreasDeprecated(group, 0,
462 avoidClasses(clHill, 2, clPlayer, 2),
463 scaleByMapSize(50, 300), 20,
467 placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2));
469 setTerrainAmbientColor(0.44,0.51,0.56);
470 setUnitsAmbientColor(0.44,0.51,0.56);