Ticket #3455: _kalis_maps_v1.patch

File _kalis_maps_v1.patch, 104.4 KB (added by elexis, 8 years ago)

preview images on github

  • binaries/data/mods/public/maps/random/ambush.js

     
     1RMS.LoadLibrary("rmgen");
     2
     3InitMap();
     4
     5randomizeBiome();
     6initMapSettings();
     7initTileClasses();
     8
     9resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 2);
     10RMS.SetProgress(10);
     11
     12var pos = randomStartingPositionPattern();
     13addBases(pos.setup, pos.distance, pos.separation);
     14RMS.SetProgress(20);
     15
     16addElements([
     17    {
     18        "func": addBluffs,
     19        "avoid": [
     20            g_TileClasses.bluff, 12,
     21            g_TileClasses.hill, 5,
     22            g_TileClasses.player, 35
     23        ],
     24        "sizes": ["normal", "big", "huge"],
     25        "mixes": ["same"],
     26        "amounts": ["tons"]
     27    },
     28    {
     29        "func": addHills,
     30        "avoid": [
     31            g_TileClasses.bluff, 5,
     32            g_TileClasses.hill, 15,
     33            g_TileClasses.player, 20
     34        ],
     35        "sizes": ["normal", "big"],
     36        "mixes": ["normal"],
     37        "amounts": ["tons"]
     38    }
     39]);
     40RMS.SetProgress(30);
     41
     42addElements([
     43    {
     44        "func": addLayeredPatches,
     45        "avoid": [
     46            g_TileClasses.bluff, 2,
     47            g_TileClasses.dirt, 5,
     48            g_TileClasses.forest, 2,
     49            g_TileClasses.mountain, 2,
     50            g_TileClasses.player, 12,
     51            g_TileClasses.water, 3
     52        ],
     53        "sizes": ["normal"],
     54        "mixes": ["normal"],
     55        "amounts": ["normal"]
     56    },
     57    {
     58        "func": addDecoration,
     59        "avoid": [
     60            g_TileClasses.bluff, 2,
     61            g_TileClasses.forest, 2,
     62            g_TileClasses.mountain, 2,
     63            g_TileClasses.player, 12,
     64            g_TileClasses.water, 3
     65        ],
     66        "sizes": ["normal"],
     67        "mixes": ["normal"],
     68        "amounts": ["normal"]
     69    }
     70]);
     71RMS.SetProgress(50);
     72
     73addElements(shuffleArray([
     74    {
     75        "func": addMetal,
     76        "avoid": [
     77            g_TileClasses.berries, 5,
     78            g_TileClasses.forest, 3,
     79            g_TileClasses.mountain, 2,
     80            g_TileClasses.player, 30,
     81            g_TileClasses.rock, 10,
     82            g_TileClasses.metal, 20,
     83            g_TileClasses.water, 3
     84        ],
     85        "stay": [g_TileClasses.bluff, 5],
     86        "sizes": ["normal"],
     87        "mixes": ["same"],
     88        "amounts": ["tons"]
     89    },
     90    {
     91        "func": addStone,
     92        "avoid": [
     93            g_TileClasses.berries, 5,
     94            g_TileClasses.forest, 3,
     95            g_TileClasses.mountain, 2,
     96            g_TileClasses.player, 30,
     97            g_TileClasses.rock, 20,
     98            g_TileClasses.metal, 10,
     99            g_TileClasses.water, 3
     100        ],
     101        "stay": [g_TileClasses.bluff, 5],
     102        "sizes": ["normal"],
     103        "mixes": ["same"],
     104        "amounts": ["tons"]
     105    },
     106    {
     107        "func": addForests,
     108        "avoid": [
     109            g_TileClasses.metal, 3,
     110            g_TileClasses.mountain, 5,
     111            g_TileClasses.player, 20,
     112            g_TileClasses.rock, 3,
     113            g_TileClasses.water, 2
     114        ],
     115        "stay": [g_TileClasses.bluff, 5],
     116        "sizes": ["big", "huge"],
     117        "mixes": ["normal"],
     118        "amounts": ["tons"]
     119    }
     120]));
     121RMS.SetProgress(70);
     122
     123addElements(shuffleArray([
     124    {
     125        "func": addBerries,
     126        "avoid": [
     127            g_TileClasses.bluff, 5, g_TileClasses.forest, 5,
     128            g_TileClasses.metal, 10,
     129            g_TileClasses.mountain, 2,
     130            g_TileClasses.player, 20,
     131            g_TileClasses.rock, 10,
     132            g_TileClasses.water, 3
     133        ],
     134        "sizes": ["tiny"],
     135        "mixes": ["same"],
     136        "amounts": ["scarce"]
     137    },
     138    {
     139        "func": addAnimals,
     140        "avoid": [
     141            g_TileClasses.bluff, 5,
     142            g_TileClasses.forest, 2,
     143            g_TileClasses.metal, 2,
     144            g_TileClasses.mountain, 1,
     145            g_TileClasses.player, 20,
     146            g_TileClasses.rock, 2,
     147            g_TileClasses.water, 3
     148        ],
     149        "sizes": ["tiny"],
     150        "mixes": ["same"],
     151        "amounts": ["scarce"]
     152    },
     153    {
     154        "func": addStragglerTrees,
     155        "avoid": [
     156            g_TileClasses.berries, 5,
     157            g_TileClasses.bluff, 5,
     158            g_TileClasses.forest, 7,
     159            g_TileClasses.metal, 2,
     160            g_TileClasses.mountain, 1,
     161            g_TileClasses.player, 12,
     162            g_TileClasses.rock, 2,
     163            g_TileClasses.water, 5
     164        ],
     165        "sizes": ["tiny"],
     166        "mixes": ["same"],
     167        "amounts": ["many"]
     168    }
     169]));
     170RMS.SetProgress(90);
     171
     172ExportMap();
  • binaries/data/mods/public/maps/random/ambush.json

     
     1{
     2  "settings" : {
     3    "Name" : "Ambush",
     4    "Script" : "ambush.js",
     5    "Description" : "High bluffs overlook the terrain below.  Bountiful resources await on the cliffs, but beware of enemies planning an ambush.",
     6    "BaseTerrain" : ["medit_sea_depths"],
     7    "BaseHeight" : 2,
     8        "Preview" : "ambush.png",
     9    "CircularMap" : true
     10  }
     11}
  • binaries/data/mods/public/maps/random/empire.js

     
     1RMS.LoadLibrary("rmgen");
     2InitMap();
     3
     4randomizeBiome();
     5initMapSettings();
     6initTileClasses();
     7
     8resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, randInt(5));
     9RMS.SetProgress(10);
     10
     11addBases("stronghold", 0.37, 0.04);
     12RMS.SetProgress(20);
     13
     14// Change the starting angle and add the players again
     15var rotation = PI;
     16
     17if (g_MapInfo.teams.length == 2)
     18    rotation = PI / 2;
     19
     20if (g_MapInfo.teams.length == 4)
     21    rotation = PI + PI / 4;
     22
     23g_MapInfo.startAngle = g_MapInfo.startAngle + rotation;
     24
     25addBases("stronghold", 0.15, 0.04);
     26RMS.SetProgress(40);
     27
     28addElements(shuffleArray([
     29    {
     30        "func": addHills,
     31        "avoid": [
     32            g_TileClasses.bluff, 5,
     33            g_TileClasses.hill, 15,
     34            g_TileClasses.mountain, 2,
     35            g_TileClasses.plateau, 5,
     36            g_TileClasses.player, 20,
     37            g_TileClasses.valley, 2,
     38            g_TileClasses.water, 2
     39        ],
     40        "sizes": g_AllSizes,
     41        "mixes": g_AllMixes,
     42        "amounts": ["tons"]
     43    },
     44    {
     45        "func": addMountains,
     46        "avoid": [
     47            g_TileClasses.bluff, 20,
     48            g_TileClasses.mountain, 25,
     49            g_TileClasses.plateau, 20,
     50            g_TileClasses.player, 20,
     51            g_TileClasses.valley, 10,
     52            g_TileClasses.water, 15
     53        ],
     54        "sizes": ["huge"],
     55        "mixes": ["same", "similar"],
     56        "amounts": ["tons"]
     57    },
     58    {
     59        "func": addPlateaus,
     60        "avoid": [
     61            g_TileClasses.bluff, 20,
     62            g_TileClasses.mountain, 25,
     63            g_TileClasses.plateau, 20,
     64            g_TileClasses.player, 40,
     65            g_TileClasses.valley, 10,
     66            g_TileClasses.water, 15
     67        ],
     68        "sizes": ["huge"],
     69        "mixes": ["same", "similar"],
     70        "amounts": ["tons"]
     71    }
     72]));
     73RMS.SetProgress(50);
     74
     75addElements([
     76    {
     77        "func": addLayeredPatches,
     78        "avoid": [
     79            g_TileClasses.bluff, 2,
     80            g_TileClasses.dirt, 5,
     81            g_TileClasses.forest, 2,
     82            g_TileClasses.mountain, 2,
     83            g_TileClasses.plateau, 2,
     84            g_TileClasses.player, 12,
     85            g_TileClasses.water, 3
     86        ],
     87        "sizes": ["normal"],
     88        "mixes": ["normal"],
     89        "amounts": ["normal"]
     90    },
     91    {
     92        "func": addDecoration,
     93        "avoid": [
     94            g_TileClasses.bluff, 2,
     95            g_TileClasses.forest, 2,
     96            g_TileClasses.mountain, 2,
     97            g_TileClasses.plateau, 2,
     98            g_TileClasses.player, 12,
     99            g_TileClasses.water, 3
     100        ],
     101        "sizes": ["normal"],
     102        "mixes": ["normal"],
     103        "amounts": ["normal"]
     104    }
     105]);
     106RMS.SetProgress(60);
     107
     108addElements(shuffleArray([
     109    {
     110        "func": addMetal,
     111        "avoid": [
     112            g_TileClasses.berries, 5,
     113            g_TileClasses.bluff, 5,
     114            g_TileClasses.forest, 3,
     115            g_TileClasses.mountain, 2,
     116            g_TileClasses.player, 30,
     117            g_TileClasses.rock, 10,
     118            g_TileClasses.metal, 20,
     119            g_TileClasses.plateau, 2,
     120            g_TileClasses.water, 3
     121        ],
     122        "sizes": ["normal"],
     123        "mixes": ["same"],
     124        "amounts": g_AllAmounts
     125    },
     126    {
     127        "func": addStone,
     128        "avoid": [g_TileClasses.berries, 5,
     129            g_TileClasses.bluff, 5,
     130            g_TileClasses.forest, 3,
     131            g_TileClasses.mountain, 2,
     132            g_TileClasses.player, 30,
     133            g_TileClasses.rock, 20,
     134            g_TileClasses.metal, 10,
     135            g_TileClasses.plateau, 2,
     136            g_TileClasses.water, 3
     137        ],
     138        "sizes": ["normal"],
     139        "mixes": ["same"],
     140        "amounts": g_AllAmounts
     141    },
     142    {
     143        "func": addForests,
     144        "avoid": [
     145            g_TileClasses.berries, 5,
     146            g_TileClasses.bluff, 5,
     147            g_TileClasses.forest, 18,
     148            g_TileClasses.metal, 3,
     149            g_TileClasses.mountain, 5,
     150            g_TileClasses.plateau, 2,
     151            g_TileClasses.player, 20,
     152            g_TileClasses.rock, 3,
     153            g_TileClasses.water, 2
     154        ],
     155        "sizes": g_AllSizes,
     156        "mixes": g_AllMixes,
     157        "amounts": ["few", "normal", "many", "tons"]
     158    }
     159]));
     160RMS.SetProgress(80);
     161
     162addElements(shuffleArray([
     163    {
     164        "func": addBerries,
     165        "avoid": [
     166            g_TileClasses.berries, 30,
     167            g_TileClasses.bluff, 5,
     168            g_TileClasses.forest, 5,
     169            g_TileClasses.metal, 10,
     170            g_TileClasses.mountain, 2,
     171            g_TileClasses.plateau, 2,
     172            g_TileClasses.player, 20,
     173            g_TileClasses.rock, 10,
     174            g_TileClasses.water, 3
     175        ],
     176        "sizes": g_AllSizes,
     177        "mixes": g_AllMixes,
     178        "amounts": g_AllAmounts
     179    },
     180    {
     181        "func": addAnimals,
     182        "avoid": [
     183            g_TileClasses.animals, 20,
     184            g_TileClasses.bluff, 5,
     185            g_TileClasses.forest, 2,
     186            g_TileClasses.metal, 2,
     187            g_TileClasses.mountain, 1,
     188            g_TileClasses.plateau, 2,
     189            g_TileClasses.player, 20,
     190            g_TileClasses.rock, 2,
     191            g_TileClasses.water, 3
     192        ],
     193        "sizes": g_AllSizes,
     194        "mixes": g_AllMixes,
     195        "amounts": g_AllAmounts
     196    },
     197    {
     198        "func": addStragglerTrees,
     199        "avoid": [
     200            g_TileClasses.berries, 5,
     201            g_TileClasses.bluff, 5,
     202            g_TileClasses.forest, 7,
     203            g_TileClasses.metal, 2,
     204            g_TileClasses.mountain, 1,
     205            g_TileClasses.plateau, 2,
     206            g_TileClasses.player, 12,
     207            g_TileClasses.rock, 2,
     208            g_TileClasses.water, 5
     209        ],
     210        "sizes": g_AllSizes,
     211        "mixes": g_AllMixes,
     212        "amounts": g_AllAmounts
     213    }
     214]));
     215RMS.SetProgress(90);
     216
     217ExportMap();
  • binaries/data/mods/public/maps/random/empire.json

     
     1{
     2  "settings" : {
     3    "Name" : "Empire",
     4    "Script" : "empire.js",
     5    "Description" : "A neighboring province has pledged alegiance to your rule.  It's up to you to command them to victory.",
     6    "BaseTerrain" : ["medit_sea_depths"],
     7    "BaseHeight" : 2,
     8    "Keywords": ["demo"],
     9    "Preview" : "empire.png",
     10    "CircularMap" : true
     11  }
     12}
  • binaries/data/mods/public/maps/random/frontier.js

     
     1RMS.LoadLibrary("rmgen");
     2InitMap();
     3
     4randomizeBiome();
     5initMapSettings();
     6initTileClasses();
     7
     8RMS.SetProgress(10);
     9
     10// Pick a random elevation with a bias towards lower elevations
     11var randElevation = randInt(30);
     12if (randElevation < 25)
     13    randElevation = 1 + randInt(4);
     14
     15resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, randElevation);
     16RMS.SetProgress(20);
     17
     18var pos = randomStartingPositionPattern();
     19addBases(pos.setup, pos.distance, pos.separation);
     20RMS.SetProgress(40);
     21
     22var features = [
     23    {
     24        "func": addBluffs,
     25        "avoid": [
     26            g_TileClasses.bluff, 20,
     27            g_TileClasses.hill, 10,
     28            g_TileClasses.mountain, 20,
     29            g_TileClasses.plateau, 15,
     30            g_TileClasses.player, 30,
     31            g_TileClasses.valley, 5,
     32            g_TileClasses.water, 7
     33        ],
     34        "sizes": g_AllSizes,
     35        "mixes": g_AllMixes,
     36        "amounts": g_AllAmounts
     37    },
     38    {
     39        "func": addHills,
     40        "avoid": [
     41            g_TileClasses.bluff, 5,
     42            g_TileClasses.hill, 15,
     43            g_TileClasses.mountain, 2,
     44            g_TileClasses.plateau, 15,
     45            g_TileClasses.player, 20,
     46            g_TileClasses.valley, 2,
     47            g_TileClasses.water, 2
     48        ],
     49        "sizes": g_AllSizes,
     50        "mixes": g_AllMixes,
     51        "amounts": g_AllAmounts
     52    },
     53    {
     54        "func": addMountains,
     55        "avoid": [
     56            g_TileClasses.bluff, 20,
     57            g_TileClasses.mountain, 25,
     58            g_TileClasses.plateau, 15,
     59            g_TileClasses.player, 20,
     60            g_TileClasses.valley, 10,
     61            g_TileClasses.water, 15
     62        ],
     63        "sizes": g_AllSizes,
     64        "mixes": g_AllMixes,
     65        "amounts": g_AllAmounts
     66    },
     67    {
     68        "func": addPlateaus,
     69        "avoid": [
     70            g_TileClasses.bluff, 20,
     71            g_TileClasses.mountain, 25,
     72            g_TileClasses.plateau, 25,
     73            g_TileClasses.plateau, 25,
     74            g_TileClasses.player, 40,
     75            g_TileClasses.valley, 10,
     76            g_TileClasses.water, 15
     77        ],
     78        "sizes": g_AllSizes,
     79        "mixes": g_AllMixes,
     80        "amounts": g_AllAmounts
     81    }
     82];
     83
     84if (randElevation < 4)
     85    features = features.push(
     86        {
     87            "func": addLakes,
     88            "avoid": [
     89                g_TileClasses.bluff, 7,
     90                g_TileClasses.hill, 2,
     91                g_TileClasses.mountain, 15,
     92                g_TileClasses.plateau, 10,
     93                g_TileClasses.player, 20,
     94                g_TileClasses.valley, 10,
     95                g_TileClasses.water, 25
     96            ],
     97            "sizes": g_AllSizes,
     98            "mixes": g_AllMixes,
     99            "amounts": g_AllAmounts
     100        }
     101    );
     102
     103if (randElevation > 20)
     104    features = features.push(
     105        {
     106            "func": addValleys,
     107            "avoid": [
     108                g_TileClasses.bluff, 5,
     109                g_TileClasses.hill, 5,
     110                g_TileClasses.mountain, 25,
     111                g_TileClasses.plateau, 20,
     112                g_TileClasses.player, 40,
     113                g_TileClasses.valley, 15,
     114                g_TileClasses.water, 10
     115            ],
     116            "sizes": g_AllSizes,
     117            "mixes": g_AllMixes,
     118            "amounts": g_AllAmounts
     119        }
     120    );
     121
     122addElements(shuffleArray(features));
     123RMS.SetProgress(50);
     124
     125addElements([
     126    {
     127        "func": addLayeredPatches,
     128        "avoid": [
     129            g_TileClasses.bluff, 2,
     130            g_TileClasses.dirt, 5,
     131            g_TileClasses.forest, 2,
     132            g_TileClasses.mountain, 2,
     133            g_TileClasses.plateau, 2,
     134            g_TileClasses.player, 12,
     135            g_TileClasses.water, 3
     136        ],
     137        "sizes": ["normal"],
     138        "mixes": ["normal"],
     139        "amounts": ["normal"]
     140    },
     141    {
     142        "func": addDecoration,
     143        "avoid": [
     144            g_TileClasses.bluff, 2,
     145            g_TileClasses.forest, 2,
     146            g_TileClasses.mountain, 2,
     147            g_TileClasses.plateau, 2,
     148            g_TileClasses.player, 12,
     149            g_TileClasses.water, 3
     150        ],
     151        "sizes": ["normal"],
     152        "mixes": ["normal"],
     153        "amounts": ["normal"]
     154    }
     155]);
     156RMS.SetProgress(60);
     157
     158addElements(shuffleArray([
     159    {
     160        "func": addMetal,
     161        "avoid": [
     162            g_TileClasses.berries, 5,
     163            g_TileClasses.bluff, 5,
     164            g_TileClasses.forest, 3,
     165            g_TileClasses.mountain, 2,
     166            g_TileClasses.plateau, 2,
     167            g_TileClasses.player, 30,
     168            g_TileClasses.rock, 10,
     169            g_TileClasses.metal, 20,
     170            g_TileClasses.water, 3
     171        ],
     172        "sizes": ["normal"],
     173        "mixes": ["same"],
     174        "amounts": g_AllAmounts
     175    },
     176    {
     177        "func": addStone,
     178        "avoid": [g_TileClasses.berries, 5,
     179            g_TileClasses.bluff, 5,
     180            g_TileClasses.forest, 3,
     181            g_TileClasses.mountain, 2,
     182            g_TileClasses.plateau, 2,
     183            g_TileClasses.player, 30,
     184            g_TileClasses.rock, 20,
     185            g_TileClasses.metal, 10,
     186            g_TileClasses.water, 3
     187        ],
     188        "sizes": ["normal"],
     189        "mixes": ["same"],
     190        "amounts": g_AllAmounts
     191    },
     192    {
     193        "func": addForests,
     194        "avoid": [
     195            g_TileClasses.berries, 5,
     196            g_TileClasses.bluff, 5,
     197            g_TileClasses.forest, 18,
     198            g_TileClasses.metal, 3,
     199            g_TileClasses.mountain, 5,
     200            g_TileClasses.plateau, 5,
     201            g_TileClasses.player, 20,
     202            g_TileClasses.rock, 3,
     203            g_TileClasses.water, 2
     204        ],
     205        "sizes": g_AllSizes,
     206        "mixes": g_AllMixes,
     207        "amounts": ["few", "normal", "many", "tons"]
     208    }
     209]));
     210RMS.SetProgress(70);
     211
     212addElements(shuffleArray([
     213    {
     214        "func": addBerries,
     215        "avoid": [
     216            g_TileClasses.berries, 30,
     217            g_TileClasses.bluff, 5,
     218            g_TileClasses.forest, 5,
     219            g_TileClasses.metal, 10,
     220            g_TileClasses.mountain, 2,
     221            g_TileClasses.plateau, 2,
     222            g_TileClasses.player, 20,
     223            g_TileClasses.rock, 10,
     224            g_TileClasses.water, 3
     225        ],
     226        "sizes": g_AllSizes,
     227        "mixes": g_AllMixes,
     228        "amounts": g_AllAmounts
     229    },
     230    {
     231        "func": addAnimals,
     232        "avoid": [
     233            g_TileClasses.animals, 20,
     234            g_TileClasses.bluff, 5,
     235            g_TileClasses.forest, 2,
     236            g_TileClasses.metal, 2,
     237            g_TileClasses.mountain, 1,
     238            g_TileClasses.plateau, 2,
     239            g_TileClasses.player, 20,
     240            g_TileClasses.rock, 2,
     241            g_TileClasses.water, 3
     242        ],
     243        "sizes": g_AllSizes,
     244        "mixes": g_AllMixes,
     245        "amounts": g_AllAmounts
     246    },
     247    {
     248        "func": addStragglerTrees,
     249        "avoid": [
     250            g_TileClasses.berries, 5,
     251            g_TileClasses.bluff, 5,
     252            g_TileClasses.forest, 7,
     253            g_TileClasses.metal, 2,
     254            g_TileClasses.mountain, 1,
     255            g_TileClasses.plateau, 2,
     256            g_TileClasses.player, 12,
     257            g_TileClasses.rock, 2,
     258            g_TileClasses.water, 5
     259        ],
     260        "sizes": g_AllSizes,
     261        "mixes": g_AllMixes,
     262        "amounts": g_AllAmounts
     263    }
     264]));
     265RMS.SetProgress(90);
     266
     267ExportMap();
  • binaries/data/mods/public/maps/random/frontier.json

     
     1{
     2  "settings" : {
     3    "Name" : "Frontier",
     4    "Script" : "frontier.js",
     5    "Description" : "A wild, unknown landscape awaits rival explorers.",
     6    "BaseTerrain" : ["medit_sea_depths"],
     7    "Preview" : "frontier.png",
     8    "BaseHeight" : 2,
     9    "CircularMap" : true
     10  }
     11}
  • binaries/data/mods/public/maps/random/harbor.js

     
     1RMS.LoadLibrary("rmgen");
     2
     3InitMap();
     4
     5randomizeBiome();
     6initMapSettings();
     7initTileClasses();
     8
     9resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 2);
     10RMS.SetProgress(10);
     11
     12var players = addBases("radial", 0.38);
     13RMS.SetProgress(20);
     14
     15addCenterLake();
     16RMS.SetProgress(30);
     17
     18if (g_MapInfo.mapSize >= 192)
     19{
     20    addHarbors(players);
     21    RMS.SetProgress(40);
     22}
     23
     24addSpines();
     25RMS.SetProgress(50);
     26
     27addElements(shuffleArray([
     28    {
     29        "func": addHills,
     30        "avoid": [
     31            g_TileClasses.bluff, 5,
     32            g_TileClasses.hill, 15,
     33            g_TileClasses.mountain, 2,
     34            g_TileClasses.plateau, 5,
     35            g_TileClasses.player, 20,
     36            g_TileClasses.spine, 5,
     37            g_TileClasses.valley, 2,
     38            g_TileClasses.water, 2
     39        ],
     40        "sizes": ["tiny", "small"],
     41        "mixes": g_AllMixes,
     42        "amounts": g_AllAmounts
     43    },
     44    {
     45        "func": addMountains,
     46        "avoid": [
     47            g_TileClasses.bluff, 20,
     48            g_TileClasses.mountain, 25,
     49            g_TileClasses.plateau, 20,
     50            g_TileClasses.player, 20,
     51            g_TileClasses.spine, 20,
     52            g_TileClasses.valley, 10,
     53            g_TileClasses.water, 15
     54        ],
     55        "sizes": ["small"],
     56        "mixes": g_AllMixes,
     57        "amounts": g_AllAmounts
     58    },
     59    {
     60        "func": addPlateaus,
     61        "avoid": [
     62            g_TileClasses.bluff, 20,
     63            g_TileClasses.mountain, 25,
     64            g_TileClasses.plateau, 20,
     65            g_TileClasses.player, 40,
     66            g_TileClasses.spine, 20,
     67            g_TileClasses.valley, 10,
     68            g_TileClasses.water, 15
     69        ],
     70        "sizes": ["small"],
     71        "mixes": g_AllMixes,
     72        "amounts": g_AllAmounts
     73    }
     74]));
     75RMS.SetProgress(60);
     76
     77addElements([
     78    {
     79        "func": addLayeredPatches,
     80        "avoid": [
     81            g_TileClasses.bluff, 2,
     82            g_TileClasses.dirt, 5,
     83            g_TileClasses.forest, 2,
     84            g_TileClasses.mountain, 2,
     85            g_TileClasses.plateau, 2,
     86            g_TileClasses.player, 12,
     87            g_TileClasses.spine, 5,
     88            g_TileClasses.water, 3
     89        ],
     90        "sizes": ["normal"],
     91        "mixes": ["normal"],
     92        "amounts": ["normal"]
     93    },
     94    {
     95        "func": addDecoration,
     96        "avoid": [
     97            g_TileClasses.bluff, 2,
     98            g_TileClasses.forest, 2,
     99            g_TileClasses.mountain, 2,
     100            g_TileClasses.plateau, 2,
     101            g_TileClasses.player, 12,
     102            g_TileClasses.spine, 5,
     103            g_TileClasses.water, 3
     104        ],
     105        "sizes": ["normal"],
     106        "mixes": ["normal"],
     107        "amounts": ["normal"]
     108    }
     109]);
     110RMS.SetProgress(70);
     111
     112addElements(shuffleArray([
     113    {
     114        "func": addBerries,
     115        "avoid": [
     116            g_TileClasses.berries, 30,
     117            g_TileClasses.bluff, 5,
     118            g_TileClasses.forest, 5,
     119            g_TileClasses.metal, 10,
     120            g_TileClasses.mountain, 2,
     121            g_TileClasses.plateau, 2,
     122            g_TileClasses.player, 20,
     123            g_TileClasses.rock, 10,
     124            g_TileClasses.spine, 2,
     125            g_TileClasses.water, 3
     126        ],
     127        "sizes": g_AllSizes,
     128        "mixes": g_AllMixes,
     129        "amounts": g_AllAmounts
     130    },
     131    {
     132        "func": addAnimals,
     133        "avoid": [
     134            g_TileClasses.animals, 20,
     135            g_TileClasses.bluff, 5,
     136            g_TileClasses.forest, 2,
     137            g_TileClasses.metal, 2,
     138            g_TileClasses.mountain, 1,
     139            g_TileClasses.plateau, 2,
     140            g_TileClasses.player, 20,
     141            g_TileClasses.rock, 2,
     142            g_TileClasses.spine, 2,
     143            g_TileClasses.water, 3
     144         ],
     145        "sizes": g_AllSizes,
     146        "mixes": g_AllMixes,
     147        "amounts": g_AllAmounts
     148    },
     149    {
     150        "func": addStragglerTrees,
     151        "avoid": [
     152            g_TileClasses.berries, 5,
     153            g_TileClasses.bluff, 5,
     154            g_TileClasses.forest, 7,
     155            g_TileClasses.metal, 2,
     156            g_TileClasses.mountain, 1,
     157            g_TileClasses.plateau, 2,
     158            g_TileClasses.player, 12,
     159            g_TileClasses.rock, 2,
     160            g_TileClasses.spine, 2,
     161            g_TileClasses.water, 5
     162         ],
     163        "sizes": g_AllSizes,
     164        "mixes": g_AllMixes,
     165        "amounts": g_AllAmounts
     166    }
     167]));
     168RMS.SetProgress(80);
     169
     170addElements(shuffleArray([
     171    {
     172        "func": addBerries,
     173        "avoid": [
     174            g_TileClasses.berries, 30,
     175            g_TileClasses.bluff, 5,
     176            g_TileClasses.forest, 5,
     177            g_TileClasses.metal, 10,
     178            g_TileClasses.mountain, 2,
     179            g_TileClasses.player, 20,
     180            g_TileClasses.rock, 10,
     181            g_TileClasses.spine, 2,
     182            g_TileClasses.water, 3
     183        ],
     184        "sizes": g_AllSizes,
     185        "mixes": g_AllMixes,
     186        "amounts": g_AllAmounts
     187    },
     188    {
     189        "func": addAnimals,
     190        "avoid": [
     191            g_TileClasses.animals, 20,
     192            g_TileClasses.bluff, 5,
     193            g_TileClasses.forest, 0,
     194            g_TileClasses.mountain, 1,
     195            g_TileClasses.player, 20,
     196            g_TileClasses.spine, 2,
     197            g_TileClasses.water, 3
     198        ],
     199        "sizes": g_AllSizes,
     200        "mixes": g_AllMixes,
     201        "amounts": g_AllAmounts
     202    },
     203    {
     204        "func": addStragglerTrees,
     205        "avoid": [
     206            g_TileClasses.berries, 5,
     207            g_TileClasses.bluff, 5,
     208            g_TileClasses.forest, 7,
     209            g_TileClasses.metal, 1,
     210            g_TileClasses.mountain, 1,
     211            g_TileClasses.player, 12,
     212            g_TileClasses.rock, 1,
     213            g_TileClasses.spine, 2,
     214            g_TileClasses.water, 5
     215        ],
     216        "sizes": g_AllSizes,
     217        "mixes": g_AllMixes,
     218        "amounts": ["normal", "many", "tons"]
     219    }
     220]));
     221RMS.SetProgress(90);
     222
     223ExportMap();
     224
     225function addCenterLake()
     226{
     227    var lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6))));
     228
     229    var placer = new ChainPlacer(2, Math.floor(scaleByMapSize(2, 12)), Math.floor(scaleByMapSize(35, 160)), 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap, 0, [floor(g_MapInfo.mapSize * 0.17 * lSize)]);
     230    var terrainPainter = new LayeredPainter([g_Terrains.shore, g_Terrains.water, g_Terrains.water], [1, 100]);
     231    var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -18, 10);
     232
     233    createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.water)], avoidClasses(g_TileClasses.player, 20));
     234
     235    var fDist = 50;
     236    if (g_MapInfo.mapSize <= 192)
     237        fDist = 20;
     238
     239    // create a bunch of fish
     240    var group = new SimpleGroup([new SimpleObject(g_Gaia.fish, 20, 30, 0, fDist)], true, g_TileClasses.baseResource, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap);
     241    createObjectGroup(group, 0, [avoidClasses(g_TileClasses.player, 5, g_TileClasses.hill, 3, g_TileClasses.mountain, 3), stayClasses(g_TileClasses.water, 5)]);
     242}
     243
     244function addHarbors(players)
     245{
     246    for (var i = 0; i < players.length; ++i)
     247    {
     248        var ix = round(fractionToTiles(players[i].x));
     249        var iz = round(fractionToTiles(players[i].z));
     250        var playerDistX = g_MapInfo.centerOfMap - ix;
     251        var playerDistZ = g_MapInfo.centerOfMap - iz;
     252        var offsetX = round(playerDistX / 2.5);
     253        var offsetZ = round(playerDistZ / 2.5);
     254
     255        var placer = new ClumpPlacer(scaleByMapSize(1200, 1200), 0.5, 0.5, 1, ix + offsetX, iz + offsetZ);
     256        var terrainPainter = new LayeredPainter([g_Terrains.shore, g_Terrains.water], [2]);
     257        var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, -11, 3);
     258
     259        createArea(
     260            placer,
     261            [
     262                terrainPainter,
     263                elevationPainter,
     264                paintClass(g_TileClasses.water)
     265            ],
     266            avoidClasses(
     267                g_TileClasses.player, 15,
     268                g_TileClasses.hill, 1
     269            )
     270        );
     271
     272        // create fish in harbor
     273        var group = new SimpleGroup(
     274            [new SimpleObject(g_Gaia.fish, 6, 6, 1, 20)],
     275            true, g_TileClasses.baseResource, ix + offsetX, iz + offsetZ
     276        );
     277
     278        createObjectGroup(group, 0, [
     279            avoidClasses(
     280                g_TileClasses.hill, 3,
     281                g_TileClasses.mountain, 3
     282            ),
     283            stayClasses(g_TileClasses.water, 5)
     284        ]);
     285    }
     286}
     287
     288function addSpines()
     289{
     290    var spineTile = g_Terrains.dirt;
     291    var elevation = 35;
     292
     293    if (g_MapInfo.biome == 2)
     294        spineTile = g_Terrains.tier1Terrain;
     295
     296    if (g_MapInfo.biome == 4 || g_MapInfo.biome == 6)
     297        spineTile = g_Terrains.tier2Terrain;
     298
     299    if (g_MapInfo.biome == 8)
     300        spineTile = g_Terrains.tier4Terrain;
     301
     302    var split = 1;
     303    if (g_MapInfo.numPlayers <= 3 || (g_MapInfo.mapSize >= 320 && g_MapInfo.numPlayers <= 4))
     304        split = 2;
     305
     306    for (var i = 0; i < g_MapInfo.numPlayers * split; ++i)
     307    {
     308        var tang = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / (g_MapInfo.numPlayers * split);
     309
     310        var fx = fractionToTiles(0.5);
     311        var fz = fractionToTiles(0.5);
     312        var ix = round(fx);
     313        var iz = round(fz);
     314
     315        var mStartCo = 0.12;
     316        var mStopCo = 0.40;
     317        var mSize = 0.5;
     318        var mWaviness = 0.6;
     319        var mOffset = 0.4;
     320        var mTaper = -1.4;
     321
     322        // make small mountain dividers if we're on a small map
     323        if (g_MapInfo.mapSize <= 192)
     324        {
     325            mSize = 0.02;
     326            mTaper = -0.1;
     327            elevation = 20;
     328        }
     329
     330        var placer = new PathPlacer(fractionToTiles(0.5 + mStartCo * cos(tang)), fractionToTiles(0.5 + mStartCo * sin(tang)), fractionToTiles(0.5 + mStopCo * cos(tang)), fractionToTiles(0.5 + mStopCo * sin(tang)), scaleByMapSize(14, mSize), mWaviness, 0.1, mOffset, mTaper);
     331        var terrainPainter = new LayeredPainter([g_Terrains.cliff, spineTile], [3]);
     332        var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, elevation, 3);
     333        createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.spine)], avoidClasses(g_TileClasses.player, 5));
     334    }
     335
     336    addElements([
     337        {
     338            "func": addDecoration,
     339            "avoid": [
     340                g_TileClasses.bluff, 2,
     341                g_TileClasses.forest, 2,
     342                g_TileClasses.mountain, 2,
     343                g_TileClasses.player, 12,
     344                g_TileClasses.water, 3
     345            ],
     346            "stay": [g_TileClasses.spine, 5],
     347            "sizes": ["normal"],
     348            "mixes": ["normal"],
     349            "amounts": ["normal"]
     350        }
     351    ]);
     352
     353    addElements([
     354        {
     355            "func": addProps,
     356            "avoid": [
     357                g_TileClasses.forest, 2,
     358                g_TileClasses.player, 2,
     359                g_TileClasses.prop, 20,
     360                g_TileClasses.water, 3
     361            ],
     362            "stay": [g_TileClasses.spine, 8],
     363            "sizes": ["normal"],
     364            "mixes": ["normal"],
     365            "amounts": ["scarce"]
     366        }
     367    ]);
     368}
  • binaries/data/mods/public/maps/random/harbor.json

     
     1{
     2  "settings" : {
     3    "Name" : "Harbor",
     4    "Script" : "harbor.js",
     5    "Description" : "Players start with some light fishing opportunities in the calm waters of a sheltered harbor. A large bounty of seafood lays beyond the protective cliffs in the deep ocean. Small passages at the base of the cliffs make for tight fighting and easy fortification. Will you fight your way through the narrow passageways or take to the sea?",
     6    "BaseTerrain" : ["medit_sea_depths"],
     7    "BaseHeight" : 2,
     8    "Preview" : "harbor.png",
     9    "Keywords": ["naval"],
     10    "CircularMap" : true
     11  }
     12}
  • binaries/data/mods/public/maps/random/hells_pass.js

     
     1RMS.LoadLibrary("rmgen");
     2InitMap();
     3
     4randomizeBiome();
     5initMapSettings();
     6initTileClasses();
     7
     8resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
     9RMS.SetProgress(10);
     10
     11addBases("line", 0.2, 0.08);
     12RMS.SetProgress(20);
     13
     14placeBarriers();
     15RMS.SetProgress(40);
     16
     17addElements(shuffleArray([
     18    {
     19        "func": addBluffs,
     20        "avoid": [
     21            g_TileClasses.bluff, 20,
     22            g_TileClasses.hill, 5,
     23            g_TileClasses.mountain, 20,
     24            g_TileClasses.plateau, 20,
     25            g_TileClasses.player, 30,
     26            g_TileClasses.spine, 15,
     27            g_TileClasses.valley, 5,
     28            g_TileClasses.water, 7
     29        ],
     30        "sizes": ["normal", "big"],
     31        "mixes": ["varied"],
     32        "amounts": ["few"]
     33    },
     34    {
     35        "func": addHills,
     36        "avoid": [
     37            g_TileClasses.bluff, 5,
     38            g_TileClasses.hill, 15,
     39            g_TileClasses.mountain, 2,
     40            g_TileClasses.plateau, 5,
     41            g_TileClasses.player, 20,
     42            g_TileClasses.spine, 15,
     43            g_TileClasses.valley, 2,
     44            g_TileClasses.water, 2
     45        ],
     46        "sizes": ["normal", "big"],
     47        "mixes": ["varied"],
     48        "amounts": ["few"]
     49    },
     50    {
     51        "func": addLakes,
     52        "avoid": [
     53            g_TileClasses.bluff, 7,
     54            g_TileClasses.hill, 2,
     55            g_TileClasses.mountain, 15,
     56            g_TileClasses.plateau, 10,
     57            g_TileClasses.player, 20,
     58            g_TileClasses.spine, 15,
     59            g_TileClasses.valley, 10,
     60            g_TileClasses.water, 25
     61        ],
     62        "sizes": ["big", "huge"],
     63        "mixes": ["varied", "unique"],
     64        "amounts": ["few"]
     65    }
     66]));
     67RMS.SetProgress(50);
     68
     69addElements([
     70    {
     71        "func": addLayeredPatches,
     72        "avoid": [g_TileClasses.bluff, 2,
     73            g_TileClasses.dirt, 5,
     74            g_TileClasses.forest, 2,
     75            g_TileClasses.mountain, 2,
     76            g_TileClasses.plateau, 2,
     77            g_TileClasses.player, 12,
     78            g_TileClasses.spine, 5,
     79            g_TileClasses.water, 3
     80            ],
     81        "sizes": ["normal"],
     82        "mixes": ["normal"],
     83        "amounts": ["normal"]
     84    },
     85    {
     86        "func": addDecoration,
     87        "avoid": [g_TileClasses.bluff, 2,
     88            g_TileClasses.forest, 2,
     89            g_TileClasses.mountain, 2,
     90            g_TileClasses.plateau, 2,
     91            g_TileClasses.player, 12,
     92            g_TileClasses.spine, 5,
     93            g_TileClasses.water, 3
     94            ],
     95        "sizes": ["normal"],
     96        "mixes": ["normal"],
     97        "amounts": ["normal"]
     98    }
     99]);
     100RMS.SetProgress(60);
     101
     102addElements(shuffleArray([
     103    {
     104        "func": addMetal,
     105        "avoid": [g_TileClasses.berries, 5,
     106            g_TileClasses.bluff, 5,
     107            g_TileClasses.forest, 3,
     108            g_TileClasses.mountain, 2,
     109            g_TileClasses.plateau, 2,
     110            g_TileClasses.player, 30,
     111            g_TileClasses.rock, 10,
     112            g_TileClasses.metal, 20,
     113            g_TileClasses.spine, 5,
     114            g_TileClasses.water, 3
     115            ],
     116        "sizes": ["normal"],
     117        "mixes": ["same"],
     118        "amounts": g_AllAmounts
     119    },
     120    {
     121        "func": addStone,
     122        "avoid": [
     123            g_TileClasses.berries, 5,
     124            g_TileClasses.bluff, 5,
     125            g_TileClasses.forest, 3,
     126            g_TileClasses.mountain, 2,
     127            g_TileClasses.plateau, 2,
     128            g_TileClasses.player, 30,
     129            g_TileClasses.rock, 20,
     130            g_TileClasses.metal, 10,
     131            g_TileClasses.spine, 5,
     132            g_TileClasses.water, 3
     133            ],
     134        "sizes": ["normal"],
     135        "mixes": ["same"],
     136        "amounts": g_AllAmounts
     137    },
     138    {
     139        "func": addForests,
     140        "avoid": [g_TileClasses.berries, 5,
     141            g_TileClasses.bluff, 5,
     142            g_TileClasses.forest, 18,
     143            g_TileClasses.metal, 3,
     144            g_TileClasses.mountain, 5,
     145            g_TileClasses.plateau, 5,
     146            g_TileClasses.player, 20,
     147            g_TileClasses.rock, 3,
     148            g_TileClasses.spine, 5,
     149            g_TileClasses.water, 2
     150            ],
     151        "sizes": g_AllSizes,
     152        "mixes": g_AllMixes,
     153        "amounts": ["few", "normal", "many", "tons"]
     154    }
     155]));
     156RMS.SetProgress(80);
     157
     158addElements(shuffleArray([
     159    {
     160        "func": addBerries,
     161        "avoid": [
     162            g_TileClasses.berries, 30,
     163            g_TileClasses.bluff, 5,
     164            g_TileClasses.forest, 5,
     165            g_TileClasses.metal, 10,
     166            g_TileClasses.mountain, 2,
     167            g_TileClasses.plateau, 2,
     168            g_TileClasses.player, 20,
     169            g_TileClasses.rock, 10,
     170            g_TileClasses.spine, 2,
     171            g_TileClasses.water, 3
     172        ],
     173        "sizes": g_AllSizes,
     174        "mixes": g_AllMixes,
     175        "amounts": g_AllAmounts
     176    },
     177    {
     178        "func": addAnimals,
     179        "avoid": [
     180            g_TileClasses.animals, 20,
     181            g_TileClasses.bluff, 5,
     182            g_TileClasses.forest, 2,
     183            g_TileClasses.metal, 2,
     184            g_TileClasses.mountain, 1,
     185            g_TileClasses.plateau, 2,
     186            g_TileClasses.player, 20,
     187            g_TileClasses.rock, 2,
     188            g_TileClasses.spine, 2,
     189            g_TileClasses.water, 3
     190        ],
     191        "sizes": g_AllSizes,
     192        "mixes": g_AllMixes,
     193        "amounts": g_AllAmounts
     194    },
     195    {
     196        "func": addStragglerTrees,
     197        "avoid": [
     198            g_TileClasses.berries, 5,
     199            g_TileClasses.bluff, 5,
     200            g_TileClasses.forest, 7,
     201            g_TileClasses.metal, 2,
     202            g_TileClasses.mountain, 1,
     203            g_TileClasses.plateau, 2,
     204            g_TileClasses.player, 12,
     205            g_TileClasses.rock, 2,
     206            g_TileClasses.spine, 2,
     207            g_TileClasses.water, 5
     208        ],
     209        "sizes": g_AllSizes,
     210        "mixes": g_AllMixes,
     211        "amounts": g_AllAmounts
     212    }
     213]));
     214RMS.SetProgress(90);
     215
     216ExportMap();
     217
     218// place the mountainous barriers between the teams
     219function placeBarriers()
     220{
     221    var spineTerrain = g_Terrains.dirt;
     222
     223    if (g_MapInfo.biome == 2)
     224        spineTerrain = g_Terrains.tier1Terrain;
     225
     226    if (g_MapInfo.biome == 4 || g_MapInfo.biome == 6)
     227        spineTerrain = g_Terrains.tier2Terrain;
     228
     229    if (g_MapInfo.biome == 8)
     230        spineTerrain = g_Terrains.tier4Terrain;
     231
     232    // create mountain ranges
     233    for (var i = 0; i < g_MapInfo.teams.length; ++i)
     234    {
     235        var tang = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / g_MapInfo.teams.length;
     236
     237        var fx = fractionToTiles(0.5);
     238        var fz = fractionToTiles(0.5);
     239        var ix = round(fx);
     240        var iz = round(fz);
     241
     242        var mStartCo = 0.07;
     243        var mStopCo = 0.42;
     244        var mSize = 8;
     245        var mWaviness = 0.6;
     246        var mOffset = 0.5;
     247        var mTaper = -1.5;
     248
     249        if (g_MapInfo.teams.length > 3 || g_MapInfo.mapSize <= 192)
     250        {
     251            mWaviness = 0.2;
     252            mOffset = 0.2;
     253            mTaper = -1;
     254        }
     255
     256        if (g_MapInfo.teams.length >= 5)
     257        {
     258            mSize = 4;
     259            mWaviness = 0.2;
     260            mOffset = 0.2;
     261            mTaper = -0.7;
     262        }
     263
     264        // place barrier
     265        var placer = new PathPlacer(fractionToTiles(0.5 + mStartCo * cos(tang)), fractionToTiles(0.5 + mStartCo * sin(tang)), fractionToTiles(0.5 + mStopCo * cos(tang)), fractionToTiles(0.5 + mStopCo * sin(tang)), scaleByMapSize(14, mSize), mWaviness, 0.1, mOffset, mTaper);
     266        var terrainPainter = new LayeredPainter([g_Terrains.cliff, spineTerrain], [2]);
     267        var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 30, 2);
     268        createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.spine)], avoidClasses(g_TileClasses.player, 5, g_TileClasses.baseResource, 5));
     269    }
     270
     271    addElements([
     272        {
     273            "func": addDecoration,
     274            "avoid": [
     275                g_TileClasses.bluff, 2,
     276                g_TileClasses.forest, 2,
     277                g_TileClasses.mountain, 2,
     278                g_TileClasses.player, 12,
     279                g_TileClasses.water, 3
     280            ],
     281            "stay": [g_TileClasses.spine, 5],
     282            "sizes": ["huge"],
     283            "mixes": ["unique"],
     284            "amounts": ["tons"]
     285        }
     286    ]);
     287
     288    addElements([
     289        {
     290            "func": addProps,
     291            "avoid": [
     292                g_TileClasses.forest, 2,
     293                g_TileClasses.player, 2,
     294                g_TileClasses.prop, 20,
     295                g_TileClasses.water, 3
     296            ],
     297            "stay": [g_TileClasses.spine, 8],
     298            "sizes": ["normal"],
     299            "mixes": ["normal"],
     300            "amounts": ["scarce"]
     301        }
     302    ]);
     303}
  • binaries/data/mods/public/maps/random/hells_pass.json

     
     1{
     2  "settings" : {
     3    "Name" : "Hell's Pass",
     4    "Script" : "hells_pass.js",
     5    "Description" : "A narrow pass between steep mountains promotes tight, defensive combat. With bountiful resources far from the front-lines, teams may choose to support their exposed teammates financially, or retreat to more fertile, but less defensible ground.",
     6    "BaseTerrain" : ["medit_sea_depths"],
     7    "BaseHeight" : 1,
     8    "Preview" : "hells_pass.png",
     9    "CircularMap" : true
     10  }
     11}
  • binaries/data/mods/public/maps/random/lions_den.js

     
     1RMS.LoadLibrary("rmgen");
     2InitMap();
     3
     4randomizeBiome();
     5initMapSettings();
     6initTileClasses(["step"]);
     7
     8var topTerrain = g_Terrains.tier2Terrain;
     9
     10resetTerrain(topTerrain, g_TileClasses.land, 50);
     11RMS.SetProgress(10);
     12
     13var players = addBases("radial", 0.4, randFloat(0.05, 0.1));
     14RMS.SetProgress(20);
     15
     16createSunkenTerrain(players);
     17RMS.SetProgress(30);
     18
     19addElements([
     20    {
     21        "func": addLayeredPatches,
     22        "avoid": [
     23            g_TileClasses.dirt, 5,
     24            g_TileClasses.forest, 2,
     25            g_TileClasses.mountain, 2,
     26            g_TileClasses.player, 12,
     27            g_TileClasses.step, 5
     28        ],
     29        "stay": [g_TileClasses.valley, 7],
     30        "sizes": ["normal"],
     31        "mixes": ["normal"],
     32        "amounts": ["normal"]
     33    },
     34    {
     35        "func": addLayeredPatches,
     36        "avoid": [
     37            g_TileClasses.dirt, 5,
     38            g_TileClasses.forest, 2,
     39            g_TileClasses.mountain, 2,
     40            g_TileClasses.player, 12
     41        ],
     42        "stay": [g_TileClasses.settlement, 7],
     43        "sizes": ["normal"],
     44        "mixes": ["normal"],
     45        "amounts": ["normal"]
     46    },
     47    {
     48        "func": addLayeredPatches,
     49        "avoid": [
     50            g_TileClasses.dirt, 5,
     51            g_TileClasses.forest, 2
     52        ],
     53        "stay": [g_TileClasses.player, 1],
     54        "sizes": ["normal"],
     55        "mixes": ["normal"],
     56        "amounts": ["normal"]
     57    },
     58    {
     59        "func": addDecoration,
     60        "avoid": [g_TileClasses.forest, 2],
     61        "stay": [g_TileClasses.player, 1],
     62        "sizes": ["normal"],
     63        "mixes": ["normal"],
     64        "amounts": ["normal"]
     65    },
     66    {
     67        "func": addDecoration,
     68        "avoid": [
     69            g_TileClasses.forest, 2,
     70            g_TileClasses.mountain, 2,
     71            g_TileClasses.player, 12,
     72            g_TileClasses.step, 2
     73         ],
     74        "stay": [g_TileClasses.valley, 7],
     75        "sizes": ["normal"],
     76        "mixes": ["normal"],
     77        "amounts": ["normal"]
     78    },
     79    {
     80        "func": addDecoration,
     81        "avoid": [
     82            g_TileClasses.forest, 2,
     83            g_TileClasses.mountain, 2,
     84            g_TileClasses.player, 12
     85        ],
     86        "stay": [g_TileClasses.settlement, 7],
     87        "sizes": ["normal"],
     88        "mixes": ["normal"],
     89        "amounts": ["normal"]
     90    },
     91    {
     92        "func": addDecoration,
     93        "avoid": [
     94            g_TileClasses.forest, 2,
     95            g_TileClasses.mountain, 2,
     96            g_TileClasses.player, 12
     97        ],
     98        "stay": [g_TileClasses.step, 7],
     99        "sizes": ["normal"],
     100        "mixes": ["normal"],
     101        "amounts": ["scarce"]
     102    }
     103]);
     104RMS.SetProgress(40);
     105
     106addElements(shuffleArray([
     107    {
     108        "func": addMetal,
     109        "avoid": [
     110            g_TileClasses.berries, 5,
     111            g_TileClasses.forest, 3,
     112            g_TileClasses.player, 30,
     113            g_TileClasses.rock, 10,
     114            g_TileClasses.metal, 20
     115        ],
     116        "stay": [g_TileClasses.settlement, 7],
     117        "sizes": ["normal"],
     118        "mixes": ["same"],
     119        "amounts": ["tons"]
     120    },
     121    {
     122        "func": addMetal,
     123        "avoid": [
     124            g_TileClasses.berries, 5,
     125            g_TileClasses.forest, 3,
     126            g_TileClasses.player, 10,
     127            g_TileClasses.rock, 10,
     128            g_TileClasses.metal, 20,
     129            g_TileClasses.mountain, 5,
     130            g_TileClasses.step, 5
     131        ],
     132        "stay": [g_TileClasses.valley, 7],
     133        "sizes": ["normal"],
     134        "mixes": ["same"],
     135        "amounts": g_AllAmounts
     136    },
     137    {
     138        "func": addStone,
     139        "avoid": [
     140            g_TileClasses.berries, 5,
     141            g_TileClasses.forest, 3,
     142            g_TileClasses.player, 30,
     143            g_TileClasses.rock, 20,
     144            g_TileClasses.metal, 10
     145        ],
     146        "stay": [g_TileClasses.settlement, 7],
     147        "sizes": ["normal"],
     148        "mixes": ["same"],
     149        "amounts": ["tons"]
     150    },
     151    {
     152        "func": addStone,
     153        "avoid": [
     154            g_TileClasses.berries, 5,
     155            g_TileClasses.forest, 3,
     156            g_TileClasses.player, 10,
     157            g_TileClasses.rock, 20,
     158            g_TileClasses.metal, 10,
     159            g_TileClasses.mountain, 5,
     160            g_TileClasses.step, 5
     161        ],
     162        "stay": [g_TileClasses.valley, 7],
     163        "sizes": ["normal"],
     164        "mixes": ["same"],
     165        "amounts": g_AllAmounts
     166    },
     167    {
     168        "func": addForests,
     169        "avoid": [
     170            g_TileClasses.berries, 5,
     171            g_TileClasses.forest, 18,
     172            g_TileClasses.metal, 3,
     173            g_TileClasses.player, 20,
     174            g_TileClasses.rock, 3
     175        ],
     176        "stay": [g_TileClasses.settlement, 7],
     177        "sizes": ["normal", "big"],
     178        "mixes": ["same"],
     179        "amounts": ["tons"]
     180    },
     181    {
     182        "func": addForests,
     183        "avoid": [
     184            g_TileClasses.berries, 3,
     185            g_TileClasses.forest, 18,
     186            g_TileClasses.metal, 3,
     187            g_TileClasses.mountain, 5,
     188            g_TileClasses.player, 5,
     189            g_TileClasses.rock, 3,
     190            g_TileClasses.step, 1
     191        ],
     192        "stay": [g_TileClasses.valley, 7],
     193        "sizes": ["normal", "big"],
     194        "mixes": ["same"],
     195        "amounts": ["tons"]
     196    }
     197]));
     198RMS.SetProgress(60);
     199
     200addElements(shuffleArray([
     201    {
     202        "func": addBerries,
     203        "avoid": [
     204            g_TileClasses.berries, 30,
     205            g_TileClasses.forest, 5,
     206            g_TileClasses.metal, 10,
     207            g_TileClasses.player, 20,
     208            g_TileClasses.rock, 10
     209        ],
     210        "stay": [g_TileClasses.settlement, 7],
     211        "sizes": g_AllSizes,
     212        "mixes": g_AllMixes,
     213        "amounts": ["tons"]
     214    },
     215    {
     216        "func": addBerries,
     217        "avoid": [
     218            g_TileClasses.berries, 30,
     219            g_TileClasses.forest, 5,
     220            g_TileClasses.metal, 10,
     221            g_TileClasses.mountain, 5,
     222            g_TileClasses.player, 10,
     223            g_TileClasses.rock, 10,
     224            g_TileClasses.step, 5
     225        ],
     226        "stay": [g_TileClasses.valley, 7],
     227        "sizes": g_AllSizes,
     228        "mixes": g_AllMixes,
     229        "amounts": g_AllAmounts
     230    },
     231    {
     232        "func": addAnimals,
     233        "avoid": [
     234            g_TileClasses.animals, 20,
     235            g_TileClasses.forest, 0,
     236            g_TileClasses.metal, 1,
     237            g_TileClasses.player, 20,
     238            g_TileClasses.rock, 1
     239        ],
     240        "stay": [g_TileClasses.settlement, 7],
     241        "sizes": g_AllSizes,
     242        "mixes": g_AllMixes,
     243        "amounts": ["tons"]
     244    },
     245    {
     246        "func": addAnimals,
     247        "avoid": [
     248            g_TileClasses.animals, 20,
     249            g_TileClasses.forest, 0,
     250            g_TileClasses.metal, 1,
     251            g_TileClasses.mountain, 5,
     252            g_TileClasses.player, 10,
     253            g_TileClasses.rock, 1,
     254            g_TileClasses.step, 5
     255        ],
     256        "stay": [g_TileClasses.valley, 7],
     257        "sizes": g_AllSizes,
     258        "mixes": g_AllMixes,
     259        "amounts": g_AllAmounts
     260    },
     261    {
     262        "func": addStragglerTrees,
     263        "avoid": [
     264            g_TileClasses.berries, 5,
     265            g_TileClasses.forest, 7,
     266            g_TileClasses.metal, 3,
     267            g_TileClasses.player, 12,
     268            g_TileClasses.rock, 3
     269        ],
     270        "stay": [g_TileClasses.settlement, 7],
     271        "sizes": g_AllSizes,
     272        "mixes": g_AllMixes,
     273        "amounts": ["tons"]
     274    },
     275    {
     276        "func": addStragglerTrees,
     277        "avoid": [
     278            g_TileClasses.berries, 5,
     279            g_TileClasses.forest, 7,
     280            g_TileClasses.metal, 3,
     281            g_TileClasses.mountain, 5,
     282            g_TileClasses.player, 10,
     283            g_TileClasses.rock, 3,
     284            g_TileClasses.step, 5
     285        ],
     286        "stay": [g_TileClasses.valley, 7],
     287        "sizes": g_AllSizes,
     288        "mixes": g_AllMixes,
     289        "amounts": ["normal", "many", "tons"]
     290    },
     291    {
     292        "func": addStragglerTrees,
     293        "avoid": [
     294            g_TileClasses.berries, 5,
     295            g_TileClasses.forest, 3,
     296            g_TileClasses.metal, 5,
     297            g_TileClasses.rock, 5
     298        ],
     299        "stay": [g_TileClasses.player, 1],
     300        "sizes": ["huge"],
     301        "mixes": ["same"],
     302        "amounts": ["tons"]
     303    }
     304]));
     305RMS.SetProgress(75);
     306
     307addElements([
     308    {
     309        "func": addDecoration,
     310        "avoid": [
     311            g_TileClasses.valley, 4,
     312            g_TileClasses.player, 4,
     313            g_TileClasses.settlement, 4,
     314            g_TileClasses.step, 4
     315        ],
     316        "stay": [g_TileClasses.land, 2],
     317        "sizes": ["normal"],
     318        "mixes": ["normal"],
     319        "amounts": ["tons"]
     320    }
     321]);
     322RMS.SetProgress(80);
     323
     324addElements([
     325    {
     326        "func": addProps,
     327        "avoid": [
     328            g_TileClasses.valley, 4,
     329            g_TileClasses.player, 4,
     330            g_TileClasses.settlement, 4,
     331            g_TileClasses.step, 4
     332        ],
     333        "stay": [g_TileClasses.land, 2],
     334        "sizes": ["normal"],
     335        "mixes": ["normal"],
     336        "amounts": ["scarce"]
     337    }
     338]);
     339RMS.SetProgress(85);
     340
     341addElements([
     342    {
     343        "func": addDecoration,
     344        "avoid": [
     345            g_TileClasses.player, 4,
     346            g_TileClasses.settlement, 4,
     347            g_TileClasses.step, 4
     348        ],
     349        "stay": [g_TileClasses.mountain, 2],
     350        "sizes": ["normal"],
     351        "mixes": ["normal"],
     352        "amounts": ["tons"]
     353    }
     354]);
     355RMS.SetProgress(90);
     356
     357addElements([
     358    {
     359        "func": addProps,
     360        "avoid": [
     361            g_TileClasses.player, 4,
     362            g_TileClasses.settlement, 4,
     363            g_TileClasses.step, 4
     364        ],
     365        "stay": [g_TileClasses.mountain, 2],
     366        "sizes": ["normal"],
     367        "mixes": ["normal"],
     368        "amounts": ["scarce"]
     369    }
     370]);
     371RMS.SetProgress(95);
     372
     373ExportMap();
     374
     375// Create the sunken terrain
     376function createSunkenTerrain(players)
     377{
     378    var base = g_Terrains.mainTerrain;
     379    var middle = g_Terrains.dirt;
     380    var lower = g_Terrains.tier2Terrain;
     381    var road = g_Terrains.road;
     382
     383    if (g_MapInfo.biome == 2)
     384    {
     385        middle = g_Terrains.tier2Terrain;
     386        lower = g_Terrains.tier1Terrain;
     387    }
     388
     389    if (g_MapInfo.biome == 4)
     390    {
     391        middle = g_Terrains.shore;
     392        lower = g_Terrains.tier4Terrain;
     393    }
     394
     395    if (g_MapInfo.biome == 5)
     396    {
     397        middle = g_Terrains.tier1Terrain;
     398        lower = g_Terrains.forestFloor1;
     399    }
     400
     401    if (g_MapInfo.biome == 6)
     402    {
     403        middle = g_Terrains.tier2Terrain;
     404        lower = g_Terrains.tier4Terrain;
     405    }
     406
     407    if (g_MapInfo.biome == 7 || g_MapInfo.biome == 8)
     408        road = g_Terrains.roadWild;
     409
     410    if (g_MapInfo.biome == 8)
     411        middle = g_Terrains.shore;
     412
     413    var expSize = g_MapInfo.mapArea * 0.015 / (g_MapInfo.numPlayers / 4);
     414    var expDist = 0.1 + (g_MapInfo.numPlayers / 200);
     415    if (g_MapInfo.numPlayers == 2)
     416        expSize = g_MapInfo.mapArea * 0.015 / 0.7;
     417
     418    var nRoad = 0.44;
     419    var nExp = 0.425;
     420
     421    if (g_MapInfo.numPlayers < 4)
     422    {
     423        nRoad = 0.42;
     424        nExp = 0.4;
     425    }
     426
     427    // Create central valley
     428    var placer = new ClumpPlacer(g_MapInfo.mapArea * 0.26, 1, 1, 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap);
     429    var terrainPainter = new LayeredPainter([g_Terrains.cliff, lower], [3]);
     430    var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 0, 3);
     431    createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.valley)]);
     432
     433    // Create the center hill
     434    var placer = new ClumpPlacer(g_MapInfo.mapArea * 0.14, 1, 1, 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap);
     435    var terrainPainter = new LayeredPainter([g_Terrains.cliff, topTerrain], [3]);
     436    var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, g_MapInfo.mapHeight, 3);
     437    createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.mountain)]);
     438
     439    for(var i = 0; i < players.length; ++i)
     440    {
     441        var playerAngle = g_MapInfo.startAngle + i * TWO_PI / g_MapInfo.numPlayers;
     442        var pX = round(fractionToTiles(0.5 + 0.4 * cos(playerAngle)));
     443        var pZ = round(fractionToTiles(0.5 + 0.4 * sin(playerAngle)));
     444        var expX = round(fractionToTiles(0.5 + expDist * cos(g_MapInfo.startAngle + (i + 0.75) * TWO_PI / g_MapInfo.numPlayers)));
     445        var expZ = round(fractionToTiles(0.5 + expDist * sin(g_MapInfo.startAngle + (i + 0.75) * TWO_PI / g_MapInfo.numPlayers)));
     446        var rearX = round(fractionToTiles(0.5 + 0.47 * cos(playerAngle)));
     447        var rearZ = round(fractionToTiles(0.5 + 0.47 * sin(playerAngle)));
     448        var prePlayerAngle = g_MapInfo.startAngle + (i - 0.5) * TWO_PI / g_MapInfo.numPlayers;
     449        var preX = round(fractionToTiles(0.5 + nRoad * cos(prePlayerAngle)));
     450        var preZ = round(fractionToTiles(0.5 + nRoad * sin(prePlayerAngle)));
     451        var nextPlayerAngle = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / g_MapInfo.numPlayers;
     452        var nextX = round(fractionToTiles(0.5 + nRoad * cos(nextPlayerAngle)));
     453        var nextZ = round(fractionToTiles(0.5 + nRoad * sin(nextPlayerAngle)));
     454
     455        // Create path to expansion
     456        var placer = new PathPlacer(pX, pZ, expX, expZ, scaleByMapSize(12, 12), 0.7, 0.5, 0.1, -1);
     457        var terrainPainter = new LayeredPainter([g_Terrains.cliff, middle, road], [3, 4]);
     458        var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 10, 3);
     459        createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.step)]);
     460
     461        // Create path to neighbor
     462        var placer = new PathPlacer(rearX, rearZ, nextX, nextZ, scaleByMapSize(19, 19), 0.4, 0.5, 0.1, -0.6);
     463        var terrainPainter = new LayeredPainter([g_Terrains.cliff, middle, road], [3, 6]);
     464        var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 10, 3);
     465        createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.step)]);
     466
     467        // Create path to neighbor
     468        var placer = new PathPlacer(rearX, rearZ, preX, preZ, scaleByMapSize(19, 19), 0.4, 0.5, 0.1, -0.6);
     469        var terrainPainter = new LayeredPainter([g_Terrains.cliff, middle, road], [3, 6]);
     470        var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 10, 3);
     471        createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.step)]);
     472
     473        // Create the den
     474        var placer = new ClumpPlacer(g_MapInfo.mapArea * 0.03, 0.9, 0.3, 1, pX, pZ);
     475        var terrainPainter = new LayeredPainter([g_Terrains.cliff, base], [3]);
     476        var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 15, 3);
     477        createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.valley)]);
     478
     479        // Create the expansion
     480        var placer = new ClumpPlacer(expSize, 0.9, 0.3, 1, expX, expZ);
     481        var terrainPainter = new LayeredPainter([g_Terrains.cliff, base], [3]);
     482        var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 15, 3);
     483        var area = createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.settlement)], [avoidClasses(g_TileClasses.settlement, 2)]);
     484        var unpainter = new TileClassUnPainter(new TileClass(g_MapInfo.mapSize, g_TileClasses.mountain));
     485        unpainter.paint(area);
     486    }
     487
     488    // Create the neighbor expansions
     489    for (var i = 0; i < g_MapInfo.numPlayers; ++i)
     490    {
     491        var nextPlayerAngle = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / g_MapInfo.numPlayers;
     492        var nextX = round(fractionToTiles(0.5 + nExp * cos(nextPlayerAngle)));
     493        var nextZ = round(fractionToTiles(0.5 + nExp * sin(nextPlayerAngle)));
     494
     495        // Create the neightbor expansion
     496        var placer = new ClumpPlacer(expSize, 0.9, 0.3, 1, nextX, nextZ);
     497        var terrainPainter = new LayeredPainter([g_Terrains.cliff, lower], [3]);
     498        var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 0, 3);
     499        var area = createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.settlement)]);
     500    }
     501}
  • binaries/data/mods/public/maps/random/lions_den.json

     
     1{
     2  "settings" : {
     3    "Name" : "Lion's Den",
     4    "Script" : "lions_den.js",
     5    "Description" : "High cliffs protect a player's main base. Venturing into the unknown can be risky, but necessary.",
     6    "BaseTerrain" : ["medit_sea_depths"],
     7    "BaseHeight" : 50,
     8    "Preview" : "lions_den.png",
     9    "Keywords": ["demo"],
     10    "CircularMap" : true
     11  }
     12}
  • binaries/data/mods/public/maps/random/rmgen/gaia.js

     
     1const g_Props = {
     2    "barrels": "actor|props/special/eyecandy/barrels_buried.xml",
     3    "crate": "actor|props/special/eyecandy/crate_a.xml",
     4    "cart": "actor|props/special/eyecandy/handcart_1_broken.xml",
     5    "well": "actor|props/special/eyecandy/well_1_c.xml",
     6    "skeleton": "actor|props/special/eyecandy/skeleton.xml",
     7    "blood": "actor|props/units/blood_01.xml",
     8    "bigBlood": "actor|props/units/blood_whale.xml"
     9};
     10
     11const g_DefaultDeviation = 0.1;
     12
     13/**
     14 * Create bluffs, i.e. a slope hill reachable from ground level.
     15 * Fill it with wood, mines, animals and decoratives.
     16 *
     17 * @param {Array} constraint - where to place them
     18 * @param {number} size - size of the bluffs (1.2 would be 120% of normal)
     19 * @param {number} deviation - degree of deviation from the defined size (0.2 would be 20% plus/minus)
     20 * @param {number} fill - size of map to fill (1.5 would be 150% of normal)
     21 */
     22function addBluffs(constraint, size, deviation, fill)
     23{
     24    deviation = deviation || g_DefaultDeviation;
     25    size = size || 1;
     26    fill = fill || 1;
     27
     28    var count = fill * scaleByMapSize(15, 15);
     29    var minSize = scaleByMapSize(5, 5);
     30    var maxSize = scaleByMapSize(7, 7);
     31    var elevation = 30;
     32    var spread = scaleByMapSize(100, 100);
     33
     34    for (var i = 0; i < count; ++i)
     35    {
     36        var offset = getRandomDeviation(size, deviation);
     37
     38        var pMinSize = Math.floor(minSize * offset);
     39        var pMaxSize = Math.floor(maxSize * offset);
     40        var pSpread = Math.floor(spread * offset);
     41        var pElevation = Math.floor(elevation * offset);
     42
     43        var placer = new ChainPlacer(pMinSize, pMaxSize, pSpread, 0.5);
     44        var terrainPainter = new LayeredPainter([g_Terrains.cliff, g_Terrains.mainTerrain, g_Terrains.tier2Terrain], [2, 3]);
     45        var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, pElevation, 2);
     46        var rendered = createAreas(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.bluff)], constraint, 1);
     47
     48        // Find the bounding box of the bluff
     49        if (rendered[0] === undefined)
     50            continue;
     51
     52        var points = rendered[0].points;
     53
     54        var corners = findCorners(points);
     55        var area = points.length;
     56
     57        // Seed an array the size of the bounding box
     58        var bb = createBoundingBox(points, corners);
     59
     60        // Get a random starting position for the baseline and the endline
     61        var angle = randInt(4);
     62        var opAngle = angle - 2;
     63        if (angle < 2)
     64            opAngle = angle + 2;
     65
     66        // Find the edges of the bluff
     67        var baseLine;
     68        var endLine;
     69
     70        // If we can't access the bluff, try different angles
     71        var retries = 0;
     72        var bluffCat = 2;
     73        while (bluffCat != 0 && retries < 5)
     74        {
     75            baseLine = findClearLine(bb, corners, angle);
     76            endLine = findClearLine(bb, corners, opAngle);
     77
     78            bluffCat = unreachableBluff(bb, corners, baseLine, endLine);
     79            ++angle;
     80            if (angle > 3)
     81                angle = 0;
     82
     83            opAngle = angle - 2;
     84            if (angle < 2)
     85                opAngle = angle + 2;
     86
     87            ++retries;
     88        }
     89
     90        // Found a bluff that can't be accessed, so turn it into a plateau
     91        if (retries == 5)
     92            removeBluff(points);
     93
     94        // If we couldn't find the slope lines, turn it into a plateau
     95        if (bluffCat == 1)
     96            continue;
     97
     98        var ground = createTerrain(g_Terrains.mainTerrain);
     99
     100        var slopeLength = getDistance(baseLine.midX, baseLine.midZ, endLine.midX, endLine.midZ);
     101
     102        // Adjust the height of each point in the bluff
     103        for (var p = 0; p < points.length; ++p)
     104        {
     105            var pt = points[p];
     106            var dist = distanceOfPointFromLine(baseLine.x1, baseLine.z1, baseLine.x2, baseLine.z2, pt.x, pt.z);
     107
     108            var curHeight = g_Map.getHeight(pt.x, pt.z);
     109            var newHeight = curHeight - curHeight * (dist / slopeLength) - 2;
     110
     111            newHeight = Math.max(newHeight, endLine.height);
     112
     113            if (newHeight <= endLine.height + 2 && g_Map.validT(pt.x, pt.z) && g_Map.getTexture(pt.x, pt.z).indexOf('cliff') > -1)
     114                ground.place(pt.x, pt.z);
     115
     116            g_Map.setHeight(pt.x, pt.z, newHeight);
     117        }
     118
     119        // Smooth out the ground around the bluff
     120        fadeToGround(bb, corners.minX, corners.minZ, endLine.height);
     121    }
     122
     123    addElements([
     124        {
     125            "func": addHills,
     126            "avoid": [
     127                g_TileClasses.hill, 3,
     128                g_TileClasses.player, 20,
     129                g_TileClasses.valley, 2,
     130                g_TileClasses.water, 2
     131            ],
     132            "stay": [g_TileClasses.bluff, 3],
     133            "sizes": g_AllSizes,
     134            "mixes": g_AllMixes,
     135            "amounts": g_AllAmounts
     136        }
     137    ]);
     138
     139    addElements([
     140        {
     141            "func": addLayeredPatches,
     142            "avoid": [
     143                g_TileClasses.dirt, 5,
     144                g_TileClasses.forest, 2,
     145                g_TileClasses.mountain, 2,
     146                g_TileClasses.player, 12,
     147                g_TileClasses.water, 3
     148            ],
     149            "stay": [g_TileClasses.bluff, 5],
     150            "sizes": ["normal"],
     151            "mixes": ["normal"],
     152            "amounts": ["normal"]
     153        }
     154    ]);
     155
     156    addElements([
     157        {
     158            "func": addDecoration,
     159            "avoid": [
     160                g_TileClasses.forest, 2,
     161                g_TileClasses.player, 12,
     162                g_TileClasses.water, 3
     163            ],
     164            "stay": [g_TileClasses.bluff, 5],
     165            "sizes": ["normal"],
     166            "mixes": ["normal"],
     167            "amounts": ["normal"]
     168        }
     169    ]);
     170
     171    addElements([
     172        {
     173            "func": addProps,
     174            "avoid": [
     175                g_TileClasses.forest, 2,
     176                g_TileClasses.player, 12,
     177                g_TileClasses.prop, 40,
     178                g_TileClasses.water, 3
     179            ],
     180            "stay": [
     181                g_TileClasses.bluff, 7,
     182                g_TileClasses.mountain, 7
     183            ],
     184            "sizes": ["normal"],
     185            "mixes": ["normal"],
     186            "amounts": ["scarce"]
     187        }
     188    ]);
     189
     190    addElements(shuffleArray([
     191        {
     192            "func": addForests,
     193            "avoid": [
     194                g_TileClasses.berries, 5,
     195                g_TileClasses.forest, 18,
     196                g_TileClasses.metal, 5,
     197                g_TileClasses.mountain, 5,
     198                g_TileClasses.player, 20,
     199                g_TileClasses.rock, 5,
     200                g_TileClasses.water, 2
     201            ],
     202            "stay": [g_TileClasses.bluff, 6],
     203            "sizes": g_AllSizes,
     204            "mixes": g_AllMixes,
     205            "amounts":  ["normal", "many", "tons"]
     206        },
     207        {
     208            "func": addMetal,
     209            "avoid": [
     210                g_TileClasses.berries, 5,
     211                g_TileClasses.forest, 5,
     212                g_TileClasses.mountain, 2,
     213                g_TileClasses.player, 50,
     214                g_TileClasses.rock, 15,
     215                g_TileClasses.metal, 40,
     216                g_TileClasses.water, 3
     217            ],
     218            "stay": [g_TileClasses.bluff, 6],
     219            "sizes": ["normal"],
     220            "mixes": ["same"],
     221            "amounts":  ["normal", "many", "tons"]
     222        },
     223        {
     224            "func": addStone,
     225            "avoid": [
     226                g_TileClasses.berries, 5,
     227                g_TileClasses.forest, 5,
     228                g_TileClasses.mountain, 2,
     229                g_TileClasses.player, 50,
     230                g_TileClasses.rock, 40,
     231                g_TileClasses.metal, 15,
     232                g_TileClasses.water, 3
     233            ],
     234            "stay": [g_TileClasses.bluff, 6],
     235            "sizes": ["normal"],
     236            "mixes": ["same"],
     237            "amounts": ["normal", "many", "tons"]
     238        }
     239    ]));
     240
     241    addElements(shuffleArray([
     242        {
     243            "func": addStragglerTrees,
     244            "avoid": [
     245                g_TileClasses.berries, 5,
     246                g_TileClasses.forest, 10,
     247                g_TileClasses.metal, 5,
     248                g_TileClasses.mountain, 1,
     249                g_TileClasses.player, 12,
     250                g_TileClasses.rock, 5,
     251                g_TileClasses.water, 5
     252             ],
     253            "stay": [g_TileClasses.bluff, 6],
     254            "sizes": g_AllSizes,
     255            "mixes": g_AllMixes,
     256            "amounts": ["normal", "many", "tons"]
     257        },
     258        {
     259            "func": addAnimals,
     260            "avoid": [
     261                g_TileClasses.animals, 20,
     262                g_TileClasses.forest, 5,
     263                g_TileClasses.mountain, 1,
     264                g_TileClasses.player, 20,
     265                g_TileClasses.rock, 5,
     266                g_TileClasses.metal, 5,
     267                g_TileClasses.water, 3
     268             ],
     269            "stay": [g_TileClasses.bluff, 6],
     270            "sizes": g_AllSizes,
     271            "mixes": g_AllMixes,
     272            "amounts": ["normal", "many", "tons"]
     273        },
     274        {
     275            "func": addBerries,
     276            "avoid": [
     277                g_TileClasses.berries, 50,
     278                g_TileClasses.forest, 5,
     279                g_TileClasses.metal, 10,
     280                g_TileClasses.mountain, 2,
     281                g_TileClasses.player, 20,
     282                g_TileClasses.rock, 10,
     283                g_TileClasses.water, 3
     284            ],
     285            "stay": [g_TileClasses.bluff, 6],
     286            "sizes": g_AllSizes,
     287            "mixes": g_AllMixes,
     288            "amounts": ["normal", "many", "tons"]
     289        }
     290    ]));
     291}
     292
     293/**
     294 * Add grass, rocks and bushes.
     295 */
     296function addDecoration(constraint, size, deviation, fill)
     297{
     298    deviation = deviation || g_DefaultDeviation;
     299    size = size || 1;
     300    fill = fill || 1;
     301
     302    var offset = getRandomDeviation(size, deviation);
     303    var decorations = [
     304        [
     305            new SimpleObject(g_Decoratives.rockMedium, 1 * offset, 3 * offset, 0, 1 * offset)
     306        ],
     307        [
     308            new SimpleObject(g_Decoratives.rockLarge, 1 * offset, 2 * offset, 0, 1 * offset),
     309            new SimpleObject(g_Decoratives.rockMedium, 1 * offset, 3 * offset, 0, 2 * offset)
     310        ],
     311        [
     312            new SimpleObject(g_Decoratives.grassShort, 1 * offset, 2 * offset, 0, 1 * offset, -PI / 8, PI / 8)
     313        ],
     314        [
     315            new SimpleObject(g_Decoratives.grass, 2 * offset, 4 * offset, 0, 1.8 * offset, -PI / 8, PI / 8),
     316            new SimpleObject(g_Decoratives.grassShort, 3 * offset, 6 * offset, 1.2 * offset, 2.5 * offset, -PI / 8, PI / 8)
     317        ],
     318        [
     319            new SimpleObject(g_Decoratives.bushMedium, 1 * offset, 2 * offset, 0, 2 * offset),
     320            new SimpleObject(g_Decoratives.bushSmall, 2 * offset, 4 * offset, 0, 2 * offset)
     321        ]
     322    ];
     323
     324    var baseCount = 1;
     325    if (g_MapInfo.biome == 7)
     326        baseCount = 8;
     327
     328    var counts = [
     329        scaleByMapSize(16, 262),
     330        scaleByMapSize(8, 131),
     331        baseCount * scaleByMapSize(13, 200),
     332        baseCount * scaleByMapSize(13, 200),
     333        baseCount * scaleByMapSize(13, 200)
     334    ];
     335
     336    for (var i = 0; i < decorations.length; ++i)
     337    {
     338        var decorCount = Math.floor(counts[i] * fill);
     339        var group = new SimpleGroup(decorations[i], true);
     340        createObjectGroups(group, 0, constraint, decorCount, 5);
     341    }
     342}
     343
     344/**
     345 * Create varying elevations.
     346 *
     347 * @param {Array} constraint - avoid/stay-classes
     348 *
     349 * @param {Object} el - the element to be rendered, for example:
     350 *  "class": g_TileClasses.hill,
     351 *  "painter": [g_Terrains.mainTerrain, g_Terrains.mainTerrain],
     352 *  "size": 1,
     353 *  "deviation": 0.2,
     354 *  "fill": 1,
     355 *  "count": scaleByMapSize(8, 8),
     356 *  "minSize": Math.floor(scaleByMapSize(5, 5)),
     357 *  "maxSize": Math.floor(scaleByMapSize(8, 8)),
     358 *  "spread": Math.floor(scaleByMapSize(20, 20)),
     359 *  "minElevation": 6,
     360 *  "maxElevation": 12,
     361 *  "steepness": 1.5
     362 */
     363
     364function addElevation(constraint, el)
     365{
     366    var deviation = el.deviation || g_DefaultDeviation;
     367    var size = el.size || 1;
     368    var fill = el.fill || 1;
     369
     370    var count = fill * el.count;
     371    var minSize = el.minSize;
     372    var maxSize = el.maxSize;
     373    var spread = el.spread;
     374
     375    var elType = ELEVATION_MODIFY;
     376    if (el.class == g_TileClasses.water)
     377        elType = ELEVATION_SET;
     378
     379    var widths = [];
     380
     381    // Allow for shore and cliff rendering
     382    for (var s = el.painter.length; s > 2; --s)
     383        widths.push(1);
     384
     385    for (var i = 0; i < count; ++i)
     386    {
     387        var elevation = el.minElevation + randInt(el.maxElevation - el.minElevation);
     388        var smooth = Math.floor(elevation / el.steepness);
     389
     390        var offset = getRandomDeviation(size, el.deviation);
     391        var pMinSize = Math.floor(minSize * offset);
     392        var pMaxSize = Math.floor(maxSize * offset);
     393        var pSpread = Math.floor(spread * offset);
     394        var pSmooth = Math.abs(Math.floor(smooth * offset));
     395        var pElevation = Math.floor(elevation * offset);
     396
     397        pElevation = Math.max(el.minElevation, Math.min(pElevation, el.maxElevation));
     398
     399        pMinSize = Math.min(pMinSize, pMaxSize);
     400        pMaxSize = Math.min(pMaxSize, el.maxSize);
     401        pMinSize = Math.max(pMaxSize, el.minSize);
     402
     403        pSmooth = Math.max(pSmooth, 1);
     404
     405        var pWidths = widths.concat(pSmooth);
     406
     407        var placer = new ChainPlacer(pMinSize, pMaxSize, pSpread, 0.5);
     408        var terrainPainter = new LayeredPainter(el.painter, [pWidths]);
     409        var elevationPainter = new SmoothElevationPainter(elType, pElevation, pSmooth);
     410        createAreas(placer, [terrainPainter, elevationPainter, paintClass(el.class)], constraint, 1);
     411    }
     412}
     413
     414/**
     415 * Create rolling hills.
     416 */
     417function addHills(constraint, size, deviation, fill)
     418{
     419    addElevation(constraint, {
     420        "class": g_TileClasses.hill,
     421        "painter": [g_Terrains.mainTerrain, g_Terrains.mainTerrain],
     422        "size": size,
     423        "deviation": deviation,
     424        "fill": fill,
     425        "count": scaleByMapSize(8, 8),
     426        "minSize": Math.floor(scaleByMapSize(5, 5)),
     427        "maxSize": Math.floor(scaleByMapSize(8, 8)),
     428        "spread": Math.floor(scaleByMapSize(20, 20)),
     429        "minElevation": 6,
     430        "maxElevation": 12,
     431        "steepness": 1.5
     432    });
     433}
     434
     435/**
     436 * Create random lakes with fish in it.
     437 */
     438function addLakes(constraint, size, deviation, fill)
     439{
     440    var lakeTile = g_Terrains.water;
     441
     442    if (g_MapInfo.biome == 0 || g_MapInfo.biome == 1 || g_MapInfo.biome == 7)
     443        lakeTile = g_Terrains.dirt;
     444
     445    if (g_MapInfo.biome == 5)
     446        lakeTile = g_Terrains.tier2Terrain;
     447
     448    if (g_MapInfo.biome == 8)
     449        lakeTile = g_Terrains.shore;
     450
     451    addElevation(constraint, {
     452        "class": g_TileClasses.water,
     453        "painter": [lakeTile, lakeTile],
     454        "size": size,
     455        "deviation": deviation,
     456        "fill": fill,
     457        "count": scaleByMapSize(6, 6),
     458        "minSize": Math.floor(scaleByMapSize(7, 7)),
     459        "maxSize": Math.floor(scaleByMapSize(9, 9)),
     460        "spread": Math.floor(scaleByMapSize(70, 70)),
     461        "minElevation": -15,
     462        "maxElevation": -2,
     463        "steepness": 1.5
     464    });
     465
     466    addElements([
     467        {
     468            "func": addFish,
     469            "avoid": [
     470                g_TileClasses.fish, 12,
     471                g_TileClasses.hill, 8,
     472                g_TileClasses.mountain, 8,
     473                g_TileClasses.player, 8
     474            ],
     475            "stay": [g_TileClasses.water, 7],
     476            "sizes": g_AllSizes,
     477            "mixes": g_AllMixes,
     478            "amounts": ["normal", "many", "tons"]
     479        }
     480    ]);
     481
     482    var group = new SimpleGroup([new SimpleObject(g_Decoratives.rockMedium, 1, 3, 1, 3)], true, g_TileClasses.dirt);
     483    createObjectGroups(group, 0, [stayClasses(g_TileClasses.water, 1), borderClasses(g_TileClasses.water, 4, 3)], 1000, 100);
     484
     485    group = new SimpleGroup([new SimpleObject(g_Decoratives.reeds, 10, 15, 1, 3), new SimpleObject(g_Decoratives.rockMedium, 1, 3, 1, 3)], true, g_TileClasses.dirt);
     486    createObjectGroups(group, 0, [stayClasses(g_TileClasses.water, 2), borderClasses(g_TileClasses.water, 4, 3)], 1000, 100);
     487}
     488
     489/**
     490 * Universal function to create layered patches.
     491 */
     492function addLayeredPatches(constraint, size, deviation, fill)
     493{
     494    deviation = deviation || g_DefaultDeviation;
     495    size = size || 1;
     496    fill = fill || 1;
     497
     498    var minRadius = 1;
     499    var maxRadius = Math.floor(scaleByMapSize(3, 5));
     500    var count = fill * scaleByMapSize(15, 45);
     501
     502    var sizes = [
     503        scaleByMapSize(3, 6),
     504        scaleByMapSize(5, 10),
     505        scaleByMapSize(8, 21)
     506    ];
     507
     508    for (var i = 0; i < sizes.length; ++i)
     509    {
     510        var offset = getRandomDeviation(size, deviation);
     511        var patchMinRadius = Math.floor(minRadius * offset);
     512        var patchMaxRadius = Math.floor(maxRadius * offset);
     513        var patchSize = Math.floor(sizes[i] * offset);
     514        var patchCount = count * offset;
     515
     516        if (patchMinRadius > patchMaxRadius)
     517            patchMinRadius = patchMaxRadius;
     518
     519        var placer = new ChainPlacer(patchMinRadius, patchMaxRadius, patchSize, 0.5);
     520        var painter = new LayeredPainter(
     521            [
     522                [g_Terrains.mainTerrain, g_Terrains.tier1Terrain],
     523                [g_Terrains.tier1Terrain, g_Terrains.tier2Terrain],
     524                [g_Terrains.tier2Terrain, g_Terrains.tier3Terrain],
     525                [g_Terrains.tier4Terrain]
     526            ],
     527            [1, 1] // widths
     528        );
     529        createAreas(placer, [painter, paintClass(g_TileClasses.dirt)], constraint, patchCount);
     530    }
     531}
     532
     533/**
     534 * Create steep mountains.
     535 */
     536function addMountains(constraint, size, deviation, fill)
     537{
     538    addElevation(constraint, {
     539        "class": g_TileClasses.mountain,
     540        "painter": [g_Terrains.cliff, g_Terrains.hill],
     541        "size": size,
     542        "deviation": deviation,
     543        "fill": fill,
     544        "count": scaleByMapSize(8, 8),
     545        "minSize": Math.floor(scaleByMapSize(2, 2)),
     546        "maxSize": Math.floor(scaleByMapSize(4, 4)),
     547        "spread": Math.floor(scaleByMapSize(100, 100)),
     548        "minElevation": 100,
     549        "maxElevation": 120,
     550        "steepness": 4
     551    });
     552}
     553
     554/**
     555 * Create plateaus.
     556 */
     557function addPlateaus(constraint, size, deviation, fill)
     558{
     559    var plateauTile = g_Terrains.dirt;
     560
     561    if (g_MapInfo.biome == 2)
     562        plateauTile = g_Terrains.tier1Terrain;
     563
     564    if (g_MapInfo.biome == 4 || g_MapInfo.biome == 6)
     565        plateauTile = g_Terrains.tier2Terrain;
     566
     567    if (g_MapInfo.biome == 8)
     568        plateauTile = g_Terrains.tier4Terrain;
     569
     570    addElevation(constraint, {
     571        "class": g_TileClasses.plateau,
     572        "painter": [g_Terrains.cliff, plateauTile],
     573        "size": size,
     574        "deviation": deviation,
     575        "fill": fill,
     576        "count": scaleByMapSize(15, 15),
     577        "minSize": Math.floor(scaleByMapSize(2, 2)),
     578        "maxSize": Math.floor(scaleByMapSize(4, 4)),
     579        "spread": Math.floor(scaleByMapSize(200, 200)),
     580        "minElevation": 20,
     581        "maxElevation": 30,
     582        "steepness": 8
     583    });
     584
     585    for (var i = 0; i < 40; ++i)
     586    {
     587        var placer = new ChainPlacer(3, 15, 1, 0.5);
     588        var terrainPainter = new LayeredPainter([plateauTile, plateauTile], [3]);
     589        var hillElevation = 4 + randInt(15);
     590        var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, hillElevation, hillElevation - 2);
     591
     592        createAreas(
     593            placer,
     594            [
     595                terrainPainter,
     596                elevationPainter,
     597                paintClass(g_TileClasses.hill)
     598            ],
     599            [
     600                avoidClasses(g_TileClasses.hill, 7),
     601                stayClasses(g_TileClasses.plateau, 7)
     602            ],
     603            1
     604        );
     605    }
     606
     607    addElements([
     608        {
     609            "func": addDecoration,
     610            "avoid": [
     611                g_TileClasses.dirt, 15,
     612                g_TileClasses.forest, 2,
     613                g_TileClasses.player, 12,
     614                g_TileClasses.water, 3
     615            ],
     616            "stay": [g_TileClasses.plateau, 8],
     617            "sizes": ["normal"],
     618            "mixes": ["normal"],
     619            "amounts": ["tons"]
     620        },
     621        {
     622            "func": addProps,
     623            "avoid": [
     624                g_TileClasses.forest, 2,
     625                g_TileClasses.player, 12,
     626                g_TileClasses.prop, 40,
     627                g_TileClasses.water, 3
     628            ],
     629            "stay": [g_TileClasses.plateau, 8],
     630            "sizes": ["normal"],
     631            "mixes": ["normal"],
     632            "amounts": ["scarce"]
     633        }
     634    ]);
     635}
     636
     637/**
     638 * Place less usual decoratives like barrels or crates.
     639 */
     640function addProps(constraint, size, deviation, fill)
     641{
     642    deviation = deviation || g_DefaultDeviation;
     643    size = size || 1;
     644    fill = fill || 1;
     645
     646    var offset = getRandomDeviation(size, deviation);
     647
     648    var props = [
     649        [
     650            new SimpleObject(g_Props.skeleton, 1 * offset, 5 * offset, 0, 3 * offset + 2),
     651            new SimpleObject(g_Props.blood, 1 * offset, 2 * offset, 0, 1 * offset + 3),
     652            new SimpleObject(g_Props.bigBlood, 1 * offset, 3 * offset, 0, 2 * offset + 3)
     653        ],
     654        [
     655            new SimpleObject(g_Props.barrels, 1 * offset, 2 * offset, 2, 3 * offset + 2),
     656            new SimpleObject(g_Props.cart, 0, 1 * offset, 5, 2.5 * offset + 5),
     657            new SimpleObject(g_Props.crate, 1 * offset, 2 * offset, 2, 2 * offset + 2),
     658            new SimpleObject(g_Props.well, 0, 1, 2, 2 * offset + 2)
     659        ]
     660    ];
     661
     662    var baseCount = 1;
     663
     664    var counts = [
     665        scaleByMapSize(16, 262),
     666        scaleByMapSize(8, 131),
     667        baseCount * scaleByMapSize(13, 200),
     668        baseCount * scaleByMapSize(13, 200),
     669        baseCount * scaleByMapSize(13, 200)
     670    ];
     671
     672    // Add small props
     673    for (var i = 0; i < props.length; ++i)
     674    {
     675        var propCount = Math.floor(counts[i] * fill);
     676        var group = new SimpleGroup(props[i], true);
     677        createObjectGroups(group, 0, constraint, propCount, 5);
     678    }
     679
     680    // Add decorative trees
     681    var trees = new SimpleObject(g_Decoratives.tree, 5 * offset, 30 * offset, 2, 3 * offset + 10);
     682    createObjectGroups(new SimpleGroup([trees], true), 0, constraint, counts[0] * 5 * fill, 5);
     683}
     684
     685/**
     686 * Create rivers.
     687 */
     688function addRivers(constraint, size, deviation, fill)
     689{
     690    deviation = deviation || g_DefaultDeviation;
     691    size = size || 1;
     692    fill = fill || 1;
     693
     694    var count = 5;
     695    var minSize = scaleByMapSize(15, 15);
     696    var maxSize = scaleByMapSize(15, 15);
     697    var elevation = -2;
     698    var spread = scaleByMapSize(5, 5);
     699
     700    for (var i = 0; i < count; ++i)
     701    {
     702        var offset = getRandomDeviation(size, deviation);
     703
     704        var startAngle = randFloat(0, 2 * PI);
     705        var endAngle = startAngle + randFloat(PI * 0.5, PI * 1.5);
     706
     707        var startX = g_MapInfo.centerOfMap + Math.floor(g_MapInfo.centerOfMap * Math.cos(startAngle));
     708        var startZ = g_MapInfo.centerOfMap + Math.floor(g_MapInfo.centerOfMap * Math.sin(startAngle));
     709
     710        var endX = g_MapInfo.centerOfMap + Math.floor(g_MapInfo.centerOfMap * Math.cos(endAngle));
     711        var endZ = g_MapInfo.centerOfMap + Math.floor(g_MapInfo.centerOfMap * Math.sin(endAngle));
     712
     713        var pMinSize = Math.floor(minSize * offset);
     714        var pMaxSize = Math.floor(maxSize * offset);
     715        var pSpread = Math.floor(spread * offset);
     716
     717        var placer = new PathPlacer(startX, startZ, endX, endZ, 12, 0.25, 1, 0.05, 0.3);
     718        var terrainPainter = new LayeredPainter([g_Terrains.water, g_Terrains.shore], [2]);
     719        var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, elevation, 2);
     720        createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.water)], constraint);
     721    }
     722}
     723
     724/**
     725 * Create valleys.
     726 */
     727function addValleys(constraint, size, deviation, fill)
     728{
     729    if (g_MapInfo.mapHeight < 6)
     730        return;
     731
     732    var minElevation = (-1 * g_MapInfo.mapHeight) / (size * (1 + deviation)) + 1;
     733    if (minElevation < -1 * g_MapInfo.mapHeight)
     734        minElevation = -1 * g_MapInfo.mapHeight;
     735
     736    var valleySlope = g_Terrains.tier1Terrain;
     737    var valleyFloor = g_Terrains.tier4Terrain;
     738
     739    if (g_MapInfo.biome == 0)
     740    {
     741        valleySlope = g_Terrains.dirt;
     742        valleyFloor = g_Terrains.tier2Terrain;
     743    }
     744
     745    if (g_MapInfo.biome == 3)
     746    {
     747        valleySlope = g_Terrains.tier3Terrain;
     748        valleyFloor = g_Terrains.dirt;
     749    }
     750
     751    if (g_MapInfo.biome == 5)
     752    {
     753        valleySlope = g_Terrains.tier2Terrain;
     754        valleyFloor = g_Terrains.dirt;
     755    }
     756
     757    if (g_MapInfo.biome == 4 || g_MapInfo.biome == 6)
     758        valleyFloor = g_Terrains.tier2Terrain;
     759
     760    if (g_MapInfo.biome == 7)
     761        valleySlope = g_Terrains.dirt;
     762
     763    if (g_MapInfo.biome == 8)
     764        valleyFloor = g_Terrains.tier3Terrain;
     765
     766    addElevation(constraint, {
     767        "class": g_TileClasses.valley,
     768        "painter": [valleySlope, valleyFloor],
     769        "size": size,
     770        "deviation": deviation,
     771        "fill": fill,
     772        "count": scaleByMapSize(8, 8),
     773        "minSize": Math.floor(scaleByMapSize(5, 5)),
     774        "maxSize": Math.floor(scaleByMapSize(8, 8)),
     775        "spread": Math.floor(scaleByMapSize(30, 30)),
     776        "minElevation": minElevation,
     777        "maxElevation": -2,
     778        "steepness": 4
     779    });
     780}
     781
     782/**
     783 * Create huntable animals.
     784 */
     785function addAnimals(constraint, size, deviation, fill)
     786{
     787    deviation = deviation || g_DefaultDeviation;
     788    size = size || 1;
     789    fill = fill || 1;
     790
     791    var groupOffset = getRandomDeviation(size, deviation);
     792
     793    var animals = [
     794        [new SimpleObject(g_Gaia.mainHuntableAnimal, 5 * groupOffset, 7 * groupOffset, 0, 4 * groupOffset)],
     795        [new SimpleObject(g_Gaia.secondaryHuntableAnimal, 2 * groupOffset, 3 * groupOffset, 0, 2 * groupOffset)]
     796    ];
     797
     798    var counts = [scaleByMapSize(30, 30) * fill, scaleByMapSize(30, 30) * fill];
     799
     800    for (var i = 0; i < animals.length; ++i)
     801    {
     802        var group = new SimpleGroup(animals[i], true, g_TileClasses.animals);
     803        createObjectGroups(group, 0, constraint, Math.floor(counts[i]), 50);
     804    }
     805}
     806
     807/**
     808 * Create fruits.
     809 */
     810function addBerries(constraint, size, deviation, fill)
     811{
     812    deviation = deviation || g_DefaultDeviation;
     813    size = size || 1;
     814    fill = fill || 1;
     815
     816    var groupOffset = getRandomDeviation(size, deviation);
     817
     818    var count = scaleByMapSize(50, 50) * fill;
     819    var berries = [[new SimpleObject(g_Gaia.fruitBush, 5 * groupOffset, 5 * groupOffset, 0, 3 * groupOffset)]];
     820
     821    for (var i = 0; i < berries.length; ++i)
     822    {
     823        var group = new SimpleGroup(berries[i], true, g_TileClasses.berries);
     824        createObjectGroups(group, 0, constraint, Math.floor(count), 40);
     825    }
     826}
     827
     828/**
     829 * Create fish.
     830 */
     831function addFish(constraint, size, deviation, fill)
     832{
     833    deviation = deviation || g_DefaultDeviation;
     834    size = size || 1;
     835    fill = fill || 1;
     836
     837    var groupOffset = getRandomDeviation(size, deviation);
     838
     839    var fish = [
     840        [new SimpleObject(g_Gaia.fish, 1 * groupOffset, 2 * groupOffset, 0, 2 * groupOffset)],
     841        [new SimpleObject(g_Gaia.fish, 2 * groupOffset, 4 * groupOffset, 10 * groupOffset, 20 * groupOffset)]
     842    ];
     843
     844    var counts = [scaleByMapSize(40, 40) * fill, scaleByMapSize(40, 40) * fill];
     845
     846    for (var i = 0; i < fish.length; ++i)
     847    {
     848        var group = new SimpleGroup(fish[i], true, g_TileClasses.fish);
     849        createObjectGroups(group, 0, constraint, floor(counts[i]), 50);
     850    }
     851}
     852
     853/**
     854 * Create dense forests.
     855 */
     856function addForests(constraint, size, deviation, fill)
     857{
     858    deviation = deviation || g_DefaultDeviation;
     859    size = size || 1;
     860    fill = fill || 1;
     861
     862    // No forests for the african biome
     863    if (g_MapInfo.biome == 6)
     864        return;
     865
     866    var types = [
     867        [
     868            [g_Terrains.forestFloor2, g_Terrains.mainTerrain, g_Forests.forest1],
     869            [g_Terrains.forestFloor2, g_Forests.forest1]
     870        ],
     871        [
     872            [g_Terrains.forestFloor2, g_Terrains.mainTerrain, g_Forests.forest2],
     873            [g_Terrains.forestFloor1, g_Forests.forest2]],
     874        [
     875            [g_Terrains.forestFloor1, g_Terrains.mainTerrain, g_Forests.forest1],
     876            [g_Terrains.forestFloor2, g_Forests.forest1]],
     877        [
     878            [g_Terrains.forestFloor1, g_Terrains.mainTerrain, g_Forests.forest2],
     879            [g_Terrains.forestFloor1, g_Forests.forest2]
     880        ]
     881    ];
     882
     883    for (var i = 0; i < types.length; ++i)
     884    {
     885        var offset = getRandomDeviation(size, deviation);
     886        var minSize = floor(scaleByMapSize(3, 5) * offset);
     887        var maxSize = Math.floor(scaleByMapSize(50, 50) * offset);
     888        var forestCount = scaleByMapSize(10, 10) * fill;
     889
     890        var placer = new ChainPlacer(1, minSize, maxSize, 0.5);
     891        var painter = new LayeredPainter(types[i], [2]);
     892        createAreas(placer, [painter, paintClass(g_TileClasses.forest)], constraint, forestCount);
     893    }
     894}
     895
     896/**
     897 * Create metal mines.
     898 */
     899function addMetal(constraint, size, deviation, fill)
     900{
     901    deviation = deviation || g_DefaultDeviation;
     902    size = size || 1;
     903    fill = fill || 1;
     904
     905    var offset = getRandomDeviation(size, deviation);
     906    var count = 1 + scaleByMapSize(20, 20) * fill;
     907    var mines = [[new SimpleObject(g_Gaia.metalLarge, 1 * offset, 1 * offset, 0, 4 * offset)]];
     908
     909    for (var i = 0; i < mines.length; ++i)
     910    {
     911        var group = new SimpleGroup(mines[i], true, g_TileClasses.metal);
     912        createObjectGroups(group, 0, constraint, count, 100);
     913    }
     914}
     915
     916/**
     917 * Create stone mines.
     918 */
     919function addStone(constraint, size, deviation, fill)
     920{
     921    deviation = deviation || g_DefaultDeviation;
     922    size = size || 1;
     923    fill = fill || 1;
     924
     925    var offset = getRandomDeviation(size, deviation);
     926    var count = 1 + scaleByMapSize(20, 20) * fill;
     927    var mines = [
     928        [
     929            new SimpleObject(g_Gaia.stoneSmall, 0, 2 * offset, 0, 4 * offset),
     930            new SimpleObject(g_Gaia.stoneLarge, 1 * offset, 1 * offset, 0, 4 * offset)
     931        ],
     932        [
     933            new SimpleObject(g_Gaia.stoneSmall, 2 * offset, 5 * offset, 1 * offset, 3 * offset)
     934        ]
     935    ];
     936
     937    for (var i = 0; i < mines.length; ++i)
     938    {
     939        var group = new SimpleGroup(mines[i], true, g_TileClasses.rock);
     940        createObjectGroups(group, 0, constraint, count, 100);
     941    }
     942}
     943
     944/**
     945 * Create straggler trees.
     946 */
     947function addStragglerTrees(constraint, size, deviation, fill)
     948{
     949    deviation = deviation || g_DefaultDeviation;
     950    size = size || 1;
     951    fill = fill || 1;
     952
     953    // Ensure minimum distribution on african biome
     954    if (g_MapInfo.biome == 6)
     955    {
     956        fill = Math.max(fill, 2);
     957        size = Math.max(size, 1);
     958    }
     959
     960    var trees = [g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree3, g_Gaia.tree4];
     961
     962    var treesPerPlayer = 40;
     963    var playerBonus = Math.max(1, (g_MapInfo.numPlayers - 3) / 2);
     964
     965    var offset = getRandomDeviation(size, deviation);
     966    var treeCount = treesPerPlayer * playerBonus * fill;
     967    var totalTrees = scaleByMapSize(treeCount, treeCount);
     968
     969    var count = Math.floor(totalTrees / trees.length) * fill;
     970    var min = 1 * offset;
     971    var max = 4 * offset;
     972    var minDist = 1 * offset;
     973    var maxDist = 5 * offset;
     974
     975    // More trees for the african biome
     976    if (g_MapInfo.biome == 6)
     977    {
     978        min = 3 * offset;
     979        max = 5 * offset;
     980        minDist = 2 * offset + 1;
     981        maxDist = 3 * offset + 2;
     982    }
     983
     984    for (var i = 0; i < trees.length; ++i)
     985    {
     986        var treesMax = max;
     987
     988        // Don't clump fruit trees
     989        if (i == 2 && (g_MapInfo.biome == 3 || g_MapInfo.biome == 5))
     990            treesMax = 1;
     991
     992        min = Math.min(min, treesMax);
     993
     994        var group = new SimpleGroup([new SimpleObject(trees[i], min, treesMax, minDist, maxDist)], true, g_TileClasses.forest);
     995        createObjectGroups(group, 0, constraint, count);
     996    }
     997}
     998
     999///////////
     1000// Terrain Helpers
     1001///////////
     1002
     1003/**
     1004 * Determine if the endline of the bluff is within the tilemap.
     1005 */
     1006function unreachableBluff(bb, corners, baseLine, endLine)
     1007{
     1008    // If we couldn't find a slope line
     1009    if (typeof baseLine.midX === "undefined" || typeof endLine.midX === "undefined")
     1010        return 1;
     1011
     1012    // If the end points aren't on the tilemap
     1013    if ((!g_Map.validT(endLine.x1, endLine.z1) || checkIfInClass(endLine.x1, endLine.z1, g_TileClasses.player)) &&
     1014        (!g_Map.validT(endLine.x2, endLine.z2) || checkIfInClass(endLine.x2, endLine.z2, g_TileClasses.player)))
     1015        return 2;
     1016
     1017    var minTilesInGroup = 1;
     1018    var insideBluff = false;
     1019    var outsideBluff = false;
     1020
     1021    // If there aren't enough points in each row
     1022    for (var x = 0; x < bb.length; ++x)
     1023    {
     1024        var count = 0;
     1025        for (var z = 0; z < bb[x].length; ++z)
     1026        {
     1027            if (!bb[x][z].isFeature)
     1028                continue;
     1029
     1030            var valid = g_Map.validT(x + corners.minX, z + corners.minZ);
     1031
     1032            if (valid)
     1033                ++count;
     1034
     1035            if (!insideBluff && valid)
     1036                insideBluff = true;
     1037
     1038            if (outsideBluff && valid)
     1039                return 3;
     1040        }
     1041
     1042        // We're expecting the end of the bluff
     1043        if (insideBluff && count < minTilesInGroup)
     1044            outsideBluff = true;
     1045    }
     1046
     1047    var insideBluff = false;
     1048    var outsideBluff = false;
     1049
     1050    // If there aren't enough points in each column
     1051    for (var z = 0; z < bb[0].length; ++z)
     1052    {
     1053        var count = 0;
     1054        for (var x = 0; x < bb.length; ++x)
     1055        {
     1056            if (!bb[x][z].isFeature)
     1057                continue;
     1058
     1059            var valid = g_Map.validT(x + corners.minX, z + corners.minZ);
     1060
     1061            if (valid)
     1062                ++count;
     1063
     1064            if (!insideBluff && valid)
     1065                insideBluff = true;
     1066
     1067            if (outsideBluff && valid)
     1068                return 3;
     1069        }
     1070
     1071        // We're expecting the end of the bluff
     1072        if (insideBluff && count < minTilesInGroup)
     1073            outsideBluff = true;
     1074    }
     1075
     1076    // Bluff is reachable
     1077    return 0;
     1078}
     1079
     1080/**
     1081 * Remove the bluff class and turn it into a plateau.
     1082 */
     1083function removeBluff(points)
     1084{
     1085    for (var i = 0; i < points.length; ++i)
     1086        addToClass(points[i].x, points[i].z, g_TileClasses.mountain);
     1087}
     1088
     1089/**
     1090 * Create an array of points the fill a bounding box around a terrain feature.
     1091 */
     1092function createBoundingBox(points, corners)
     1093{
     1094    var bb = [];
     1095    var width = corners.maxX - corners.minX + 1;
     1096    var length = corners.maxZ - corners.minZ + 1;
     1097    for (var w = 0; w < width; ++w)
     1098    {
     1099        bb[w] = [];
     1100        for (var l = 0; l < length; ++l)
     1101        {
     1102            var curHeight = g_Map.getHeight(w + corners.minX, l + corners.minZ);
     1103            bb[w][l] = {
     1104                "height": curHeight,
     1105                "isFeature": false
     1106            };
     1107        }
     1108    }
     1109
     1110    // Define the coordinates that represent the bluff
     1111    for (var p = 0; p < points.length; ++p)
     1112    {
     1113        var pt = points[p];
     1114        bb[pt.x - corners.minX][pt.z - corners.minZ].isFeature = true;
     1115    }
     1116
     1117    return bb;
     1118}
     1119
     1120/**
     1121 * Flattens the ground touching a terrain feature.
     1122 */
     1123function fadeToGround(bb, minX, minZ, elevation)
     1124{
     1125    var ground = createTerrain(g_Terrains.mainTerrain);
     1126    for (var x = 0; x < bb.length; ++x)
     1127        for (var z = 0; z < bb[x].length; ++z)
     1128        {
     1129            var pt = bb[x][z];
     1130            if (!pt.isFeature && nextToFeature(bb, x, z))
     1131            {
     1132                var newEl = smoothElevation(x + minX, z + minZ);
     1133                g_Map.setHeight(x + minX, z + minZ, newEl);
     1134                ground.place(x + minX, z + minZ);
     1135            }
     1136        }
     1137}
     1138
     1139/**
     1140 * Find a 45 degree line in a bounding box that does not intersect any terrain feature.
     1141 */
     1142function findClearLine(bb, corners, angle)
     1143{
     1144    // Angle - 0: northwest; 1: northeast; 2: southeast; 3: southwest
     1145    var z = corners.maxZ;
     1146    var xOffset = -1;
     1147    var zOffset = -1;
     1148
     1149    switch(angle)
     1150    {
     1151        case 1:
     1152            xOffset = 1;
     1153            break;
     1154        case 2:
     1155            xOffset = 1;
     1156            zOffset = 1;
     1157            z = corners.minZ;
     1158            break;
     1159        case 3:
     1160            zOffset = 1;
     1161            z = corners.minZ;
     1162            break;
     1163    }
     1164
     1165    var clearLine = {};
     1166
     1167    for (var x = corners.minX; x <= corners.maxX; ++x)
     1168    {
     1169        var x2 = x;
     1170        var z2 = z;
     1171
     1172        var clear = true;
     1173
     1174        while (x2 >= corners.minX && x2 <= corners.maxX && z2 >= corners.minZ && z2 <= corners.maxZ)
     1175        {
     1176            var bp = bb[x2 - corners.minX][z2 - corners.minZ];
     1177            if (bp.isFeature && g_Map.validT(x2, z2))
     1178            {
     1179                clear = false;
     1180                break;
     1181            }
     1182
     1183            x2 = x2 + xOffset;
     1184            z2 = z2 + zOffset;
     1185        }
     1186
     1187        if (clear)
     1188        {
     1189            var lastX = x2 - xOffset;
     1190            var lastZ = z2 - zOffset;
     1191            var midX = Math.floor((x + lastX) / 2);
     1192            var midZ = Math.floor((z + lastZ) / 2);
     1193            clearLine = {
     1194                "x1": x,
     1195                "z1": z,
     1196                "x2": lastX,
     1197                "z2": lastZ,
     1198                "midX": midX,
     1199                "midZ": midZ,
     1200                "height": g_MapInfo.mapHeight
     1201            };
     1202        }
     1203
     1204        if (clear && (angle == 1 || angle == 2))
     1205            break;
     1206
     1207        if (!clear && (angle == 0 || angle == 3))
     1208            break;
     1209    }
     1210
     1211    return clearLine;
     1212}
     1213
     1214/**
     1215 * Returns the corners of a bounding box.
     1216 */
     1217function findCorners(points)
     1218{
     1219    // Find the bounding box of the terrain feature
     1220    var minX = g_MapInfo.mapSize + 1;
     1221    var minZ = g_MapInfo.mapSize + 1;
     1222    var maxX = -1;
     1223    var maxZ = -1;
     1224
     1225    for (var p = 0; p < points.length; ++p)
     1226    {
     1227        var pt = points[p];
     1228
     1229        minX = Math.min(pt.x, minX);
     1230        minZ = Math.min(pt.z, minZ);
     1231
     1232        maxX = Math.max(pt.x, maxX);
     1233        maxZ = Math.max(pt.z, maxZ);
     1234    }
     1235
     1236    return {
     1237        "minX": minX,
     1238        "minZ": minZ,
     1239        "maxX": maxX,
     1240        "maxZ": maxZ
     1241    };
     1242}
     1243
     1244/**
     1245 * Finds the average elevation around a point.
     1246 */
     1247function smoothElevation(x, z)
     1248{
     1249    var min = g_Map.getHeight(x, z);
     1250
     1251    for (var xOffset = -1; xOffset <= 1; ++xOffset)
     1252        for (var zOffset = -1; zOffset <= 1; ++zOffset)
     1253        {
     1254            var thisX = x + xOffset;
     1255            var thisZ = z + zOffset;
     1256            if (!g_Map.validT(thisX, thisZ))
     1257                continue;
     1258
     1259            var height = g_Map.getHeight(thisX, thisZ);
     1260            if (height < min)
     1261                min = height;
     1262        }
     1263
     1264    return min;
     1265}
     1266
     1267/**
     1268 * Determines if a point in a bounding box array is next to a terrain feature.
     1269 */
     1270function nextToFeature(bb, x, z)
     1271{
     1272    for (var xOffset = -1; xOffset <= 1; ++xOffset)
     1273        for (var zOffset = -1; zOffset <= 1; ++zOffset)
     1274        {
     1275            var thisX = x + xOffset;
     1276            var thisZ = z + zOffset;
     1277            if (thisX < 0 || thisX >= bb.length || thisZ < 0 || thisZ >= bb[x].length || (thisX == 0 && thisZ == 0))
     1278                continue;
     1279
     1280            if (bb[thisX][thisZ].isFeature)
     1281                return true;
     1282        }
     1283
     1284    return false;
     1285}
     1286
     1287/**
     1288 * Returns a number within a random deviation of a base number.
     1289 */
     1290function getRandomDeviation(base, deviation)
     1291{
     1292    deviation = Math.min(base, deviation);
     1293    deviation = base + randInt(20 * deviation) / 10 - deviation;
     1294    return deviation.toFixed(2);
     1295}
  • binaries/data/mods/public/maps/random/rmgen/setup.js

     
     1const g_Amounts = {
     2    "scarce": 0.2,
     3    "few": 0.5,
     4    "normal": 1,
     5    "many": 1.75,
     6    "tons": 3
     7};
     8
     9const g_Mixes = {
     10    "same": 0,
     11    "similar": 0.1,
     12    "normal": 0.25,
     13    "varied": 0.5,
     14    "unique": 0.75
     15};
     16
     17const g_Sizes = {
     18    "tiny": 0.5,
     19    "small": 0.75,
     20    "normal": 1,
     21    "big": 1.25,
     22    "huge": 1.5,
     23};
     24
     25const g_AllAmounts = Object.keys(g_Amounts);
     26const g_AllMixes = Object.keys(g_Mixes);
     27const g_AllSizes = Object.keys(g_Sizes);
     28
     29const g_DefaultTileClasses = [
     30    "animals",
     31    "baseResource",
     32    "berries",
     33    "bluff",
     34    "bluffSlope",
     35    "dirt",
     36    "fish",
     37    "food",
     38    "forest",
     39    "hill",
     40    "land",
     41    "map",
     42    "metal",
     43    "mountain",
     44    "plateau",
     45    "player",
     46    "prop",
     47    "ramp",
     48    "rock",
     49    "settlement",
     50    "spine",
     51    "valley",
     52    "water"
     53];
     54
     55var g_MapInfo;
     56var g_TileClasses;
     57
     58var g_Terrains;
     59var g_Gaia;
     60var g_Decoratives;
     61var g_Forests;
     62
     63/**
     64 * Adds an array of elements to the map.
     65 */
     66function addElements(els)
     67{
     68    for (var i = 0; i < els.length; ++i)
     69    {
     70        var stay = null;
     71        if (els[i].stay !== undefined)
     72            stay = els[i].stay;
     73
     74        els[i].func(
     75            [avoidClasses.apply(null, els[i].avoid), stayClasses.apply(null, stay)],
     76            pickSize(els[i].sizes),
     77            pickMix(els[i].mixes),
     78            pickAmount(els[i].amounts)
     79        );
     80    }
     81}
     82
     83/**
     84 * Converts "amount" terms to numbers.
     85 */
     86function pickAmount(amounts)
     87{
     88    var amount = amounts[randInt(amounts.length)];
     89
     90    if (amount in g_Amounts)
     91        return g_Amounts[amount];
     92
     93    return g_Mixes.normal;
     94}
     95
     96/**
     97 * Converts "mix" terms to numbers.
     98 */
     99function pickMix(mixes)
     100{
     101    var mix = mixes[randInt(mixes.length)];
     102
     103    if (mix in g_Mixes)
     104        return g_Mixes[mix];
     105
     106    return g_Mixes.normal;
     107}
     108
     109/**
     110 * Converts "size" terms to numbers.
     111 */
     112function pickSize(sizes)
     113{
     114    var size = sizes[randInt(sizes.length)];
     115
     116    if (size in g_Sizes)
     117        return g_Sizes[size];
     118
     119    return g_Sizes.normal;
     120}
     121
     122/**
     123 * Paints the entire map with a single tile type.
     124 */
     125function resetTerrain(terrain, tc, elevation)
     126{
     127    g_MapInfo.mapSize = getMapSize();
     128    g_MapInfo.mapArea = g_MapInfo.mapSize * g_MapInfo.mapSize;
     129    g_MapInfo.centerOfMap = Math.floor(g_MapInfo.mapSize / 2);
     130    g_MapInfo.mapRadius = -PI / 4;
     131
     132    var placer = new ClumpPlacer(g_MapInfo.mapArea, 1, 1, 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap);
     133    var terrainPainter = new LayeredPainter([terrain], []);
     134    var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, elevation, 1);
     135    createArea(placer, [terrainPainter, elevationPainter, paintClass(tc)], null);
     136
     137    g_MapInfo.mapHeight = elevation;
     138}
     139
     140/**
     141 * Euclidian distance between two points.
     142 */
     143function euclid_distance(x1, z1, x2, z2)
     144{
     145    return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(z2 - z1, 2));
     146}
     147
     148/**
     149 * Chose starting locations for the given players.
     150 *
     151 * @param {string} type - "radial", "stacked", "stronghold", "random"
     152 * @param {number} distance - radial distance from the center of the map
     153 */
     154function addBases(type, distance, groupedDistance)
     155{
     156    type = type || "radial";
     157    distance = distance || 0.3;
     158    groupedDistance = groupedDistance || 0.05;
     159
     160    var playerIDs = randomizePlayers();
     161    var players = {};
     162
     163    switch(type)
     164    {
     165        case "line":
     166            players = placeLine(playerIDs, distance, groupedDistance);
     167            break;
     168        case "radial":
     169            players = placeRadial(playerIDs, distance);
     170            break;
     171        case "random":
     172            players = placeRandom(playerIDs);
     173            break;
     174        case "stronghold":
     175            players = placeStronghold(playerIDs, distance, groupedDistance);
     176            break;
     177    }
     178
     179    return players;
     180}
     181
     182/**
     183 * Create the base for a single player.
     184 *
     185 * @param {Object} - contains id, angle, x, z
     186 * @param {boolean} - Whether or not iberian gets starting walls
     187 */
     188function createBase(player, walls)
     189{
     190    // Get the x and z in tiles
     191    var fx = fractionToTiles(player.x);
     192    var fz = fractionToTiles(player.z);
     193    var ix = round(fx);
     194    var iz = round(fz);
     195    addToClass(ix, iz, g_TileClasses.player);
     196    addToClass(ix + 5, iz, g_TileClasses.player);
     197    addToClass(ix, iz + 5, g_TileClasses.player);
     198    addToClass(ix - 5, iz, g_TileClasses.player);
     199    addToClass(ix, iz - 5, g_TileClasses.player);
     200
     201    // Create starting units
     202    if ((walls || walls === undefined) && g_MapInfo.mapSize > 192)
     203        placeCivDefaultEntities(fx, fz, player.id, g_MapInfo.mapRadius);
     204    else
     205        placeCivDefaultEntities(fx, fz, player.id, g_MapInfo.mapRadius, { 'iberWall': false });
     206
     207    // Create the city patch
     208    var cityRadius = scaleByMapSize(15, 25) / 3;
     209    var placer = new ClumpPlacer(PI * cityRadius * cityRadius, 0.6, 0.3, 10, ix, iz);
     210    var painter = new LayeredPainter([g_Terrains.roadWild, g_Terrains.road], [1]);
     211    createArea(placer, painter, null);
     212
     213    // Custom base terrain function
     214
     215    // Create animals
     216    for (var j = 0; j < 2; ++j)
     217    {
     218        var aAngle = randFloat(0, TWO_PI);
     219        var aDist = 7;
     220        var aX = round(fx + aDist * cos(aAngle));
     221        var aZ = round(fz + aDist * sin(aAngle));
     222        var group = new SimpleGroup(
     223            [new SimpleObject(g_Gaia.chicken, 5, 5, 0, 2)],
     224            true, g_TileClasses.baseResource, aX, aZ
     225        );
     226        createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2));
     227    }
     228
     229    // Create berry bushes
     230    var bbAngle = randFloat(0, TWO_PI);
     231    var bbDist = 12;
     232    var bbX = round(fx + bbDist * cos(bbAngle));
     233    var bbZ = round(fz + bbDist * sin(bbAngle));
     234    group = new SimpleGroup(
     235        [new SimpleObject(g_Gaia.fruitBush, 5, 5, 0, 3)],
     236        true, g_TileClasses.baseResource, bbX, bbZ
     237    );
     238    createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2));
     239
     240    // Create metal mine
     241    var mAngle = bbAngle;
     242    while(abs(mAngle - bbAngle) < PI / 3)
     243        mAngle = randFloat(0, TWO_PI);
     244
     245    var mDist = 12;
     246    var mX = round(fx + mDist * cos(mAngle));
     247    var mZ = round(fz + mDist * sin(mAngle));
     248    group = new SimpleGroup(
     249        [new SimpleObject(g_Gaia.metalLarge, 1, 1, 0, 0)],
     250        true, g_TileClasses.baseResource, mX, mZ
     251    );
     252    createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2));
     253
     254    // Create stone mines
     255    mAngle += randFloat(PI / 8, PI / 4);
     256    mX = round(fx + mDist * cos(mAngle));
     257    mZ = round(fz + mDist * sin(mAngle));
     258    group = new SimpleGroup(
     259        [new SimpleObject(g_Gaia.stoneLarge, 1, 1, 0, 2)],
     260        true, g_TileClasses.baseResource, mX, mZ
     261    );
     262    createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2));
     263
     264    var hillSize = PI * g_MapInfo.mapRadius * g_MapInfo.mapRadius;
     265
     266    // Create starting trees
     267    var num = 5;
     268    var tAngle = randFloat(0, TWO_PI);
     269    var tDist = randFloat(12, 13);
     270    var tX = round(fx + tDist * cos(tAngle));
     271    var tZ = round(fz + tDist * sin(tAngle));
     272
     273    group = new SimpleGroup(
     274        [new SimpleObject(g_Gaia.tree1, num, num, 0, 3)],
     275        false, g_TileClasses.baseResource, tX, tZ
     276    );
     277    createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2));
     278
     279    // Create grass tufts
     280    var num = hillSize / 250;
     281    for (var j = 0; j < num; ++j)
     282    {
     283        var gAngle = randFloat(0, TWO_PI);
     284        var gDist = g_MapInfo.mapRadius - (5 + randInt(7));
     285        var gX = round(fx + gDist * cos(gAngle));
     286        var gZ = round(fz + gDist * sin(gAngle));
     287        group = new SimpleGroup(
     288            [new SimpleObject(g_Decoratives.grassShort, 2, 5, 0, 1, -PI / 8, PI / 8)],
     289            false, g_TileClasses.baseResource, gX, gZ
     290        );
     291        createObjectGroup(group, 0, avoidClasses(g_TileClasses.baseResource, 2));
     292    }
     293}
     294
     295/**
     296 * Return an array where each element is an array of playerIndices of a team.
     297 */
     298function getTeams(numPlayers)
     299{
     300    // Group players by team
     301    var teams = [];
     302    for (var i = 0; i < numPlayers; ++i)
     303    {
     304        let team = getPlayerTeam(i);
     305        if (team == -1)
     306            continue;
     307
     308        if (!teams[team])
     309            teams[team] = [];
     310
     311        teams[team].push(i+1);
     312    }
     313
     314    // Players without a team get a custom index
     315    for (var i = 0; i < numPlayers; ++i)
     316        if (getPlayerTeam(i) == -1)
     317            teams.push([i+1]);
     318
     319    // Remove unused indices
     320    return teams.filter(team => true);
     321}
     322
     323/**
     324 * Chose a random pattern for placing the bases of the players.
     325 */
     326function randomStartingPositionPattern()
     327{
     328    var formats = ["radial"];
     329
     330    // Enable stronghold if we have a few teams and a big enough map
     331    if (g_MapInfo.teams.length >= 2 && g_MapInfo.numPlayers >= 4 && g_MapInfo.mapSize >= 256)
     332        formats.push("stronghold");
     333
     334    // Enable random if we have enough teams or enough players on a big enough map
     335    if (g_MapInfo.mapSize >= 256 && (g_MapInfo.teams.length >= 3 || g_MapInfo.numPlayers > 4))
     336        formats.push("random");
     337
     338    // Enable line if we have enough teams and players on a big enough map
     339    if (g_MapInfo.teams.length >= 2 && g_MapInfo.numPlayers >= 4 && g_MapInfo.mapSize >= 384)
     340        formats.push("line");
     341
     342    return {
     343        "setup": formats[randInt(formats.length)],
     344        "distance": randFloat(0.2, 0.35),
     345        "separation": randFloat(0.05, 0.1)
     346    };
     347}
     348
     349/**
     350 * Mix player indices but sort by team.
     351 *
     352 * @returns {Array} - every item is an array of player indices
     353 */
     354function randomizePlayers()
     355{
     356    var playerIDs = [];
     357    for (var i = 0; i < g_MapInfo.numPlayers; ++i)
     358        playerIDs.push(i + 1);
     359
     360    return sortPlayers(playerIDs);
     361}
     362
     363/**
     364 * Place teams in a line-pattern.
     365 *
     366 * @param {Array} playerIDs - typically randomized indices of players of a single team
     367 * @param {number} distance - radial distance from the center of the map
     368 * @param {number} groupedDistance - distance between players
     369 *
     370 * @returns {Array} - contains id, angle, x, z for every player
     371 */
     372function placeLine(playerIDs, distance, groupedDistance)
     373{
     374    var players = [];
     375
     376    for (var i = 0; i < g_MapInfo.teams.length; ++i)
     377    {
     378        var safeDist = distance;
     379        if (distance + g_MapInfo.teams[i].length * groupedDistance > 0.45)
     380            safeDist = 0.45 - g_MapInfo.teams[i].length * groupedDistance;
     381
     382        var teamAngle = g_MapInfo.startAngle + (i + 1) * TWO_PI / g_MapInfo.teams.length;
     383
     384        // Create player base
     385        for (var p = 0; p < g_MapInfo.teams[i].length; ++p)
     386        {
     387            players[g_MapInfo.teams[i][p]] = {
     388                "id": g_MapInfo.teams[i][p],
     389                "angle": g_MapInfo.startAngle + (p + 1) * TWO_PI / g_MapInfo.teams[i].length,
     390                "x": 0.5 + (safeDist + p * groupedDistance) * cos(teamAngle),
     391                "z": 0.5 + (safeDist + p * groupedDistance) * sin(teamAngle)
     392            };
     393            createBase(players[g_MapInfo.teams[i][p]], false);
     394        }
     395    }
     396
     397    return players;
     398}
     399
     400/**
     401 * Place players in a circle-pattern.
     402 *
     403 * @param {number} distance - radial distance from the center of the map
     404 */
     405function placeRadial(playerIDs, distance)
     406{
     407    var players = new Array(g_MapInfo.numPlayers);
     408
     409    for (var i = 0; i < g_MapInfo.numPlayers; ++i)
     410    {
     411        var angle = g_MapInfo.startAngle + i * TWO_PI / g_MapInfo.numPlayers;
     412        players[i] = {
     413            "id": playerIDs[i],
     414            "angle": angle,
     415            "x": 0.5 + distance * cos(angle),
     416            "z": 0.5 + distance * sin(angle)
     417        };
     418        createBase(players[i]);
     419    }
     420
     421    return players;
     422}
     423
     424/**
     425 * Chose arbitrary starting locations.
     426 */
     427function placeRandom(playerIDs)
     428{
     429    var players = [];
     430    var placed = [];
     431
     432    for (var i = 0; i < g_MapInfo.numPlayers; ++i)
     433    {
     434        var attempts = 0;
     435        var playerAngle = randFloat(0, TWO_PI);
     436        var distance = randFloat(0, 0.42);
     437        var x = 0.5 + distance * cos(playerAngle);
     438        var z = 0.5 + distance * sin(playerAngle);
     439
     440        var tooClose = false;
     441        for (var j = 0; j < placed.length; ++j)
     442        {
     443            var sep = euclid_distance(x, z, placed[j].x, placed[j].z);
     444            if (sep < 0.25)
     445            {
     446                tooClose = true;
     447                break;
     448            }
     449        }
     450
     451        if (tooClose)
     452        {
     453            --i;
     454            ++attempts;
     455
     456            // Reset if we're in what looks like an infinite loop
     457            if (attempts > 100)
     458            {
     459                players = [];
     460                placed = [];
     461                i = -1;
     462                attempts = 0;
     463            }
     464
     465            continue;
     466        }
     467
     468        players[i] = {
     469            "id": playerIDs[i],
     470            "angle": playerAngle,
     471            "x": x,
     472            "z": z
     473        };
     474
     475        placed.push(players[i]);
     476    }
     477
     478    // Create the bases
     479    for (var i = 0; i < g_MapInfo.numPlayers; ++i)
     480        createBase(players[i]);
     481
     482    return players;
     483}
     484
     485/**
     486 * Place given players in a stronghold-pattern.
     487 *
     488 * @param distance - radial distance from the center of the map
     489 * @param groupedDistance - distance between neighboring players
     490 */
     491function placeStronghold(playerIDs, distance, groupedDistance)
     492{
     493    var players = [];
     494
     495    for (var i = 0; i < g_MapInfo.teams.length; ++i)
     496    {
     497        var teamAngle = g_MapInfo.startAngle + (i + 1) * TWO_PI / g_MapInfo.teams.length;
     498        var fractionX = 0.5 + distance * cos(teamAngle);
     499        var fractionZ = 0.5 + distance * sin(teamAngle);
     500
     501        // If we have a team of above average size, make sure they're spread out
     502        if (g_MapInfo.teams[i].length > 4)
     503            groupedDistance = randFloat(0.08, 0.12);
     504
     505        // If we have a team of below average size, make sure they're together
     506        if (g_MapInfo.teams[i].length < 3)
     507            groupedDistance = randFloat(0.04, 0.06);
     508
     509        // If we have a solo player, place them on the center of the team's location
     510        if (g_MapInfo.teams[i].length == 1)
     511            groupedDistance = 0;
     512
     513        // Create player base
     514        for (var p = 0; p < g_MapInfo.teams[i].length; ++p)
     515        {
     516            var angle = g_MapInfo.startAngle + (p + 1) * TWO_PI / g_MapInfo.teams[i].length;
     517            players[g_MapInfo.teams[i][p]] = {
     518                "id": g_MapInfo.teams[i][p],
     519                "angle": angle,
     520                "x": fractionX + groupedDistance * cos(angle),
     521                "z": fractionZ + groupedDistance * sin(angle)
     522            };
     523            createBase(players[g_MapInfo.teams[i][p]], false);
     524        }
     525    }
     526
     527    return players;
     528}
     529
     530/**
     531 * Creates tileClass for the default classes and every class given.
     532 *
     533 * @param {Array} newClasses
     534 * @returns {Object} - maps from classname to ID
     535 */
     536function initTileClasses(newClasses)
     537{
     538    var classNames = g_DefaultTileClasses;
     539
     540    if (newClasses !== undefined)
     541        classNames = classNames.concat(newClasses);
     542
     543    g_TileClasses = {};
     544    for (var className of classNames)
     545        g_TileClasses[className] = createTileClass();
     546}
     547
     548/**
     549 * Get biome-specific names of entities and terrain after randomization.
     550 */
     551function initBiome()
     552{
     553    g_Terrains = {
     554        "mainTerrain": rBiomeT1(),
     555        "forestFloor1": rBiomeT2(),
     556        "forestFloor2": rBiomeT3(),
     557        "cliff": rBiomeT4(),
     558        "tier1Terrain": rBiomeT5(),
     559        "tier2Terrain": rBiomeT6(),
     560        "tier3Terrain": rBiomeT7(),
     561        "hill": rBiomeT8(),
     562        "dirt": rBiomeT9(),
     563        "road": rBiomeT10(),
     564        "roadWild": rBiomeT11(),
     565        "tier4Terrain": rBiomeT12(),
     566        "shoreBlend": rBiomeT13(),
     567        "shore": rBiomeT14(),
     568        "water": rBiomeT15()
     569    };
     570
     571    g_Gaia = {
     572        "tree1": rBiomeE1(),
     573        "tree2": rBiomeE2(),
     574        "tree3": rBiomeE3(),
     575        "tree4": rBiomeE4(),
     576        "tree5": rBiomeE5(),
     577        "fruitBush": rBiomeE6(),
     578        "chicken": rBiomeE7(),
     579        "mainHuntableAnimal": rBiomeE8(),
     580        "fish": rBiomeE9(),
     581        "secondaryHuntableAnimal": rBiomeE10(),
     582        "stoneLarge": rBiomeE11(),
     583        "stoneSmall": rBiomeE12(),
     584        "metalLarge": rBiomeE13()
     585    };
     586
     587    g_Decoratives = {
     588        "grass": rBiomeA1(),
     589        "grassShort": rBiomeA2(),
     590        "reeds": rBiomeA3(),
     591        "lillies": rBiomeA4(),
     592        "rockLarge": rBiomeA5(),
     593        "rockMedium": rBiomeA6(),
     594        "bushMedium": rBiomeA7(),
     595        "bushSmall": rBiomeA8(),
     596        "tree": rBiomeA9()
     597    };
     598
     599    g_Forests = {
     600        "forest1": [
     601            g_Terrains.forestFloor2 + TERRAIN_SEPARATOR + g_Gaia.tree1,
     602            g_Terrains.forestFloor2 + TERRAIN_SEPARATOR + g_Gaia.tree2,
     603            g_Terrains.forestFloor2
     604        ],
     605        "forest2": [
     606            g_Terrains.forestFloor1 + TERRAIN_SEPARATOR + g_Gaia.tree4,
     607            g_Terrains.forestFloor1 + TERRAIN_SEPARATOR + g_Gaia.tree5,
     608            g_Terrains.forestFloor1
     609        ]
     610    };
     611}
     612
     613/**
     614 * Creates an object of commonly used functions.
     615 */
     616function initMapSettings()
     617{
     618    initBiome();
     619
     620    let numPlayers = getNumPlayers();
     621    g_MapInfo = {
     622        "biome": biomeID,
     623        "numPlayers": numPlayers,
     624        "teams": getTeams(numPlayers),
     625        "startAngle": randFloat(0, TWO_PI)
     626    };
     627}
  • binaries/data/mods/public/maps/random/stronghold.js

     
     1RMS.LoadLibrary("rmgen");
     2InitMap();
     3
     4randomizeBiome();
     5initMapSettings();
     6initTileClasses();
     7
     8resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 30);
     9RMS.SetProgress(20);
     10
     11addBases("stronghold", randFloat(0.2, 0.35), randFloat(0.05, 0.1));
     12RMS.SetProgress(30);
     13
     14addElements(shuffleArray([
     15    {
     16        "func": addBluffs,
     17        "avoid": [
     18            g_TileClasses.bluff, 20,
     19            g_TileClasses.hill, 5,
     20            g_TileClasses.mountain, 20,
     21            g_TileClasses.plateau, 20,
     22            g_TileClasses.player, 30,
     23            g_TileClasses.valley, 5,
     24            g_TileClasses.water, 7
     25        ],
     26        "sizes": ["big", "huge"],
     27        "mixes": g_AllMixes,
     28        "amounts": g_AllAmounts
     29    },
     30    {
     31        "func": addHills,
     32        "avoid": [
     33            g_TileClasses.bluff, 5,
     34            g_TileClasses.hill, 15,
     35            g_TileClasses.mountain, 2,
     36            g_TileClasses.plateau, 2,
     37            g_TileClasses.player, 20,
     38            g_TileClasses.valley, 2,
     39            g_TileClasses.water, 2
     40        ],
     41        "sizes": ["normal", "big"],
     42        "mixes": g_AllMixes,
     43        "amounts": g_AllAmounts
     44    },
     45    {
     46        "func": addMountains,
     47        "avoid": [
     48            g_TileClasses.bluff, 20,
     49            g_TileClasses.mountain, 25,
     50            g_TileClasses.plateau, 20,
     51            g_TileClasses.player, 20,
     52            g_TileClasses.valley, 10,
     53            g_TileClasses.water, 15
     54        ],
     55        "sizes": ["big", "huge"],
     56        "mixes": g_AllMixes,
     57        "amounts": g_AllAmounts
     58    },
     59    {
     60        "func": addPlateaus,
     61        "avoid": [
     62            g_TileClasses.bluff, 20,
     63            g_TileClasses.mountain, 25,
     64            g_TileClasses.plateau, 25,
     65            g_TileClasses.player, 40,
     66            g_TileClasses.valley, 10,
     67            g_TileClasses.water, 15
     68        ],
     69        "sizes": ["big", "huge"],
     70        "mixes": g_AllMixes,
     71        "amounts": g_AllAmounts
     72    },
     73    {
     74        "func": addValleys,
     75        "avoid": [g_TileClasses.bluff, 5,
     76            g_TileClasses.hill, 5,
     77            g_TileClasses.mountain, 25,
     78            g_TileClasses.plateau, 10,
     79            g_TileClasses.player, 40,
     80            g_TileClasses.valley, 15,
     81            g_TileClasses.water, 10
     82        ],
     83        "sizes": ["normal", "big"],
     84        "mixes": g_AllMixes,
     85        "amounts": g_AllAmounts
     86    }
     87]));
     88RMS.SetProgress(60);
     89
     90addElements([
     91    {
     92        "func": addLayeredPatches,
     93        "avoid": [
     94            g_TileClasses.bluff, 2,
     95            g_TileClasses.dirt, 5,
     96            g_TileClasses.forest, 2,
     97            g_TileClasses.mountain, 2,
     98            g_TileClasses.plateau, 2,
     99            g_TileClasses.player, 12,
     100            g_TileClasses.valley, 5,
     101            g_TileClasses.water, 3
     102        ],
     103        "sizes": ["normal"],
     104        "mixes": ["normal"],
     105        "amounts": ["normal"]
     106    },
     107    {
     108        "func": addDecoration,
     109        "avoid": [
     110            g_TileClasses.bluff, 2,
     111            g_TileClasses.forest, 2,
     112            g_TileClasses.mountain, 2,
     113            g_TileClasses.plateau, 2,
     114            g_TileClasses.player, 12,
     115            g_TileClasses.water, 3
     116        ],
     117        "sizes": ["normal"],
     118        "mixes": ["normal"],
     119        "amounts": ["normal"]
     120    }
     121]);
     122RMS.SetProgress(70);
     123
     124addElements(shuffleArray([
     125    {
     126        "func": addMetal,
     127        "avoid": [
     128            g_TileClasses.berries, 5,
     129            g_TileClasses.bluff, 5,
     130            g_TileClasses.forest, 3,
     131            g_TileClasses.mountain, 2,
     132            g_TileClasses.plateau, 2,
     133            g_TileClasses.player, 30,
     134            g_TileClasses.rock, 10,
     135            g_TileClasses.metal, 20,
     136            g_TileClasses.water, 3
     137        ],
     138        "sizes": ["normal"],
     139        "mixes": ["same"],
     140        "amounts": g_AllAmounts
     141    },
     142    {
     143        "func": addStone,
     144        "avoid": [
     145            g_TileClasses.berries, 5,
     146            g_TileClasses.bluff, 5,
     147            g_TileClasses.forest, 3,
     148            g_TileClasses.mountain, 2,
     149            g_TileClasses.plateau, 2,
     150            g_TileClasses.player, 30,
     151            g_TileClasses.rock, 20,
     152            g_TileClasses.metal, 10,
     153            g_TileClasses.water, 3
     154        ],
     155        "sizes": ["normal"],
     156        "mixes": ["same"],
     157        "amounts": g_AllAmounts
     158    },
     159    {
     160        "func": addForests,
     161        "avoid": [
     162            g_TileClasses.berries,
     163            5, g_TileClasses.bluff,
     164            5, g_TileClasses.forest,
     165            18, g_TileClasses.metal, 3,
     166            g_TileClasses.mountain, 5,
     167            g_TileClasses.plateau, 5,
     168            g_TileClasses.player, 20,
     169            g_TileClasses.rock, 3,
     170            g_TileClasses.water, 2
     171        ],
     172        "sizes": g_AllSizes,
     173        "mixes": g_AllMixes,
     174        "amounts": ["few", "normal", "many", "tons"]
     175    }
     176]));
     177RMS.SetProgress(80);
     178
     179addElements(shuffleArray([
     180    {
     181        "func": addBerries,
     182        "avoid": [
     183            g_TileClasses.berries, 30,
     184            g_TileClasses.bluff, 5,
     185            g_TileClasses.forest, 5,
     186            g_TileClasses.metal, 10,
     187            g_TileClasses.mountain, 2,
     188            g_TileClasses.plateau, 2,
     189            g_TileClasses.player, 20,
     190            g_TileClasses.rock, 10,
     191            g_TileClasses.spine, 2,
     192            g_TileClasses.water, 3
     193        ],
     194        "sizes": g_AllSizes,
     195        "mixes": g_AllMixes,
     196        "amounts": g_AllAmounts
     197    },
     198    {
     199        "func": addAnimals,
     200        "avoid": [
     201            g_TileClasses.animals, 20,
     202            g_TileClasses.bluff, 5,
     203            g_TileClasses.forest, 2,
     204            g_TileClasses.metal, 2,
     205            g_TileClasses.mountain, 1,
     206            g_TileClasses.plateau, 2,
     207            g_TileClasses.player, 20,
     208            g_TileClasses.rock, 2,
     209            g_TileClasses.spine, 2,
     210            g_TileClasses.water, 3
     211        ],
     212        "sizes": g_AllSizes,
     213        "mixes": g_AllMixes,
     214        "amounts": g_AllAmounts
     215    },
     216    {
     217        "func": addStragglerTrees,
     218        "avoid": [
     219            g_TileClasses.berries, 5,
     220            g_TileClasses.bluff, 5,
     221            g_TileClasses.forest, 7,
     222            g_TileClasses.metal, 2,
     223            g_TileClasses.mountain, 1,
     224            g_TileClasses.plateau, 2,
     225            g_TileClasses.player, 12,
     226            g_TileClasses.rock, 2,
     227            g_TileClasses.spine, 2,
     228            g_TileClasses.water, 5
     229        ],
     230        "sizes": g_AllSizes,
     231        "mixes": g_AllMixes,
     232        "amounts": g_AllAmounts
     233    }
     234]));
     235RMS.SetProgress(90);
     236
     237ExportMap();
  • binaries/data/mods/public/maps/random/stronghold.json

     
     1{
     2  "settings" : {
     3    "Name" : "Stronghold",
     4    "Script" : "stronghold.js",
     5    "Description" : "Teams start off with nearly adjacent town centers, offering easy military and construction cooperation. With slivers of personal territory, teammates must rely on each other to defend their rear.",
     6    "BaseTerrain" : ["medit_sea_depths"],
     7    "BaseHeight" : 30,
     8    "Preview" : "stronghold.png",
     9    "CircularMap" : true
     10  }
     11}