Replace deprecated randInt calls (besides those in the Unknown maps).
[0ad.git] / binaries / data / mods / public / maps / random / northern_lights.js
blob4d44db00fe790ba0b73004f682c674cb69028c23
1 RMS.LoadLibrary("rmgen");
3 const tSnowA = ["polar_snow_b"];
4 const tSnowB = "polar_ice_snow";
5 const tSnowC = "polar_ice";
6 const tSnowD = "polar_snow_a";
7 const tForestFloor = "polar_tundra_snow";
8 const tCliff = "polar_snow_rocks";
9 const tSnowE = ["polar_snow_glacial"];
10 const tRoad = "new_alpine_citytile";
11 const tRoadWild = "new_alpine_citytile";
12 const tShoreBlend = "alpine_shore_rocks_icy";
13 const tShore = "alpine_shore_rocks";
14 const tWater = "alpine_shore_rocks";
16 // gaia entities
17 const oPine = "gaia/flora_tree_pine_w";
18 const oStoneLarge = "gaia/geology_stonemine_alpine_quarry";
19 const oStoneSmall = "gaia/geology_stone_alpine_a";
20 const oMetalLarge = "gaia/geology_metal_alpine_slabs";
21 const oFish = "gaia/fauna_fish";
22 const oWalrus = "gaia/fauna_walrus";
23 const oWolf = "gaia/fauna_wolf_snow";
25 // decorative props
26 const aRockLarge = "actor|geology/stone_granite_med.xml";
27 const aRockMedium = "actor|geology/stone_granite_med.xml";
28 const aIceberg = "actor|props/special/eyecandy/iceberg.xml";
30 const pForestD = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor, tForestFloor];
31 const pForestS = [tForestFloor + TERRAIN_SEPARATOR + oPine, tForestFloor, tForestFloor, tForestFloor];
33 log("Initializing map...");
35 InitMap();
37 const numPlayers = getNumPlayers();
38 const mapSize = getMapSize();
39 const mapArea = mapSize*mapSize;
41 // create tile classes
43 var clPlayer = createTileClass();
44 var clHill = createTileClass();
45 var clHill2 = createTileClass();
46 var clHill3 = createTileClass();
47 var clHill4 = createTileClass();
48 var clForest = createTileClass();
49 var clWater = createTileClass();
50 var clDirt = createTileClass();
51 var clRock = createTileClass();
52 var clMetal = createTileClass();
53 var clFood = createTileClass();
54 var clBaseResource = createTileClass();
55 var clSettlement = createTileClass();
58 // randomize player order
59 var playerIDs = [];
60 for (var i = 0; i < numPlayers; i++)
62         playerIDs.push(i+1);
64 playerIDs = sortPlayers(playerIDs);
66 // place players
68 var playerX = new Array(numPlayers);
69 var playerZ = new Array(numPlayers);
70 var playerPos = new Array(numPlayers);
72 for (var i = 0; i < numPlayers; i++)
74         playerPos[i] = (i + 1) / (numPlayers + 1);
75         playerX[i] = playerPos[i];
76         playerZ[i] = 0.35 + 0.2*(i%2);
79 for (var i = 0; i < numPlayers; i++)
81         var id = playerIDs[i];
82         log("Creating base for player " + id + "...");
84         // some constants
85         var radius = scaleByMapSize(15,25);
86         var cliffRadius = 2;
87         var elevation = 20;
89         // get the x and z in tiles
90         var fx = fractionToTiles(playerX[i]);
91         var fz = fractionToTiles(playerZ[i]);
92         var ix = round(fx);
93         var iz = round(fz);
94         addToClass(ix, iz, clPlayer);
95         addToClass(ix+5, iz, clPlayer);
96         addToClass(ix, iz+5, clPlayer);
97         addToClass(ix-5, iz, clPlayer);
98         addToClass(ix, iz-5, clPlayer);
100         // create the city patch
101         var cityRadius = radius/3;
102         var placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
103         var painter = new LayeredPainter([tRoadWild, tRoad], [1]);
104         createArea(placer, painter, null);
106         // create starting units
107         placeCivDefaultEntities(fx, fz, id);
109         // create metal mine
110         var bbAngle = randFloat(0, TWO_PI);
111         var bbDist = 12;
112         var bbX = round(fx + bbDist * cos(bbAngle));
113         var bbZ = round(fz + bbDist * sin(bbAngle));
114         var mAngle = bbAngle;
115         while(abs(mAngle - bbAngle) < PI/3)
116         {
117                 mAngle = randFloat(0, TWO_PI);
118         }
119         var mDist = 12;
120         var mX = round(fx + mDist * cos(mAngle));
121         var mZ = round(fz + mDist * sin(mAngle));
122         var group = new SimpleGroup(
123                 [new SimpleObject(oMetalLarge, 1,1, 0,0)],
124                 true, clBaseResource, mX, mZ
125         );
126         createObjectGroup(group, 0);
128         // create stone mines
129         mAngle += randFloat(PI/8, PI/4);
130         mX = round(fx + mDist * cos(mAngle));
131         mZ = round(fz + mDist * sin(mAngle));
132         group = new SimpleGroup(
133                 [new SimpleObject(oStoneLarge, 1,1, 0,2)],
134                 true, clBaseResource, mX, mZ
135         );
136         createObjectGroup(group, 0);
137         var hillSize = PI * radius * radius;
138         // create starting trees
139         var num = floor(hillSize / 60);
140         var tAngle = randFloat(-PI/3, 4*PI/3);
141         var tDist = randFloat(12, 13);
142         var tX = round(fx + tDist * cos(tAngle));
143         var tZ = round(fz + tDist * sin(tAngle));
144         group = new SimpleGroup(
145                 [new SimpleObject(oPine, num, num, 0,3)],
146                 false, clBaseResource, tX, tZ
147         );
148         createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
152 RMS.SetProgress(15);
154 // create northern sea
155 var fadedistance = 8;
157 for (var ix = 0; ix < mapSize; ix++)
159         for (var iz = 0; iz < mapSize; iz++)
160         {
162                 if (iz > 0.69 * mapSize)
163                 {
164                         if (iz < 0.69 * mapSize + fadedistance)
165                         {
166                                 setHeight(ix, iz, 3 - 8 * (iz - 0.69 * mapSize) / fadedistance);
167                                 if (ix, iz, 3 - 8 * (iz - 0.69 * mapSize) / fadedistance < 0.5)
168                                         addToClass(ix, iz, clWater);
169                         }
170                         else
171                         {
172                                 setHeight(ix, iz, -5);
173                                 addToClass(ix, iz, clWater);
174                         }
175                 }
176         }
179 // create shore
180 log("Creating shores...");
181 for (var i = 0; i < scaleByMapSize(20,120); i++)
183         placer = new ChainPlacer(
184                 1,
185                 Math.floor(scaleByMapSize(4, 6)),
186                 Math.floor(scaleByMapSize(16, 30)),
187                 1,
188                 randIntExclusive(0.1 * mapSize, 0.9 * mapSize),
189                 randIntExclusive(0.67 * mapSize, 0.74 * mapSize));
191         var terrainPainter = new LayeredPainter(
192                 [tSnowA, tSnowA],               // terrains
193                 [2]                                                             // widths
194         );
195         var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3);
196         createArea(
197                 placer,
198                 [terrainPainter, elevationPainter, unPaintClass(clWater)],
199                 null
200         );
203 // create islands
204 log("Creating islands...");
205 placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(16, 40)), 0.1);
206 var terrainPainter = new LayeredPainter(
207         [tSnowA, tSnowA],               // terrains
208         [3]                                                             // widths
210 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 3);
211 createAreas(
212         placer,
213         [terrainPainter, elevationPainter, unPaintClass(clWater)],
214         stayClasses(clWater, 7),
215         scaleByMapSize(10, 80)
218 paintTerrainBasedOnHeight(-6, 1, 1, tWater);
220 // create lakes
221 log("Creating lakes...");
222 var numLakes = round(scaleByMapSize(1,4) * numPlayers);
223 var placer = new ChainPlacer(1, floor(scaleByMapSize(5, 7)), floor(scaleByMapSize(20, 50)), 0.1);
224 var terrainPainter = new LayeredPainter(
225         [tShoreBlend, tShore, tWater],          // terrains
226         [1,1]                                                   // widths
228 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 3);
229 var waterAreas = createAreas(
230         placer,
231         [terrainPainter, elevationPainter, paintClass(clWater)],
232         avoidClasses(clPlayer, 20, clWater, 20),
233         numLakes
236 paintTerrainBasedOnHeight(1, 2.8, 1, tShoreBlend);
237 paintTileClassBasedOnHeight(-6, 0.5, 1, clWater);
239 RMS.SetProgress(45);
241 // create hills
242 log("Creating hills...");
243 placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(16, 40)), 0.1);
244 var terrainPainter = new LayeredPainter(
245         [tCliff, tSnowA],               // terrains
246         [3]                                                             // widths
248 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 25, 3);
249 createAreas(
250         placer,
251         [terrainPainter, elevationPainter, paintClass(clHill)],
252         avoidClasses(clPlayer, 20, clHill, 15, clWater, 2, clBaseResource, 2),
253         scaleByMapSize(1, 4) * numPlayers
257 // calculate desired number of trees for map (based on size)
259 var MIN_TREES = 100;
260 var MAX_TREES = 625;
261 var P_FOREST = 0.7;
263 var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES);
264 var numForest = totalTrees * P_FOREST;
265 var numStragglers = totalTrees * (1.0 - P_FOREST);
267 // create forests
268 log("Creating forests...");
269 var types = [
270         [[tSnowA, tSnowA, tSnowA, tSnowA, pForestD], [tSnowA, tSnowA, tSnowA, pForestD]],
271         [[tSnowA, tSnowA, tSnowA, tSnowA, pForestS], [tSnowA, tSnowA, tSnowA, pForestS]]
272 ];      // some variation
275 var size = numForest / (scaleByMapSize(3,6) * numPlayers);
277 var num = floor(size / types.length);
278 for (var i = 0; i < types.length; ++i)
280         placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), numForest / (num * floor(scaleByMapSize(2,4))), 1);
281         painter = new LayeredPainter(
282                 types[i],               // terrains
283                 [2]                                                                                     // widths
284                 );
285         createAreas(
286                 placer,
287                 [painter, paintClass(clForest)],
288                 avoidClasses(clPlayer, 20, clForest, 20, clHill, 0, clWater, 8),
289                 num
290         );
293 log("Creating iceberg...");
294 // create iceberg
295 group = new SimpleGroup([new SimpleObject(aIceberg, 0,2, 0,4)], true, clRock);
296 createObjectGroups(group, 0,
297         [avoidClasses(clRock, 6), stayClasses(clWater, 4)],
298         scaleByMapSize(4,16), 100
301 RMS.SetProgress(70);
303 // create dirt patches
304 log("Creating dirt patches...");
305 var sizes = [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)];
306 for (var i = 0; i < sizes.length; i++)
308         placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5);
309         painter = new LayeredPainter(
310                 [tSnowD,tSnowB,tSnowC],                 // terrains
311                 [2,1]                                                                                                                   // widths
312         );
313         createAreas(
314                 placer,
315                 [painter, paintClass(clDirt)],
316                 avoidClasses(clWater, 8, clForest, 0, clHill, 0, clPlayer, 20, clDirt, 16),
317                 scaleByMapSize(20, 80)
318         );
320 var sizes = [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)];
321 for (var i = 0; i < sizes.length; i++)
323         placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5);
324         painter = new LayeredPainter(
325                 [tSnowE,tSnowE],                // terrains
326                 [1]                                                                                                                     // widths
327         );
328         createAreas(
329                 placer,
330                 [painter, paintClass(clDirt)],
331                 avoidClasses(clWater, 8, clForest, 0, clHill, 0, clPlayer, 20, clDirt, 16),
332                 scaleByMapSize(20, 80)
333         );
336 log("Creating stone mines...");
337 // create large stone quarries
338 group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock);
339 createObjectGroups(group, 0,
340         avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
341         scaleByMapSize(8,32), 100
344 // create small stone quarries
345 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock);
346 createObjectGroups(group, 0,
347         avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
348         scaleByMapSize(8,32), 100
351 log("Creating metal mines...");
352 // create large metal quarries
353 group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal);
354 createObjectGroups(group, 0,
355         avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1),
356         scaleByMapSize(8,32), 100
360 RMS.SetProgress(95);
362 // create straggler trees
363 log("Creating straggler trees...");
364 var types = [oPine];    // some variation
365 var num = floor(numStragglers / types.length);
366 for (var i = 0; i < types.length; ++i)
368         group = new SimpleGroup(
369                 [new SimpleObject(types[i], 1,1, 0,3)],
370                 true, clForest
371         );
372         createObjectGroups(group, 0,
373                 avoidClasses(clWater, 5, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 6, clRock, 6),
374                 num
375         );
378 // create deer
379 log("Creating deer...");
380 group = new SimpleGroup(
381         [new SimpleObject(oWalrus, 5,7, 0,4)],
382         true, clFood
384 createObjectGroups(group, 0,
385         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20),
386         3 * numPlayers, 50
389 RMS.SetProgress(75);
391 // create sheep
392 log("Creating sheep...");
393 group = new SimpleGroup(
394         [new SimpleObject(oWolf, 2,3, 0,2)],
395         true, clFood
397 createObjectGroups(group, 0,
398         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 20),
399         3 * numPlayers, 50
402 // create fish
403 log("Creating fish...");
404 group = new SimpleGroup(
405         [new SimpleObject(oFish, 2,3, 0,2)],
406         true, clFood
408 createObjectGroups(group, 0,
409         [avoidClasses(clFood, 20), stayClasses(clWater, 6)],
410         25 * numPlayers, 60
413 setSunColor(0.6, 0.6, 0.6);
414 setSunElevation(PI/ 6);
416 setWaterColor(0.02, 0.17, 0.52);
417 setWaterTint(0.494, 0.682, 0.808);
418 setWaterMurkiness(0.82);
419 setWaterWaviness(0.5);
420 setWaterType("ocean");
422 setFogFactor(0.95);
423 setFogThickness(0.09);
424 setPPSaturation(0.28);
425 setPPEffect("hdr");
427 setSkySet("fog");
428 ExportMap();