Remove rmgen euclidian distance helper function, refs rP20328 / D969.
[0ad.git] / binaries / data / mods / public / maps / random / oasis.js
blob4e236eaa6085e9b1f6468fa0ff3f59670a112df2
1 RMS.LoadLibrary("rmgen");
3 const tSand = ["desert_sand_dunes_100", "desert_dirt_cracks","desert_sand_smooth", "desert_dirt_rough", "desert_dirt_rough_2", "desert_sand_smooth"];
4 const tDune = ["desert_sand_dunes_50"];
5 const tForestFloor = "desert_forestfloor_palms";
6 const tDirt = ["desert_dirt_rough","desert_dirt_rough","desert_dirt_rough", "desert_dirt_rough_2", "desert_dirt_rocks_2"];
7 const tRoad = "desert_city_tile";;
8 const tRoadWild = "desert_city_tile";;
9 const tShoreBlend = "desert_sand_wet";
10 const tShore = "dirta";
11 const tWater = "desert_sand_wet";
13 const ePalmShort = "gaia/flora_tree_cretan_date_palm_short";
14 const ePalmTall = "gaia/flora_tree_cretan_date_palm_tall";
15 const eBush = "gaia/flora_bush_grapes";
16 const eCamel = "gaia/fauna_camel";
17 const eGazelle = "gaia/fauna_gazelle";
18 const eLion = "gaia/fauna_lion";
19 const eLioness = "gaia/fauna_lioness";
20 const eStoneMine = "gaia/geology_stonemine_desert_quarry";
21 const eMetalMine = "gaia/geology_metal_desert_slabs";
23 const aFlower1 = "actor|props/flora/decals_flowers_daisies.xml";
24 const aWaterFlower = "actor|props/flora/water_lillies.xml";
25 const aReedsA = "actor|props/flora/reeds_pond_lush_a.xml";
26 const aReedsB = "actor|props/flora/reeds_pond_lush_b.xml";
27 const aRock = "actor|geology/stone_desert_med.xml";
28 const aBushA = "actor|props/flora/bush_desert_dry_a.xml";
29 const aBushB = "actor|props/flora/bush_desert_dry_a.xml";
30 const aSand = "actor|particle/blowing_sand.xml";
32 const pForestMain = [tForestFloor + TERRAIN_SEPARATOR + ePalmShort, tForestFloor + TERRAIN_SEPARATOR + ePalmTall, tForestFloor];
33 const pOasisForestLight = [tForestFloor + TERRAIN_SEPARATOR + ePalmShort, tForestFloor + TERRAIN_SEPARATOR + ePalmTall, tForestFloor,tForestFloor,tForestFloor
34                                         ,tForestFloor,tForestFloor,tForestFloor,tForestFloor];
36 InitMap();
38 const numPlayers = getNumPlayers();
39 const mapSize = getMapSize();
41 var clPlayer = createTileClass();
42 var clHill = createTileClass();
43 var clForest = createTileClass();
44 var clWater = createTileClass();
45 var clPassage = createTileClass();
46 var clRock = createTileClass();
47 var clMetal = createTileClass();
48 var clFood = createTileClass();
49 var clBaseResource = createTileClass();
51 initTerrain(tSand);
53 var [playerIDs, playerX, playerZ] = radialPlayerPlacement();
55 var placer = undefined;
56 var fx = 0; var fz = 0;
57 var ix =0; var iz = 0;
58 for (var i = 0; i < numPlayers; i++)
60         var id = playerIDs[i];
61         log("Creating base for player " + id + "...");
63         var radius = scaleByMapSize(15,25);
64         var elevation = 20;
66         // get the x and z in tiles
67         fx = fractionToTiles(playerX[i]);
68         fz = fractionToTiles(playerZ[i]);
69         ix = round(fx);
70         iz = round(fz);
71         addCivicCenterAreaToClass(ix, iz, clPlayer);
73         // create the city patch
74         var cityRadius = radius/3;
75         placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
76         var painter = new LayeredPainter([tRoadWild, tRoad], [1]);
77         createArea(placer, painter, null);
79         placeCivDefaultEntities(fx, fz, id);
81         placeDefaultChicken(fx, fz, clBaseResource);
83         // create berry bushes
84         var bbAngle = randFloat(0, TWO_PI);
85         var bbDist = 12;
86         var bbX = round(fx + bbDist * cos(bbAngle));
87         var bbZ = round(fz + bbDist * sin(bbAngle));
88         var group = new SimpleGroup(
89                 [new SimpleObject(eBush, 5,5, 0,3)],
90                 true, clBaseResource, bbX, bbZ
91         );
92         createObjectGroup(group, 0);
94         // create metal mine
95         var mAngle = bbAngle;
96         while(abs(mAngle - bbAngle) < PI/3)
97         {
98                 mAngle = randFloat(0, TWO_PI);
99         }
100         var mDist = radius*1.3;
101         var mX = round(fx + mDist * cos(mAngle));
102         var mZ = round(fz + mDist * sin(mAngle));
103         group = new SimpleGroup(
104                 [new SimpleObject(eMetalMine, 1,1, 0,0),new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3),new SimpleObject(ePalmShort, 2,2, 2,3),new SimpleObject(ePalmTall, 1,1, 2,2)],
105                 true, clBaseResource, mX, mZ
106         );
107         createObjectGroup(group, 0);
108         mX = round(fx + mDist*1.5 * cos(mAngle + PI/1.578));
109         mZ = round(fz + mDist*1.5 * sin(mAngle + PI/1.578));
110         group = new SimpleGroup(
111                                                         [new SimpleObject(eMetalMine, 1,1, 0,0),new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3),new SimpleObject(ePalmShort, 2,2, 2,3),new SimpleObject(ePalmTall, 1,1, 2,2)],
112                                                         true, clBaseResource, mX, mZ
113                                                         );
114         createObjectGroup(group, 0);
116         // create stone mines
117         mAngle += randFloat(PI/8, PI/4);
118         mX = round(fx + mDist * cos(mAngle));
119         mZ = round(fz + mDist * sin(mAngle));
120         group = new SimpleGroup(
121                 [new SimpleObject(eStoneMine, 1,1, 0,2),new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3),new SimpleObject(ePalmShort, 2,2, 2,3),new SimpleObject(ePalmTall, 1,1, 2,2)],
122                 true, clBaseResource, mX, mZ
123         );
124         createObjectGroup(group, 0);
125         mX = round(fx + mDist * 1.4 * cos(mAngle - PI /2.46));
126         mZ = round(fz + mDist * 1.4 * sin(mAngle - PI /2.46));
127         group = new SimpleGroup(
128                                                         [new SimpleObject(eStoneMine, 1,1, 0,2),new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 3,3),new SimpleObject(ePalmShort, 2,2, 3,3),new SimpleObject(ePalmTall, 1,1, 3,3)],
129                                                         true, clBaseResource, mX, mZ
130                                                         );
131         createObjectGroup(group, 0);
133         // Create starting batches of wood
134         let forestX = 0;
135         let forestY = 0;
136         let forestAngle = 0
137         let forestDist = radius * 1.2;
139         do {
140                 forestAngle = Math.PI / 3 * randFloat(1, 2);
141                 forestX = Math.round(fx + forestDist * Math.cos(forestAngle));
142                 forestY = Math.round(fz + forestDist * Math.sin(forestAngle));
143         } while (
144                 !createArea(
145                         new ClumpPlacer(70, 1, 0.5, 10, forestX, forestY),
146                         [
147                                 new LayeredPainter([tForestFloor, pForestMain], [0]),
148                                 paintClass(clBaseResource)
149                         ],
150                         avoidClasses(clBaseResource, 0)));
152         // Creating the water patch explaining the forest
153         do {
154                 var watAngle = forestAngle + randFloat((PI/3), (5*PI/3));
155                 var watX = round(forestX + 6 * cos(watAngle));
156                 var watY = round(forestY + 6 * sin(watAngle));
158                 createObjectGroup(
159                         new SimpleGroup(
160                                 [new SimpleObject(aFlower1, 1, 5, 0, 3)],
161                                 true,
162                                 undefined,
163                                 Math.round(forestX + 3 * Math.cos(watAngle)),
164                                 Math.round(forestY + 3 * Math.sin(watAngle))),
165                         0);
167                 createObjectGroup(
168                         new SimpleGroup(
169                                 [new SimpleObject(aReedsA, 1, 3, 0, 0)],
170                                 true,
171                                 undefined,
172                                 Math.round(forestX + 5 * Math.cos(watAngle)),
173                                 Math.round(forestY + 5 * Math.sin(watAngle))),
174                         0);
176         } while (
177                 !createArea(
178                         new ClumpPlacer(60, 0.9, 0.4, 5, watX, watY),
179                         [
180                                 new LayeredPainter([tShore, tShoreBlend], [1]),
181                                 new SmoothElevationPainter(ELEVATION_MODIFY, -5, 3)
182                         ],
183                         avoidClasses(clBaseResource, 0)));
185 RMS.SetProgress(20);
187 log("Creating bumps...");
188 createAreas(
189         new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1),
190         new SmoothElevationPainter(ELEVATION_MODIFY, 4, 3),
191         avoidClasses(clPlayer, 10, clBaseResource, 6),
192         scaleByMapSize(30, 70));
194 log("Creating dirt Patches...");
195 createAreas(
196         new ClumpPlacer(80, 0.3, 0.06, 1),
197         new TerrainPainter(tDirt),
198         avoidClasses(clPlayer, 10, clBaseResource, 6),
199         scaleByMapSize(15, 50));
201 log("Creating Dunes...");
202 createAreas(
203         new ClumpPlacer(120, 0.3, 0.06, 1),
204         [
205                 new TerrainPainter(tDune),
206                 new SmoothElevationPainter(ELEVATION_MODIFY, 18, 30)
207         ],
208         avoidClasses(clPlayer, 10, clBaseResource, 6),
209         scaleByMapSize(15, 50));
211 log("Creating actual oasis...");
212 var fx = fractionToTiles(0.5);
213 var fz = fractionToTiles(0.5);
214 createArea(
215         new ClumpPlacer(Math.square(mapSize * 0.2) * 1.1, 0.8, 0.2, 10, Math.round(fx), Math.round(fz)),
216         [
217                 new LayeredPainter([pOasisForestLight,tShoreBlend, tWater, tWater, tWater], [scaleByMapSize(6, 20), 3, 5, 2]),
218                 new SmoothElevationPainter(ELEVATION_SET, -3, 15),
219                 paintClass(clWater)
220         ],
221         null);
222 RMS.SetProgress(50);
224 if (mapSize > 150 && randBool())
226         log("Creating path though the oasis...");
227         var pAngle = randFloat(0, TWO_PI);
228         var px = round(fx) + round(fractionToTiles(0.13 * cos(pAngle)));
229         var py = round(fz) + round(fractionToTiles(0.13 * sin(pAngle)));
230         var pex = round(fx) + round(fractionToTiles(0.13 * -cos(pAngle)));
231         var pey = round(fz) + round(fractionToTiles(0.13 * sin(pAngle + PI)));
232         createArea(
233                 new PathPlacer(px, py, pex, pey, scaleByMapSize(7, 18), 0.4, 1, 0.2, 0),
234                 [
235                         new TerrainPainter(tSand),
236                         new SmoothElevationPainter(ELEVATION_MODIFY, 4, 5),
237                         paintClass(clPassage)
238                 ],
239                 null);
241 log("Creating some straggler trees around the Passage...");
242 var group = new SimpleGroup([new SimpleObject(ePalmTall, 1,1, 0,0),new SimpleObject(ePalmShort, 1, 2, 1, 2), new SimpleObject(aBushA, 0,2, 1,3)], true, clForest);
243 createObjectGroupsDeprecated(group, 0, stayClasses(clPassage, 1), scaleByMapSize(60, 250), 100);
245 log("Creating stone mines...");
246 group = new SimpleGroup([new SimpleObject(eStoneMine, 1,1, 0,0),new SimpleObject(ePalmShort, 1,2, 3,3),new SimpleObject(ePalmTall, 0,1, 3,3)
247                                                  ,new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3)], true, clRock);
248 createObjectGroupsDeprecated(group, 0,
249         avoidClasses(clWater, 10, clForest, 1, clPlayer, 30, clRock, 10,clBaseResource, 2, clHill, 1),
250         scaleByMapSize(6,25), 100
253 log("Creating metal mines...");
254 group = new SimpleGroup([new SimpleObject(eMetalMine, 1,1, 0,0),new SimpleObject(ePalmShort, 1,2, 2,3),new SimpleObject(ePalmTall, 0,1, 2,2)
255                                                  ,new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3)], true, clMetal);
256 createObjectGroupsDeprecated(group, 0,
257         avoidClasses(clWater, 10, clForest, 1, clPlayer, 30, clMetal, 10,clBaseResource, 2, clRock, 10, clHill, 1),
258         scaleByMapSize(6,25), 100
260 RMS.SetProgress(65);
262 log("Creating small decorative rocks...");
263 group = new SimpleGroup( [new SimpleObject(aRock, 2,4, 0,2)], true, undefined );
264 createObjectGroupsDeprecated(group, 0, avoidClasses(clWater, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 30, scaleByMapSize(10,50) );
266 RMS.SetProgress(70);
268 log("Creating Camels...");
269 group = new SimpleGroup(
270         [new SimpleObject(eCamel, 1,2, 0,4)],
271         true, clFood
273 createObjectGroupsDeprecated(group, 0,
274         avoidClasses(clWater, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20),
275         1 * numPlayers, 50
277 RMS.SetProgress(75);
279 log("Creating Gazelles...");
280 group = new SimpleGroup(
281         [new SimpleObject(eGazelle, 2,4, 0,2)],
282         true, clFood
284 createObjectGroupsDeprecated(group, 0,
285         avoidClasses(clWater, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20),
286         1 * numPlayers, 50
288 RMS.SetProgress(85);
290 log("Creating Oasis Animals...");
291 for (var p = 0; p < scaleByMapSize(5,30); p++)
293         var aAngle = randFloat(0, TWO_PI);
294         var aDist = fractionToTiles(0.11);
295         var animX = round(fx + aDist * cos(aAngle));
296         var animY = round(fz + aDist * sin(aAngle));
297         group = new RandomGroup(
298                 [new SimpleObject(eLion, 1,2, 0,4),new SimpleObject(eLioness, 1,2, 2,4),new SimpleObject(eGazelle, 4,6, 1,5),new SimpleObject(eCamel, 1,2, 1,5)], true, clFood, animX,animY);
299         createObjectGroup(group, 0);
301 RMS.SetProgress(90);
303 log("Creating bushes...");
304 group = new SimpleGroup(
305         [new SimpleObject(aBushB, 1,2, 0,2), new SimpleObject(aBushA, 2,4, 0,2)]
307 createObjectGroupsDeprecated(group, 0,
308         avoidClasses(clWater, 2, clHill, 1, clPlayer, 1, clPassage, 1),
309         scaleByMapSize(10, 40), 20
311 log ("Creating Sand blows and beautifications");
312 for (var sandx = 0; sandx < mapSize; sandx += 4)
313         for (var sandz = 0; sandz < mapSize; sandz += 4)
314         {
315                 if (getHeight(sandx,sandz) > 3.4)
316                 {
317                         if (randBool((getHeight(sandx,sandz) - 3.4) / 1.4))
318                         {
319                                 group = new SimpleGroup( [new SimpleObject(aSand, 0,1, 0,2)], true, undefined, sandx,sandz );
320                                 createObjectGroup(group, 0);
321                         }
322                 }
323                 else if (getHeight(sandx, sandz) > -2.5 && getHeight(sandx,sandz) < -1)
324                 {
325                         if (randBool(0.4))
326                         {
327                                 group = new SimpleGroup( [new SimpleObject(aWaterFlower, 1,4, 1,2)], true, undefined, sandx,sandz );
328                                 createObjectGroup(group, 0);
329                         }
330                         else if (randBool(0.7) && getHeight(sandx,sandz) < -1.9)
331                         {
332                                 group = new SimpleGroup( [new SimpleObject(aReedsA, 5,12, 0,2),new SimpleObject(aReedsB, 5,12, 0,2)], true, undefined, sandx,sandz );
333                                 createObjectGroup(group, 0);
334                         }
336                         if (getTileClass(clPassage).countInRadius(sandx,sandz,2,true) > 0) {
337                                 if (randBool(0.4))
338                                 {
339                                         group = new SimpleGroup( [new SimpleObject(aWaterFlower, 1,4, 1,2)], true, undefined, sandx,sandz );
340                                         createObjectGroup(group, 0);
341                                 }
342                                 else if (randBool(0.7) && getHeight(sandx,sandz) < -1.9)
343                                 {
344                                         group = new SimpleGroup( [new SimpleObject(aReedsA, 5,12, 0,2),new SimpleObject(aReedsB, 5,12, 0,2)], true, undefined, sandx,sandz );
345                                         createObjectGroup(group, 0);
346                                 }
347                         }
348                 }
349         }
351 setSkySet("sunny");
352 setSunColor(0.914,0.827,0.639);
353 setSunRotation(PI/3);
354 setSunElevation(0.5);
355 setWaterColor(0, 0.227, 0.843);
356 setWaterTint(0, 0.545, 0.859);
357 setWaterWaviness(1.0);
358 setWaterType("clap");
359 setWaterMurkiness(0.5);
360 setTerrainAmbientColor(0.45, 0.5, 0.6);
361 setUnitsAmbientColor(0.501961, 0.501961, 0.501961);
363 ExportMap();