Invincible women on survival of the fittest to prevent women fights and cheap tower...
[0ad.git] / binaries / data / mods / public / maps / random / unknown.js
blob75b2adee0af3a79e56bbe373041399b8e2c358f6
1 RMS.LoadLibrary("rmgen");
3 TILE_CENTERED_HEIGHT_MAP = true;
4 //random terrain textures
5 var random_terrain = randomizeBiome();
7 const tMainTerrain = rBiomeT1();
8 const tForestFloor1 = rBiomeT2();
9 const tForestFloor2 = rBiomeT3();
10 const tCliff = rBiomeT4();
11 const tTier1Terrain = rBiomeT5();
12 const tTier2Terrain = rBiomeT6();
13 const tTier3Terrain = rBiomeT7();
14 const tHill = rBiomeT8();
15 const tDirt = rBiomeT9();
16 const tRoad = rBiomeT10();
17 const tRoadWild = rBiomeT11();
18 const tTier4Terrain = rBiomeT12();
19 const tShoreBlend = rBiomeT13();
20 const tShore = rBiomeT14();
21 const tWater = rBiomeT15();
23 // gaia entities
24 const oTree1 = rBiomeE1();
25 const oTree2 = rBiomeE2();
26 const oTree3 = rBiomeE3();
27 const oTree4 = rBiomeE4();
28 const oTree5 = rBiomeE5();
29 const oFruitBush = rBiomeE6();
30 const oMainHuntableAnimal = rBiomeE8();
31 const oFish = rBiomeE9();
32 const oSecondaryHuntableAnimal = rBiomeE10();
33 const oStoneLarge = rBiomeE11();
34 const oStoneSmall = rBiomeE12();
35 const oMetalLarge = rBiomeE13();
36 const oWood = "gaia/special_treasure_wood";
38 // decorative props
39 const aGrass = rBiomeA1();
40 const aGrassShort = rBiomeA2();
41 const aReeds = rBiomeA3();
42 const aLillies = rBiomeA4();
43 const aRockLarge = rBiomeA5();
44 const aRockMedium = rBiomeA6();
45 const aBushMedium = rBiomeA7();
46 const aBushSmall = rBiomeA8();
48 const pForest1 = [tForestFloor2 + TERRAIN_SEPARATOR + oTree1, tForestFloor2 + TERRAIN_SEPARATOR + oTree2, tForestFloor2];
49 const pForest2 = [tForestFloor1 + TERRAIN_SEPARATOR + oTree4, tForestFloor1 + TERRAIN_SEPARATOR + oTree5, tForestFloor1];
51 log("Initializing map...");
53 InitMap();
55 const numPlayers = getNumPlayers();
56 const mapSize = getMapSize();
57 const mapArea = mapSize*mapSize;
59 // create tile classes
61 var clPlayer = createTileClass();
62 var clHill = createTileClass();
63 var clForest = createTileClass();
64 var clWater = createTileClass();
65 var clDirt = createTileClass();
66 var clRock = createTileClass();
67 var clMetal = createTileClass();
68 var clFood = createTileClass();
69 var clBaseResource = createTileClass();
70 var clSettlement = createTileClass();
71 var clLand = createTileClass();
72 var clShallow = createTileClass();
74 for (var ix = 0; ix < mapSize; ix++)
76         for (var iz = 0; iz < mapSize; iz++)
77         {
78                 var x = ix / (mapSize + 1.0);
79                 var z = iz / (mapSize + 1.0);
80                         placeTerrain(ix, iz, tWater);
81         }
84 var iberianTowers = false;
85 var md = randInt(1,13);
86 var needsAdditionalWood = false;
87 //*****************************************************************************************************************************
88 if (md == 1) //archipelago and island
90         needsAdditionalWood = true;
91         iberianTowers = true;
93         // randomize player order
94         var playerIDs = [];
95         for (var i = 0; i < numPlayers; i++)
96         {
97                 playerIDs.push(i+1);
98         }
99         playerIDs = sortPlayers(playerIDs);
101         // place players
103         var playerX = new Array(numPlayers);
104         var playerZ = new Array(numPlayers);
105         var playerAngle = new Array(numPlayers);
107         var startAngle = randFloat(0, TWO_PI);
108         for (var i = 0; i < numPlayers; i++)
109         {
110                 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
111                 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
112                 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
113         }
115         var mdd1 = randInt(1,3);
117         for (var i = 0; i < numPlayers; ++i)
118         {
119                 var radius = scaleByMapSize(17, 29);
120                 var shoreRadius = 4;
121                 var elevation = 3;
123                 var hillSize = PI * radius * radius;
124                 // get the x and z in tiles
125                 var fx = fractionToTiles(playerX[i]);
126                 var fz = fractionToTiles(playerZ[i]);
127                 var ix = round(fx);
128                 var iz = round(fz);
129                 // create a player island
130                 var placer = new ClumpPlacer(hillSize, 0.80, 0.1, 10, ix, iz);
131                 var terrainPainter = new LayeredPainter(
132                         [tMainTerrain , tMainTerrain, tMainTerrain],            // terrains
133                         [1, shoreRadius]                // widths
134                 );
135                 var elevationPainter = new SmoothElevationPainter(
136                         ELEVATION_SET,                  // type
137                         elevation,                              // elevation
138                         shoreRadius                             // blend radius
139                 );
140                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clPlayer)], null);
141         }
142         if (mdd1 == 1) //archipelago
143         {
144                 // create islands
145                 log("Creating islands...");
146                 placer = new ClumpPlacer(floor(hillSize*randFloat(0.8,1.2)), 0.80, 0.1, 10);
147                 terrainPainter = new LayeredPainter(
148                         [tMainTerrain, tMainTerrain],           // terrains
149                         [2]                                                             // widths
150                 );
151                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4);
152                 createAreas(
153                         placer,
154                         [terrainPainter, elevationPainter, paintClass(clLand)],
155                         null,
156                         scaleByMapSize(2, 5)*randInt(8,14)
157                 );
159                 // create shore jaggedness
160                 log("Creating shore jaggedness...");
161                 placer = new ClumpPlacer(scaleByMapSize(15, 80), 0.2, 0.1, 1);
162                 terrainPainter = new LayeredPainter(
163                         [tCliff, tHill],                // terrains
164                         [2]                                                             // widths
165                 );
166                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4);
167                 createAreas(
168                         placer,
169                         [terrainPainter, elevationPainter, paintClass(clLand)],
170                         borderClasses(clLand, 6, 3),
171                         scaleByMapSize(12, 130) * 2, 150
172                 );
173         }
174         else if (mdd1 == 2) //islands
175         {
176                 // create islands
177                 log("Creating islands...");
178                 placer = new ClumpPlacer(floor(hillSize*randFloat(0.6,1.4)), 0.80, 0.1, randFloat(0.0, 0.2));
179                 terrainPainter = new LayeredPainter(
180                         [tMainTerrain, tMainTerrain],           // terrains
181                         [2]                                                             // widths
182                 );
183                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4);
184                 createAreas(
185                         placer,
186                         [terrainPainter, elevationPainter, paintClass(clLand)],
187                         avoidClasses(clLand, 3, clPlayer, 3),
188                         scaleByMapSize(6, 10)*randInt(8,14)
189                 );
191                 // create small islands
192                 log("Creating small islands...");
193                 placer = new ClumpPlacer(floor(hillSize*randFloat(0.3,0.7)), 0.80, 0.1, 0.07);
194                 terrainPainter = new LayeredPainter(
195                         [tMainTerrain, tMainTerrain],           // terrains
196                         [2]                                                             // widths
197                 );
198                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 6);
199                 createAreas(
200                         placer,
201                         [terrainPainter, elevationPainter, paintClass(clLand)],
202                         avoidClasses(clLand, 3, clPlayer, 3),
203                         scaleByMapSize(2, 6)*randInt(6,15), 25
204                 );
205         }
206         else if (mdd1 == 3) // tight islands
207         {
208                 // create islands
209                 log("Creating islands...");
210                 placer = new ClumpPlacer(floor(hillSize*randFloat(0.8,1.2)), 0.80, 0.1, 10);
211                 terrainPainter = new LayeredPainter(
212                         [tMainTerrain, tMainTerrain],           // terrains
213                         [2]                                                             // widths
214                 );
215                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4);
216                 createAreas(
217                         placer,
218                         [terrainPainter, elevationPainter, paintClass(clLand)],
219                         avoidClasses(clLand, randInt(8, 16), clPlayer, 3),
220                         scaleByMapSize(2, 5)*randInt(8,14)
221                 );
222         }
225 //********************************************************************************************************
226 else if (md == 2) //continent
229         // randomize player order
230         var playerIDs = [];
231         for (var i = 0; i < numPlayers; i++)
232         {
233                 playerIDs.push(i+1);
234         }
235         playerIDs = sortPlayers(playerIDs);
237         // place players
239         var playerX = new Array(numPlayers);
240         var playerZ = new Array(numPlayers);
241         var playerAngle = new Array(numPlayers);
243         var startAngle = randFloat(0, TWO_PI);
244         for (var i = 0; i < numPlayers; i++)
245         {
246                 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
247                 playerX[i] = 0.5 + 0.25*cos(playerAngle[i]);
248                 playerZ[i] = 0.5 + 0.25*sin(playerAngle[i]);
250                 var fx = fractionToTiles(playerX[i]);
251                 var fz = fractionToTiles(playerZ[i]);
252                 var ix = round(fx);
253                 var iz = round(fz);
254                 addToClass(ix, iz, clPlayer);
255                 addToClass(ix+5, iz, clPlayer);
256                 addToClass(ix, iz+5, clPlayer);
257                 addToClass(ix-5, iz, clPlayer);
258                 addToClass(ix, iz-5, clPlayer);
259         }
261         var fx = fractionToTiles(0.5);
262         var fz = fractionToTiles(0.5);
263         ix = round(fx);
264         iz = round(fz);
266         var placer = new ClumpPlacer(mapArea * 0.45, 0.9, 0.09, 10, ix, iz);
267         var terrainPainter = new LayeredPainter(
268                 [tWater, tShore, tMainTerrain],         // terrains
269                 [4, 2]          // widths
270         );
271         var elevationPainter = new SmoothElevationPainter(
272                 ELEVATION_SET,                  // type
273                 3,                              // elevation
274                 4                               // blend radius
275         );
276         createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null);
278         var clPeninsulaSteam = createTileClass();
280         if (randInt(1,3)==1) // peninsula
281         {
282                 var angle = randFloat(0, TWO_PI);
284                 var fx = fractionToTiles(0.5 + 0.25*cos(angle));
285                 var fz = fractionToTiles(0.5 + 0.25*sin(angle));
286                 ix = round(fx);
287                 iz = round(fz);
289                 var placer = new ClumpPlacer(mapArea * 0.45, 0.9, 0.09, 10, ix, iz);
290                 var terrainPainter = new LayeredPainter(
291                         [tWater, tShore, tMainTerrain],         // terrains
292                         [4, 2]          // widths
293                 );
294                 var elevationPainter = new SmoothElevationPainter(
295                         ELEVATION_SET,                  // type
296                         3,                              // elevation
297                         4                               // blend radius
298                 );
299                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null);
301                 var fx = fractionToTiles(0.5 + 0.35*cos(angle));
302                 var fz = fractionToTiles(0.5 + 0.35*sin(angle));
303                 ix = round(fx);
304                 iz = round(fz);
306                 var placer = new ClumpPlacer(mapArea * 0.3, 0.9, 0.01, 10, ix, iz);
307                 createArea(placer, [paintClass(clPeninsulaSteam)], null);
308         }
310         // create shore jaggedness
311         log("Creating shore jaggedness...");
312         placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1);
313         terrainPainter = new LayeredPainter(
314                 [tCliff, tHill],                // terrains
315                 [2]                                                             // widths
316         );
317         elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 4);
318         createAreas(
319                 placer,
320                 [terrainPainter, elevationPainter, unPaintClass(clLand)],
321                 [avoidClasses(clPlayer, 20, clPeninsulaSteam, 20), borderClasses(clLand, 7, 7)],
322                 scaleByMapSize(7, 130) * 2, 150
323         );
325         // create outward shore jaggedness
326         log("Creating shore jaggedness...");
327         placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1);
328         terrainPainter = new LayeredPainter(
329                 [tCliff, tHill],                // terrains
330                 [2]                                                             // widths
331         );
332         elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4);
333         createAreas(
334                 placer,
335                 [terrainPainter, elevationPainter, paintClass(clLand)],
336                 [avoidClasses(clPlayer, 20), borderClasses(clLand, 7, 7)],
337                 scaleByMapSize(7, 130) * 2, 150
338         );
340 //********************************************************************************************************
341 else if (md == 3) //central sea
343 // randomize player order
344 var playerIDs = [];
345 for (var i = 0; i < numPlayers; i++)
347         playerIDs.push(i+1);
349 playerIDs = primeSortPlayers(sortPlayers(playerIDs));
351         // place players
353         var playerX = new Array(numPlayers);
354         var playerZ = new Array(numPlayers);
355         var playerAngle = new Array(numPlayers);
356         var playerPos = new Array(numPlayers);
357         var iop = 0;
359         var mdd1 = randInt(1,2);
360         if (mdd1 == 1) //vertical
361         {
362                 for (var i = 0; i < numPlayers; i++)
363                 {
364                         iop = i - 1;
365                         if (!(numPlayers%2)){
366                                 playerPos[i] = ((iop + abs(iop%2))/2 + 1) / ((numPlayers / 2) + 1);
367                         }
368                         else
369                         {
370                                 if (iop%2)
371                                 {
372                                         playerPos[i] = ((iop + abs(iop%2))/2 + 1) / (((numPlayers + 1) / 2) + 1);
373                                 }
374                                 else
375                                 {
376                                         playerPos[i] = ((iop)/2 + 1) / ((((numPlayers - 1)) / 2) + 1);
377                                 }
378                         }
379                         playerZ[i] = playerPos[i];
380                         playerX[i] = 0.2 + 0.6*(i%2);
381                 }
382         }
383         else //horizontal
384         {
385                 for (var i = 0; i < numPlayers; i++)
386                 {
387                         iop = i - 1;
388                         if (!(numPlayers%2)){
389                                 playerPos[i] = ((iop + abs(iop%2))/2 + 1) / ((numPlayers / 2) + 1);
390                         }
391                         else
392                         {
393                                 if (iop%2)
394                                 {
395                                         playerPos[i] = ((iop + abs(iop%2))/2 + 1) / (((numPlayers + 1) / 2) + 1);
396                                 }
397                                 else
398                                 {
399                                         playerPos[i] = ((iop)/2 + 1) / ((((numPlayers - 1)) / 2) + 1);
400                                 }
401                         }
402                         playerZ[i] = 0.2 + 0.6*(i%2);
403                         playerX[i] = playerPos[i];
404                 }
405         }
408         var WATER_WIDTH = randFloat(0.22,0.3)+scaleByMapSize(1,4)/20;
409         log("Creating sea");
410         var theta = randFloat(0, 1);
411         var theta2 = randFloat(0, 1);
412         var seed = randFloat(2,3);
413         var seed2 = randFloat(2,3);
414         for (var ix = 0; ix < mapSize; ix++)
415         {
416                 for (var iz = 0; iz < mapSize; iz++)
417                 {
418                         var x = ix / (mapSize + 1.0);
419                         var z = iz / (mapSize + 1.0);
421                         // add the rough shape of the water
422                         var km = 20/scaleByMapSize(35, 160);
424                         var fadeDist = 0.05;
426                         if (mdd1 == 1) //vertical
427                         {
428                                 var cu = km*rndRiver(theta+z*0.5*(mapSize/64),seed);
429                                 var cu2 = km*rndRiver(theta2+z*0.5*(mapSize/64),seed2);
431                                 if ((x > cu + 0.5 - WATER_WIDTH/2) && (x < cu2 + 0.5 + WATER_WIDTH/2))
432                                 {
433                                         var h;
434                                         if (x < (cu + 0.5 + fadeDist - WATER_WIDTH/2))
435                                         {
436                                                 h = 3 - 6 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - x)/fadeDist);
437                                         }
438                                         else if (x > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))
439                                         {
440                                                 h = 3 - 6 * (1 - (x - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist);
441                                         }
442                                         else
443                                         {
444                                                 h = -3.0;
445                                         }
447                                         if (h < -1.5)
448                                         {
449                                                 placeTerrain(ix, iz, tWater);
450                                         }
451                                         else
452                                         {
453                                                 placeTerrain(ix, iz, tShore);
454                                         }
456                                         setHeight(ix, iz, h);
457                                         if (h < 0){
458                                                 addToClass(ix, iz, clWater);
459                                         }
460                                 }
461                                 else
462                                 {
463                                         setHeight(ix, iz, 3.1);
464                                         addToClass(ix, iz, clLand);
465                                 }
466                         }
467                         else //horizontal
468                         {
469                                 var cu = km*rndRiver(theta+x*0.5*(mapSize/64),seed);
470                                 var cu2 = km*rndRiver(theta2+x*0.5*(mapSize/64),seed2);
472                                 if ((z > cu + 0.5 - WATER_WIDTH/2) && (z < cu2 + 0.5 + WATER_WIDTH/2))
473                                 {
474                                         var h;
475                                         if (z < (cu + 0.5 + fadeDist - WATER_WIDTH/2))
476                                         {
477                                                 h = 3 - 6 * (1 - ((cu + 0.5 + fadeDist - WATER_WIDTH/2) - z)/fadeDist);
478                                         }
479                                         else if (z > (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))
480                                         {
481                                                 h = 3 - 6 * (1 - (z - (cu2 + 0.5 - fadeDist + WATER_WIDTH/2))/fadeDist);
482                                         }
483                                         else
484                                         {
485                                                 h = -3.0;
486                                         }
488                                         if (h < -1.5)
489                                         {
490                                                 placeTerrain(ix, iz, tWater);
491                                         }
492                                         else
493                                         {
494                                                 placeTerrain(ix, iz, tShore);
495                                         }
497                                         setHeight(ix, iz, h);
498                                         if (h < 0){
499                                                 addToClass(ix, iz, clWater);
500                                         }
501                                 }
502                                 else
503                                 {
504                                         setHeight(ix, iz, 3.1);
505                                         addToClass(ix, iz, clLand);
506                                 }
507                         }
508                 }
509         }
511         if (!randInt(3))
512         {
513                 // linked
514                 if (mdd1 == 1) //vertical
515                 {
516                         var placer = new PathPlacer(1, fractionToTiles(0.5), fractionToTiles(0.99), fractionToTiles(0.5), scaleByMapSize(randInt(16,24),randInt(100,140)), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01);
517                 }
518                 else
519                 {
520                         var placer = new PathPlacer(fractionToTiles(0.5), 1, fractionToTiles(0.5), fractionToTiles(0.99), scaleByMapSize(randInt(16,24),randInt(100,140)), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01);
521                 }
522                 var terrainPainter = new LayeredPainter(
523                         [tMainTerrain, tMainTerrain, tMainTerrain],             // terrains
524                         [1, 3]                                                          // widths
525                 );
526                 var elevationPainter = new SmoothElevationPainter(
527                         ELEVATION_SET,                  // type
528                         3.1,                            // elevation
529                         4                               // blend radius
530                 );
531                 createArea(placer, [terrainPainter, elevationPainter, unPaintClass(clWater)], null);
532         }
533         var mdd2 = randInt(1,7);
534         if (mdd2 == 1)
535         {
536                 // create islands
537                 log("Creating islands...");
538                 placer = new ClumpPlacer(randInt(scaleByMapSize(8,15),scaleByMapSize(15,23))*randInt(scaleByMapSize(8,15),scaleByMapSize(15,23)), 0.80, 0.1, randFloat(0.0, 0.2));
539                 terrainPainter = new LayeredPainter(
540                         [tMainTerrain, tMainTerrain],           // terrains
541                         [2]                                                             // widths
542                 );
543                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4);
544                 createAreas(
545                         placer,
546                         [terrainPainter, elevationPainter, paintClass(clLand)],
547                         avoidClasses(clLand, 3, clPlayer, 3),
548                         scaleByMapSize(2, 5)*randInt(8,14)
549                 );
550         }
551         else if (mdd2 == 2)
552         {
553                 // create extentions
554                 log("Creating extentions...");
555                 placer = new ClumpPlacer(randInt(scaleByMapSize(13,24),scaleByMapSize(24,45))*randInt(scaleByMapSize(13,24),scaleByMapSize(24,45)), 0.80, 0.1, 10);
556                 terrainPainter = new LayeredPainter(
557                         [tMainTerrain, tMainTerrain],           // terrains
558                         [2]                                                             // widths
559                 );
560                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4);
561                 createAreas(
562                         placer,
563                         [terrainPainter, elevationPainter, paintClass(clLand)],
564                         null,
565                         scaleByMapSize(2, 5)*randInt(8,14)
566                 );
567         }
569 //********************************************************************************************************
570 else if (md == 4) //central river
573         for (var ix = 0; ix < mapSize; ix++)
574         {
575                 for (var iz = 0; iz < mapSize; iz++)
576                 {
577                         var x = ix / (mapSize + 1.0);
578                         var z = iz / (mapSize + 1.0);
579                                 setHeight(ix, iz, 3);
580                 }
581         }
583         // randomize player order
584         var playerIDs = [];
585         for (var i = 0; i < numPlayers; i++)
586         {
587                 playerIDs.push(i+1);
588         }
589         playerIDs = primeSortPlayers(sortPlayers(playerIDs));
591         // place players
593         var playerX = new Array(numPlayers);
594         var playerZ = new Array(numPlayers);
595         var playerAngle = new Array(numPlayers);
596         var playerPos = new Array(numPlayers);
597         var iop = 0;
598         var mdd1 = randInt(1,2);
599         if (mdd1 == 1) //horizontal
600         {
601                 for (var i = 0; i < numPlayers; i++)
602                 {
603                         iop = i - 1;
604                         if (!(numPlayers%2)){
605                                 playerPos[i] = ((iop + abs(iop%2))/2 + 1) / ((numPlayers / 2) + 1);
606                         }
607                         else
608                         {
609                                 if (iop%2)
610                                 {
611                                         playerPos[i] = ((iop + abs(iop%2))/2 + 1) / (((numPlayers + 1) / 2) + 1);
612                                 }
613                                 else
614                                 {
615                                         playerPos[i] = ((iop)/2 + 1) / ((((numPlayers - 1)) / 2) + 1);
616                                 }
617                         }
619                         playerZ[i] = 0.25 + 0.5*(i%2);
620                         playerX[i] = playerPos[i];
621                 }
622         }
623         else //vertical
624         {
625                 for (var i = 0; i < numPlayers; i++)
626                 {
627                         iop = i - 1;
628                         if (!(numPlayers%2)){
629                                 playerPos[i] = ((iop + abs(iop%2))/2 + 1) / ((numPlayers / 2) + 1);
630                         }
631                         else
632                         {
633                                 if (iop%2)
634                                 {
635                                         playerPos[i] = ((iop + abs(iop%2))/2 + 1) / (((numPlayers + 1) / 2) + 1);
636                                 }
637                                 else
638                                 {
639                                         playerPos[i] = ((iop)/2 + 1) / ((((numPlayers - 1)) / 2) + 1);
640                                 }
641                         }
643                         playerZ[i] = playerPos[i];
644                         playerX[i] = 0.25 + 0.5*(i%2);
645                 }
646         }
648         // create the main river
649         log("Creating the main river");
651         if (mdd1 == 2)
652                 var placer = new PathPlacer(fractionToTiles(0.5), 1, fractionToTiles(0.5) , fractionToTiles(0.99), scaleByMapSize(14,24), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01);
653         else
654                 var placer = new PathPlacer(1, fractionToTiles(0.5), fractionToTiles(0.99), fractionToTiles(0.5), scaleByMapSize(14,24), 0.5, 3*(scaleByMapSize(1,4)), 0.1, 0.01);
656         var terrainPainter = new LayeredPainter(
657                 [tShore, tWater, tWater],               // terrains
658                 [1, 3]                                                          // widths
659         );
660         var elevationPainter = new SmoothElevationPainter(
661                 ELEVATION_SET,                  // type
662                 -4,                             // elevation
663                 4                               // blend radius
664         );
665         createArea(placer, [terrainPainter, elevationPainter], avoidClasses(clPlayer, 4));
667         if (mdd1 == 1)
668                 placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, 1, fractionToTiles(0.5));
669         else
670                 placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5), 1);
672         var painter = new LayeredPainter([tWater, tWater], [1]);
673         var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2);
674         createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 8));
676         if (mdd1 == 1)
677                 placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.99), fractionToTiles(0.5));
678         else
679                 placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5), fractionToTiles(0.99));
681         var painter = new LayeredPainter([tWater, tWater], [1]);
682         var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2);
683         createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 8));
685         var mdd2 = randInt(1,2);
686         if (mdd2 == 1)
687         {
688                 // create the shallows of the main river
689                 log("Creating the shallows of the main river");
691                 for (var i = 0; i <= randInt(1, scaleByMapSize(4,8)); i++)
692                 {
693                         var cLocation = randFloat(0.15,0.85);
694                         if (mdd1 == 1)
695                                 passageMaker(floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4);
696                         else
697                                 passageMaker(floor(fractionToTiles(0.35)), floor(fractionToTiles(cLocation)), floor(fractionToTiles(0.65)), floor(fractionToTiles(cLocation)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4);
698                 }
699         }
701         if (randInt(1,2) == 1)
702         {
703                 for (var i = 0; i < numPlayers; i++)
704                 {
705                         var fx = fractionToTiles(playerX[i]);
706                         var fz = fractionToTiles(playerZ[i]);
707                         var ix = round(fx);
708                         var iz = round(fz);
709                         // create the city patch
710                         var cityRadius = scaleByMapSize(17,29)/3;
711                         placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
712                         createArea(placer, paintClass(clPlayer), null);
713                 }
715                 // create tributaries
716                 log("Creating tributaries");
718                 for (var i = 0; i <= randInt(8, (scaleByMapSize(12,20))); i++)
719                 {
720                         var cLocation = randFloat(0.05,0.95);
721                         var tang = randFloat(PI*0.2, PI*0.8)*((randInt(2)-0.5)*2);
722                         if (tang > 0)
723                         {
724                                 var cDistance = 0.05;
725                         }
726                         else
727                         {
728                                 var cDistance = -0.05;
729                         }
730                         if (mdd1 == 1)
731                                 var point = getTIPIADBON([fractionToTiles(cLocation), fractionToTiles(0.5 + cDistance)], [fractionToTiles(cLocation), fractionToTiles(0.5 - cDistance)], [-6, -1.5], 0.5, 5, 0.01);
732                         else
733                                 var point = getTIPIADBON([fractionToTiles(0.5 + cDistance), fractionToTiles(cLocation)], [fractionToTiles(0.5 - cDistance), fractionToTiles(cLocation)], [-6, -1.5], 0.5, 5, 0.01);
735                         if (point !== undefined)
736                         {
737                                 if (mdd1 == 1)
738                                         var placer = new PathPlacer(floor(point[0]), floor(point[1]), floor(fractionToTiles(0.5 + 0.49*cos(tang))), floor(fractionToTiles(0.5 + 0.49*sin(tang))), scaleByMapSize(10,20), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.05);
739                                 else
740                                         var placer = new PathPlacer(floor(point[0]), floor(point[1]), floor(fractionToTiles(0.5 + 0.49*sin(tang))), floor(fractionToTiles(0.5 + 0.49*cos(tang))), scaleByMapSize(10,20), 0.4, 3*(scaleByMapSize(1,4)), 0.1, 0.05);
743                                 var terrainPainter = new LayeredPainter(
744                                         [tShore, tWater, tWater],               // terrains
745                                         [1, 3]                                                          // widths
746                                 );
747                                 var elevationPainter = new SmoothElevationPainter(
748                                         ELEVATION_SET,                  // type
749                                         -4,                             // elevation
750                                         4                               // blend radius
751                                 );
752                                 var success = createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 3, clWater, 3, clShallow, 2));
753                                 if (success !== undefined)
754                                 {
755                                         if (mdd1 == 1)
756                                                 placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)));
757                                         else
758                                                 placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,20)*scaleByMapSize(10,20)/4), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*sin(tang)), fractionToTiles(0.5 + 0.49*cos(tang)));
760                                         var painter = new LayeredPainter([tWater, tWater], [1]);
761                                         var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 2);
762                                         createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 3));
763                                 }
764                         }
765                 }
766         if (mdd2 == 1)
767         {
768                 if (mdd1 == 1)
769                 {
770                         passageMaker(floor(fractionToTiles(0.2)), floor(fractionToTiles(0.25)), floor(fractionToTiles(0.8)), floor(fractionToTiles(0.25)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4);
771                         passageMaker(floor(fractionToTiles(0.2)), floor(fractionToTiles(0.75)), floor(fractionToTiles(0.8)), floor(fractionToTiles(0.75)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4);
772                 }
773                         passageMaker(floor(fractionToTiles(0.25)), floor(fractionToTiles(0.2)), floor(fractionToTiles(0.25)), floor(fractionToTiles(0.8)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4);
774                         passageMaker(floor(fractionToTiles(0.75)), floor(fractionToTiles(0.2)), floor(fractionToTiles(0.75)), floor(fractionToTiles(0.8)), scaleByMapSize(4,8), -2, -2, 2, clShallow, undefined, -4);
775                 }
776         }
778 //********************************************************************************************************
779 else if (md == 5) //rivers and lake
782         // randomize player order
783         var playerIDs = [];
784         for (var i = 0; i < numPlayers; i++)
785         {
786                 playerIDs.push(i+1);
787         }
788         playerIDs = sortPlayers(playerIDs);
790         // place players
792         var playerX = new Array(numPlayers);
793         var playerZ = new Array(numPlayers);
794         var playerAngle = new Array(numPlayers);
796         var startAngle = randFloat(0, TWO_PI);
797         for (var i = 0; i < numPlayers; i++)
798         {
799                 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
800                 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
801                 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
803                 var fx = fractionToTiles(playerX[i]);
804                 var fz = fractionToTiles(playerZ[i]);
805                 var ix = round(fx);
806                 var iz = round(fz);
807                 addToClass(ix, iz, clPlayer);
808                 addToClass(ix+5, iz, clPlayer);
809                 addToClass(ix, iz+5, clPlayer);
810                 addToClass(ix-5, iz, clPlayer);
811                 addToClass(ix, iz-5, clPlayer);
812         }
816         for (var ix = 0; ix < mapSize; ix++)
817         {
818                 for (var iz = 0; iz < mapSize; iz++)
819                 {
820                         var x = ix / (mapSize + 1.0);
821                         var z = iz / (mapSize + 1.0);
822                                 setHeight(ix, iz, 3);
823                 }
824         }
825         var mdd1 = randInt(1,2);
826         if (mdd1 == 1) //lake
827         {
828                 var fx = fractionToTiles(0.5);
829                 var fz = fractionToTiles(0.5);
830                 ix = round(fx);
831                 iz = round(fz);
833                 var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6))));
835                 var placer = new ClumpPlacer(mapArea * 0.09 * lSize, 0.7, 0.1, 10, ix, iz);
836                 var terrainPainter = new LayeredPainter(
837                         [tShore, tWater, tWater, tWater],               // terrains
838                         [1, 4, 2]               // widths
839                 );
840                 var elevationPainter = new SmoothElevationPainter(
841                         ELEVATION_SET,                  // type
842                         -4,                             // elevation
843                         4                               // blend radius
844                 );
845                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null);
847                 // create shore jaggedness
848                 log("Creating shore jaggedness...");
849                 placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1);
850                 terrainPainter = new LayeredPainter(
851                         [tCliff, tHill],                // terrains
852                         [2]                                                             // widths
853                 );
854                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 4);
855                 createAreas(
856                         placer,
857                         [terrainPainter, elevationPainter, paintClass(clWater)],
858                         [avoidClasses(clPlayer, 20), borderClasses(clWater, 6, 4)],
859                         scaleByMapSize(7, 130) * 2, 150
860                 );
862                 placer = new ClumpPlacer(scaleByMapSize(15, 80), 0.2, 0.1, 1);
863                 terrainPainter = new LayeredPainter(
864                         [tCliff, tHill],                // terrains
865                         [2]                                                             // widths
866                 );
867                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4);
868                 createAreas(
869                         placer,
870                         [terrainPainter, elevationPainter, unPaintClass(clWater)],
871                         borderClasses(clWater, 4, 7),
872                         scaleByMapSize(12, 130) * 2, 150
873                 );
874         }
876         if (randInt(1,2) == 1) //rivers
877         {
878                 //create rivers
879                 log ("Creating rivers...");
880                 for (var m = 0; m < numPlayers; m++)
881                 {
882                         var tang = startAngle + (m+0.5)*TWO_PI/(numPlayers);
883                         var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05);
884                         var terrainPainter = new LayeredPainter(
885                                 [tShore, tWater, tWater],               // terrains
886                                 [1, 3]                                                          // widths
887                         );
888                         var elevationPainter = new SmoothElevationPainter(
889                                 ELEVATION_SET,                  // type
890                                 -4,                             // elevation
891                                 4                               // blend radius
892                         );
893                         createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
894                         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)));
895                         var painter = new LayeredPainter([tWater, tWater], [1]);
896                         var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 0);
897                         createArea(placer, [painter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
899                 }
901                 var fx = fractionToTiles(0.5);
902                 var fz = fractionToTiles(0.5);
903                 ix = round(fx);
904                 iz = round(fz);
906                 var placer = new ClumpPlacer(mapArea * 0.005, 0.7, 0.1, 10, ix, iz);
907                 var terrainPainter = new LayeredPainter(
908                         [tShore, tWater, tWater, tWater],               // terrains
909                         [1, 4, 2]               // widths
910                 );
911                 var elevationPainter = new SmoothElevationPainter(
912                         ELEVATION_SET,                  // type
913                         -4,                             // elevation
914                         4                               // blend radius
915                 );
916                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null);
917         }
919         if ((randInt(1,3) == 1)&&(mdd1 == 1))//island
920         {
921                 var placer = new ClumpPlacer(mapArea * 0.006 * lSize, 0.7, 0.1, 10, ix, iz);
922                 var terrainPainter = new LayeredPainter(
923                         [tShore, tWater, tWater, tWater],               // terrains
924                         [1, 4, 2]               // widths
925                 );
926                 var elevationPainter = new SmoothElevationPainter(
927                         ELEVATION_SET,                  // type
928                         3,                              // elevation
929                         4                               // blend radius
930                 );
931                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null);
932         }
934 //********************************************************************************************************
935 else if (md == 6) //edge seas
938         for (var ix = 0; ix < mapSize; ix++)
939         {
940                 for (var iz = 0; iz < mapSize; iz++)
941                 {
942                         var x = ix / (mapSize + 1.0);
943                         var z = iz / (mapSize + 1.0);
944                                 setHeight(ix, iz, 3);
945                 }
946         }
948         var mdd1 = randInt(1,2);
950         // randomize player order
951         var playerIDs = [];
952         for (var i = 0; i < numPlayers; i++)
953         {
954                 playerIDs.push(i+1);
955         }
956         playerIDs = sortPlayers(playerIDs);
958         // place players
960         var playerX = new Array(numPlayers);
961         var playerZ = new Array(numPlayers);
962         var playerPos = new Array(numPlayers);
964         for (var i = 0; i < numPlayers; i++)
965         {
966                 playerPos[i] = (i + 1) / (numPlayers + 1);
967                 if (mdd1 == 1) //horizontal
968                 {
969                         playerX[i] = playerPos[i];
970                         playerZ[i] = 0.4 + 0.2*(i%2);
971                 }
972                 else //vertical
973                 {
974                         playerX[i] = 0.4 + 0.2*(i%2);
975                         playerZ[i] = playerPos[i];
976                 }
978                 var fx = fractionToTiles(playerX[i]);
979                 var fz = fractionToTiles(playerZ[i]);
980                 var ix = round(fx);
981                 var iz = round(fz);
982                 addToClass(ix, iz, clPlayer);
983                 addToClass(ix+5, iz, clPlayer);
984                 addToClass(ix, iz+5, clPlayer);
985                 addToClass(ix-5, iz, clPlayer);
986                 addToClass(ix, iz-5, clPlayer);
987         }
989         var mdd2 = randInt(1,3);
990         var fadedistance = 7;
992         if (mdd1 == 1)
993         {
994                 if ((mdd2 == 1)||(mdd2 == 3))
995                 {
996                         var distance = randFloat(0., 0.1);
997                         for (var ix = 0; ix < mapSize; ix++)
998                         {
999                                 for (var iz = 0; iz < mapSize; iz++)
1000                                 {
1001                                         if (iz > (0.69+distance) * mapSize)
1002                                         {
1003                                                 if (iz < (0.69+distance) * mapSize + fadedistance)
1004                                                 {
1005                                                         setHeight(ix, iz, 3 - 7 * (iz - (0.69+distance) * mapSize) / fadedistance);
1006                                                         if (3 - 7 * (iz - (0.69+distance) * mapSize) / fadedistance < 0.5)
1007                                                                 addToClass(ix, iz, clWater);
1008                                                 }
1009                                                 else
1010                                                 {
1011                                                         setHeight(ix, iz, -4);
1012                                                         addToClass(ix, iz, clWater);
1013                                                 }
1014                                         }
1015                                 }
1017                         }
1019                         for (var i = 0; i < scaleByMapSize(20,120); i++)
1020                         {
1021                                 placer = new ClumpPlacer(scaleByMapSize(50, 70), 0.2, 0.1, 10, randFloat(0.1,0.9)*mapSize, randFloat(0.67+distance,0.74+distance)*mapSize);
1022                                 var terrainPainter = new LayeredPainter(
1023                                         [tMainTerrain, tMainTerrain],           // terrains
1024                                         [2]                                                             // widths
1025                                 );
1026                                 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3);
1027                                 createArea(
1028                                         placer,
1029                                         [terrainPainter, elevationPainter, unPaintClass(clWater)],
1030                                         null
1031                                 );
1032                         }
1033                 }
1034                 if ((mdd2 == 2)||(mdd2 == 3))
1035                 {
1036                         var distance = randFloat(0., 0.1);
1037                         for (var ix = 0; ix < mapSize; ix++)
1038                         {
1039                                 for (var iz = 0; iz < mapSize; iz++)
1040                                 {
1041                                         if (iz < (0.31-distance) * mapSize)
1042                                         {
1043                                                 if (iz > (0.31-distance) * mapSize - fadedistance)
1044                                                 {
1045                                                         setHeight(ix, iz, 3 - 7 * ((0.31-distance) * mapSize - iz) / fadedistance);
1046                                                         if (3 - 7 * ((0.31-distance) * mapSize - iz) / fadedistance < 0.5)
1047                                                                 addToClass(ix, iz, clWater);
1048                                                 }
1049                                                 else
1050                                                 {
1051                                                         setHeight(ix, iz, -4);
1052                                                         addToClass(ix, iz, clWater);
1053                                                 }
1054                                         }
1055                                 }
1056                         }
1058                         for (var i = 0; i < scaleByMapSize(20,120); i++)
1059                         {
1060                                 placer = new ClumpPlacer(scaleByMapSize(50, 70), 0.2, 0.1, 10, randFloat(0.1,0.9)*mapSize, randFloat(0.26-distance,0.34-distance)*mapSize);
1061                                 var terrainPainter = new LayeredPainter(
1062                                         [tMainTerrain, tMainTerrain],           // terrains
1063                                         [2]                                                             // widths
1064                                 );
1065                                 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3);
1066                                 createArea(
1067                                         placer,
1068                                         [terrainPainter, elevationPainter, unPaintClass(clWater)],
1069                                         null
1070                                 );
1071                         }
1072                 }
1073         }
1074         else //vertical
1075         {
1076                 if ((mdd2 == 1)||(mdd2 == 3))
1077                 {
1078                         var distance = randFloat(0., 0.1);
1079                         for (var ix = 0; ix < mapSize; ix++)
1080                         {
1081                                 for (var iz = 0; iz < mapSize; iz++)
1082                                 {
1083                                         if (ix > (0.69+distance) * mapSize)
1084                                         {
1085                                                 if (ix < (0.69+distance) * mapSize + fadedistance)
1086                                                 {
1087                                                         setHeight(ix, iz, 3 - 7 * (ix - (0.69+distance) * mapSize) / fadedistance);
1088                                                         if (3 - 7 * (ix - (0.69+distance) * mapSize) / fadedistance < 0.5)
1089                                                                 addToClass(ix, iz, clWater);
1090                                                 }
1091                                                 else
1092                                                 {
1093                                                         setHeight(ix, iz, -4);
1094                                                         addToClass(ix, iz, clWater);
1095                                                 }
1096                                         }
1097                                 }
1098                         }
1099                 }
1100                 if ((mdd2 == 2)||(mdd2 == 3))
1101                 {
1102                         var distance = randFloat(0., 0.1);
1103                         for (var ix = 0; ix < mapSize; ix++)
1104                         {
1105                                 for (var iz = 0; iz < mapSize; iz++)
1106                                 {
1107                                         if (ix < (0.31-distance) * mapSize)
1108                                         {
1109                                                 if (ix > (0.31-distance) * mapSize - fadedistance)
1110                                                 {
1111                                                         setHeight(ix, iz, 3 - 7 * ((0.31-distance) * mapSize - ix) / fadedistance);
1112                                                         if (3 - 7 * ((0.31-distance) * mapSize - ix) / fadedistance < 0.5)
1113                                                                 addToClass(ix, iz, clWater);
1114                                                 }
1115                                                 else
1116                                                 {
1117                                                         setHeight(ix, iz, -4);
1118                                                         addToClass(ix, iz, clWater);
1119                                                 }
1120                                         }
1121                                 }
1122                         }
1123                 }
1124         }
1126         // create shore jaggedness
1127         log("Creating shore jaggedness...");
1128         placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1);
1129         terrainPainter = new LayeredPainter(
1130                 [tCliff, tHill],                // terrains
1131                 [2]                                                             // widths
1132         );
1133         elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 4);
1134         createAreas(
1135                 placer,
1136                 [terrainPainter, elevationPainter, paintClass(clWater)],
1137                 [avoidClasses(clPlayer, 20), borderClasses(clWater, 6, 4)],
1138                 scaleByMapSize(7, 130) * 2, 150
1139         );
1141         placer = new ClumpPlacer(scaleByMapSize(15, 80), 0.2, 0.1, 1);
1142         terrainPainter = new LayeredPainter(
1143                 [tCliff, tHill],                // terrains
1144                 [2]                                                             // widths
1145         );
1146         elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 4);
1147         createAreas(
1148                 placer,
1149                 [terrainPainter, elevationPainter, unPaintClass(clWater)],
1150                 borderClasses(clWater, 4, 7),
1151                 scaleByMapSize(12, 130) * 2, 150
1152         );
1154         var mdd3 = randInt(1,3);
1155         if (mdd3 == 1)
1156         {
1157                 // create islands
1158                 log("Creating islands...");
1159                 placer = new ClumpPlacer(randInt(scaleByMapSize(8,15),scaleByMapSize(15,23))*randInt(scaleByMapSize(8,15),scaleByMapSize(15,23)), 0.80, 0.1, randFloat(0.0, 0.2));
1160                 terrainPainter = new LayeredPainter(
1161                         [tMainTerrain, tMainTerrain],           // terrains
1162                         [2]                                                             // widths
1163                 );
1164                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4);
1165                 createAreas(
1166                         placer,
1167                         [terrainPainter, elevationPainter, paintClass(clLand)],
1168                         avoidClasses(clLand, 3, clPlayer, 3),
1169                         scaleByMapSize(2, 5)*randInt(8,14)
1170                 );
1171         }
1172         else if (mdd3 == 2)
1173         {
1174                 // create extentions
1175                 log("Creating extentions...");
1176                 placer = new ClumpPlacer(randInt(scaleByMapSize(13,24),scaleByMapSize(24,45))*randInt(scaleByMapSize(13,24),scaleByMapSize(24,45)), 0.80, 0.1, 10);
1177                 terrainPainter = new LayeredPainter(
1178                         [tMainTerrain, tMainTerrain],           // terrains
1179                         [2]                                                             // widths
1180                 );
1181                 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3.1, 4);
1182                 createAreas(
1183                         placer,
1184                         [terrainPainter, elevationPainter, paintClass(clLand)],
1185                         null,
1186                         scaleByMapSize(2, 5)*randInt(8,14)
1187                 );
1188         }
1190 //********************************************************************************************************
1191 else if (md == 7) //gulf
1194         for (var ix = 0; ix < mapSize; ix++)
1195         {
1196                 for (var iz = 0; iz < mapSize; iz++)
1197                 {
1198                         var x = ix / (mapSize + 1.0);
1199                         var z = iz / (mapSize + 1.0);
1200                                 setHeight(ix, iz, 3);
1201                 }
1202         }
1204         var mdd1 = randFloat(0,4);
1206         // randomize player order
1207         var playerIDs = [];
1208         for (var i = 0; i < numPlayers; i++)
1209         {
1210                 playerIDs.push(i+1);
1211         }
1212         playerIDs = sortPlayers(playerIDs);
1214         // place players
1216         var playerX = new Array(numPlayers);
1217         var playerZ = new Array(numPlayers);
1218         var playerAngle = new Array(numPlayers);
1220         var startAngle = -PI/6 + (mdd1-1)*PI/2;
1221         for (var i = 0; i < numPlayers; i++)
1222         {
1223                 playerAngle[i] = startAngle + i*TWO_PI/(numPlayers-1)*2/3;
1224                 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
1225                 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
1226         }
1228         for (var i = 0; i < numPlayers; i++)
1229         {
1230                 var fx = fractionToTiles(playerX[i]);
1231                 var fz = fractionToTiles(playerZ[i]);
1232                 var ix = round(fx);
1233                 var iz = round(fz);
1234                 // create the city patch
1235                 var cityRadius = scaleByMapSize(17,29)/3;
1236                 placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
1237                 createArea(placer, paintClass(clPlayer), null);
1238         }
1240         fx = fractionToTiles(0.5);
1241         fz = fractionToTiles(0.5);
1242         ix = round(fx);
1243         iz = round(fz);
1245         var lSize = 1;
1247         var placer = new ClumpPlacer(mapArea * 0.08 * lSize, 0.7, 0.05, 10, ix, iz);
1248         var terrainPainter = new LayeredPainter(
1249                 [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain],               // terrains
1250                 [1, 4, 2]               // widths
1251         );
1253         var elevationPainter = new SmoothElevationPainter(
1254                 ELEVATION_SET,                  // type
1255                 -3,                             // elevation
1256                 4                               // blend radius
1257         );
1258         createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,floor(scaleByMapSize(15,25))));
1260         fx = fractionToTiles(0.5 - 0.2*cos(mdd1*PI/2));
1261         fz = fractionToTiles(0.5 - 0.2*sin(mdd1*PI/2));
1262         ix = round(fx);
1263         iz = round(fz);
1265         var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6))));
1267         var placer = new ClumpPlacer(mapArea * 0.13 * lSize, 0.7, 0.05, 10, ix, iz);
1268         var terrainPainter = new LayeredPainter(
1269                 [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain],               // terrains
1270                 [1, 4, 2]               // widths
1271         );
1272         var elevationPainter = new SmoothElevationPainter(
1273                 ELEVATION_SET,                  // type
1274                 -3,                             // elevation
1275                 4                               // blend radius
1276         );
1277         createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,floor(scaleByMapSize(15,25))));
1279         fx = fractionToTiles(0.5 - 0.49*cos(mdd1*PI/2));
1280         fz = fractionToTiles(0.5 - 0.49*sin(mdd1*PI/2));
1281         ix = round(fx);
1282         iz = round(fz);
1284         var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6))));
1286         var placer = new ClumpPlacer(mapArea * 0.15 * lSize, 0.7, 0.05, 10, ix, iz);
1287         var terrainPainter = new LayeredPainter(
1288                 [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain],               // terrains
1289                 [1, 4, 2]               // widths
1290         );
1291         var elevationPainter = new SmoothElevationPainter(
1292                 ELEVATION_SET,                  // type
1293                 -3,                             // elevation
1294                 4                               // blend radius
1295         );
1296         createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer,floor(scaleByMapSize(15,25))));
1298 //********************************************************************************************************
1299 else if (md == 8) //lakes
1302         // randomize player order
1303         var playerIDs = [];
1304         for (var i = 0; i < numPlayers; i++)
1305         {
1306                 playerIDs.push(i+1);
1307         }
1308         playerIDs = sortPlayers(playerIDs);
1310         // place players
1312         var playerX = new Array(numPlayers);
1313         var playerZ = new Array(numPlayers);
1314         var playerAngle = new Array(numPlayers);
1316         var startAngle = randFloat(0, TWO_PI);
1317         for (var i = 0; i < numPlayers; i++)
1318         {
1319                 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
1320                 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
1321                 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
1322         }
1324         for (var ix = 0; ix < mapSize; ix++)
1325         {
1326                 for (var iz = 0; iz < mapSize; iz++)
1327                 {
1328                         var x = ix / (mapSize + 1.0);
1329                         var z = iz / (mapSize + 1.0);
1330                                 setHeight(ix, iz, 3);
1331                 }
1332         }
1334         for (var i = 0; i < numPlayers; i++)
1335         {
1336                 var fx = fractionToTiles(playerX[i]);
1337                 var fz = fractionToTiles(playerZ[i]);
1338                 var ix = round(fx);
1339                 var iz = round(fz);
1340                 // create the city patch
1341                 var cityRadius = scaleByMapSize(17,29)/3;
1342                 placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
1343                 createArea(placer, paintClass(clPlayer), null);
1344         }
1346         // create lakes
1347         log("Creating lakes...");
1348         placer = new ClumpPlacer(scaleByMapSize(160, 700), 0.2, 0.1, 1);
1349         terrainPainter = new LayeredPainter(
1350                 [tShore, tWater, tWater],               // terrains
1351                 [1, 3]                                                          // widths
1352         );
1353         elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -5, 5);
1354         if (randInt(1,2) == 1)
1355         {
1356                 createAreas(
1357                         placer,
1358                         [terrainPainter, elevationPainter, paintClass(clWater)],
1359                         avoidClasses(clPlayer, 12, clWater, 8),
1360                         scaleByMapSize(5, 16)
1361                 );
1362         }
1363         else
1364         {
1365                 createAreas(
1366                         placer,
1367                         [terrainPainter, elevationPainter, paintClass(clWater)],
1368                         avoidClasses(clPlayer, 12),
1369                         scaleByMapSize(5, 16)
1370                 );
1371         }
1373 //********************************************************************************************************
1374 else if (md == 9) //passes
1377         // randomize player order
1378         var playerIDs = [];
1379         for (var i = 0; i < numPlayers; i++)
1380         {
1381                 playerIDs.push(i+1);
1382         }
1383         playerIDs = sortPlayers(playerIDs);
1385         // place players
1387         var playerX = new Array(numPlayers);
1388         var playerZ = new Array(numPlayers);
1389         var playerAngle = new Array(numPlayers);
1391         var startAngle = randFloat(0, TWO_PI);
1392         for (var i = 0; i < numPlayers; i++)
1393         {
1394                 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
1395                 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
1396                 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
1397         }
1399         for (var ix = 0; ix < mapSize; ix++)
1400         {
1401                 for (var iz = 0; iz < mapSize; iz++)
1402                 {
1403                         var x = ix / (mapSize + 1.0);
1404                         var z = iz / (mapSize + 1.0);
1405                                 setHeight(ix, iz, 3);
1406                 }
1407         }
1409         //create ranges
1410         log ("Creating ranges...");
1411         for (var m = 0; m < numPlayers; m++)
1412         {
1413                 var tang = startAngle + (m+0.5)*TWO_PI/(numPlayers);
1414                 var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05);
1415                 var terrainPainter = new LayeredPainter(
1416                         [tShore, tWater, tWater],               // terrains
1417                         [1, 3]                                                          // widths
1418                 );
1419                 var elevationPainter = new SmoothElevationPainter(
1420                         ELEVATION_SET,                  // type
1421                         24,                             // elevation
1422                         3                               // blend radius
1423                 );
1424                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
1425                 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)));
1426                 var painter = new LayeredPainter([tWater, tWater], [1]);
1427                 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 24, 0);
1428                 createArea(placer, [painter, elevationPainter], avoidClasses(clPlayer, 5));
1430                 var placer = new PathPlacer(fractionToTiles(0.5 + 0.3*cos(tang) - 0.1 * cos(tang+PI/2)), fractionToTiles(0.5 + 0.3*sin(tang) - 0.1 * sin(tang+PI/2)), fractionToTiles(0.5 + 0.3*cos(tang) + 0.1 * cos(tang+PI/2)), fractionToTiles(0.5 + 0.3*sin(tang) + 0.1 * sin(tang+PI/2)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05);
1431                 var painter = new LayeredPainter([tCliff, tCliff], [1]);
1432                 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 2);
1433                 createArea(placer, [painter, elevationPainter], null);
1434         }
1435         var mdd1 = randInt (1,3);
1436         if (mdd1 <= 2)
1437         {
1438                 var fx = fractionToTiles(0.5);
1439                 var fz = fractionToTiles(0.5);
1440                 ix = round(fx);
1441                 iz = round(fz);
1443                 var placer = new ClumpPlacer(mapArea * 0.005, 0.7, 0.1, 10, ix, iz);
1444                 var terrainPainter = new LayeredPainter(
1445                         [tShore, tWater, tWater, tWater],               // terrains
1446                         [1, 4, 2]               // widths
1447                 );
1448                 var elevationPainter = new SmoothElevationPainter(
1449                         ELEVATION_SET,                  // type
1450                         24,                             // elevation
1451                         4                               // blend radius
1452                 );
1453                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null);
1454         }
1455         else
1456         {
1457                 var fx = fractionToTiles(0.5);
1458                 var fz = fractionToTiles(0.5);
1459                 ix = round(fx);
1460                 iz = round(fz);
1462                 var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6))));
1464                 var placer = new ClumpPlacer(mapArea * 0.03 * lSize, 0.7, 0.1, 10, ix, iz);
1465                 var terrainPainter = new LayeredPainter(
1466                         [tShore, tWater, tWater, tWater],               // terrains
1467                         [1, 4, 2]               // widths
1468                 );
1469                 var elevationPainter = new SmoothElevationPainter(
1470                         ELEVATION_SET,                  // type
1471                         -4,                             // elevation
1472                         3                               // blend radius
1473                 );
1474                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null);
1475         }
1477 //********************************************************************************************************
1478 else if (md == 10) //lowlands
1480         // randomize player order
1481         var playerIDs = [];
1482         for (var i = 0; i < numPlayers; i++)
1483         {
1484                 playerIDs.push(i+1);
1485         }
1486         playerIDs = sortPlayers(playerIDs);
1488         // place players
1490         var playerX = new Array(numPlayers);
1491         var playerZ = new Array(numPlayers);
1492         var playerAngle = new Array(numPlayers);
1494         var startAngle = randFloat(0, TWO_PI);
1495         for (var i = 0; i < numPlayers; i++)
1496         {
1497                 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
1498                 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
1499                 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
1500         }
1502         for (var ix = 0; ix < mapSize; ix++)
1503         {
1504                 for (var iz = 0; iz < mapSize; iz++)
1505                 {
1506                         var x = ix / (mapSize + 1.0);
1507                         var z = iz / (mapSize + 1.0);
1508                                 setHeight(ix, iz, 30);
1509                 }
1510         }
1513         var radius = scaleByMapSize(18,32);
1514         var cliffRadius = 2;
1515         var elevation = 20;
1516         var hillSize = PI * radius * radius;
1518         var split = 1;
1519         if ((mapSize / 64 == 2)&&(numPlayers <= 2))
1520         {
1521                 split = 2;
1522         }
1523         else if ((mapSize / 64 == 3)&&(numPlayers <= 3))
1524         {
1525                 split = 2;
1526         }
1527         else if ((mapSize / 64 == 4)&&(numPlayers <= 4))
1528         {
1529                 split = 2;
1530         }
1531         else if ((mapSize / 64 == 5)&&(numPlayers <= 4))
1532         {
1533                 split = 2;
1534         }
1535         else if ((mapSize / 64 == 6)&&(numPlayers <= 5))
1536         {
1537                 split = 2;
1538         }
1539         else if ((mapSize / 64 == 7)&&(numPlayers <= 6))
1540         {
1541                 split = 2;
1542         }
1544         for (var i = 0; i < numPlayers*split; i++)
1545         {
1546                 var tang = startAngle + (i)*TWO_PI/(numPlayers*split);
1547                 var fx = fractionToTiles(0.5 + 0.35*cos(tang));
1548                 var fz = fractionToTiles(0.5 + 0.35*sin(tang));
1549                 var ix = round(fx);
1550                 var iz = round(fz);
1551                 // create the hill
1552                 var placer = new ClumpPlacer(hillSize, 0.65, 0.1, 10, ix, iz);
1553                 var terrainPainter = new LayeredPainter(
1554                         [tMainTerrain, tMainTerrain],           // terrains
1555                         [cliffRadius]           // widths
1556                 );
1557                 var elevationPainter = new SmoothElevationPainter(
1558                         ELEVATION_SET,                  // type
1559                         3,                              // elevation
1560                         cliffRadius                             // blend radius
1561                 );
1562                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clLand)], null);
1563         }
1565         var fx = fractionToTiles(0.5);
1566         var fz = fractionToTiles(0.5);
1567         ix = round(fx);
1568         iz = round(fz);
1570         var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6))));
1572         var placer = new ClumpPlacer(mapArea * 0.091 * lSize, 0.7, 0.1, 10, ix, iz);
1573         var terrainPainter = new LayeredPainter(
1574                 [tMainTerrain, tMainTerrain, tMainTerrain, tMainTerrain],               // terrains
1575                 [1, 4, 2]               // widths
1576         );
1577         var elevationPainter = new SmoothElevationPainter(
1578                 ELEVATION_SET,                  // type
1579                 3,                              // elevation
1580                 4                               // blend radius
1581         );
1582         createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null);
1584         for (var m = 0; m < numPlayers*split; m++)
1585         {
1586                 var tang = startAngle + m*TWO_PI/(numPlayers*split);
1587                 var placer = new PathPlacer(fractionToTiles(0.5), fractionToTiles(0.5), fractionToTiles(0.5 + 0.35*cos(tang)), fractionToTiles(0.5 + 0.35*sin(tang)), scaleByMapSize(14,24), 0.4, 3*(scaleByMapSize(1,3)), 0.2, 0.05);
1588                 var terrainPainter = new LayeredPainter(
1589                         [tMainTerrain, tMainTerrain, tMainTerrain],             // terrains
1590                         [1, 3]                                                          // widths
1591                 );
1592                 var elevationPainter = new SmoothElevationPainter(
1593                         ELEVATION_SET,                  // type
1594                         3,                              // elevation
1595                         4                               // blend radius
1596                 );
1597                 createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], null);
1598         }
1600 //********************************************************************************************************
1601 else //mainland
1604         // randomize player order
1605         var playerIDs = [];
1606         for (var i = 0; i < numPlayers; i++)
1607         {
1608                 playerIDs.push(i+1);
1609         }
1610         playerIDs = sortPlayers(playerIDs);
1612         // place players
1614         var playerX = new Array(numPlayers);
1615         var playerZ = new Array(numPlayers);
1616         var playerAngle = new Array(numPlayers);
1618         var startAngle = randFloat(0, TWO_PI);
1619         for (var i = 0; i < numPlayers; i++)
1620         {
1621                 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
1622                 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
1623                 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
1624         }
1626         for (var ix = 0; ix < mapSize; ix++)
1627         {
1628                 for (var iz = 0; iz < mapSize; iz++)
1629                 {
1630                         var x = ix / (mapSize + 1.0);
1631                         var z = iz / (mapSize + 1.0);
1632                                 setHeight(ix, iz, 3);
1633                 }
1634         }
1638 paintTerrainBasedOnHeight(3.12, 40, 1, tCliff);
1639 paintTerrainBasedOnHeight(3, 3.12, 1, tMainTerrain);
1640 paintTerrainBasedOnHeight(1, 3, 1, tShore);
1641 paintTerrainBasedOnHeight(-8, 1, 2, tWater);
1642 unPaintTileClassBasedOnHeight(0, 3.12, 1, clWater);
1643 unPaintTileClassBasedOnHeight(-6, 0, 1, clLand);
1644 paintTileClassBasedOnHeight(-6, 0, 1, clWater);
1645 paintTileClassBasedOnHeight(0, 3.12, 1, clLand);
1646 paintTileClassBasedOnHeight(3.12, 40, 1, clHill);
1648 for (var i = 0; i < numPlayers; i++)
1650         var id = playerIDs[i];
1651         log("Creating base for player " + id + "...");
1653         // some constants
1654         var radius = scaleByMapSize(17,29);
1655         var shoreRadius = 4;
1656         var elevation = 3;
1658         var hillSize = PI * radius * radius;
1659         // get the x and z in tiles
1660         var fx = fractionToTiles(playerX[i]);
1661         var fz = fractionToTiles(playerZ[i]);
1662         var ix = round(fx);
1663         var iz = round(fz);
1665         // create starting units
1666         if (iberianTowers)
1667                 placeCivDefaultEntities(fx, fz, id, { 'iberWall': 'towers' });
1668         else
1669                 placeCivDefaultEntities(fx, fz, id);
1671         placeDefaultChicken(fx, fz, clBaseResource);
1673         // create berry bushes
1674         var bbAngle = randFloat(0, TWO_PI);
1675         var bbDist = 12;
1676         var bbX = round(fx + bbDist * cos(bbAngle));
1677         var bbZ = round(fz + bbDist * sin(bbAngle));
1678         var group = new SimpleGroup(
1679                 [new SimpleObject(oFruitBush, 5,5, 0,3)],
1680                 true, clBaseResource, bbX, bbZ
1681         );
1682         createObjectGroup(group, 0);
1683         if (needsAdditionalWood)
1684         {
1685                 // create woods
1686                 var bbAngle = randFloat(0, TWO_PI);
1687                 var bbDist = 13;
1688                 var bbX = round(fx + bbDist * cos(bbAngle));
1689                 var bbZ = round(fz + bbDist * sin(bbAngle));
1690                 group = new SimpleGroup(
1691                         [new SimpleObject(oWood, 14,14, 0,3)],
1692                         true, clBaseResource, bbX, bbZ
1693                 );
1694                 createObjectGroup(group, 0);
1695         }
1697         // create metal mine
1698         var mAngle = bbAngle;
1699         while(abs(mAngle - bbAngle) < PI/3)
1700         {
1701                 mAngle = randFloat(0, TWO_PI);
1702         }
1703         var mDist = 12;
1704         var mX = round(fx + mDist * cos(mAngle));
1705         var mZ = round(fz + mDist * sin(mAngle));
1706         group = new SimpleGroup(
1707                 [new SimpleObject(oMetalLarge, 1,1, 0,0)],
1708                 true, clBaseResource, mX, mZ
1709         );
1710         createObjectGroup(group, 0);
1712         // create stone mines
1713         mAngle += randFloat(PI/8, PI/4);
1714         mX = round(fx + mDist * cos(mAngle));
1715         mZ = round(fz + mDist * sin(mAngle));
1716         group = new SimpleGroup(
1717                 [new SimpleObject(oStoneLarge, 1,1, 0,2)],
1718                 true, clBaseResource, mX, mZ
1719         );
1720         createObjectGroup(group, 0);
1721         var hillSize = PI * radius * radius;
1722         // create starting trees
1723         var num = floor(hillSize / 100);
1724         var tAngle = randFloat(-PI/3, 4*PI/3);
1725         var tDist = randFloat(11, 13);
1726         var tX = round(fx + tDist * cos(tAngle));
1727         var tZ = round(fz + tDist * sin(tAngle));
1728         group = new SimpleGroup(
1729                 [new SimpleObject(oTree1, num, num, 0,5)],
1730                 false, clBaseResource, tX, tZ
1731         );
1732         createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
1734         // create grass tufts
1735         var num = hillSize / 250;
1736         for (var j = 0; j < num; j++)
1737         {
1738                 var gAngle = randFloat(0, TWO_PI);
1739                 var gDist = radius - (5 + randInt(7));
1740                 var gX = round(fx + gDist * cos(gAngle));
1741                 var gZ = round(fz + gDist * sin(gAngle));
1742                 group = new SimpleGroup(
1743                         [new SimpleObject(aGrassShort, 2,5, 0,1, -PI/8,PI/8)],
1744                         false, clBaseResource, gX, gZ
1745                 );
1746                 createObjectGroup(group, 0);
1747         }
1750 for (var i = 0; i < numPlayers; i++)
1752         var fx = fractionToTiles(playerX[i]);
1753         var fz = fractionToTiles(playerZ[i]);
1754         var ix = round(fx);
1755         var iz = round(fz);
1756         // create the city patch
1757         var cityRadius = radius/3;
1758         placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
1759         var painter = new LayeredPainter([tRoadWild, tRoad], [1]);
1760         createArea(placer, [painter, paintClass(clPlayer)], null);
1763 // create bumps
1764 log("Creating bumps...");
1765 placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1);
1766 painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2);
1767 createAreas(
1768         placer,
1769         painter,
1770         [avoidClasses(clWater, 2, clPlayer, 10), stayClasses(clLand, 3)],
1771         randInt(0,scaleByMapSize(200, 400))
1774 // create hills
1775 log("Creating hills...");
1776 placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1);
1777 terrainPainter = new LayeredPainter(
1778         [tCliff, tHill],                // terrains
1779         [2]                                                             // widths
1781 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 18, 2);
1782 createAreas(
1783         placer,
1784         [terrainPainter, elevationPainter, paintClass(clHill)],
1785         [avoidClasses(clPlayer, 20, clHill, randInt(6, 18)), stayClasses(clLand, 0)],
1786         randInt(0, scaleByMapSize(4, 8))*randInt(1, scaleByMapSize(4, 9))
1789 var multiplier = sqrt(randFloat(0.5,1.2)*randFloat(0.5,1.2));
1790 // calculate desired number of trees for map (based on size)
1791 if (random_terrain == g_BiomeSavanna)
1793         var MIN_TREES = floor(200*multiplier);
1794         var MAX_TREES = floor(1250*multiplier);
1795         var P_FOREST = randFloat(0.02, 0.05);
1797 else if (random_terrain == g_BiomeTropic)
1799         var MIN_TREES = floor(1000*multiplier);
1800         var MAX_TREES = floor(6000*multiplier);
1801         var P_FOREST = randFloat(0.5, 0.7);
1803 else
1805         var MIN_TREES = floor(500*multiplier);
1806         var MAX_TREES = floor(3000*multiplier);
1807         var P_FOREST = randFloat(0.5,0.8);
1809 var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES);
1810 var numForest = totalTrees * P_FOREST;
1811 var numStragglers = totalTrees * (1.0 - P_FOREST);
1813 // create forests
1814 log("Creating forests...");
1815 var types = [
1816         [[tForestFloor2, tMainTerrain, pForest1], [tForestFloor2, pForest1]],
1817         [[tForestFloor1, tMainTerrain, pForest2], [tForestFloor1, pForest2]]
1818 ];      // some variation
1820 if (random_terrain == g_BiomeSavanna)
1821         var size = numForest / (0.5 * scaleByMapSize(2,8) * numPlayers);
1822 else
1823         var size = numForest / (scaleByMapSize(2,8) * numPlayers);
1825 var num = floor(size / types.length);
1826 for (var i = 0; i < types.length; ++i)
1828         placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 1);
1829         painter = new LayeredPainter(
1830                 types[i],               // terrains
1831                 [2]                                                                                     // widths
1832                 );
1833         createAreas(
1834                 placer,
1835                 [painter, paintClass(clForest)],
1836                 [avoidClasses(clPlayer, 20, clForest, randInt(5, 15), clHill, 0), stayClasses(clLand, 4)],
1837                 num
1838         );
1841 RMS.SetProgress(50);
1842 // create dirt patches
1843 log("Creating dirt patches...");
1844 var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)];
1845 var numb = 1;
1846 if (random_terrain == g_BiomeSavanna)
1847         numb = 3;
1848 for (var i = 0; i < sizes.length; i++)
1850         placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
1851         painter = new LayeredPainter(
1852                 [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]],            // terrains
1853                 [1,1]                                                                                                                   // widths
1854         );
1855         createAreas(
1856                 placer,
1857                 [painter, paintClass(clDirt)],
1858                 [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 7), stayClasses(clLand, 4)],
1859                 numb*scaleByMapSize(15, 45)
1860         );
1863 // create grass patches
1864 log("Creating grass patches...");
1865 var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)];
1866 for (var i = 0; i < sizes.length; i++)
1868         placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
1869         painter = new TerrainPainter(tTier4Terrain);
1870         createAreas(
1871                 placer,
1872                 painter,
1873                 [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 7), stayClasses(clLand, 4)],
1874                 numb*scaleByMapSize(15, 45)
1875         );
1877 RMS.SetProgress(55);
1880 log("Creating stone mines...");
1881 // create large stone quarries
1882 group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock);
1883 createObjectGroups(group, 0,
1884         [avoidClasses(clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), stayClasses(clLand, 4)],
1885         randInt(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100
1888 // create small stone quarries
1889 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock);
1890 createObjectGroups(group, 0,
1891         [avoidClasses(clForest, 1, clPlayer, 20, clRock, 10, clHill, 1), stayClasses(clLand, 4)],
1892         randInt(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100
1895 log("Creating metal mines...");
1896 // create large metal quarries
1897 group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal);
1898 createObjectGroups(group, 0,
1899         [avoidClasses(clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1), stayClasses(clLand, 4)],
1900         randInt(scaleByMapSize(2,9),scaleByMapSize(9,40)), 100
1903 RMS.SetProgress(65);
1905 // create small decorative rocks
1906 log("Creating small decorative rocks...");
1907 group = new SimpleGroup(
1908         [new SimpleObject(aRockMedium, 1,3, 0,1)],
1909         true
1911 createObjectGroups(
1912         group, 0,
1913         [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 4)],
1914         scaleByMapSize(16, 262), 50
1918 // create large decorative rocks
1919 log("Creating large decorative rocks...");
1920 group = new SimpleGroup(
1921         [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)],
1922         true
1924 createObjectGroups(
1925         group, 0,
1926         [avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 4)],
1927         scaleByMapSize(8, 131), 50
1930 RMS.SetProgress(70);
1932 // create deer
1933 log("Creating deer...");
1934 group = new SimpleGroup(
1935         [new SimpleObject(oMainHuntableAnimal, 5,7, 0,4)],
1936         true, clFood
1938 createObjectGroups(group, 0,
1939         [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 4)],
1940         randInt(numPlayers+3, 5*numPlayers+4), 50
1943 // create berry bush
1944 log("Creating berry bush...");
1945 group = new SimpleGroup(
1946         [new SimpleObject(oFruitBush, 5,7, 0,4)],
1947         true, clFood
1949 createObjectGroups(group, 0,
1950         [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 4)],
1951         randInt(1, 4) * numPlayers + 2, 50
1954 RMS.SetProgress(75);
1956 // create sheep
1957 log("Creating sheep...");
1958 group = new SimpleGroup(
1959         [new SimpleObject(oSecondaryHuntableAnimal, 2,3, 0,2)],
1960         true, clFood
1962 createObjectGroups(group, 0,
1963         [avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20), stayClasses(clLand, 4)],
1964         randInt(numPlayers+3, 5*numPlayers+4), 50
1967 // create fish
1968 log("Creating fish...");
1969 group = new SimpleGroup(
1970         [new SimpleObject(oFish, 2,3, 0,2)],
1971         true, clFood
1973 createObjectGroups(group, 0,
1974         avoidClasses(clLand, 5, clForest, 0, clPlayer, 0, clHill, 0, clFood, 20),
1975         randInt(15, 40) * numPlayers, 60
1978 RMS.SetProgress(85);
1981 // create straggler trees
1982 log("Creating straggler trees...");
1983 var types = [oTree1, oTree2, oTree4, oTree3];   // some variation
1984 var num = floor(numStragglers / types.length);
1985 for (var i = 0; i < types.length; ++i)
1987         group = new SimpleGroup(
1988                 [new SimpleObject(types[i], 1,1, 0,3)],
1989                 true, clForest
1990         );
1991         createObjectGroups(group, 0,
1992                 [avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 0, clMetal, 1, clRock, 1), stayClasses(clLand, 4)],
1993                 num
1994         );
1997 var planetm = 1;
1998 if (random_terrain == g_BiomeTropic)
1999         planetm = 8;
2001 //create small grass tufts
2002 log("Creating small grass tufts...");
2003 group = new SimpleGroup(
2004         [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)]
2006 createObjectGroups(group, 0,
2007         [avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 4)],
2008         planetm * scaleByMapSize(13, 200)
2011 RMS.SetProgress(90);
2013 // create large grass tufts
2014 log("Creating large grass tufts...");
2015 group = new SimpleGroup(
2016         [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)]
2018 createObjectGroups(group, 0,
2019         [avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 4)],
2020         planetm * scaleByMapSize(13, 200)
2023 RMS.SetProgress(95);
2025 // create shallow flora
2026 log("Creating shallow flora...");
2027 group = new SimpleGroup(
2028         [new SimpleObject(aLillies, 1,2, 0,2), new SimpleObject(aReeds, 2,4, 0,2)]
2030 createObjectGroups(group, 0,
2031         stayClasses(clShallow, 1),
2032         60 * scaleByMapSize(13, 200), 80
2035 // create bushes
2036 log("Creating bushes...");
2037 group = new SimpleGroup(
2038         [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)]
2040 createObjectGroups(group, 0,
2041         [avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1), stayClasses(clLand, 3)],
2042         planetm * scaleByMapSize(13, 200), 50
2045 random_terrain = randInt(1,6);
2046 if (random_terrain == 1)
2047         setSkySet("cirrus");
2048 else if (random_terrain == 2)
2049         setSkySet("cumulus");
2050 else if (random_terrain == 3)
2051         setSkySet("sunny");
2052 else if (random_terrain == 4)
2053         setSkySet("sunny 1");
2054 else if (random_terrain == 5)
2055         setSkySet("mountainous");
2056 else if (random_terrain == 6)
2057         setSkySet("stratus");
2059 setSunRotation(randFloat(0, TWO_PI));
2060 setSunElevation(randFloat(PI/ 5, PI / 3));
2062 // Export map data
2063 ExportMap();