Fix the two incorrect replacements in rP21434, refs #4950.
[0ad.git] / binaries / data / mods / public / maps / random / pompeii.js
bloba908cfe18cc74838f66799c278b9953c17bb5f29
1 /**
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
7  *
8  * Licensing: Public Domain, https://visibleearth.nasa.gov/useteEngine.php
9  *
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.
17  */
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");
100 createArea(
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");
107 createArea(
108         new MapBoundsPlacer(),
109         new SmoothingPainter(1, 0.8, 1));
110 Engine.SetProgress(25);
112 g_Map.log("Marking water");
113 createArea(
114         new MapBoundsPlacer(),
115         new TileClassPainter(g_TileClasses.water),
116         new HeightConstraint(-Infinity, heightWaterLevel));
117 Engine.SetProgress(30);
119 g_Map.log("Marking land");
120 createArea(
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");
127 createArea(
128         new MapBoundsPlacer(),
129         [
130                 new TerrainPainter(g_Terrains.cliff),
131                 new TileClassPainter(g_TileClasses.mountain),
132         ],
133         [
134                 avoidClasses(g_TileClasses.water, 2),
135                 new SlopeConstraint(2, Infinity)
136         ]);
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))),
142         [
143                 new LayeredPainter([g_Terrains.lavaOuter,g_Terrains.lavaInner, g_Terrains.lavaCenter], [scaleByMapSize(1, 3), 2]),
144                 new TileClassPainter(g_TileClasses.lava)
145         ],
146         new HeightConstraint(heightLavaVesuv, Infinity));
147 Engine.SetProgress(46);
149 g_Map.log("Adding smoke");
150 createObjectGroupsByAreas(
151         new SimpleGroup(
152                 [
153                         new SimpleObject(g_Decoratives.smoke1, 1, 1, 0, 4),
154                         new SimpleObject(g_Decoratives.smoke2, 2, 2, 0, 4)
155                 ],
156                 false),
157         0,
158         stayClasses(g_TileClasses.lava, 0),
159         scaleByMapSize(4, 12),
160         20,
161         [areaVesuv]);
162 Engine.SetProgress(48);
164 if (!isNomad())
166         g_Map.log("Placing players");
167         let [playerIDs, playerPosition] = createBases(
168                 ...playerPlacementRandom(
169                         sortAllPlayers(),
170                         [
171                                 avoidClasses(g_TileClasses.mountain, 5),
172                                 stayClasses(g_TileClasses.land, scaleByMapSize(5, 15))
173                         ]),
174                 false);
176         g_Map.log("Flatten the initial CC area");
177         for (let position of playerPosition)
178                 createArea(
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");
185 var dockTypes = [
186         { "template": g_Gaia.dock, "count": scaleByMapSize(1, 2) },
187         { "template": g_Gaia.dockRubble, "count": scaleByMapSize(2, 3) }
189 for (let dockType of dockTypes)
190         placeDocks(
191                 dockType.template,
192                 0,
193                 dockType.count,
194                 g_TileClasses.water,
195                 g_TileClasses.dock,
196                 heightDockMin,
197                 heightDockMax,
198                 [
199                         avoidClasses(g_TileClasses.dock, scaleByMapSize(10, 25)),
200                         new StaticConstraint(avoidClasses(
201                                 g_TileClasses.mountain, scaleByMapSize(6, 8),
202                                 g_TileClasses.baseResource, 10))
203                 ],
204                 0,
205                 50)
206 Engine.SetProgress(55);
208 addElements([
209         {
210                 "func": addLayeredPatches,
211                 "avoid": [
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
218                 ],
219                 "sizes": ["normal"],
220                 "mixes": ["normal"],
221                 "amounts": ["normal"]
222         },
223         {
224                 "func": addDecoration,
225                 "avoid": [
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
231                 ],
232                 "sizes": ["normal"],
233                 "mixes": ["normal"],
234                 "amounts": ["normal"]
235         }
237 Engine.SetProgress(60);
239 addElements(shuffleArray([
240         {
241                 "func": addMetal,
242                 "avoid": [
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
251                 ],
252                 "sizes": ["normal"],
253                 "mixes": ["same"],
254                 "amounts": ["few"]
255         },
256         {
257                 "func": addStone,
258                 "avoid": [
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
267                 ],
268                 "sizes": ["normal"],
269                 "mixes": ["same"],
270                 "amounts": ["few"]
271         },
272         {
273                 "func": addForests,
274                 "avoid": [
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
282                 ],
283                 "sizes": ["normal"],
284                 "mixes": ["same"],
285                 "amounts": ["many"]
286         }
287 ]));
288 Engine.SetProgress(65);
290 addElements(shuffleArray([
291         {
292                 "func": addAnimals,
293                 "avoid": [
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
302                 ],
303                 "sizes": ["normal"],
304                 "mixes": ["same"],
305                 "amounts": ["few"]
306         },
307         {
308                 "func": addFish,
309                 "avoid": [
310                         g_TileClasses.fish, 12,
311                         g_TileClasses.player, 8
312                 ],
313                 "stay": [g_TileClasses.water, 4],
314                 "sizes": ["normal"],
315                 "mixes": ["same"],
316                 "amounts": ["few"]
317         },
318         {
319                 "func": addStragglerTrees,
320                 "avoid": [
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
329                 ],
330                 "sizes": ["normal"],
331                 "mixes": ["same"],
332                 "amounts": ["tons"]
333         }
334 ]));
335 Engine.SetProgress(70);
337 g_Map.log("Adding gatherable stone statues");
338 createObjectGroups(
339         new SimpleGroup(
340                 [new SimpleObject(g_Gaia.romanStatue, 1, 1, 1, 4)],
341                 true,
342                 g_TileClasses.metal
343         ),
344         0,
345         avoidClasses(
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
352         ),
353         5 * scaleByMapSize(1, 4),
354         50);
355 Engine.SetProgress(75);
357 g_Map.log("Adding stone ruins");
358 createObjectGroups(
359         new SimpleGroup(
360                 [
361                         new SimpleObject(g_Gaia.unfinishedTemple, 0, 1, 1, 4),
362                         new SimpleObject(g_Gaia.columnsDoric, 1, 1, 1, 4)
363                 ],
364                 true,
365                 g_TileClasses.decorative
366         ),
367         0,
368         avoidClasses(
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
375         ),
376         scaleByMapSize(1, 4),
377         20);
378 Engine.SetProgress(80);
380 g_Map.log("Adding shipwrecks");
381 createObjectGroups(
382         new SimpleGroup(g_Decoratives.shipwrecks.map(shipwreck => new SimpleObject(shipwreck, 0, 1, 1, 20)), true, g_TileClasses.decorative),
383         0,
384         [
385                 avoidClasses(g_TileClasses.decorative, 20),
386                 stayClasses(g_TileClasses.water, 0)
387         ],
388         scaleByMapSize(1, 5),
389         20);
390 Engine.SetProgress(85);
392 g_Map.log("Adding more statues");
393 createObjectGroups(
394         new SimpleGroup(g_Decoratives.statues.map(ruin => new SimpleObject(ruin, 0, 1, 1, 20)), true, g_TileClasses.decorative),
395         0,
396         avoidClasses(
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
403         ),
404         scaleByMapSize(3, 15),
405         30);
406 Engine.SetProgress(90);
408 g_Map.log("Adding skeletons");
409 createObjectGroups(
410         new SimpleGroup(
411                 [new SimpleObject(g_Decoratives.skeleton, 3, 10, 1, 7)],
412                 true,
413                 g_TileClasses.dirt
414         ),
415         0,
416         avoidClasses(
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
422         ),
423         scaleByMapSize(1, 5),
424         50);
425 Engine.SetProgress(95);
427 placePlayersNomad(
428         g_Map.createTileClass(),
429         [
430                 stayClasses(g_TileClasses.land, 5),
431                 avoidClasses(
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)
437         ]);
439 setWaterTint(0.5, 0.5, 0.5);
440 setWaterColor(0.3, 0.3, 0.3);
441 setWaterWaviness(8);
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);
452 setFogFactor(0);
453 setFogThickness(0);
454 setFogColor(0.69, 0.616, 0.541);
456 setSkySet("stormy");
458 setPPEffect("hdr");
459 setPPContrast(0.67);
460 setPPSaturation(0.42);
461 setPPBloom(0.23);
463 g_Map.ExportMap();