Unify Caledonian Meadows and Wild Lake player location duplication from rP19704 ...
[0ad.git] / binaries / data / mods / public / maps / random / ardennes_forest.js
blob4f7f683ad078f424da9e4e54e3b31cf9a38d081e
1 RMS.LoadLibrary("rmgen");
3 InitMap();
5 const numPlayers = getNumPlayers();
6 const mapSize = getMapSize();
8 const tGrass = ["new_alpine_grass_b", "new_alpine_grass_c", "new_alpine_grass_d"];
9 const tPineForestFloor = "temp_forestfloor_pine";
10 const tForestFloor = [tPineForestFloor, tPineForestFloor, "alpine_dirt_grass_50"];
11 const tCliff = ["alpine_cliff_c", "alpine_cliff_c", "alpine_grass_rocky"];
12 const tCity = ["new_alpine_citytile", "new_alpine_grass_dirt_a"];
13 const tGrassPatch = ["alpine_grass_a", "alpine_grass_b"];
15 const oBoar = "gaia/fauna_boar";
16 const oDeer = "gaia/fauna_deer";
17 const oBear = "gaia/fauna_bear";
18 const oPig = "gaia/fauna_pig";
19 const oBerryBush = "gaia/flora_bush_berry";
20 const oMetalSmall = "gaia/geology_metal_alpine";
21 const oMetalLarge = "gaia/geology_metal_temperate_slabs";
22 const oStoneSmall = "gaia/geology_stone_alpine_a";
23 const oStoneLarge = "gaia/geology_stonemine_temperate_quarry";
25 const oOak = "gaia/flora_tree_oak";
26 const oOakLarge = "gaia/flora_tree_oak_large";
27 const oPine = "gaia/flora_tree_pine";
28 const oAleppoPine = "gaia/flora_tree_aleppo_pine";
30 const aTreeA = "actor|flora/trees/oak.xml";
31 const aTreeB = "actor|flora/trees/oak_large.xml";
32 const aTreeC = "actor|flora/trees/pine.xml";
33 const aTreeD = "actor|flora/trees/aleppo_pine.xml";
35 const aTrees = [aTreeA, aTreeB, aTreeC, aTreeD];
37 const aGrassLarge = "actor|props/flora/grass_soft_large.xml";
38 const aWoodLarge = "actor|props/special/eyecandy/wood_pile_1_b.xml";
39 const aWoodA = "actor|props/special/eyecandy/wood_sm_pile_a.xml";
40 const aWoodB = "actor|props/special/eyecandy/wood_sm_pile_b.xml";
41 const aBarrel = "actor|props/special/eyecandy/barrel_a.xml";
42 const aWheel = "actor|props/special/eyecandy/wheel_laying.xml";
43 const aCeltHomestead = "actor|structures/celts/homestead.xml";
44 const aCeltHouse = "actor|structures/celts/house.xml";
45 const aCeltLongHouse = "actor|structures/celts/longhouse.xml";
47 var pForest = [
48                 tPineForestFloor+TERRAIN_SEPARATOR+oOak, tForestFloor,
49                 tPineForestFloor+TERRAIN_SEPARATOR+oPine, tForestFloor,
50                 tPineForestFloor+TERRAIN_SEPARATOR+oAleppoPine, tForestFloor,
51                 tForestFloor
52                 ];
54 var clPlayer = createTileClass();
55 var clHill = createTileClass();
56 var clForest = createTileClass();
57 var clForestJoin = createTileClass();
58 var clWater = createTileClass();
59 var clRock = createTileClass();
60 var clMetal = createTileClass();
61 var clFood = createTileClass();
62 var clBaseResource = createTileClass();
63 var clHillDeco = createTileClass();
65 log("Creating the central dip...");
66 createArea(
67         new ClumpPlacer(mapSize * scaleByMapSize(70, 300), 0.94, 0.05, 0.1, fractionToTiles(0.5), fractionToTiles(0.5)),
68         [
69                 new LayeredPainter([tCliff, tGrass], [3]),
70                 new SmoothElevationPainter(ELEVATION_SET, 30, 3)
71         ],
72         null);
74 RMS.SetProgress(5);
76 // Find all hills
77 var noise0 = new Noise2D(20);
78 for (var ix = 0; ix < mapSize; ix++)
79         for (var iz = 0; iz < mapSize; iz++)
80         {
81                 var h = getHeight(ix,iz);
82                 if(h > 40){
83                         addToClass(ix,iz,clHill);
85                         // Add hill noise
86                         var x = ix / (mapSize + 1.0);
87                         var z = iz / (mapSize + 1.0);
88                         var n = (noise0.get(x,z) - 0.5) * 40;
89                         setHeight(ix, iz, h + n);
90                 }
91         }
93 var [playerIDs, playerX, playerZ] = radialPlayerPlacement(0.3);
95 function distanceToPlayers(x, z)
97         var r = 10000;
98         for (var i = 0; i < numPlayers; i++)
99         {
100                 var dx = x - playerX[i];
101                 var dz = z - playerZ[i];
102                 r = min(r, dx*dx + dz*dz);
103         }
104         return sqrt(r);
107 function playerNearness(x, z)
109         var d = fractionToTiles(distanceToPlayers(x,z));
111         if (d < 13)
112                 return 0;
114         if (d < 19)
115                 return (d-13)/(19-13);
117         return 1;
120 RMS.SetProgress(10);
122 for (var i=0; i < numPlayers; i++)
124         var id = playerIDs[i];
125         log("Creating base for player " + id + "...");
127         // get the x and z in tiles
128         var fx = fractionToTiles(playerX[i]);
129         var fz = fractionToTiles(playerZ[i]);
130         var ix = round(fx);
131         var iz = round(fz);
133         placeCivDefaultEntities(fx, fz, id);
135         var citySize = 250;
137         var placer = new ClumpPlacer(citySize, 0.95, 0.3, 0.1, ix, iz);
138         createArea(placer, [paintClass(clPlayer)], null);
140         // Create the city patch
141         var placer = new ClumpPlacer(citySize * 0.4, 0.6, 0.05, 10, ix, iz);
142         var painter = new TerrainPainter([tCity]);
143         createArea(placer, painter, null);
145         // Create starter animals
146         placeDefaultChicken(fx, fz, clBaseResource, undefined, oPig);
148         // Create starter berry bushes
149         var bbAngle = randFloat(0, TWO_PI);
150         var bbDist = 12;
151         var bbX = round(fx + bbDist * cos(bbAngle));
152         var bbZ = round(fz + bbDist * sin(bbAngle));
153         group = new SimpleGroup(
154                 [new SimpleObject(oBerryBush, 3,3, 0,3)],
155                 true, clBaseResource, bbX, bbZ
156         );
157         createObjectGroup(group, 0);
159         // Create starter metal mine
160         var mAngle = bbAngle;
161         while(abs(mAngle - bbAngle) < PI/3)
162         {
163                 mAngle = randFloat(0, TWO_PI);
164         }
165         var mDist = bbDist + 4;
166         var mX = round(fx + mDist * cos(mAngle));
167         var mZ = round(fz + mDist * sin(mAngle));
168         group = new SimpleGroup(
169                 [new SimpleObject(oMetalLarge, 1,1, 0,0)],
170                 true, clBaseResource, mX, mZ
171         );
172         createObjectGroup(group, 0);
174         // Create starter stone mines
175         mAngle += randFloat(PI/8, PI/4);
176         mX = round(fx + mDist * cos(mAngle));
177         mZ = round(fz + mDist * sin(mAngle));
178         group = new SimpleGroup(
179                 [new SimpleObject(oStoneLarge, 1,1, 0,2)],
180                 true, clBaseResource, mX, mZ
181         );
182         createObjectGroup(group, 0);
184         // create starting trees
185         var num = 2;
186         var tAngle = randFloat(-PI/3, 4*PI/3);
187         var tDist = randFloat(11, 13);
188         var tX = round(fx + tDist * cos(tAngle));
189         var tZ = round(fz + tDist * sin(tAngle));
190         group = new SimpleGroup(
191                 [new SimpleObject(oOak, num, num, 0,5)],
192                 false, clBaseResource, tX, tZ
193         );
194         createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
198 RMS.SetProgress(30);
200 log("Creating hills...");
201 for (let size of [scaleByMapSize(50, 800), scaleByMapSize(50, 400), scaleByMapSize(10, 30), scaleByMapSize(10, 30)])
203         let mountains = createAreas(
204                 new ClumpPlacer(size, 0.1, 0.2, 0.1),
205                 [
206                         new LayeredPainter([tCliff, [tForestFloor, tForestFloor, tCliff]], [2]),
207                         new SmoothElevationPainter(ELEVATION_SET, 50, size < 50 ? 2 : 4),
208                         paintClass(clHill)
209                 ],
210                 avoidClasses(clPlayer, 8, clBaseResource, 2, clHill, 5),
211                 scaleByMapSize(1, 4));
213         if (size > 100 && mountains.length)
214                 createAreasInAreas(
215                         new ClumpPlacer(size * 0.3, 0.94, 0.05, 0.1),
216                         [
217                                 new LayeredPainter([tCliff, tForestFloor], [2]),
218                                 new SmoothElevationPainter(ELEVATION_MODIFY, 10, 3)
219                         ],
220                         stayClasses(clHill, 4),
221                         mountains.length * 2,
222                         20,
223                         mountains);
225         let ravine = createAreas(
226                 new ClumpPlacer(size, 0.1, 0.2, 0.1),
227                 [
228                         painter,
229                         paintClass(clHill),
230                         new SmoothElevationPainter(ELEVATION_SET, 10, 2)
231                 ],
232                 avoidClasses(clPlayer, 6, clBaseResource, 2, clHill, 5),
233                 scaleByMapSize(1, 3));
235         if (size > 150 && ravine.length)
236         {
237                 log("Placing huts in ravines...");
238                 createObjectGroupsByAreasDeprecated(
239                         new RandomGroup(
240                                 [
241                                         new SimpleObject(aCeltHouse, 0, 1, 4, 5),
242                                         new SimpleObject(aCeltLongHouse, 1, 1, 4, 5)
243                                 ],
244                                 true,
245                                 clHillDeco),
246                         0,
247                         [avoidClasses(clHillDeco, 3), stayClasses(clHill, 3)],
248                         ravine.length * 5, 20,
249                         ravine);
251                 createObjectGroupsByAreasDeprecated(
252                         new RandomGroup([new SimpleObject(aCeltHomestead, 1, 1, 1, 1)], true, clHillDeco),
253                         0,
254                         [avoidClasses(clHillDeco, 5), stayClasses(clHill, 4)],
255                         ravine.length * 2, 100,
256                         ravine);
258                 // Place noise
259                 createAreasInAreas(
260                         new ClumpPlacer(size * 0.3, 0.94, 0.05, 0.1),
261                         [
262                                 new LayeredPainter([tCliff, tForestFloor], [2]),
263                                 new SmoothElevationPainter(ELEVATION_SET, 2, 2)
264                         ],
265                         [avoidClasses(clHillDeco, 2), stayClasses(clHill, 0)],
266                         ravine.length * 2,
267                         20,
268                         ravine);
270                 createAreasInAreas(
271                         new ClumpPlacer(size * 0.1, 0.3, 0.05, 0.1),
272                         [
273                                 new LayeredPainter([tCliff, tForestFloor], [2]),
274                                 new SmoothElevationPainter(ELEVATION_SET, 40, 2),
275                                 paintClass(clHill)
276                         ],
277                         [avoidClasses(clHillDeco, 2), borderClasses(clHill, 15, 1)],
278                         ravine.length * 2,
279                         50,
280                         ravine);
281         }
284 RMS.SetProgress(50);
286 var explorableArea = {};
287 explorableArea.points = [];
289 var playerClass = getTileClass(clPlayer);
290 var hillDecoClass = getTileClass(clHillDeco);
292 for (var ix = 0; ix < mapSize; ix++)
294         for (var iz = 0; iz < mapSize; iz++)
295         {
296                 var h = getHeight(ix,iz);
298                 if(h > 15 && h < 45 && playerClass.countMembersInRadius(ix, iz, 1) == 0)
299                 {
300                         // explorable area
301                         var pt = {};
302                         pt.x = ix;
303                         pt.z = iz;
304                         explorableArea.points.push(pt);
305                 }
307                 if (h > 35 && randBool(0.1) ||
308                     h < 15 && randBool(0.05) && hillDecoClass.countMembersInRadius(ix, iz, 1) == 0)
309                         placeObject(ix + randFloat(0, 1), iz + randFloat(0, 1), pickRandom(aTrees), 0, randFloat(0, 2 * PI));
310         }
313 RMS.SetProgress(55);
315 // Add some general noise - after placing height dependant trees
316 for (var ix = 0; ix < mapSize; ix++)
318         var x = ix / (mapSize + 1.0);
319         for (var iz = 0; iz < mapSize; iz++)
320         {
321                 var z = iz / (mapSize + 1.0);
322                 var h = getHeight(ix,iz);
323                 var pn = playerNearness(x,z);
324                 var n = (noise0.get(x,z) - 0.5) * 10;
325                 setHeight(ix, iz, h + (n * pn));
326         }
329 RMS.SetProgress(60);
331 log("Creating forests...");
332 var [forestTrees, stragglerTrees] = getTreeCounts(400, 6000, 0.8);
333 var [forestTreesJoin, forestTrees] = getTreeCounts(forestTrees, forestTrees, 0.25);
335 var num = forestTrees / (scaleByMapSize(6, 16) * numPlayers);
336 createAreasInAreas(
337         new ClumpPlacer(forestTrees / num, 0.1, 0.1, 1),
338         [
339                 new TerrainPainter(pForest),
340                 paintClass(clForest)
341         ],
342         avoidClasses(clPlayer, 5, clBaseResource, 4, clForest, 6, clHill, 4),
343         num,
344         100,
345         [explorableArea]
348 var num = forestTreesJoin / (scaleByMapSize(4,6) * numPlayers);
349 createAreasInAreas(
350         new ClumpPlacer(forestTreesJoin / num, 0.1, 0.1, 1),
351         [
352                 new TerrainPainter(pForest),
353                 paintClass(clForest),
354                 paintClass(clForestJoin)
355         ],
356         [avoidClasses(clPlayer, 5, clBaseResource, 4, clForestJoin, 5, clHill, 4), borderClasses(clForest, 1, 4)],
357         num,
358         100,
359         [explorableArea]
362 RMS.SetProgress(70);
364 log("Creating grass patches...");
365 for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)])
366         createAreas(
367                 new ClumpPlacer(size, 0.3, 0.06, 0.5),
368                 new LayeredPainter([[tGrass, tGrassPatch], [tGrassPatch, tGrass], [tGrass, tGrassPatch]], [1, 1]),
369                 avoidClasses(clForest, 0, clHill, 2, clPlayer, 5),
370                 scaleByMapSize(15, 45));
372 log("Creating chopped forest patches...");
373 for (let size of [scaleByMapSize(20, 120)])
374         createAreas(
375                 new ClumpPlacer(size, 0.3, 0.06, 0.5),
376                 new TerrainPainter(tForestFloor),
377                 avoidClasses(clForest, 1, clHill, 2, clPlayer, 5),
378                 scaleByMapSize(4, 12));
380 RMS.SetProgress(75);
382 log("Creating stone mines...");
383 var group = new SimpleGroup([new SimpleObject(oStoneSmall, 1,2, 0,4), new SimpleObject(oStoneLarge, 0,1, 0,4)], true, clRock);
384 createObjectGroupsByAreasDeprecated(group, 0,
385         [avoidClasses(clHill, 4, clForest, 2, clPlayer, 20, clRock, 10)],
386         scaleByMapSize(6,20), 100,
387         [explorableArea]
390 log("Creating small stone mines...");
391 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock);
392 createObjectGroupsByAreasDeprecated(group, 0,
393         [avoidClasses(clHill, 4, clForest, 2, clPlayer, 20, clRock, 10)],
394         scaleByMapSize(6,20), 100,
395         [explorableArea]
398 log("Creating metal mines...");
399 group = new SimpleGroup([new SimpleObject(oMetalSmall, 1,2, 0,4), new SimpleObject(oMetalLarge, 0,1, 0,4)], true, clMetal);
400 createObjectGroupsByAreasDeprecated(group, 0,
401         [avoidClasses(clHill, 4, clForest, 2, clPlayer, 20, clMetal, 10, clRock, 5)],
402         scaleByMapSize(6,20), 100,
403         [explorableArea]
406 RMS.SetProgress(80);
408 log("Creating wildlife...");
409 group = new SimpleGroup(
410         [new SimpleObject(oDeer, 5,7, 0,4)],
411         true, clFood
413 createObjectGroupsByAreasDeprecated(group, 0,
414         avoidClasses(clHill, 4, clForest, 0, clPlayer, 0, clBaseResource, 20),
415         3 * numPlayers, 100,
416         [explorableArea]
419 group = new SimpleGroup(
420         [new SimpleObject(oBoar, 2,3, 0,5)],
421         true, clFood
423 createObjectGroupsByAreasDeprecated(group, 0,
424         avoidClasses(clHill, 4, clForest, 0, clPlayer, 0, clBaseResource, 15),
425         numPlayers, 50,
426         [explorableArea]
429 group = new SimpleGroup(
430         [new SimpleObject(oBear, 1,1, 0,4)],
431         false, clFood
433 createObjectGroupsByAreasDeprecated(group, 0,
434         avoidClasses(clHill, 4, clForest, 0, clPlayer, 20),
435         scaleByMapSize(3, 12), 200,
436         [explorableArea]
439 RMS.SetProgress(85);
441 log("Creating berry bush...");
442 group = new SimpleGroup(
443         [new SimpleObject(oBerryBush, 5,7, 0,4)],
444         true, clFood
446 createObjectGroupsDeprecated(group, 0,
447         avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 4, clFood, 20),
448         randIntInclusive(3, 12) * numPlayers + 2, 50
451 log("Creating decorative props...");
452 group = new SimpleGroup(
453         [
454                 new SimpleObject(aWoodA, 1,2, 0,1),
455                 new SimpleObject(aWoodB, 1,3, 0,1),
456                 new SimpleObject(aWheel, 0,2, 0,1),
457                 new SimpleObject(aWoodLarge, 0,1, 0,1),
458                 new SimpleObject(aBarrel, 0,2, 0,1)
459         ],
460         true
462 createObjectGroupsByAreasDeprecated(
463         group, 0,
464         avoidClasses(clForest, 0),
465         scaleByMapSize(5, 50), 50,
466         [explorableArea]
469 RMS.SetProgress(90);
471 log("Creating straggler trees...");
472 var types = [oOak, oOakLarge, oPine, oAleppoPine];
473 var num = Math.floor(stragglerTrees / types.length);
474 for (let type of types)
475         createObjectGroupsByAreasDeprecated(
476                 new SimpleGroup([new SimpleObject(type, 1, 1, 0, 3)], true, clForest),
477                 0,
478                 avoidClasses(clForest, 4, clHill, 5, clPlayer, 10, clBaseResource, 2, clMetal, 5, clRock, 5),
479                 num, 20,
480                 [explorableArea]);
482 RMS.SetProgress(95);
484 log("Creating grass tufts...");
485 group = new SimpleGroup(
486         [new SimpleObject(aGrassLarge, 1,2, 0,1, -PI/8,PI/8)]
488 createObjectGroupsByAreasDeprecated(group, 0,
489         avoidClasses(clHill, 2, clPlayer, 2),
490         scaleByMapSize(50, 300), 20,
491         [explorableArea]
494 setTerrainAmbientColor(0.44,0.51,0.56);
495 setUnitsAmbientColor(0.44,0.51,0.56);
497 ExportMap();