Merge 'remotes/trunk'
[0ad.git] / binaries / data / mods / public / maps / random / archipelago.js
blobb9072b93fe4de53d89001043e288146c7e7978a0
1 Engine.LoadLibrary("rmgen");
2 Engine.LoadLibrary("rmgen-common");
3 Engine.LoadLibrary("rmbiome");
5 function* GenerateMap()
7         TILE_CENTERED_HEIGHT_MAP = true;
9         setSelectedBiome();
11         const biomeTweaks = Engine.ReadJSONFile("maps/random/archipelago_biome_tweaks.json");
13         const tMainTerrain = g_Terrains.mainTerrain;
14         const tForestFloor1 = g_Terrains.forestFloor1;
15         const tForestFloor2 = g_Terrains.forestFloor2;
16         const tCliff = g_Terrains.cliff;
17         const tTier1Terrain = g_Terrains.tier1Terrain;
18         const tTier2Terrain = g_Terrains.tier2Terrain;
19         const tTier3Terrain = g_Terrains.tier3Terrain;
20         const tHill = g_Terrains.hill;
21         const tTier4Terrain = g_Terrains.dirt;
22         const tRoad = g_Terrains.road;
23         const tRoadWild = g_Terrains.roadWild;
24         const tShore = g_Terrains.shore;
25         const tWater = g_Terrains.water;
27         const oTree1 = g_Gaia.tree1;
28         const oTree2 = g_Gaia.tree2;
29         const oTree3 = g_Gaia.tree3;
30         const oTree4 = g_Gaia.tree4;
31         const oTree5 = g_Gaia.tree5;
32         const oFruitBush = g_Gaia.fruitBush;
33         const oMainHuntableAnimal = g_Gaia.mainHuntableAnimal;
34         const oFish = g_Gaia.fish;
35         const oSecondaryHuntableAnimal = g_Gaia.secondaryHuntableAnimal;
36         const oStoneLarge = g_Gaia.stoneLarge;
37         const oStoneSmall = g_Gaia.stoneSmall;
38         const oMetalLarge = g_Gaia.metalLarge;
39         const oWoodTreasure = "gaia/treasure/wood";
41         const aGrass = g_Decoratives.grass;
42         const aGrassShort = g_Decoratives.grassShort;
43         const aRockLarge = g_Decoratives.rockLarge;
44         const aRockMedium = g_Decoratives.rockMedium;
45         const aBushMedium = g_Decoratives.bushMedium;
46         const aBushSmall = g_Decoratives.bushSmall;
48         const pForest1 = [
49                 tForestFloor2 + TERRAIN_SEPARATOR + oTree1,
50                 tForestFloor2 + TERRAIN_SEPARATOR + oTree2,
51                 tForestFloor2
52         ];
53         const pForest2 = [
54                 tForestFloor1 + TERRAIN_SEPARATOR + oTree4,
55                 tForestFloor1 + TERRAIN_SEPARATOR + oTree5,
56                 tForestFloor1
57         ];
59         const heightSeaGround = -5;
60         const heightLand = 3;
61         const heightShore = 1;
63         globalThis.g_Map = new RandomMap(heightSeaGround, tWater);
65         const numPlayers = getNumPlayers();
67         const clPlayer = g_Map.createTileClass();
68         const clHill = g_Map.createTileClass();
69         const clForest = g_Map.createTileClass();
70         const clDirt = g_Map.createTileClass();
71         const clRock = g_Map.createTileClass();
72         const clMetal = g_Map.createTileClass();
73         const clFood = g_Map.createTileClass();
74         const clBaseResource = g_Map.createTileClass();
75         const clLand = g_Map.createTileClass();
77         const islandRadius = scaleByMapSize(22, 31);
79         const [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35));
81         g_Map.log("Creating player islands");
82         for (let i = 0; i < numPlayers; ++i)
83                 createArea(
84                         new ChainPlacer(
85                                 2,
86                                 Math.floor(scaleByMapSize(5, 10)),
87                                 Math.floor(scaleByMapSize(25, 60)),
88                                 Infinity,
89                                 playerPosition[i],
90                                 0,
91                                 [Math.floor(islandRadius)]),
92                         [
93                                 new SmoothElevationPainter(ELEVATION_SET, heightLand, 4),
94                                 new TileClassPainter(clLand)
95                         ]);
97         g_Map.log("Creating random islands");
98         createAreas(
99                 new ChainPlacer(
100                         Math.floor(scaleByMapSize(4, 8)),
101                         Math.floor(scaleByMapSize(8, 14)),
102                         Math.floor(scaleByMapSize(25, 60)),
103                         0.07,
104                         undefined,
105                         scaleByMapSize(30, 70)),
106                 [
107                         new SmoothElevationPainter(ELEVATION_SET, heightLand, 4),
108                         new TileClassPainter(clLand)
109                 ],
110                 null,
111                 scaleByMapSize(1, 5) * randIntInclusive(5, 10));
113         paintTerrainBasedOnHeight(heightLand - 0.6, heightLand + 0.4, 3, tMainTerrain);
114         paintTerrainBasedOnHeight(heightShore, heightLand, 0, tShore);
115         paintTerrainBasedOnHeight(heightSeaGround, heightShore, 2, tWater);
117         placePlayerBases({
118                 "PlayerPlacement": [playerIDs, playerPosition],
119                 // PlayerTileClass marked below
120                 "BaseResourceClass": clBaseResource,
121                 "Walls": "towers",
122                 "CityPatch": {
123                         "outerTerrain": tRoadWild,
124                         "innerTerrain": tRoad,
125                         "radius": islandRadius / 3,
126                         "painters": [
127                                 new TileClassPainter(clPlayer)
128                         ]
129                 },
130                 "StartingAnimal": {
131                 },
132                 "Berries": {
133                         "template": oFruitBush
134                 },
135                 "Mines": {
136                         "types": [
137                                 { "template": oMetalLarge },
138                                 { "template": oStoneLarge }
139                         ]
140                 },
141                 "Treasures": {
142                         "types": [
143                                 {
144                                         "template": oWoodTreasure,
145                                         "count": 14
146                                 }
147                         ]
148                 },
149                 "Trees": {
150                         "template": oTree1,
151                         "count": scaleByMapSize(15, 30)
152                 },
153                 "Decoratives": {
154                         "template": aGrassShort,
155                 }
156         });
158         createBumps([avoidClasses(clPlayer, 10), stayClasses(clLand, 5)]);
160         if (randBool())
161                 createHills([tMainTerrain, tCliff, tHill],
162                         [avoidClasses(clPlayer, 2, clHill, 15), stayClasses(clLand, 0)],
163                         clHill,
164                         scaleByMapSize(1, 4) * numPlayers);
165         else
166                 createMountains(tCliff,
167                         [avoidClasses(clPlayer, 2, clHill, 15), stayClasses(clLand, 0)],
168                         clHill,
169                         scaleByMapSize(1, 4) * numPlayers);
171         // adjust biomes (especially wood)
172         const biomeSpecifics = biomeTweaks[currentBiome()] || biomeTweaks.baseline;
174         const [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(biomeSpecifics.treeAmount));
175         createForests(
176                 [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2],
177                 [
178                         avoidClasses(
179                                 clPlayer, biomeSpecifics.forestPlayerSpacing,
180                                 clForest, biomeSpecifics.forestForestSpacing,
181                                 clHill, 0),
182                         stayClasses(clLand, 3)
183                 ],
184                 clForest,
185                 forestTrees
186         );
187         yield 50;
189         g_Map.log("Creating dirt patches");
190         createLayeredPatches(
191                 [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)],
192                 [[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]],
193                 [1, 1],
194                 [avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 12), stayClasses(clLand, 7)],
195                 scaleByMapSize(15, 45),
196                 clDirt
197         );
199         g_Map.log("Creating grass patches");
200         createPatches(
201                 [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)],
202                 tTier4Terrain,
203                 [avoidClasses(clForest, 0, clHill, 0, clDirt, 3, clPlayer, 12), stayClasses(clLand, 7)],
204                 scaleByMapSize(15, 45),
205                 clDirt
206         );
207         yield 55;
209         g_Map.log("Creating stone mines");
210         createMines(
211                 [
212                         [
213                                 new SimpleObject(oStoneSmall, 0, 2, 0, 4, 0, 2 * Math.PI, 1),
214                                 new SimpleObject(oStoneLarge, 1, 1, 0, 4)
215                         ],
216                         [new SimpleObject(oStoneSmall, 2, 5, 1, 3)]
217                 ],
218                 [avoidClasses(clForest, 1, clPlayer, 7, clRock, 10, clHill, 1), stayClasses(clLand, 6)],
219                 clRock
220         );
222         g_Map.log("Creating metal mines");
223         createMines(
224                 [[new SimpleObject(oMetalLarge, 1, 1, 0, 4)]],
225                 [
226                         avoidClasses(clForest, 1, clPlayer, 7, clMetal, 10, clRock, 5, clHill, 1),
227                         stayClasses(clLand, 6)
228                 ],
229                 clMetal
230         );
231         yield 65;
233         const planetm = currentBiome() == "generic/india" ? 8 : 1;
234         createDecoration(
235                 [
236                         [new SimpleObject(aRockMedium, 1, 3, 0, 1)],
237                         [new SimpleObject(aRockLarge, 1, 2, 0, 1), new SimpleObject(aRockMedium, 1, 3, 0, 2)],
238                         [new SimpleObject(aGrassShort, 1, 2, 0, 1)],
239                         [new SimpleObject(aGrass, 2, 4, 0, 1.8), new SimpleObject(aGrassShort, 3, 6, 1.2, 2.5)],
240                         [new SimpleObject(aBushMedium, 1, 2, 0, 2), new SimpleObject(aBushSmall, 2, 4, 0, 2)]
241                 ],
242                 [
243                         scaleByMapAreaAbsolute(16),
244                         scaleByMapAreaAbsolute(8),
245                         planetm * scaleByMapAreaAbsolute(13),
246                         planetm * scaleByMapAreaAbsolute(13),
247                         planetm * scaleByMapAreaAbsolute(13)
248                 ],
249                 [avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 5)]);
250         yield 70;
252         createFood(
253                 [
254                         [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)],
255                         [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)]
256                 ],
257                 [
258                         3 * numPlayers,
259                         3 * numPlayers
260                 ],
261                 [avoidClasses(clForest, 0, clPlayer, 1, clHill, 1, clFood, 20), stayClasses(clLand, 3)],
262                 clFood);
264         yield 75;
266         createFood(
267                 [
268                         [new SimpleObject(oFruitBush, 5, 7, 0, 4)]
269                 ],
270                 [
271                         3 * numPlayers
272                 ],
273                 [avoidClasses(clForest, 0, clPlayer, 1, clHill, 1, clFood, 10), stayClasses(clLand, 3)],
274                 clFood);
276         yield 80;
278         createFood(
279                 [
280                         [new SimpleObject(oFish, 2, 3, 0, 2)]
281                 ],
282                 [
283                         25 * numPlayers
284                 ],
285                 avoidClasses(clLand, 3, clPlayer, 2, clFood, 20),
286                 clFood);
288         yield 85;
290         createStragglerTrees(
291                 [oTree1, oTree2, oTree4, oTree3],
292                 [
293                         avoidClasses(clForest, 7, clHill, 1, clPlayer, 3, clMetal, 6, clRock, 6),
294                         stayClasses(clLand, 7)
295                 ],
296                 clForest,
297                 stragglerTrees);
299         placePlayersNomad(
300                 clPlayer,
301                 new AndConstraint([
302                         stayClasses(clLand, 4),
303                         avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)]));
305         setWaterWaviness(4.0);
306         setWaterType("ocean");
308         return g_Map;