2 * Heightmap image source:
3 * Imagery by Jesse Allen, NASA's Earth Observatory,
4 * using data from the General Bathymetric Chart of the Oceans (GEBCO)
5 * produced by the British Oceanographic Data Centre.
6 * https://visibleearth.nasa.gov/view.php?id=73934
8 * Licensing: Public Domain, https://visibleearth.nasa.gov/useteEngine.php
10 * The heightmap image is reproduced using:
11 * wget https://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73934/gebco_08_rev_elev_C1_grey_geo.tif
12 * lat=41.1; lon=14.25; width=1.4;
13 * lat1=$(bc <<< ";scale=5;$lat-$width/2"); lon1=$(bc <<< ";scale=5;$lon+$width/2"); lat2=$(bc <<< ";scale=5;$lat+$width/2"); lon2=$(bc <<< ";scale=5;$lon-$width/2")
14 * gdal_translate -projwin $lon2 $lat2 $lon1 $lat1 gebco_08_rev_elev_C1_grey_geo.tif pompeii.tif
15 * convert pompeii.tif -resize 512 -contrast-stretch 0 pompeii.png
16 * No further changes should be applied to the image to keep it easily interchangeable.
19 Engine.LoadLibrary("rmgen");
20 Engine.LoadLibrary("rmgen-common");
21 Engine.LoadLibrary("rmgen2");
22 Engine.LoadLibrary("rmbiome");
24 setBiome("generic/mediterranean");
26 g_Terrains.lavaOuter = "LavaTest06";
27 g_Terrains.lavaInner = "LavaTest05";
28 g_Terrains.lavaCenter = "LavaTest04";
29 g_Terrains.mainTerrain = "ocean_rock_a";
30 g_Terrains.forestFloor1 = "dirt_burned";
31 g_Terrains.forestFloor2 = "shoreline_stoney_a";
32 g_Terrains.tier1Terrain = "rock_metamorphic";
33 g_Terrains.tier2Terrain = "fissures";
34 g_Terrains.tier3Terrain = "LavaTest06";
35 g_Terrains.tier4Terrain = "ocean_rock_b";
36 g_Terrains.roadWild = "road1";
37 g_Terrains.road = "road1";
38 g_Terrains.water = "ocean_rock_a";
39 g_Terrains.cliff = "ocean_rock_b";
41 g_Gaia.mainHuntableAnimal = "gaia/fauna_goat";
42 g_Gaia.secondaryHuntableAnimal = "gaia/fauna_hawk";
43 g_Gaia.fruitBush = "gaia/fauna_chicken";
44 g_Gaia.fish = "gaia/fauna_fish";
45 g_Gaia.tree1 = "gaia/flora_tree_dead";
46 g_Gaia.tree2 = "gaia/flora_tree_oak_dead";
47 g_Gaia.tree3 = "gaia/flora_tree_dead";
48 g_Gaia.tree4 = "gaia/flora_tree_oak_dead";
49 g_Gaia.tree5 = "gaia/flora_tree_dead";
50 g_Gaia.stoneSmall = "gaia/geology_stone_alpine_a";
51 g_Gaia.columnsDoric = "gaia/ruins/column_doric";
52 g_Gaia.romanStatue = "gaia/ruins/stone_statues_roman";
53 g_Gaia.unfinishedTemple = "gaia/ruins/unfinished_greek_temple";
54 g_Gaia.dock = "structures/rome_dock";
55 g_Gaia.dockRubble = "rubble/rubble_rome_dock";
57 g_Decoratives.smoke1 = "actor|particle/smoke_volcano.xml";
58 g_Decoratives.smoke2 = "actor|particle/smoke_curved.xml";
59 g_Decoratives.grass = "actor|props/flora/grass_field_parched_short.xml";
60 g_Decoratives.grassShort = "actor|props/flora/grass_soft_dry_tuft_a.xml";
61 g_Decoratives.bushMedium = "actor|props/special/eyecandy/barrels_buried.xml";
62 g_Decoratives.bushSmall = "actor|props/special/eyecandy/handcart_1_broken.xml";
63 g_Decoratives.skeleton = "actor|props/special/eyecandy/skeleton.xml";
64 g_Decoratives.shipwrecks = [
65 "actor|props/special/eyecandy/shipwreck_hull.xml",
66 "actor|props/special/eyecandy/shipwreck_ram_side.xml",
67 "actor|props/special/eyecandy/shipwreck_sail_boat.xml",
68 "actor|props/special/eyecandy/shipwreck_sail_boat_cut.xml",
69 "actor|props/special/eyecandy/barrels_floating.xml"
71 g_Decoratives.statues = [
72 "actor|props/special/eyecandy/statue_aphrodite_huge.xml",
73 "actor|props/special/eyecandy/sele_colonnade.xml",
74 "actor|props/special/eyecandy/well_1_b.xml",
75 "actor|props/special/eyecandy/anvil.xml",
76 "actor|props/special/eyecandy/wheel_laying.xml",
77 "actor|props/special/eyecandy/vase_rome_a.xml"
80 const heightScale = num => num * g_MapSettings.Size / 320;
82 const heightSeaGround = heightScale(-30);
83 const heightDockMin = heightScale(-6);
84 const heightShorelineMin = heightScale(-1);
85 const heightShorelineMax = heightScale(0);
86 const heightWaterLevel = heightScale(0);
87 const heightDockMax = heightScale(1);
88 const heightLavaVesuv = heightScale(38);
89 const heightMountains = 140;
91 var g_Map = new RandomMap(0, g_Terrains.mainTerrain);
92 var mapCenter = g_Map.getCenter();
94 initTileClasses(["decorative", "lava", "dock"]);
96 g_Map.LoadHeightmapImage("pompeii.png", 0, heightMountains);
97 Engine.SetProgress(15);
99 g_Map.log("Lowering sea ground");
101 new MapBoundsPlacer(),
102 new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 2),
103 new HeightConstraint(-Infinity, heightWaterLevel));
104 Engine.SetProgress(20);
106 g_Map.log("Smoothing heightmap");
108 new MapBoundsPlacer(),
109 new SmoothingPainter(1, 0.8, 1));
110 Engine.SetProgress(25);
112 g_Map.log("Marking water");
114 new MapBoundsPlacer(),
115 new TileClassPainter(g_TileClasses.water),
116 new HeightConstraint(-Infinity, heightWaterLevel));
117 Engine.SetProgress(30);
119 g_Map.log("Marking land");
121 new MapBoundsPlacer(),
122 new TileClassPainter(g_TileClasses.land),
123 avoidClasses(g_TileClasses.water, 0));
124 Engine.SetProgress(35);
126 g_Map.log("Painting cliffs");
128 new MapBoundsPlacer(),
130 new TerrainPainter(g_Terrains.cliff),
131 new TileClassPainter(g_TileClasses.mountain),
134 avoidClasses(g_TileClasses.water, 2),
135 new SlopeConstraint(2, Infinity)
137 Engine.SetProgress(45);
139 g_Map.log("Painting lava");
140 var areaVesuv = createArea(
141 new RectPlacer(new Vector2D(mapCenter.x, fractionToTiles(0.3)), new Vector2D(fractionToTiles(0.7), fractionToTiles(0.15))),
143 new LayeredPainter([g_Terrains.lavaOuter,g_Terrains.lavaInner, g_Terrains.lavaCenter], [scaleByMapSize(1, 3), 2]),
144 new TileClassPainter(g_TileClasses.lava)
146 new HeightConstraint(heightLavaVesuv, Infinity));
147 Engine.SetProgress(46);
149 g_Map.log("Adding smoke");
150 createObjectGroupsByAreas(
153 new SimpleObject(g_Decoratives.smoke1, 1, 1, 0, 4),
154 new SimpleObject(g_Decoratives.smoke2, 2, 2, 0, 4)
158 stayClasses(g_TileClasses.lava, 0),
159 scaleByMapSize(4, 12),
162 Engine.SetProgress(48);
166 g_Map.log("Placing players");
167 let [playerIDs, playerPosition] = createBases(
168 ...playerPlacementRandom(
171 avoidClasses(g_TileClasses.mountain, 5),
172 stayClasses(g_TileClasses.land, scaleByMapSize(5, 15))
176 g_Map.log("Flatten the initial CC area");
177 for (let position of playerPosition)
179 new ClumpPlacer(diskArea(defaultPlayerBaseRadius() * 0.8), 0.95, 0.6, Infinity, position),
180 new SmoothElevationPainter(ELEVATION_SET, g_Map.getHeight(position), 6));
182 Engine.SetProgress(50);
184 g_Map.log("Placing docks");
186 { "template": g_Gaia.dock, "count": scaleByMapSize(1, 2) },
187 { "template": g_Gaia.dockRubble, "count": scaleByMapSize(2, 3) }
189 for (let dockType of dockTypes)
199 avoidClasses(g_TileClasses.dock, scaleByMapSize(10, 25)),
200 new StaticConstraint(avoidClasses(
201 g_TileClasses.mountain, scaleByMapSize(6, 8),
202 g_TileClasses.baseResource, 10))
206 Engine.SetProgress(55);
210 "func": addLayeredPatches,
212 g_TileClasses.dirt, 5,
213 g_TileClasses.forest, 2,
214 g_TileClasses.mountain, 2,
215 g_TileClasses.player, 12,
216 g_TileClasses.lava, 2,
217 g_TileClasses.water, 3
221 "amounts": ["normal"]
224 "func": addDecoration,
226 g_TileClasses.forest, 2,
227 g_TileClasses.mountain, 2,
228 g_TileClasses.player, 12,
229 g_TileClasses.lava, 2,
230 g_TileClasses.water, 3
234 "amounts": ["normal"]
237 Engine.SetProgress(60);
239 addElements(shuffleArray([
243 g_TileClasses.berries, 5,
244 g_TileClasses.forest, 3,
245 g_TileClasses.mountain, 2,
246 g_TileClasses.player, 30,
247 g_TileClasses.rock, 10,
248 g_TileClasses.metal, 20,
249 g_TileClasses.lava, 5,
250 g_TileClasses.water, 3
259 g_TileClasses.berries, 5,
260 g_TileClasses.forest, 3,
261 g_TileClasses.mountain, 2,
262 g_TileClasses.player, 30,
263 g_TileClasses.rock, 20,
264 g_TileClasses.metal, 10,
265 g_TileClasses.lava, 5,
266 g_TileClasses.water, 5
275 g_TileClasses.berries, 5,
276 g_TileClasses.forest, 18,
277 g_TileClasses.metal, 3,
278 g_TileClasses.mountain, 5,
279 g_TileClasses.player, 20,
280 g_TileClasses.rock, 3,
281 g_TileClasses.water, 2
288 Engine.SetProgress(65);
290 addElements(shuffleArray([
294 g_TileClasses.animals, 20,
295 g_TileClasses.forest, 2,
296 g_TileClasses.metal, 2,
297 g_TileClasses.mountain, 1,
298 g_TileClasses.player, 20,
299 g_TileClasses.rock, 2,
300 g_TileClasses.lava, 10,
301 g_TileClasses.water, 3
310 g_TileClasses.fish, 12,
311 g_TileClasses.player, 8
313 "stay": [g_TileClasses.water, 4],
319 "func": addStragglerTrees,
321 g_TileClasses.berries, 5,
322 g_TileClasses.forest, 7,
323 g_TileClasses.metal, 2,
324 g_TileClasses.mountain, 1,
325 g_TileClasses.player, 12,
326 g_TileClasses.rock, 2,
327 g_TileClasses.lava, 5,
328 g_TileClasses.water, 5
335 Engine.SetProgress(70);
337 g_Map.log("Adding gatherable stone statues");
340 [new SimpleObject(g_Gaia.romanStatue, 1, 1, 1, 4)],
346 g_TileClasses.water, 2,
347 g_TileClasses.player, 20,
348 g_TileClasses.mountain, 3,
349 g_TileClasses.forest, 2,
350 g_TileClasses.lava, 5,
351 g_TileClasses.metal, 20
353 5 * scaleByMapSize(1, 4),
355 Engine.SetProgress(75);
357 g_Map.log("Adding stone ruins");
361 new SimpleObject(g_Gaia.unfinishedTemple, 0, 1, 1, 4),
362 new SimpleObject(g_Gaia.columnsDoric, 1, 1, 1, 4)
365 g_TileClasses.decorative
369 g_TileClasses.water, 2,
370 g_TileClasses.player, 20,
371 g_TileClasses.mountain, 5,
372 g_TileClasses.forest, 2,
373 g_TileClasses.lava, 5,
374 g_TileClasses.decorative, 20
376 scaleByMapSize(1, 4),
378 Engine.SetProgress(80);
380 g_Map.log("Adding shipwrecks");
382 new SimpleGroup(g_Decoratives.shipwrecks.map(shipwreck => new SimpleObject(shipwreck, 0, 1, 1, 20)), true, g_TileClasses.decorative),
385 avoidClasses(g_TileClasses.decorative, 20),
386 stayClasses(g_TileClasses.water, 0)
388 scaleByMapSize(1, 5),
390 Engine.SetProgress(85);
392 g_Map.log("Adding more statues");
394 new SimpleGroup(g_Decoratives.statues.map(ruin => new SimpleObject(ruin, 0, 1, 1, 20)), true, g_TileClasses.decorative),
397 g_TileClasses.water, 2,
398 g_TileClasses.player, 20,
399 g_TileClasses.mountain, 2,
400 g_TileClasses.forest, 2,
401 g_TileClasses.lava, 5,
402 g_TileClasses.decorative, 20
404 scaleByMapSize(3, 15),
406 Engine.SetProgress(90);
408 g_Map.log("Adding skeletons");
411 [new SimpleObject(g_Decoratives.skeleton, 3, 10, 1, 7)],
417 g_TileClasses.water, 2,
418 g_TileClasses.player, 10,
419 g_TileClasses.mountain, 2,
420 g_TileClasses.forest, 2,
421 g_TileClasses.decorative, 2
423 scaleByMapSize(1, 5),
425 Engine.SetProgress(95);
428 g_Map.createTileClass(),
430 stayClasses(g_TileClasses.land, 5),
432 g_TileClasses.forest, 1,
433 g_TileClasses.rock, 4,
434 g_TileClasses.metal, 4,
435 g_TileClasses.animals, 2,
436 g_TileClasses.mountain, 2)
439 setWaterTint(0.5, 0.5, 0.5);
440 setWaterColor(0.3, 0.3, 0.3);
442 setWaterMurkiness(0.87);
443 setWaterType("lake");
445 setTerrainAmbientColor(0.3, 0.3, 0.3);
446 setUnitsAmbientColor(0.3, 0.3, 0.3);
448 setSunColor(0.8, 0.8, 0.8);
449 setSunRotation(Math.PI);
450 setSunElevation(1/2);
454 setFogColor(0.69, 0.616, 0.541);
460 setPPSaturation(0.42);