1 Engine.LoadLibrary("rmgen");
2 Engine.LoadLibrary("rmgen-common");
4 function* GenerateMap()
7 "desert_sand_dunes_100",
11 "desert_dirt_rough_2",
14 const tDune = ["desert_sand_dunes_50"];
15 const tForestFloor = "desert_forestfloor_palms";
20 "desert_dirt_rough_2",
23 const tRoad = "desert_city_tile";
24 const tRoadWild = "desert_city_tile";
25 const tShore = "dirta";
26 const tWater = "desert_sand_wet";
28 const ePalmShort = "gaia/tree/cretan_date_palm_short";
29 const ePalmTall = "gaia/tree/cretan_date_palm_tall";
30 const eBush = "gaia/fruit/grapes";
31 const eCamel = "gaia/fauna_camel";
32 const eGazelle = "gaia/fauna_gazelle";
33 const eLion = "gaia/fauna_lion";
34 const eLioness = "gaia/fauna_lioness";
35 const eStoneMine = "gaia/rock/desert_large";
36 const eMetalMine = "gaia/ore/desert_large";
38 const aFlower1 = "actor|props/flora/decals_flowers_daisies.xml";
39 const aWaterFlower = "actor|props/flora/water_lillies.xml";
40 const aReedsA = "actor|props/flora/reeds_pond_lush_a.xml";
41 const aReedsB = "actor|props/flora/reeds_pond_lush_b.xml";
42 const aRock = "actor|geology/stone_desert_med.xml";
43 const aBushA = "actor|props/flora/bush_desert_dry_a.xml";
44 const aBushB = "actor|props/flora/bush_desert_dry_a.xml";
45 const aSand = "actor|particle/blowing_sand.xml";
48 tForestFloor + TERRAIN_SEPARATOR + ePalmShort,
49 tForestFloor + TERRAIN_SEPARATOR + ePalmTall,
52 const pOasisForestLight = [
53 tForestFloor + TERRAIN_SEPARATOR + ePalmShort,
54 tForestFloor + TERRAIN_SEPARATOR + ePalmTall,
64 const heightSeaGround = -3;
65 const heightFloraMin = -2.5;
66 const heightFloraReedsMax = -1.9;
67 const heightFloraMax = -1;
69 const heightSand = 3.4;
70 const heightOasisPath = 4;
71 const heightOffsetBump = 4;
72 const heightOffsetDune = 18;
74 globalThis.g_Map = new RandomMap(heightLand, tSand);
76 const numPlayers = getNumPlayers();
77 const mapSize = g_Map.getSize();
78 const mapCenter = g_Map.getCenter();
80 const clPlayer = g_Map.createTileClass();
81 const clHill = g_Map.createTileClass();
82 const clForest = g_Map.createTileClass();
83 const clOasis = g_Map.createTileClass();
84 const clPassage = g_Map.createTileClass();
85 const clRock = g_Map.createTileClass();
86 const clMetal = g_Map.createTileClass();
87 const clFood = g_Map.createTileClass();
88 const clBaseResource = g_Map.createTileClass();
90 const waterRadius = scaleByMapSize(7, 50);
91 const shoreDistance = scaleByMapSize(4, 10);
92 const forestDistance = scaleByMapSize(6, 20);
94 const [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35));
96 g_Map.log("Creating small oasis near the players...");
97 const forestDist = 1.2 * defaultPlayerBaseRadius();
98 for (let i = 0; i < numPlayers; ++i)
104 forestAngle = Math.PI / 3 * randFloat(1, 2);
106 Vector2D.add(playerPosition[i], new Vector2D(forestDist, 0).rotate(-forestAngle));
109 new ClumpPlacer(70, 1, 0.5, Infinity, forestPosition),
111 new LayeredPainter([tForestFloor, pForestMain], [0]),
112 new TileClassPainter(clBaseResource)
114 avoidClasses(clBaseResource, 0)));
121 const waterAngle = forestAngle + randFloat(1, 5) / 3 * Math.PI;
123 Vector2D.add(forestPosition, new Vector2D(6, 0).rotate(-waterAngle)).round();
125 Vector2D.add(forestPosition, new Vector2D(3, 0).rotate(-waterAngle)).round();
127 Vector2D.add(forestPosition, new Vector2D(5, 0).rotate(-waterAngle)).round();
130 new ClumpPlacer(diskArea(4.5), 0.9, 0.4, Infinity, waterPosition),
132 new LayeredPainter([tShore, tWater], [1]),
133 new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 3)
135 avoidClasses(clBaseResource, 0)));
137 createObjectGroup(new SimpleGroup([new SimpleObject(aFlower1, 1, 5, 0, 3)], true, undefined,
139 createObjectGroup(new SimpleGroup([new SimpleObject(aReedsA, 1, 3, 0, 0)], true, undefined,
145 "PlayerPlacement": [playerIDs, playerPosition],
146 "PlayerTileClass": clPlayer,
147 "BaseResourceClass": clBaseResource,
149 "outerTerrain": tRoadWild,
150 "innerTerrain": tRoad,
152 new TileClassPainter(clPlayer)
162 { "template": eMetalMine },
163 { "template": eStoneMine },
165 "distance": defaultPlayerBaseRadius(),
166 "maxAngle": Math.PI / 2,
167 "groupElements": shuffleArray([aBushA, aBushB, ePalmShort, ePalmTall])
168 .map(t => new SimpleObject(t, 1, 1, 3, 4))
170 // Starting trees were set above
175 g_Map.log("Creating central oasis");
177 new ClumpPlacer(diskArea(forestDistance + shoreDistance + waterRadius), 0.8, 0.2, Infinity,
180 new LayeredPainter([pOasisForestLight, tWater], [forestDistance]),
181 new SmoothElevationPainter(ELEVATION_SET, heightSeaGround,
182 forestDistance + shoreDistance),
183 new TileClassPainter(clOasis)
188 g_Map.log("Creating bumps");
190 new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, Infinity),
191 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 3),
192 avoidClasses(clPlayer, 10, clBaseResource, 6, clOasis, 4),
193 scaleByMapSize(30, 70));
195 g_Map.log("Creating dirt patches");
197 new ClumpPlacer(80, 0.3, 0.06, Infinity),
198 new TerrainPainter(tDirt),
199 avoidClasses(clPlayer, 10, clBaseResource, 6, clOasis, 4, clForest, 4),
200 scaleByMapSize(15, 50));
202 g_Map.log("Creating dunes");
204 new ClumpPlacer(120, 0.3, 0.06, Infinity),
206 new TerrainPainter(tDune),
207 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetDune, 30)
209 avoidClasses(clPlayer, 10, clBaseResource, 6, clOasis, 4, clForest, 4),
210 scaleByMapSize(15, 50));
214 if (mapSize > 150 && randBool())
216 g_Map.log("Creating path though the oasis");
217 const pathWidth = scaleByMapSize(7, 18);
218 const points = distributePointsOnCircle(2, randomAngle(),
219 waterRadius + shoreDistance + forestDistance + pathWidth, mapCenter)[0];
221 new PathPlacer(points[0], points[1], pathWidth, 0.4, 1, 0.2, 0),
223 new TerrainPainter(tSand),
224 new SmoothElevationPainter(ELEVATION_SET, heightOasisPath, 5),
225 new TileClassPainter(clPassage)
228 g_Map.log("Creating some straggler trees around the passage");
229 let group = new SimpleGroup(
231 new SimpleObject(ePalmTall, 1, 1, 0, 0),
232 new SimpleObject(ePalmShort, 1, 2, 1, 2),
233 new SimpleObject(aBushA, 0, 2, 1, 3)
235 createObjectGroupsDeprecated(group, 0, stayClasses(clPassage, 3), scaleByMapSize(60, 250), 100);
237 g_Map.log("Creating stone mines");
238 group = new SimpleGroup(
240 new SimpleObject(eStoneMine, 1, 1, 0, 0),
241 new SimpleObject(ePalmShort, 1, 2, 3, 3),
242 new SimpleObject(ePalmTall, 0, 1, 3, 3),
243 new SimpleObject(aBushB, 1, 1, 2, 2),
244 new SimpleObject(aBushA, 0, 2, 1, 3)
246 createObjectGroupsDeprecated(group, 0,
247 avoidClasses(clOasis, 10, clForest, 1, clPlayer, 30, clRock, 10, clBaseResource, 2, clHill, 1),
248 scaleByMapSize(6, 25), 100
251 g_Map.log("Creating metal mines");
252 group = new SimpleGroup(
254 new SimpleObject(eMetalMine, 1, 1, 0, 0),
255 new SimpleObject(ePalmShort, 1, 2, 2, 3),
256 new SimpleObject(ePalmTall, 0, 1, 2, 2),
257 new SimpleObject(aBushB, 1, 1, 2, 2),
258 new SimpleObject(aBushA, 0, 2, 1, 3)
260 createObjectGroupsDeprecated(group, 0,
269 scaleByMapSize(6, 25), 100
273 g_Map.log("Creating small decorative rocks");
274 group = new SimpleGroup([new SimpleObject(aRock, 2, 4, 0, 2)], true, undefined);
275 createObjectGroupsDeprecated(group, 0,
282 30, scaleByMapSize(10, 50));
286 g_Map.log("Creating camels");
287 group = new SimpleGroup(
288 [new SimpleObject(eCamel, 1, 2, 0, 4)],
291 createObjectGroupsDeprecated(group, 0,
292 avoidClasses(clOasis, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20),
297 g_Map.log("Creating gazelles");
298 group = new SimpleGroup(
299 [new SimpleObject(eGazelle, 2, 4, 0, 2)],
302 createObjectGroupsDeprecated(group, 0,
303 avoidClasses(clOasis, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20),
308 g_Map.log("Creating oasis animals");
309 for (let i = 0; i < scaleByMapSize(5, 30); ++i)
312 Vector2D.add(mapCenter, new Vector2D(forestDistance + shoreDistance + waterRadius, 0)
313 .rotate(randomAngle()));
318 new SimpleObject(eLion, 1, 2, 0, 4),
319 new SimpleObject(eLioness, 1, 2, 2, 4),
320 new SimpleObject(eGazelle, 4, 6, 1, 5),
321 new SimpleObject(eCamel, 1, 2, 1, 5)
330 g_Map.log("Creating bushes");
331 group = new SimpleGroup(
332 [new SimpleObject(aBushB, 1, 2, 0, 2), new SimpleObject(aBushA, 2, 4, 0, 2)]
334 createObjectGroupsDeprecated(group, 0,
335 avoidClasses(clOasis, 2, clHill, 1, clPlayer, 1, clPassage, 1),
336 scaleByMapSize(10, 40), 20
339 const objectsWaterFlora = [
340 new SimpleObject(aReedsA, 5, 12, 0, 2),
341 new SimpleObject(aReedsB, 5, 12, 0, 2)
344 g_Map.log("Creating sand blows and beautifications");
345 for (let sandx = 0; sandx < mapSize; sandx += 4)
346 for (let sandz = 0; sandz < mapSize; sandz += 4)
348 const position = new Vector2D(sandx, sandz);
349 const height = g_Map.getHeight(position);
351 if (height > heightSand)
353 if (randBool((height - heightSand) / 1.4))
354 createObjectGroup(new SimpleGroup([new SimpleObject(aSand, 0, 1, 0, 2)], true,
355 undefined, position), 0);
357 else if (height > heightFloraMin && height < heightFloraMax)
362 [new SimpleObject(aWaterFlower, 1, 4, 1, 2)], true, undefined,
365 else if (randBool(0.7) && height < heightFloraReedsMax)
367 new SimpleGroup(objectsWaterFlora, true, undefined, position),
370 if (clPassage.countMembersInRadius(position, 2))
375 [new SimpleObject(aWaterFlower, 1, 4, 1, 2)], true,
376 undefined, position),
378 else if (randBool(0.7) && height < heightFloraReedsMax)
380 new SimpleGroup(objectsWaterFlora, true, undefined, position),
386 placePlayersNomad(clPlayer,
387 avoidClasses(clOasis, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2));
390 setSunColor(0.914, 0.827, 0.639);
391 setSunRotation(Math.PI/3);
392 setSunElevation(0.5);
393 setWaterColor(0, 0.227, 0.843);
394 setWaterTint(0, 0.545, 0.859);
395 setWaterWaviness(1.0);
396 setWaterType("clap");
397 setWaterMurkiness(0.5);
398 setAmbientColor(0.501961, 0.501961, 0.501961);