Fix rmgen2 bug in rP17903 revealed by the 1* removal in rP20281.
[0ad.git] / binaries / data / mods / public / maps / random / sahel_watering_holes.js
blob19d60934650421486ba2bbe724d6913821d67224
1 RMS.LoadLibrary("rmgen");
3 const tGrass = "savanna_grass_a";
4 const tForestFloor = "savanna_forestfloor_a";
5 const tCliff = "savanna_cliff_b";
6 const tDirtRocksA = "savanna_dirt_rocks_c";
7 const tDirtRocksB = "savanna_dirt_rocks_a";
8 const tDirtRocksC = "savanna_dirt_rocks_b";
9 const tHill = "savanna_cliff_a";
10 const tRoad = "savanna_tile_a_red";
11 const tRoadWild = "savanna_tile_a_red";
12 const tGrassPatch = "savanna_grass_b";
13 const tShoreBlend = "savanna_riparian";
14 const tShore = "savanna_riparian_bank";
15 const tWater = "savanna_riparian_wet";
17 const oBaobab = "gaia/flora_tree_baobab";
18 const oFig = "gaia/flora_tree_fig";
19 const oBerryBush = "gaia/flora_bush_berry";
20 const oWildebeest = "gaia/fauna_wildebeest";
21 const oFish = "gaia/fauna_fish";
22 const oGazelle = "gaia/fauna_gazelle";
23 const oElephant = "gaia/fauna_elephant_african_bush";
24 const oGiraffe = "gaia/fauna_giraffe";
25 const oZebra = "gaia/fauna_zebra";
26 const oStoneLarge = "gaia/geology_stonemine_desert_quarry";
27 const oStoneSmall = "gaia/geology_stone_savanna_small";
28 const oMetalLarge = "gaia/geology_metal_savanna_slabs";
30 const aGrass = "actor|props/flora/grass_savanna.xml";
31 const aGrassShort = "actor|props/flora/grass_medit_field.xml";
32 const aReeds = "actor|props/flora/reeds_pond_lush_a.xml";
33 const aLillies = "actor|props/flora/reeds_pond_lush_b.xml";
34 const aRockLarge = "actor|geology/stone_savanna_med.xml";
35 const aRockMedium = "actor|geology/stone_savanna_med.xml";
36 const aBushMedium = "actor|props/flora/bush_desert_dry_a.xml";
37 const aBushSmall = "actor|props/flora/bush_dry_a.xml";
39 const pForest = [tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor];
41 InitMap();
43 const numPlayers = getNumPlayers();
44 const mapSize = getMapSize();
45 const mapArea = mapSize*mapSize;
47 var clPlayer = createTileClass();
48 var clHill = createTileClass();
49 var clForest = createTileClass();
50 var clWater = createTileClass();
51 var clDirt = createTileClass();
52 var clRock = createTileClass();
53 var clMetal = createTileClass();
54 var clFood = createTileClass();
55 var clBaseResource = createTileClass();
56 var clSettlement = createTileClass();
57 var clShallows = createTileClass();
59 var [playerIDs, playerX, playerZ, playerAngle, startAngle] = radialPlayerPlacement();
61 for (var i = 0; i < numPlayers; i++)
63         var id = playerIDs[i];
64         log("Creating base for player " + id + "...");
66         var radius = scaleByMapSize(15,25);
67         var cliffRadius = 2;
68         var elevation = 20;
70         // get the x and z in tiles
71         var fx = fractionToTiles(playerX[i]);
72         var fz = fractionToTiles(playerZ[i]);
73         var ix = round(fx);
74         var iz = round(fz);
75         addCivicCenterAreaToClass(ix, iz, clPlayer);
77         // create the city patch
78         var cityRadius = radius/3;
79         var placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
80         var painter = new LayeredPainter([tRoadWild, tRoad], [1]);
81         createArea(placer, painter, null);
83         placeCivDefaultEntities(fx, fz, id);
85         placeDefaultChicken(fx, fz, clBaseResource);
87         // create berry bushes
88         var bbAngle = randFloat(0, TWO_PI);
89         var bbDist = 12;
90         var bbX = round(fx + bbDist * cos(bbAngle));
91         var bbZ = round(fz + bbDist * sin(bbAngle));
92         var group = new SimpleGroup(
93                 [new SimpleObject(oBerryBush, 5,5, 0,3)],
94                 true, clBaseResource, bbX, bbZ
95         );
96         createObjectGroup(group, 0);
98         // create metal mine
99         var mAngle = bbAngle;
100         while(abs(mAngle - bbAngle) < PI/3)
101         {
102                 mAngle = randFloat(0, TWO_PI);
103         }
104         var mDist = 12;
105         var mX = round(fx + mDist * cos(mAngle));
106         var mZ = round(fz + mDist * sin(mAngle));
107         group = new SimpleGroup(
108                 [new SimpleObject(oMetalLarge, 1,1, 0,0)],
109                 true, clBaseResource, mX, mZ
110         );
111         createObjectGroup(group, 0);
113         // create stone mines
114         mAngle += randFloat(PI/8, PI/4);
115         mX = round(fx + mDist * cos(mAngle));
116         mZ = round(fz + mDist * sin(mAngle));
117         group = new SimpleGroup(
118                 [new SimpleObject(oStoneLarge, 1,1, 0,2)],
119                 true, clBaseResource, mX, mZ
120         );
121         createObjectGroup(group, 0);
123         // create starting trees
124         var num = 5;
125         var tAngle = randFloat(-PI/3, 4*PI/3);
126         var tDist = randFloat(12, 13);
127         var tX = round(fx + tDist * cos(tAngle));
128         var tZ = round(fz + tDist * sin(tAngle));
129         group = new SimpleGroup(
130                 [new SimpleObject(oBaobab, num, num, 0,3)],
131                 false, clBaseResource, tX, tZ
132         );
133         createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
135         placeDefaultDecoratives(fx, fz, aGrassShort, clBaseResource, radius);
138 RMS.SetProgress(20);
140 log ("Creating rivers...");
141 for (var m = 0; m < numPlayers; m++)
143         var tang = startAngle + (m + 0.5) * TWO_PI / numPlayers;
144         placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,50)*scaleByMapSize(10,50)/3), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.15*cos(tang)), fractionToTiles(0.5 + 0.15*sin(tang)));
145         var painter = new LayeredPainter([tShore, tWater, tWater], [1, 3]);
146         var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 4);
147         createArea(placer, [painter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
148         var placer = new PathPlacer(fractionToTiles(0.5 + 0.15*cos(tang)), fractionToTiles(0.5 + 0.15*sin(tang)), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(10,50), 0.2, 3*(scaleByMapSize(1,4)), 0.2, 0.05);
149         var terrainPainter = new LayeredPainter(
150                 [tShore, tWater, tWater],               // terrains
151                 [1, 3]                                                          // widths
152         );
153         var elevationPainter = new SmoothElevationPainter(
154                 ELEVATION_SET,                  // type
155                 -4,                             // elevation
156                 4                               // blend radius
157         );
158         createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
159         placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,50)*scaleByMapSize(10,50)/5), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)));
160         var painter = new LayeredPainter([tWater, tWater], [1]);
161         var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 4);
162         createArea(placer, [painter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
165 for (var i = 0; i < numPlayers; i++)
167         if (i+1 == numPlayers)
168         {
169                 passageMaker(
170                         round(fractionToTiles(playerX[i])),
171                         round(fractionToTiles(playerZ[i])),
172                         round(fractionToTiles(playerX[0])),
173                         round(fractionToTiles(playerZ[0])),
174                         6, -2, -2, 4, clShallows, undefined, -4);
176                 log("Creating animals in shallows...");
177                 var group = new SimpleGroup(
178                         [new SimpleObject(oElephant, 2,3, 0,4)],
179                         true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[0]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[0]))/2)
180                 );
181                 createObjectGroup(group, 0);
183                 var group = new SimpleGroup(
184                         [new SimpleObject(oWildebeest, 5,6, 0,4)],
185                         true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[0]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[0]))/2)
186                 );
187                 createObjectGroup(group, 0);
189         }
190         else
191         {
192                 passageMaker(
193                         fractionToTiles(playerX[i]),
194                         fractionToTiles(playerZ[i]),
195                         fractionToTiles(playerX[i+1]),
196                         fractionToTiles(playerZ[i+1]),
197                         6, -2, -2, 4, clShallows, undefined, -4);
199                 log("Creating animals in shallows...");
200                 var group = new SimpleGroup(
201                         [new SimpleObject(oElephant, 2,3, 0,4)],
202                         true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[i+1]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[i+1]))/2)
203                 );
204                 createObjectGroup(group, 0);
206                 var group = new SimpleGroup(
207                         [new SimpleObject(oWildebeest, 5,6, 0,4)],
208                         true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[i+1]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[i+1]))/2)
209                 );
210                 createObjectGroup(group, 0);
212         }
215 paintTerrainBasedOnHeight(-6, 2, 1, tWater);
217 log("Creating bumps...");
218 placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1);
219 painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2);
220 createAreas(
221         placer,
222         painter,
223         avoidClasses(clWater, 2, clPlayer, 20),
224         scaleByMapSize(100, 200)
227 log("Creating hills...");
228 placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1);
229 terrainPainter = new LayeredPainter(
230         [tGrass, tCliff, tHill],                // terrains
231         [1, 2]                                                          // widths
233 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 35, 3);
234 createAreas(
235         placer,
236         [terrainPainter, elevationPainter, paintClass(clHill)],
237         avoidClasses(clPlayer, 20, clHill, 15, clWater, 3),
238         scaleByMapSize(1, 4) * numPlayers
241 // calculate desired number of trees for map (based on size)
242 var MIN_TREES = 160;
243 var MAX_TREES = 900;
244 var P_FOREST = 0.02;
246 var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES);
247 var numForest = totalTrees * P_FOREST;
248 var numStragglers = totalTrees * (1.0 - P_FOREST);
250 log("Creating forests...");
251 var types = [
252         [[tForestFloor, tGrass, pForest], [tForestFloor, pForest]]
253 ];      // some variation
255 var size = numForest / (0.5 * scaleByMapSize(2,8) * numPlayers);
256 var num = floor(size / types.length);
257 for (var i = 0; i < types.length; ++i)
259         placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 1);
260         painter = new LayeredPainter(
261                 types[i],               // terrains
262                 [2]                                                                                     // widths
263                 );
264         createAreas(
265                 placer,
266                 [painter, paintClass(clForest)],
267                 avoidClasses(clPlayer, 20, clForest, 10, clHill, 0, clWater, 2),
268                 num
269         );
272 RMS.SetProgress(50);
274 log("Creating dirt patches...");
275 var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)];
276 for (var i = 0; i < sizes.length; i++)
278         placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
279         painter = new LayeredPainter(
280                 [[tGrass,tDirtRocksA],[tDirtRocksA,tDirtRocksB], [tDirtRocksB,tDirtRocksC]],            // terrains
281                 [1,1]                                                                                                                   // widths
282         );
283         createAreas(
284                 placer,
285                 [painter, paintClass(clDirt)],
286                 avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20),
287                 scaleByMapSize(15, 45)
288         );
291 log("Creating grass patches...");
292 var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)];
293 for (var i = 0; i < sizes.length; i++)
295         placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
296         painter = new TerrainPainter(tGrassPatch);
297         createAreas(
298                 placer,
299                 painter,
300                 avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20),
301                 scaleByMapSize(15, 45)
302         );
304 RMS.SetProgress(55);
306 log("Creating stone mines...");
307 group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock);
308 createObjectGroupsDeprecated(group, 0,
309         avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
310         scaleByMapSize(4,16), 100
313 log("Creating small stone quarries...");
314 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock);
315 createObjectGroupsDeprecated(group, 0,
316         avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
317         scaleByMapSize(4,16), 100
320 log("Creating metal mines...");
321 group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal);
322 createObjectGroupsDeprecated(group, 0,
323         avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1),
324         scaleByMapSize(4,16), 100
327 RMS.SetProgress(65);
329 log("Creating small decorative rocks...");
330 group = new SimpleGroup(
331         [new SimpleObject(aRockMedium, 1,3, 0,1)],
332         true
334 createObjectGroupsDeprecated(
335         group, 0,
336         avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0),
337         scaleByMapSize(16, 262), 50
340 log("Creating large decorative rocks...");
341 group = new SimpleGroup(
342         [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)],
343         true
345 createObjectGroupsDeprecated(
346         group, 0,
347         avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0),
348         scaleByMapSize(8, 131), 50
351 RMS.SetProgress(70);
353 log("Creating wildebeest...");
354 group = new SimpleGroup(
355         [new SimpleObject(oWildebeest, 5,7, 0,4)],
356         true, clFood
358 createObjectGroupsDeprecated(group, 0,
359         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
360         3 * numPlayers, 50
363 RMS.SetProgress(75);
365 log("Creating gazelle...");
366 group = new SimpleGroup(
367         [new SimpleObject(oGazelle, 2,3, 0,2)],
368         true, clFood
370 createObjectGroupsDeprecated(group, 0,
371         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
372         3 * numPlayers, 50
375 log("Creating elephant...");
376 group = new SimpleGroup(
377         [new SimpleObject(oElephant, 2,3, 0,2)],
378         true, clFood
380 createObjectGroupsDeprecated(group, 0,
381         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
382         3 * numPlayers, 50
385 log("Creating giraffe...");
386 group = new SimpleGroup(
387         [new SimpleObject(oGiraffe, 2,3, 0,2)],
388         true, clFood
390 createObjectGroupsDeprecated(group, 0,
391         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
392         3 * numPlayers, 50
395 log("Creating zebra...");
396 group = new SimpleGroup(
397         [new SimpleObject(oZebra, 2,3, 0,2)],
398         true, clFood
400 createObjectGroupsDeprecated(group, 0,
401         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
402         3 * numPlayers, 50
405 log("Creating fish...");
406 group = new SimpleGroup(
407         [new SimpleObject(oFish, 2,3, 0,2)],
408         true, clFood
410 createObjectGroupsDeprecated(group, 0,
411         [avoidClasses(clFood, 20), stayClasses(clWater, 6)],
412         25 * numPlayers, 60
415 log("Creating berry bush...");
416 group = new SimpleGroup(
417         [new SimpleObject(oBerryBush, 5,7, 0,4)],
418         true, clFood
420 createObjectGroupsDeprecated(group, 0,
421         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10),
422         randIntInclusive(1, 4) * numPlayers + 2, 50
425 RMS.SetProgress(85);
427 log("Creating straggler trees...");
428 var types = [oBaobab, oBaobab, oBaobab, oFig];  // some variation
429 var num = floor(numStragglers / types.length);
430 for (var i = 0; i < types.length; ++i)
432         group = new SimpleGroup(
433                 [new SimpleObject(types[i], 1,1, 0,3)],
434                 true, clForest
435         );
436         createObjectGroupsDeprecated(group, 0,
437                 avoidClasses(clWater, 5, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6),
438                 num
439         );
442 var planetm = 4;
443 log("Creating small grass tufts...");
444 group = new SimpleGroup(
445         [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)]
447 createObjectGroupsDeprecated(group, 0,
448         avoidClasses(clWater, 2, clHill, 2, clPlayer, 2),
449         planetm * scaleByMapSize(13, 200)
452 RMS.SetProgress(90);
454 log("Creating large grass tufts...");
455 group = new SimpleGroup(
456         [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)]
458 createObjectGroupsDeprecated(group, 0,
459         avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clForest, 0),
460         planetm * scaleByMapSize(13, 200)
463 RMS.SetProgress(95);
465 log("Creating bushes...");
466 group = new SimpleGroup(
467         [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)]
469 createObjectGroupsDeprecated(group, 0,
470         avoidClasses(clWater, 2, clHill, 1, clPlayer, 1),
471         planetm * scaleByMapSize(13, 200), 50
474 setSkySet("sunny");
476 setSunRotation(randFloat(0, TWO_PI));
477 setSunElevation(randFloat(PI/ 5, PI / 4));
478 setWaterColor(0.478,0.42,0.384);                                // greyish
479 setWaterTint(0.58,0.22,0.067);                          // reddish
480 setWaterMurkiness(0.87);
481 setWaterWaviness(0.5);
482 setWaterType("clap");
484 ExportMap();