1 Engine.LoadLibrary("rmgen");
2 Engine.LoadLibrary("rmgen-common");
3 Engine.LoadLibrary("rmbiome");
5 if (g_MapSettings.Biome)
8 setBiome("aethiopia/dry");
10 const tMainDirt = g_Terrains.mainDirt;
11 const tSecondaryDirt = g_Terrains.secondaryDirt;
12 const tDirt = g_Terrains.dirt;
13 const tLush = "desert_grass_a";
14 const tSLush = "desert_grass_a_sand";
15 const tFarmland = "desert_farmland";
16 const tRoad = "savanna_tile_a";
17 const tRoadWild = "desert_city_tile";
18 const tRiverBank = "savanna_riparian_wet";
19 const tForestFloor = "savanna_forestfloor_b";
21 const oBush = g_Gaia.berry;
22 const oBaobab = "gaia/flora_tree_baobab";
23 const oAcacia = "gaia/flora_tree_acacia";
24 const oDatePalm = "gaia/flora_tree_date_palm";
25 const oSDatePalm = "gaia/flora_tree_cretan_date_palm_short";
26 const oGazelle = "gaia/fauna_gazelle";
27 const oGiraffe = "gaia/fauna_giraffe";
28 const oLion = "gaia/fauna_lion";
29 const oFish = "gaia/fauna_fish";
30 const oHawk = "gaia/fauna_hawk";
31 const oStoneSmall = "gaia/geology_stone_savanna_small";
32 const oMetalLarge = "gaia/geology_metal_savanna_slabs";
34 const oHouse = "structures/kush_house";
35 const oFarmstead = "structures/kush_farmstead";
36 const oField = "structures/kush_field";
37 const oPyramid = "structures/kush_pyramid_small";
38 const oPyramidLarge = "structures/kush_pyramid_large";
39 const oKushSoldiers = "units/kush_infantry_javelinist_merc_e";
41 const aRain = g_Decoratives.rain;
42 const aBushA = g_Decoratives.bushA;
43 const aBushB = g_Decoratives.bushB;
44 const aBushes = [aBushA, aBushB];
45 const aReeds = "actor|props/flora/reeds_pond_lush_a.xml";
46 const aRock = "actor|geology/stone_desert_med.xml";
48 const pForestP = [tForestFloor + TERRAIN_SEPARATOR + oAcacia, tForestFloor];
50 const heightSeaGround = g_Heights.seaGround;
51 const heightReedsDepth = -2.5;
52 const heightShore = 1;
54 const heightDunes = 11;
55 const heightOffsetBump = 1.4;
57 const g_Map = new RandomMap(heightLand, tMainDirt);
59 const numPlayers = getNumPlayers();
60 const mapCenter = g_Map.getCenter();
61 const mapBounds = g_Map.getBounds();
63 var clPlayer = g_Map.createTileClass();
64 var clKushiteVillages = g_Map.createTileClass();
65 var clRiver = g_Map.createTileClass();
66 var clShore = g_Map.createTileClass();
67 var clDunes = g_Map.createTileClass();
68 var clForest = g_Map.createTileClass();
69 var clRock = g_Map.createTileClass();
70 var clMetal = g_Map.createTileClass();
71 var clFood = g_Map.createTileClass();
72 var clBaseResource = g_Map.createTileClass();
73 var clRain = g_Map.createTileClass();
75 var kushVillageBuildings = {
76 "houseA": { "template": oHouse, "offset": new Vector2D(5, 5) },
77 "houseB": { "template": oHouse, "offset": new Vector2D(5, 0) },
78 "houseC": { "template": oHouse, "offset": new Vector2D(5, -5) },
79 "farmstead": { "template": oFarmstead, "offset": new Vector2D(-5, 0) },
80 "fieldA": { "template": oField, "offset": new Vector2D(-5, 5) },
81 "fieldB": { "template": oField, "offset": new Vector2D(-5, -5) },
82 "pyramid": { "template": oPyramid, "offset": new Vector2D(0, -5) }
85 const riverTextures = [
87 "left": fractionToTiles(0),
88 "right": fractionToTiles(0.04),
93 "left": fractionToTiles(0.04),
94 "right": fractionToTiles(0.06),
100 const riverAngle = Math.PI/5;
104 "start": new Vector2D(fractionToTiles(0.25), mapBounds.top).rotateAround(riverAngle, mapCenter),
105 "end": new Vector2D(fractionToTiles(0.25), mapBounds.bottom).rotateAround(riverAngle, mapCenter),
106 "width": scaleByMapSize(12, 36),
107 "fadeDist": scaleByMapSize(3, 12),
109 "heightRiverbed": heightSeaGround,
110 "heightLand": heightShore,
113 "waterFunc": (position, height, z) => {
114 clRiver.add(position);
115 createTerrain(tRiverBank).place(position);
117 "landFunc": (position, shoreDist1, shoreDist2) => {
118 for (let riv of riverTextures)
119 if (riv.left < +shoreDist1 && +shoreDist1 < riv.right || riv.left < -shoreDist2 && -shoreDist2 < riv.right)
121 riv.tileClass.add(position);
123 createTerrain(riv.terrain).place(position);
127 Engine.SetProgress(10);
129 var [playerIDs, playerPosition] = playerPlacementRandom(sortAllPlayers(), avoidClasses(clRiver, 15, clPlayer, 30));
131 "PlayerPlacement": [playerIDs, playerPosition],
132 "BaseResourceClass": clBaseResource,
134 "outerTerrain": tRoadWild,
135 "innerTerrain": tRoad,
138 "painters": [new TileClassPainter(clPlayer)]
147 { "template": oMetalLarge },
149 "type": "stone_formation",
150 "template": oStoneSmall,
151 "terrain": tSecondaryDirt
154 "groupElements": [new RandomObject(aBushes, 2, 4, 2, 3)]
157 "template": pickRandom([oBaobab, oAcacia]),
161 Engine.SetProgress(15);
163 g_Map.log("Getting random coordinates for Kushite settlements");
164 var kushiteTownPositions = [];
165 for (let retryCount = 0; retryCount < scaleByMapSize(3, 10); ++retryCount)
167 let coordinate = g_Map.randomCoordinate(true);
168 if (new AndConstraint(avoidClasses(clPlayer, 40, clForest, 5, clKushiteVillages, 50, clRiver, 10)).allows(coordinate))
170 kushiteTownPositions.push(coordinate);
172 new ClumpPlacer(40, 0.6, 0.3, Infinity, coordinate),
174 new TerrainPainter(tRoad),
175 new TileClassPainter(clKushiteVillages)
180 g_Map.log("Placing the Kushite buildings");
181 for (let coordinate of kushiteTownPositions)
183 for (let building in kushVillageBuildings)
184 g_Map.placeEntityPassable(kushVillageBuildings[building].template, 0, Vector2D.add(coordinate, kushVillageBuildings[building].offset), Math.PI);
186 createObjectGroup(new SimpleGroup([new SimpleObject(oKushSoldiers, 5, 7, 1, 2)], true, clKushiteVillages, coordinate), 0);
189 g_Map.log("Creating kushite pyramids");
191 new SimpleGroup([new SimpleObject(oPyramidLarge, 1, 1, 0, 1)], true, clKushiteVillages),
193 avoidClasses(clPlayer, 20, clForest, 5, clKushiteVillages, 30, clRiver, 10),
194 scaleByMapSize(1, 7),
196 Engine.SetProgress(20);
198 g_Map.log("Creating bumps");
200 new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1),
201 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2),
202 new StaticConstraint(avoidClasses(clPlayer, 5, clKushiteVillages, 10, clRiver, 20)),
203 scaleByMapSize(300, 800));
205 g_Map.log("Creating dunes");
207 new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(5, 15)), 0.5),
209 new SmoothElevationPainter(ELEVATION_SET, heightDunes, 2),
210 new TileClassPainter(clDunes)
212 avoidClasses(clPlayer, 3, clRiver, 20, clDunes, 10, clKushiteVillages, 10),
213 scaleByMapSize(1, 3) * numPlayers * 3);
215 Engine.SetProgress(25);
217 var [forestTrees, stragglerTrees] = getTreeCounts(400, 2000, 0.7);
219 [tMainDirt[0], tForestFloor, tForestFloor, pForestP, pForestP],
220 avoidClasses(clPlayer, 20, clForest, 20, clDunes, 2, clRiver, 20, clKushiteVillages, 10),
223 Engine.SetProgress(40);
225 g_Map.log("Creating dirt patches");
226 for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)])
228 new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5),
229 new LayeredPainter([tSecondaryDirt, tDirt], [1]),
230 avoidClasses(clDunes, 0, clForest, 0, clPlayer, 5, clRiver, 10),
231 scaleByMapSize(50, 90));
233 g_Map.log("Creating patches of farmland");
234 for (let size of [scaleByMapSize(30, 40), scaleByMapSize(35, 50)])
236 new ClumpPlacer(size, 0.4, 0.6),
237 new TerrainPainter(tFarmland),
238 avoidClasses(clDunes, 3, clForest, 3, clPlayer, 5, clKushiteVillages, 5, clRiver, 10),
239 scaleByMapSize(1, 10));
240 Engine.SetProgress(60);
242 g_Map.log("Creating stone mines");
244 new SimpleGroup([new SimpleObject(oStoneSmall, 1, 1, 0, 4), new RandomObject(aBushes, 2, 4, 0, 2)], true, clRock),
246 [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clDunes, 1, clRiver, 15, clKushiteVillages, 10)],
247 scaleByMapSize(2, 8),
250 g_Map.log("Creating small stone quarries");
252 new SimpleGroup([new SimpleObject(oStoneSmall, 2, 5, 1, 3), new RandomObject(aBushes, 2, 4, 0, 2)], true, clRock),
254 [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clDunes, 1, clRiver, 15, clKushiteVillages, 10)],
255 scaleByMapSize(2, 8),
258 g_Map.log("Creating metal mines");
260 new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4), new RandomObject(aBushes, 2, 4, 0, 2)], true, clMetal),
262 [avoidClasses(clForest, 1, clPlayer, 10, clMetal, 10, clRock, 5, clDunes, 1, clRiver, 15, clKushiteVillages, 10)],
263 scaleByMapSize(2, 8),
265 Engine.SetProgress(70);
267 g_Map.log("Creating gazelle");
269 new SimpleGroup([new SimpleObject(oGazelle, 4, 6, 1, 4)], true, clFood),
271 avoidClasses(clForest, 0, clKushiteVillages, 10, clPlayer, 5, clDunes, 1, clFood, 25, clRiver, 2),
275 g_Map.log("Creating giraffe");
277 new SimpleGroup([new SimpleObject(oGiraffe, 4, 6, 1, 4)], true, clFood),
279 avoidClasses(clForest, 0, clKushiteVillages, 10, clPlayer, 5, clDunes, 1, clFood, 25, clRiver, 2),
283 g_Map.log("Creating lions");
286 new SimpleGroup([new SimpleObject(oLion, 2, 3, 0, 2)], true, clFood),
288 avoidClasses(clForest, 0, clKushiteVillages, 10, clPlayer, 5, clDunes, 1, clFood, 25, clRiver, 2),
292 g_Map.log("Creating hawk");
293 for (let i = 0; i < scaleByMapSize(1, 3); ++i)
294 g_Map.placeEntityAnywhere(oHawk, 0, mapCenter, randomAngle());
296 g_Map.log("Creating fish");
298 new SimpleGroup([new SimpleObject(oFish, 1, 2, 0, 1)], true, clFood),
300 [stayClasses(clRiver, 4), avoidClasses(clFood, 16)],
301 scaleByMapSize(15, 80),
303 Engine.SetProgress(80);
305 createStragglerTrees(
307 avoidClasses(clForest, 3, clFood, 1, clDunes, 1, clPlayer, 1, clMetal, 6, clRock, 6, clRiver, 15, clKushiteVillages, 15),
311 createStragglerTrees(
313 avoidClasses(clForest, 1, clFood, 1, clDunes, 3, clPlayer, 1, clMetal, 6, clRock, 6, clRiver, 15, clKushiteVillages, 15),
315 stragglerTrees * (isNomad() ? 3 : 1));
317 createStragglerTrees(
318 [oDatePalm, oSDatePalm],
319 [avoidClasses(clPlayer, 5, clFood, 1), stayClasses(clShore, 2)],
321 stragglerTrees * 10);
323 Engine.SetProgress(90);
325 g_Map.log("Creating reeds on the shore.");
327 new SimpleGroup([new SimpleObject(aReeds, 3, 5, 0, 1)], true),
329 new HeightConstraint(heightReedsDepth, heightShore),
330 scaleByMapSize(500, 1000),
333 g_Map.log("Creating small decorative rocks");
335 new SimpleGroup([new SimpleObject(aRock, 1, 3, 0, 1)], true),
337 avoidClasses(clForest, 0, clPlayer, 0, clDunes, 0),
338 scaleByMapSize(16, 262),
341 g_Map.log("Creating bushes");
343 new SimpleGroup([new SimpleObject(aBushB, 1, 2, 0, 1), new SimpleObject(aBushA, 1, 3, 0, 2)], true),
345 avoidClasses(clForest, 0, clPlayer, 0, clDunes, 0, clRiver, 15),
346 scaleByMapSize(50, 500),
348 Engine.SetProgress(95);
350 g_Map.log("Creating rain drops");
353 new SimpleGroup([new SimpleObject(aRain, 1, 1, 1, 4)], true, clRain),
355 avoidClasses(clRain, 5),
356 scaleByMapSize(60, 200));
357 Engine.SetProgress(98);
359 placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clKushiteVillages, 18, clMetal, 4, clRock, 4, clDunes, 4, clFood, 2, clRiver, 5));
361 setSunElevation(Math.PI / 8);
362 setSunRotation(randomAngle());
363 setSunColor(0.746, 0.718, 0.539);
364 setWaterColor(0.292, 0.347, 0.691);
365 setWaterTint(0.550, 0.543, 0.437);
367 setFogColor(0.8, 0.76, 0.61);
368 setFogThickness(0.2);
373 setPPSaturation(0.42);