1 Engine.LoadLibrary("rmgen");
2 Engine.LoadLibrary("rmgen-common");
3 Engine.LoadLibrary("rmbiome");
5 function* GenerateMap(mapSettings)
10 setBiome("generic/sahara");
13 const tPrimary = g_Terrains.mainTerrain;
14 const tCity = g_Terrains.roadWild;
15 const tCityPlaza = g_Terrains.road;
16 const tSand = g_Terrains.tier3Terrain;
17 const tDunes = g_Terrains.tier4Terrain;
18 const tFineSand = g_Terrains.tier2Terrain;
19 const tCliff = g_Terrains.cliff;
20 const tDirt = g_Terrains.dirt;
21 const tForestFloor = "desert_forestfloor_palms";
22 const tGrass = g_Terrains.forestFloor2;
23 const tGrassSand25 = g_Terrains.shoreBlend;
24 const tShore = g_Terrains.shore;
25 const tWaterDeep = g_Terrains.water;
27 const oBerryBush = "gaia/fruit/grapes";
28 const oCamel = "gaia/fauna_camel";
29 const oFish = g_Gaia.fish;
30 const oGazelle = "gaia/fauna_gazelle";
31 const oGiraffe = "gaia/fauna_giraffe";
32 const oGoat = "gaia/fauna_goat";
33 const oWildebeest = "gaia/fauna_wildebeest";
34 const oStoneLarge = g_Gaia.stoneLarge;
35 const oStoneSmall = g_Gaia.stoneSmall;
36 const oMetalLarge = g_Gaia.metalLarge;
37 const oMetalSmall = g_Gaia.metalSmall;
38 const oOasisTree = "gaia/tree/senegal_date_palm";
39 const oDatePalm = g_Gaia.tree1;
40 const oSDatePalm = g_Gaia.tree2;
42 const aBush1 = g_Decoratives.bushMedium;
43 const aBush2 = "actor|props/flora/bush_desert_dry_a.xml";
44 const aBush3 = g_Decoratives.bushSmall;
45 const aBush4 = "actor|props/flora/plant_desert_a.xml";
46 const aBushes = [aBush1, aBush2, aBush3, aBush4];
47 const aDecorativeRock = g_Decoratives.rockMedium;
50 tForestFloor + TERRAIN_SEPARATOR + oDatePalm,
51 tForestFloor + TERRAIN_SEPARATOR + oSDatePalm,
54 const pForestOasis = [
55 tGrass + TERRAIN_SEPARATOR + oOasisTree,
56 tGrass + TERRAIN_SEPARATOR + oDatePalm,
60 const heightLand = 10;
62 const heightOffsetOasis = -11;
63 const heightOffsetHill1 = 16;
64 const heightOffsetHill2 = 16;
65 const heightOffsetHill3 = 16;
66 const heightOffsetBump = 2;
68 globalThis.g_Map = new RandomMap(heightLand, tPrimary);
70 const numPlayers = getNumPlayers();
71 const mapSize = g_Map.getSize();
72 const mapCenter = g_Map.getCenter();
74 const clPlayer = g_Map.createTileClass();
75 const clHill1 = g_Map.createTileClass();
76 const clOasis = g_Map.createTileClass();
77 const clForest = g_Map.createTileClass();
78 const clPatch = g_Map.createTileClass();
79 const clRock = g_Map.createTileClass();
80 const clMetal = g_Map.createTileClass();
81 const clFood = g_Map.createTileClass();
82 const clBaseResource = g_Map.createTileClass();
84 const oasisRadius = scaleByMapSize(14, 40);
86 const [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35));
89 for (let i = 0; i < numPlayers; ++i)
91 new ClumpPlacer(diskArea(defaultPlayerBaseRadius()), 0.9, 0.5, Infinity,
93 new TileClassPainter(clPlayer));
96 "PlayerPlacement": [playerIDs, playerPosition],
97 "PlayerTileClass": clPlayer,
98 "BaseResourceClass": clBaseResource,
100 "outerTerrain": tCity,
101 "innerTerrain": tCityPlaza,
108 "template": oBerryBush
112 { "template": oMetalLarge },
113 { "template": oStoneLarge }
117 "template": oDatePalm
123 g_Map.log("Creating dune patches");
125 new ClumpPlacer(scaleByMapSize(40, 150), 0.2, 0.1, 0),
127 new TerrainPainter(tDunes),
128 new TileClassPainter(clPatch)
130 avoidClasses(clPatch, 2, clPlayer, 0),
131 scaleByMapSize(5, 20));
134 g_Map.log("Creating sand patches");
136 new ClumpPlacer(scaleByMapSize(25, 100), 0.2, 0.1, 0),
138 new TerrainPainter([tSand, tFineSand]),
139 new TileClassPainter(clPatch)
141 avoidClasses(clPatch, 2, clPlayer, 0),
142 scaleByMapSize(15, 50));
145 g_Map.log("Creating dirt patches");
147 new ClumpPlacer(scaleByMapSize(25, 100), 0.2, 0.1, 0),
149 new TerrainPainter([tDirt]),
150 new TileClassPainter(clPatch)
152 avoidClasses(clPatch, 2, clPlayer, 0),
153 scaleByMapSize(15, 50));
156 g_Map.log("Creating oasis");
158 new ClumpPlacer(diskArea(oasisRadius), 0.6, 0.15, 0, mapCenter),
163 [tGrassSand25, pForestOasis],
169 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetOasis, 8),
170 new TileClassPainter(clOasis)
175 g_Map.log("Creating oasis wildlife");
176 let num = Math.round(Math.PI * oasisRadius / 8);
177 let constraint = new AndConstraint([borderClasses(clOasis, 0, 3), avoidClasses(clOasis, 0)]);
178 for (let i = 0; i < num; ++i)
182 const angle = 2 * Math.PI / num * i;
185 // Work outward until constraint met
186 animalPosition = Vector2D.add(mapCenter, new Vector2D(r, 0).rotate(-angle)).round();
188 } while (!constraint.allows(animalPosition) && r < mapSize / 2);
193 new SimpleObject(oGiraffe, 2, 4, 0, 3),
194 new SimpleObject(oWildebeest, 3, 5, 0, 3),
195 new SimpleObject(oGazelle, 5, 7, 0, 3)
203 g_Map.log("Creating oasis fish");
204 constraint = new AndConstraint([borderClasses(clOasis, 15, 0), avoidClasses(clFood, 5)]);
205 num = Math.round(Math.PI * oasisRadius / 16);
206 for (let i = 0; i < num; ++i)
210 const angle = 2 * Math.PI / num * i;
213 // Work outward until constraint met
214 fishPosition = Vector2D.add(mapCenter, new Vector2D(r, 0).rotate(-angle));
216 } while (!constraint.allows(fishPosition) && r < mapSize / 2);
219 new SimpleGroup([new SimpleObject(oFish, 1, 1, 0, 1)], true, clFood, fishPosition), 0);
223 g_Map.log("Creating level 1 hills");
224 let hillAreas = createAreas(
225 new ClumpPlacer(scaleByMapSize(50, 300), 0.25, 0.1, 0.5),
227 new LayeredPainter([tCliff, tSand], [1]),
228 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHill1, 1),
229 new TileClassPainter(clHill1)
231 avoidClasses(clOasis, 3, clPlayer, 0, clHill1, 10),
232 scaleByMapSize(10, 20), 100
236 g_Map.log("Creating small level 1 hills");
237 hillAreas = hillAreas.concat(
239 new ClumpPlacer(scaleByMapSize(25, 150), 0.25, 0.1, 0.5),
241 new LayeredPainter([tCliff, tSand], [1]),
242 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHill2, 1),
243 new TileClassPainter(clHill1)
245 avoidClasses(clOasis, 3, clPlayer, 0, clHill1, 3),
246 scaleByMapSize(15, 25),
251 g_Map.log("Creating decorative rocks");
252 createObjectGroupsByAreasDeprecated(
254 [new RandomObject([aDecorativeRock, aBush2, aBush3], 3, 8, 0, 2)],
257 borderClasses(clHill1, 0, 3),
258 scaleByMapSize(40, 200), 50,
263 g_Map.log("Creating level 2 hills");
265 new ClumpPlacer(scaleByMapSize(25, 150), 0.25, 0.1, 0),
267 new LayeredPainter([tCliff, tSand], [1]),
268 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHill2, 1)
270 [stayClasses(clHill1, 0)],
271 scaleByMapSize(15, 25),
277 g_Map.log("Creating level 3 hills");
279 new ClumpPlacer(scaleByMapSize(12, 75), 0.25, 0.1, 0),
281 new LayeredPainter([tCliff, tSand], [1]),
282 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetHill3, 1)
284 [stayClasses(clHill1, 0)],
285 scaleByMapSize(15, 25),
290 g_Map.log("Creating bumps");
292 new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 0),
293 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 2),
294 avoidClasses(clOasis, 0, clPlayer, 0, clHill1, 2),
295 scaleByMapSize(100, 200)
300 g_Map.log("Creating forests");
301 const [forestTrees, stragglerTrees] = getTreeCounts(500, 2500, 0.5);
302 num = g_DefaultNumberOfForests;
304 new ClumpPlacer(forestTrees / num, 0.15, 0.1, 0.5),
306 new TerrainPainter([tSand, pForest]),
307 new TileClassPainter(clForest)
309 avoidClasses(clPlayer, 1, clOasis, 10, clForest, 10, clHill1, 1),
314 g_Map.log("Creating metal mines");
315 createBalancedMetalMines(
319 avoidClasses(clOasis, 2, clForest, 0, clPlayer, scaleByMapSize(15, 25), clHill1, 1)
322 g_Map.log("Creating stone mines");
323 createBalancedStoneMines(
327 avoidClasses(clOasis, 2, clForest, 0, clPlayer, scaleByMapSize(15, 25), clHill1, 1, clMetal, 10)
331 g_Map.log("Creating gazelles");
332 let group = new SimpleGroup([new SimpleObject(oGazelle, 5, 7, 0, 4)], true, clFood);
333 createObjectGroupsDeprecated(group, 0,
334 avoidClasses(clOasis, 1, clForest, 0, clPlayer, 5, clHill1, 1, clFood, 10),
335 scaleByMapSize(5, 20), 50
338 g_Map.log("Creating goats");
339 group = new SimpleGroup([new SimpleObject(oGoat, 2, 4, 0, 3)], true, clFood);
340 createObjectGroupsDeprecated(group, 0,
341 avoidClasses(clOasis, 1, clForest, 0, clPlayer, 5, clHill1, 1, clFood, 10),
342 scaleByMapSize(5, 20), 50
345 g_Map.log("Creating camels");
346 group = new SimpleGroup([new SimpleObject(oCamel, 2, 4, 0, 2)], true, clFood);
347 createObjectGroupsDeprecated(group, 0,
348 avoidClasses(clOasis, 1, clForest, 0, clPlayer, 5, clHill1, 1, clFood, 10),
349 scaleByMapSize(5, 20), 50
353 createStragglerTrees(
354 [oDatePalm, oSDatePalm],
355 avoidClasses(clOasis, 1, clForest, 0, clHill1, 1, clPlayer, 4, clMetal, 6, clRock, 6),
360 g_Map.log("Creating bushes");
361 group = new SimpleGroup([new RandomObject(aBushes, 2, 3, 0, 2)]);
362 createObjectGroupsDeprecated(group, 0,
363 avoidClasses(clOasis, 1, clHill1, 1, clPlayer, 0, clForest, 0),
364 scaleByMapSize(16, 262)
367 g_Map.log("Creating more decorative rocks");
368 group = new SimpleGroup([new SimpleObject(aDecorativeRock, 1, 2, 0, 2)]);
369 createObjectGroupsDeprecated(group, 0,
370 avoidClasses(clOasis, 1, clHill1, 1, clPlayer, 0, clForest, 0),
371 scaleByMapSize(16, 262)
374 placePlayersNomad(clPlayer,
375 avoidClasses(clOasis, 4, clForest, 1, clMetal, 4, clRock, 4, clHill1, 4, clFood, 2));
377 setWaterWaviness(1.0);
378 setWaterType("clap");