Invincible women on survival of the fittest to prevent women fights and cheap tower...
[0ad.git] / binaries / data / mods / public / maps / random / sahel_watering_holes.js
blob412b9a1d6797c3b69d72bf66968809dd60c78eb0
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 // gaia entities
18 const oBaobab = "gaia/flora_tree_baobab";
19 const oFig = "gaia/flora_tree_fig";
20 const oBerryBush = "gaia/flora_bush_berry";
21 const oWildebeest = "gaia/fauna_wildebeest";
22 const oFish = "gaia/fauna_fish";
23 const oGazelle = "gaia/fauna_gazelle";
24 const oElephant = "gaia/fauna_elephant_african_bush";
25 const oGiraffe = "gaia/fauna_giraffe";
26 const oZebra = "gaia/fauna_zebra";
27 const oStoneLarge = "gaia/geology_stonemine_desert_quarry";
28 const oStoneSmall = "gaia/geology_stone_savanna_small";
29 const oMetalLarge = "gaia/geology_metal_savanna_slabs";
31 // decorative props
32 const aGrass = "actor|props/flora/grass_savanna.xml";
33 const aGrassShort = "actor|props/flora/grass_medit_field.xml";
34 const aReeds = "actor|props/flora/reeds_pond_lush_a.xml";
35 const aLillies = "actor|props/flora/reeds_pond_lush_b.xml";
36 const aRockLarge = "actor|geology/stone_savanna_med.xml";
37 const aRockMedium = "actor|geology/stone_savanna_med.xml";
38 const aBushMedium = "actor|props/flora/bush_desert_dry_a.xml";
39 const aBushSmall = "actor|props/flora/bush_dry_a.xml";
41 const pForest = [tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor];
43 log("Initializing map...");
45 InitMap();
47 const numPlayers = getNumPlayers();
48 const mapSize = getMapSize();
49 const mapArea = mapSize*mapSize;
51 // create tile classes
53 var clPlayer = createTileClass();
54 var clHill = createTileClass();
55 var clForest = createTileClass();
56 var clWater = createTileClass();
57 var clDirt = createTileClass();
58 var clRock = createTileClass();
59 var clMetal = createTileClass();
60 var clFood = createTileClass();
61 var clBaseResource = createTileClass();
62 var clSettlement = createTileClass();
63 var clShallows = createTileClass();
65 // randomize player order
66 var playerIDs = [];
67 for (var i = 0; i < numPlayers; i++)
69         playerIDs.push(i+1);
71 playerIDs = sortPlayers(playerIDs);
73 // place players
75 var playerX = new Array(numPlayers);
76 var playerZ = new Array(numPlayers);
77 var playerAngle = new Array(numPlayers);
79 var startAngle = randFloat(0, TWO_PI);
80 for (var i = 0; i < numPlayers; i++)
82         playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
83         playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
84         playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
87 for (var i = 0; i < numPlayers; i++)
89         var id = playerIDs[i];
90         log("Creating base for player " + id + "...");
92         // some constants
93         var radius = scaleByMapSize(15,25);
94         var cliffRadius = 2;
95         var elevation = 20;
97         // get the x and z in tiles
98         var fx = fractionToTiles(playerX[i]);
99         var fz = fractionToTiles(playerZ[i]);
100         var ix = round(fx);
101         var iz = round(fz);
102         addToClass(ix, iz, clPlayer);
103         addToClass(ix+5, iz, clPlayer);
104         addToClass(ix, iz+5, clPlayer);
105         addToClass(ix-5, iz, clPlayer);
106         addToClass(ix, iz-5, clPlayer);
108         // create the city patch
109         var cityRadius = radius/3;
110         var 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         // create starting units
115         placeCivDefaultEntities(fx, fz, id);
117         placeDefaultChicken(fx, fz, clBaseResource);
119         // create berry bushes
120         var bbAngle = randFloat(0, TWO_PI);
121         var bbDist = 12;
122         var bbX = round(fx + bbDist * cos(bbAngle));
123         var bbZ = round(fz + bbDist * sin(bbAngle));
124         var group = new SimpleGroup(
125                 [new SimpleObject(oBerryBush, 5,5, 0,3)],
126                 true, clBaseResource, bbX, bbZ
127         );
128         createObjectGroup(group, 0);
130         // create metal mine
131         var mAngle = bbAngle;
132         while(abs(mAngle - bbAngle) < PI/3)
133         {
134                 mAngle = randFloat(0, TWO_PI);
135         }
136         var mDist = 12;
137         var mX = round(fx + mDist * cos(mAngle));
138         var mZ = round(fz + mDist * sin(mAngle));
139         group = new SimpleGroup(
140                 [new SimpleObject(oMetalLarge, 1,1, 0,0)],
141                 true, clBaseResource, mX, mZ
142         );
143         createObjectGroup(group, 0);
145         // create stone mines
146         mAngle += randFloat(PI/8, PI/4);
147         mX = round(fx + mDist * cos(mAngle));
148         mZ = round(fz + mDist * sin(mAngle));
149         group = new SimpleGroup(
150                 [new SimpleObject(oStoneLarge, 1,1, 0,2)],
151                 true, clBaseResource, mX, mZ
152         );
153         createObjectGroup(group, 0);
154         var hillSize = PI * radius * radius;
155         // create starting trees
156         var num = 5;
157         var tAngle = randFloat(-PI/3, 4*PI/3);
158         var tDist = randFloat(12, 13);
159         var tX = round(fx + tDist * cos(tAngle));
160         var tZ = round(fz + tDist * sin(tAngle));
161         group = new SimpleGroup(
162                 [new SimpleObject(oBaobab, num, num, 0,3)],
163                 false, clBaseResource, tX, tZ
164         );
165         createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
167         // create grass tufts
168         var num = hillSize / 250;
169         for (var j = 0; j < num; j++)
170         {
171                 var gAngle = randFloat(0, TWO_PI);
172                 var gDist = radius - (5 + randInt(7));
173                 var gX = round(fx + gDist * cos(gAngle));
174                 var gZ = round(fz + gDist * sin(gAngle));
175                 group = new SimpleGroup(
176                         [new SimpleObject(aGrassShort, 2,5, 0,1, -PI/8,PI/8)],
177                         false, clBaseResource, gX, gZ
178                 );
179                 createObjectGroup(group, 0);
180         }
183 RMS.SetProgress(20);
185 //create rivers
186 log ("Creating rivers...");
187 for (var m = 0; m < numPlayers; m++)
189         var tang = startAngle + (m + 0.5) * TWO_PI / numPlayers;
190         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)));
191         var painter = new LayeredPainter([tShore, tWater, tWater], [1, 3]);
192         var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 4);
193         createArea(placer, [painter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
194         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);
195         var terrainPainter = new LayeredPainter(
196                 [tShore, tWater, tWater],               // terrains
197                 [1, 3]                                                          // widths
198         );
199         var elevationPainter = new SmoothElevationPainter(
200                 ELEVATION_SET,                  // type
201                 -4,                             // elevation
202                 4                               // blend radius
203         );
204         createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
205         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)));
206         var painter = new LayeredPainter([tWater, tWater], [1]);
207         var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 4);
208         createArea(placer, [painter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
212 for (var i = 0; i < numPlayers; i++)
214         if (i+1 == numPlayers)
215         {
216                 passageMaker(
217                         round(fractionToTiles(playerX[i])),
218                         round(fractionToTiles(playerZ[i])),
219                         round(fractionToTiles(playerX[0])),
220                         round(fractionToTiles(playerZ[0])),
221                         6, -2, -2, 4, clShallows, undefined, -4);
223                 // create animals in shallows
224                 log("Creating animals in shallows...");
225                 var group = new SimpleGroup(
226                         [new SimpleObject(oElephant, 2,3, 0,4)],
227                         true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[0]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[0]))/2)
228                 );
229                 createObjectGroup(group, 0);
231                 var group = new SimpleGroup(
232                         [new SimpleObject(oWildebeest, 5,6, 0,4)],
233                         true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[0]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[0]))/2)
234                 );
235                 createObjectGroup(group, 0);
237         }
238         else
239         {
240                 passageMaker(
241                         fractionToTiles(playerX[i]),
242                         fractionToTiles(playerZ[i]),
243                         fractionToTiles(playerX[i+1]),
244                         fractionToTiles(playerZ[i+1]),
245                         6, -2, -2, 4, clShallows, undefined, -4);
247                 // create animals in shallows
248                 log("Creating animals in shallows...");
249                 var group = new SimpleGroup(
250                         [new SimpleObject(oElephant, 2,3, 0,4)],
251                         true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[i+1]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[i+1]))/2)
252                 );
253                 createObjectGroup(group, 0);
255                 var group = new SimpleGroup(
256                         [new SimpleObject(oWildebeest, 5,6, 0,4)],
257                         true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[i+1]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[i+1]))/2)
258                 );
259                 createObjectGroup(group, 0);
261         }
264 paintTerrainBasedOnHeight(-6, 2, 1, tWater);
267 // create bumps
268 log("Creating bumps...");
269 placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1);
270 painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2);
271 createAreas(
272         placer,
273         painter,
274         avoidClasses(clWater, 2, clPlayer, 20),
275         scaleByMapSize(100, 200)
278 // create hills
279 log("Creating hills...");
280 placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1);
281 terrainPainter = new LayeredPainter(
282         [tGrass, tCliff, tHill],                // terrains
283         [1, 2]                                                          // widths
285 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 35, 3);
286 createAreas(
287         placer,
288         [terrainPainter, elevationPainter, paintClass(clHill)],
289         avoidClasses(clPlayer, 20, clHill, 15, clWater, 3),
290         scaleByMapSize(1, 4) * numPlayers
294 // calculate desired number of trees for map (based on size)
295 var MIN_TREES = 160;
296 var MAX_TREES = 900;
297 var P_FOREST = 0.02;
299 var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES);
300 var numForest = totalTrees * P_FOREST;
301 var numStragglers = totalTrees * (1.0 - P_FOREST);
303 // create forests
304 log("Creating forests...");
305 var types = [
306         [[tForestFloor, tGrass, pForest], [tForestFloor, pForest]]
307 ];      // some variation
310 var size = numForest / (0.5 * scaleByMapSize(2,8) * numPlayers);
311 var num = floor(size / types.length);
312 for (var i = 0; i < types.length; ++i)
314         placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 1);
315         painter = new LayeredPainter(
316                 types[i],               // terrains
317                 [2]                                                                                     // widths
318                 );
319         createAreas(
320                 placer,
321                 [painter, paintClass(clForest)],
322                 avoidClasses(clPlayer, 20, clForest, 10, clHill, 0, clWater, 2),
323                 num
324         );
327 RMS.SetProgress(50);
329 // create dirt patches
330 log("Creating dirt patches...");
331 var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)];
332 for (var i = 0; i < sizes.length; i++)
334         placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
335         painter = new LayeredPainter(
336                 [[tGrass,tDirtRocksA],[tDirtRocksA,tDirtRocksB], [tDirtRocksB,tDirtRocksC]],            // terrains
337                 [1,1]                                                                                                                   // widths
338         );
339         createAreas(
340                 placer,
341                 [painter, paintClass(clDirt)],
342                 avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20),
343                 scaleByMapSize(15, 45)
344         );
347 // create grass patches
348 log("Creating grass patches...");
349 var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)];
350 for (var i = 0; i < sizes.length; i++)
352         placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
353         painter = new TerrainPainter(tGrassPatch);
354         createAreas(
355                 placer,
356                 painter,
357                 avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20),
358                 scaleByMapSize(15, 45)
359         );
361 RMS.SetProgress(55);
364 log("Creating stone mines...");
365 // create large stone quarries
366 group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock);
367 createObjectGroups(group, 0,
368         avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
369         scaleByMapSize(4,16), 100
372 // create small stone quarries
373 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock);
374 createObjectGroups(group, 0,
375         avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
376         scaleByMapSize(4,16), 100
379 log("Creating metal mines...");
380 // create large metal quarries
381 group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal);
382 createObjectGroups(group, 0,
383         avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1),
384         scaleByMapSize(4,16), 100
387 RMS.SetProgress(65);
389 // create small decorative rocks
390 log("Creating small decorative rocks...");
391 group = new SimpleGroup(
392         [new SimpleObject(aRockMedium, 1,3, 0,1)],
393         true
395 createObjectGroups(
396         group, 0,
397         avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0),
398         scaleByMapSize(16, 262), 50
402 // create large decorative rocks
403 log("Creating large decorative rocks...");
404 group = new SimpleGroup(
405         [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)],
406         true
408 createObjectGroups(
409         group, 0,
410         avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0),
411         scaleByMapSize(8, 131), 50
414 RMS.SetProgress(70);
416 // create wildebeest
417 log("Creating wildebeest...");
418 group = new SimpleGroup(
419         [new SimpleObject(oWildebeest, 5,7, 0,4)],
420         true, clFood
422 createObjectGroups(group, 0,
423         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
424         3 * numPlayers, 50
427 RMS.SetProgress(75);
429 // create gazelle
430 log("Creating gazelle...");
431 group = new SimpleGroup(
432         [new SimpleObject(oGazelle, 2,3, 0,2)],
433         true, clFood
435 createObjectGroups(group, 0,
436         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
437         3 * numPlayers, 50
440 // create elephant
441 log("Creating elephant...");
442 group = new SimpleGroup(
443         [new SimpleObject(oElephant, 2,3, 0,2)],
444         true, clFood
446 createObjectGroups(group, 0,
447         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
448         3 * numPlayers, 50
451 // create giraffe
452 log("Creating giraffe...");
453 group = new SimpleGroup(
454         [new SimpleObject(oGiraffe, 2,3, 0,2)],
455         true, clFood
457 createObjectGroups(group, 0,
458         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
459         3 * numPlayers, 50
462 // create zebra
463 log("Creating zebra...");
464 group = new SimpleGroup(
465         [new SimpleObject(oZebra, 2,3, 0,2)],
466         true, clFood
468 createObjectGroups(group, 0,
469         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
470         3 * numPlayers, 50
473 // create fish
474 log("Creating fish...");
475 group = new SimpleGroup(
476         [new SimpleObject(oFish, 2,3, 0,2)],
477         true, clFood
479 createObjectGroups(group, 0,
480         [avoidClasses(clFood, 20), stayClasses(clWater, 6)],
481         25 * numPlayers, 60
484 // create berry bush
485 log("Creating berry bush...");
486 group = new SimpleGroup(
487         [new SimpleObject(oBerryBush, 5,7, 0,4)],
488         true, clFood
490 createObjectGroups(group, 0,
491         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10),
492         randInt(1, 4) * numPlayers + 2, 50
495 RMS.SetProgress(85);
497 // create straggler trees
498 log("Creating straggler trees...");
499 var types = [oBaobab, oBaobab, oBaobab, oFig];  // some variation
500 var num = floor(numStragglers / types.length);
501 for (var i = 0; i < types.length; ++i)
503         group = new SimpleGroup(
504                 [new SimpleObject(types[i], 1,1, 0,3)],
505                 true, clForest
506         );
507         createObjectGroups(group, 0,
508                 avoidClasses(clWater, 5, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 1, clRock, 1),
509                 num
510         );
513 var planetm = 4;
514 //create small grass tufts
515 log("Creating small grass tufts...");
516 group = new SimpleGroup(
517         [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)]
519 createObjectGroups(group, 0,
520         avoidClasses(clWater, 2, clHill, 2, clPlayer, 2),
521         planetm * scaleByMapSize(13, 200)
524 RMS.SetProgress(90);
526 // create large grass tufts
527 log("Creating large grass tufts...");
528 group = new SimpleGroup(
529         [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)]
531 createObjectGroups(group, 0,
532         avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clForest, 0),
533         planetm * scaleByMapSize(13, 200)
536 RMS.SetProgress(95);
538 // create bushes
539 log("Creating bushes...");
540 group = new SimpleGroup(
541         [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)]
543 createObjectGroups(group, 0,
544         avoidClasses(clWater, 2, clHill, 1, clPlayer, 1),
545         planetm * scaleByMapSize(13, 200), 50
549 setSkySet("sunny");
551 setSunRotation(randFloat(0, TWO_PI));
552 setSunElevation(randFloat(PI/ 5, PI / 4));
553 setWaterColor(0.478,0.42,0.384);                                // greyish
554 setWaterTint(0.58,0.22,0.067);                          // reddish
555 setWaterMurkiness(0.87);
556 setWaterWaviness(0.5);
557 setWaterType("clap");
559 // Export map data
561 ExportMap();