Fix rmgen2 bug in rP17903 revealed by the 1* removal in rP20281.
[0ad.git] / binaries / data / mods / public / maps / random / alpine_valley.js
blobab2f288e12fa63f8531052e987327e93d2ad38d8
1 RMS.LoadLibrary("rmgen");
3 TILE_CENTERED_HEIGHT_MAP = true;
5 // late spring
6 if (randBool())
8         var tPrimary = ["alpine_dirt_grass_50"];
9         var tForestFloor = "alpine_forrestfloor";
10         var tCliff = ["alpine_cliff_a", "alpine_cliff_b", "alpine_cliff_c"];
11         var tSecondary = "alpine_grass_rocky";
12         var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"];
13         var tSnowLimited = ["alpine_snow_rocky"];
14         var tDirt = "alpine_dirt";
15         var tRoad = "new_alpine_citytile";
16         var tRoadWild = "new_alpine_citytile";
17         var tShore = "alpine_shore_rocks_grass_50";
18         var tWater = "alpine_shore_rocks";
20         // gaia entities
21         var oPine = "gaia/flora_tree_pine";
22         var oBerryBush = "gaia/flora_bush_berry";
23         var oDeer = "gaia/fauna_deer";
24         var oRabbit = "gaia/fauna_rabbit";
25         var oStoneLarge = "gaia/geology_stonemine_alpine_quarry";
26         var oStoneSmall = "gaia/geology_stone_alpine_a";
27         var oMetalLarge = "gaia/geology_metal_alpine_slabs";
29         // decorative props
30         var aGrass = "actor|props/flora/grass_soft_small_tall.xml";
31         var aGrassShort = "actor|props/flora/grass_soft_large.xml";
32         var aRockLarge = "actor|geology/stone_granite_med.xml";
33         var aRockMedium = "actor|geology/stone_granite_med.xml";
34         var aBushMedium = "actor|props/flora/bush_medit_me.xml";
35         var aBushSmall = "actor|props/flora/bush_medit_sm.xml";
37 else
38 //winter
40         var tPrimary = ["alpine_snow_a", "alpine_snow_b"];
41         var tForestFloor = "alpine_forrestfloor_snow";
42         var tCliff = ["alpine_cliff_snow"];
43         var tSecondary = "alpine_grass_snow_50";
44         var tHalfSnow = ["alpine_grass_snow_50", "alpine_dirt_snow"];
45         var tSnowLimited = ["alpine_snow_a", "alpine_snow_b"];
46         var tDirt = "alpine_dirt";
47         var tRoad = "new_alpine_citytile";
48         var tRoadWild = "new_alpine_citytile";
49         var tShore = "alpine_shore_rocks_icy";
50         var tWater = "alpine_shore_rocks";
52         // gaia entities
53         var oPine = "gaia/flora_tree_pine_w";
54         var oBerryBush = "gaia/flora_bush_berry";
55         var oDeer = "gaia/fauna_deer";
56         var oRabbit = "gaia/fauna_rabbit";
57         var oStoneLarge = "gaia/geology_stonemine_alpine_quarry";
58         var oStoneSmall = "gaia/geology_stone_alpine_a";
59         var oMetalLarge = "gaia/geology_metal_alpine_slabs";
61         // decorative props
62         var aGrass = "actor|props/flora/grass_soft_dry_small_tall.xml";
63         var aGrassShort = "actor|props/flora/grass_soft_dry_large.xml";
64         var aRockLarge = "actor|geology/stone_granite_med.xml";
65         var aRockMedium = "actor|geology/stone_granite_med.xml";
66         var aBushMedium = "actor|props/flora/bush_medit_me_dry.xml";
67         var aBushSmall = "actor|props/flora/bush_medit_sm_dry.xml";
70 const pForest = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor];
72 InitMap();
74 const numPlayers = getNumPlayers();
75 const mapSize = getMapSize();
76 const mapArea = mapSize*mapSize;
78 var clPlayer = createTileClass();
79 var clHill = createTileClass();
80 var clForest = createTileClass();
81 var clDirt = createTileClass();
82 var clRock = createTileClass();
83 var clMetal = createTileClass();
84 var clFood = createTileClass();
85 var clBaseResource = createTileClass();
86 var clSettlement = createTileClass();
88 initTerrain(tPrimary);
90 var [playerIDs, playerX, playerZ, playerAngle, startAngle] = radialPlayerPlacement();
92 for (var i = 0; i < numPlayers; i++)
94         var id = playerIDs[i];
95         log("Creating base for player " + id + "...");
97         var radius = scaleByMapSize(15,25);
98         var cliffRadius = 2;
99         var elevation = 20;
101         // get the x and z in tiles
102         var fx = fractionToTiles(playerX[i]);
103         var fz = fractionToTiles(playerZ[i]);
104         ix = round(fx);
105         iz = round(fz);
106         addCivicCenterAreaToClass(ix, iz, clPlayer);
108         // create the city patch
109         var cityRadius = radius/3;
110         placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
111         var painter = new LayeredPainter([tRoadWild, tRoad], [1]);
112         createArea(placer, painter, null);
114         placeCivDefaultEntities(fx, fz, id);
116         placeDefaultChicken(fx, fz, clBaseResource);
118         // create berry bushes
119         var bbAngle = randFloat(0, TWO_PI);
120         var bbDist = 12;
121         var bbX = round(fx + bbDist * cos(bbAngle));
122         var bbZ = round(fz + bbDist * sin(bbAngle));
123         var group = new SimpleGroup(
124                 [new SimpleObject(oBerryBush, 5,5, 0,3)],
125                 true, clBaseResource, bbX, bbZ
126         );
127         createObjectGroup(group, 0);
129         // create metal mine
130         var mAngle = bbAngle;
131         while(abs(mAngle - bbAngle) < PI/3)
132                 mAngle = randFloat(0, TWO_PI);
134         var mDist = 12;
135         var mX = round(fx + mDist * cos(mAngle));
136         var mZ = round(fz + mDist * sin(mAngle));
137         group = new SimpleGroup(
138                 [new SimpleObject(oMetalLarge, 1,1, 0,0)],
139                 true, clBaseResource, mX, mZ
140         );
141         createObjectGroup(group, 0);
143         // create stone mines
144         mAngle += randFloat(PI/8, PI/4);
145         mX = round(fx + mDist * cos(mAngle));
146         mZ = round(fz + mDist * sin(mAngle));
147         group = new SimpleGroup(
148                 [new SimpleObject(oStoneLarge, 1,1, 0,2)],
149                 true, clBaseResource, mX, mZ
150         );
151         createObjectGroup(group, 0);
152         var hillSize = PI * radius * radius;
153         // create starting trees
154         var num = floor(hillSize / 100);
155         var tAngle = randFloat(-PI/3, 4*PI/3);
156         var tDist = randFloat(11, 13);
157         var tX = round(fx + tDist * cos(tAngle));
158         var tZ = round(fz + tDist * sin(tAngle));
159         group = new SimpleGroup(
160                 [new SimpleObject(oPine, num, num, 0,5)],
161                 false, clBaseResource, tX, tZ
162         );
163         createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
165         placeDefaultDecoratives(fx, fz, aGrassShort, clBaseResource, radius);
167 RMS.SetProgress(20);
169 //place the mountains
170 var points = [];
172 var edgesConncetedToPoints = [];
174 //we want the points near the start locations be the first ones. hence we use two "for" blocks
175 for (var i = 0; i < numPlayers; ++i)
177         playerAngle[i] = startAngle + (i+0.5)*TWO_PI/numPlayers;
178         points.push([round(fractionToTiles(0.5 + 0.49 * cos(playerAngle[i]))), round(fractionToTiles(0.5 + 0.49 * sin(playerAngle[i])))]);
181 //the order of the other points doesn't matter
182 for (var i = 0; i < numPlayers; ++i)
184         playerAngle[i] = startAngle + (i+0.7)*TWO_PI/numPlayers;
185         points.push([round(fractionToTiles(0.5 + 0.34 * cos(playerAngle[i]))), round(fractionToTiles(0.5 + 0.34 * sin(playerAngle[i])))]);
186         playerAngle[i] = startAngle + (i+0.3)*TWO_PI/numPlayers;
187         points.push([round(fractionToTiles(0.5 + 0.34 * cos(playerAngle[i]))), round(fractionToTiles(0.5 + 0.34 * sin(playerAngle[i])))]);
188         playerAngle[i] = startAngle + (i+0.5)*TWO_PI/numPlayers;
189         points.push([round(fractionToTiles(0.5 + 0.18 * cos(playerAngle[i]))), round(fractionToTiles(0.5 + 0.18 * sin(playerAngle[i])))]);
192 //add the center of the map
193 points.push([round(fractionToTiles(0.5)), round(fractionToTiles(0.5))]);
195 var numPoints = numPlayers * 4 + 1;
197 for (var i = 0; i < numPoints; ++i)
198         edgesConncetedToPoints.push(0);
200 //we are making a planar graph where every edge is a straight line.
201 var possibleEdges = [];
203 //add all of the possible combinations
204 for (var i = 0; i < numPoints; ++i)
205         for (var j = numPlayers; j < numPoints; ++j)
206                 if (j > i)
207                         possibleEdges.push([i,j]);
209 //we need a matrix so that we can prevent the mountain ranges from bocking a player
210 var matrix = [];
211 for (var i = 0; i < numPoints; ++i)
213         matrix.push([]);
214         for (var j = 0; j < numPoints; ++j)
215                 matrix[i].push(i < numPlayers && j < numPlayers && i != j && (i == j - 1 || i == j + 1))
218 //find and place the edges
219 while (possibleEdges.length)
221         var index = randIntExclusive(0, possibleEdges.length);
223         //ensure that a point is connected to a maximum of 3 others
224         if (edgesConncetedToPoints[possibleEdges[index][0]] > 2 || edgesConncetedToPoints[possibleEdges[index][1]] > 2)
225         {
226                 possibleEdges.splice(index,1);
227                 continue;
228         }
230         //we don't want ranges that are longer than half of the map's size
231         if ((((points[possibleEdges[index][0]][0] - points[possibleEdges[index][1]][0]) *
232                 (points[possibleEdges[index][0]][0] - points[possibleEdges[index][1]][0])) +
233                 ((points[possibleEdges[index][0]][1] - points[possibleEdges[index][1]][1]) *
234                 (points[possibleEdges[index][0]][1] - points[possibleEdges[index][1]][1]))) >
235                 mapArea)
236         {
237                 possibleEdges.splice(index,1);
238                 continue;
239         }
241         //dfs
242         var q = [possibleEdges[index][0]];
244         matrix[possibleEdges[index][0]][possibleEdges[index][1]] = true;
245         matrix[possibleEdges[index][1]][possibleEdges[index][0]] = true;
246         var selected, accept = true, tree = [], backtree = [];
247         while (q.length > 0)
248         {
249                 selected = q.shift();
250                 if (tree.indexOf(selected) == -1)
251                 {
252                         tree.push(selected);
253                         backtree.push(-1);
254                 }
256                 for (var i = 0; i < numPoints; ++i)
257                         if (matrix[selected][i])
258                         {
259                                 if (i == backtree[tree.lastIndexOf(selected)])
260                                         continue;
262                                 if (tree.indexOf(i) == -1)
263                                 {
264                                         tree.push(i);
265                                         backtree.push(selected);
266                                         q.unshift(i);
267                                 }
268                                 else
269                                 {
270                                         accept = false;
271                                         matrix[possibleEdges[index][0]][possibleEdges[index][1]] = false;
272                                         matrix[possibleEdges[index][1]][possibleEdges[index][0]] = false;
273                                         break;
274                                 }
275                         }
276         }
278         if (!accept)
279         {
280                 possibleEdges.splice(index,1);
281                 continue;
282         }
284         var ix = points[possibleEdges[index][0]][0];
285         var iz = points[possibleEdges[index][0]][1];
286         var ix2 = points[possibleEdges[index][1]][0];
287         var iz2 = points[possibleEdges[index][1]][1];
288         var placer = new PathPlacer(ix, iz, ix2, iz2, scaleByMapSize(9,15), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.1, 0.1);
289         var terrainPainter = new LayeredPainter(
290                 [tCliff, tPrimary],             // terrains
291                 [3]             // widths
292         );
293         var elevationPainter = new SmoothElevationPainter(
294                 ELEVATION_SET,                  // type
295                 30,                             // elevation
296                 2                               // blend radius
297         );
298         accept = createArea(placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 20));
300         if (accept == null)
301         {
302                 matrix[possibleEdges[index][0]][possibleEdges[index][1]] = false;
303                 matrix[possibleEdges[index][1]][possibleEdges[index][0]] = false;
304                 possibleEdges.splice(index,1);
305                 continue;
306         }
307         else
308         {
309                 placer = new ClumpPlacer(floor(PI*scaleByMapSize(9,15)*scaleByMapSize(9,15)/4), 0.95, 0.6, 10, ix, iz);
310                 var terrainPainter = new LayeredPainter(
311                         [tCliff, tPrimary],             // terrains
312                         [3]             // widths
313                 );
314                 var elevationPainter = new SmoothElevationPainter(
315                         ELEVATION_SET,                  // type
316                         30,                             // elevation
317                         2                               // blend radius
318                 );
319                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 5));
321                 placer = new ClumpPlacer(floor(PI*scaleByMapSize(9,15)*scaleByMapSize(9,15)/4), 0.95, 0.6, 10, ix2, iz2);
322                 var terrainPainter = new LayeredPainter(
323                         [tCliff, tPrimary],             // terrains
324                         [3]             // widths
325                 );
326                 var elevationPainter = new SmoothElevationPainter(
327                         ELEVATION_SET,                  // type
328                         30,                             // elevation
329                         2                               // blend radius
330                 );
331                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clHill)], avoidClasses(clPlayer, 5));
332         }
334         for (var i = 0; i < possibleEdges.length; ++i)
335         {
336                 if (possibleEdges[index][0] != possibleEdges[i][0] && possibleEdges[index][1] != possibleEdges[i][0] &&
337                         possibleEdges[index][0] != possibleEdges[i][1] && possibleEdges[index][1] != possibleEdges[i][1])
338                 {
340                         if (checkIfIntersect (points[possibleEdges[index][0]][0], points[possibleEdges[index][0]][1],
341                                 points[possibleEdges[index][1]][0], points[possibleEdges[index][1]][1], points[possibleEdges[i][0]][0],
342                                 points[possibleEdges[i][0]][1], points[possibleEdges[i][1]][0], points[possibleEdges[i][1]][1], scaleByMapSize(9,15) + scaleByMapSize(10,15)))
343                         {
344                                 possibleEdges.splice(i,1);
345                                 --i;
346                                 if (index > i)
347                                         --index;
348                         }
349                 }
350                 else if (((possibleEdges[index][0] == possibleEdges[i][0] && possibleEdges[index][1] != possibleEdges[i][1]) ||
351                         (possibleEdges[index][1] == possibleEdges[i][0] && possibleEdges[index][0] != possibleEdges[i][1])) &&
352                         distanceOfPointFromLine(points[possibleEdges[index][0]][0],points[possibleEdges[index][0]][1],
353                         points[possibleEdges[index][1]][0], points[possibleEdges[index][1]][1],points[possibleEdges[i][1]][0], points[possibleEdges[i][1]][1])
354                         < scaleByMapSize(9,15) + scaleByMapSize(10,15))
355                 {
356                         possibleEdges.splice(i,1);
357                         --i;
358                         if (index > i)
359                                 --index;
360                 }
361                 else if (((possibleEdges[index][0] == possibleEdges[i][1] && possibleEdges[index][1] != possibleEdges[i][0]) ||
362                         (possibleEdges[index][1] == possibleEdges[i][1] && possibleEdges[index][0] != possibleEdges[i][0])) &&
363                         distanceOfPointFromLine(points[possibleEdges[index][0]][0],points[possibleEdges[index][0]][1],
364                         points[possibleEdges[index][1]][0], points[possibleEdges[index][1]][1],points[possibleEdges[i][0]][0], points[possibleEdges[i][0]][1])
365                         < scaleByMapSize(9,15) + scaleByMapSize(10,15))
366                 {
367                         possibleEdges.splice(i,1);
368                         --i;
369                         if (index > i)
370                                 --index;
371                 }
373         }
375         edgesConncetedToPoints[possibleEdges[index][0]] += 1;
376         edgesConncetedToPoints[possibleEdges[index][1]] += 1;
378         possibleEdges.splice(index,1);
381 paintTerrainBasedOnHeight(3.1, 29, 0, tCliff);
382 paintTerrainBasedOnHeight(29, 30, 3, tSnowLimited);
384 log("Creating bumps...");
385 placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1);
386 painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2);
387 createAreas(
388         placer,
389         painter,
390         avoidClasses(clPlayer, 10),
391         scaleByMapSize(100, 200)
393 RMS.SetProgress(40);
395 log("Creating hills...");
396 placer = new ClumpPlacer(scaleByMapSize(40, 150), 0.2, 0.1, 1);
397 var terrainPainter = new LayeredPainter(
398         [tCliff, tSnowLimited],         // terrains
399         [2]                                                             // widths
401 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 30, 2);
402 createAreas(
403         placer,
404         [terrainPainter, elevationPainter, paintClass(clHill)],
405         avoidClasses(clPlayer, 20, clHill, 14),
406         scaleByMapSize(10, 80) * numPlayers
408 RMS.SetProgress(50);
410 // calculate desired number of trees for map (based on size)
411 var MIN_TREES = 500;
412 var MAX_TREES = 3000;
413 var P_FOREST = 0.7;
415 var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES);
416 var numForest = totalTrees * P_FOREST;
417 var numStragglers = totalTrees * (1.0 - P_FOREST);
419 log("Creating forests...");
420 var types = [
421         [[tForestFloor, tPrimary, pForest], [tForestFloor, pForest]]
422 ];      // some variation
424 var size = numForest / (scaleByMapSize(2,8) * numPlayers);
426 var num = floor(size / types.length);
427 for (var i = 0; i < types.length; ++i)
429         placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 1);
430         painter = new LayeredPainter(
431                 types[i],               // terrains
432                 [2]                                                                                     // widths
433                 );
434         createAreas(
435                 placer,
436                 [painter, paintClass(clForest)],
437                 avoidClasses(clPlayer, 12, clForest, 10, clHill, 0),
438                 num
439         );
441 RMS.SetProgress(60);
443 log("Creating dirt patches...");
444 var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)];
445 for (var i = 0; i < sizes.length; i++)
447         placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
448         painter = new LayeredPainter(
449                 [[tDirt,tHalfSnow], [tHalfSnow,tSnowLimited]],          // terrains
450                 [2]                                                                                                                     // widths
451         );
452         createAreas(
453                 placer,
454                 [painter, paintClass(clDirt)],
455                 avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12),
456                 scaleByMapSize(15, 45)
457         );
460 log("Creating grass patches...");
461 var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)];
462 for (var i = 0; i < sizes.length; i++)
464         placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
465         painter = new TerrainPainter(tSecondary);
466         createAreas(
467                 placer,
468                 painter,
469                 avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 12),
470                 scaleByMapSize(15, 45)
471         );
473 RMS.SetProgress(65);
475 log("Creating stone mines...");
476 group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock);
477 createObjectGroupsDeprecated(group, 0,
478         avoidClasses(clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
479         scaleByMapSize(4,16), 100
482 log("Creating small stone mines...");
483 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock);
484 createObjectGroupsDeprecated(group, 0,
485         avoidClasses(clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
486         scaleByMapSize(4,16), 100
489 log("Creating metal mines...");
490 group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal);
491 createObjectGroupsDeprecated(group, 0,
492         avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1),
493         scaleByMapSize(4,16), 100
495 RMS.SetProgress(70);
497 log("Creating small decorative rocks...");
498 group = new SimpleGroup(
499         [new SimpleObject(aRockMedium, 1,3, 0,1)],
500         true
502 createObjectGroupsDeprecated(
503         group, 0,
504         avoidClasses(clForest, 0, clPlayer, 0, clHill, 0),
505         scaleByMapSize(16, 262), 50
508 log("Creating large decorative rocks...");
509 group = new SimpleGroup(
510         [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)],
511         true
513 createObjectGroupsDeprecated(
514         group, 0,
515         avoidClasses(clForest, 0, clPlayer, 0, clHill, 0),
516         scaleByMapSize(8, 131), 50
518 RMS.SetProgress(75);
520 log("Creating deer...");
521 group = new SimpleGroup(
522         [new SimpleObject(oDeer, 5,7, 0,4)],
523         true, clFood
525 createObjectGroupsDeprecated(group, 0,
526         avoidClasses(clForest, 0, clPlayer, 10, clHill, 1, clFood, 20),
527         3 * numPlayers, 50
530 log("Creating berry bush...");
531 group = new SimpleGroup(
532         [new SimpleObject(oBerryBush, 5,7, 0,4)],
533         true, clFood
535 createObjectGroupsDeprecated(group, 0,
536         avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clFood, 10),
537         randIntInclusive(1, 4) * numPlayers + 2, 50
540 log("Creating rabbit...");
541 group = new SimpleGroup(
542         [new SimpleObject(oRabbit, 2,3, 0,2)],
543         true, clFood
545 createObjectGroupsDeprecated(group, 0,
546         avoidClasses(clForest, 0, clPlayer, 10, clHill, 1, clFood, 20),
547         3 * numPlayers, 50
549 RMS.SetProgress(85);
551 log("Creating straggler trees...");
552 var types = [oPine, oPine];     // some variation
553 var num = floor(numStragglers / types.length);
554 for (var i = 0; i < types.length; ++i)
556         group = new SimpleGroup(
557                 [new SimpleObject(types[i], 1,1, 0,3)],
558                 true, clForest
559         );
560         createObjectGroupsDeprecated(group, 0,
561                 avoidClasses(clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6),
562                 num
563         );
566 log("Creating small grass tufts...");
567 var planetm = 1;
569 group = new SimpleGroup(
570         [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)]
572 createObjectGroupsDeprecated(group, 0,
573         avoidClasses(clHill, 2, clPlayer, 2, clDirt, 0),
574         planetm * scaleByMapSize(13, 200)
576 RMS.SetProgress(90);
578 log("Creating large grass tufts...");
579 group = new SimpleGroup(
580         [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)]
582 createObjectGroupsDeprecated(group, 0,
583         avoidClasses(clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0),
584         planetm * scaleByMapSize(13, 200)
586 RMS.SetProgress(95);
588 log("Creating bushes...");
589 group = new SimpleGroup(
590         [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)]
592 createObjectGroupsDeprecated(group, 0,
593         avoidClasses(clHill, 1, clPlayer, 1, clDirt, 1),
594         planetm * scaleByMapSize(13, 200), 50
597 setSkySet(pickRandom(["cirrus", "cumulus", "sunny"]));
598 setSunRotation(randFloat(0, TWO_PI));
599 setSunElevation(randFloat(PI/ 5, PI / 3));
600 setWaterColor(0.0, 0.047, 0.286);                               // dark majestic blue
601 setWaterTint(0.471, 0.776, 0.863);                              // light blue
602 setWaterMurkiness(0.72);
603 setWaterWaviness(2.0);
604 setWaterType("lake");
606 ExportMap();