Move getMapCenter and getMapBounds to the RandomMap object, refs #4964.
[0ad.git] / binaries / data / mods / public / maps / random / oasis.js
blobcaa623ae6babe5ce9d3578308fff634a1f553522
1 Engine.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 tShore = "dirta";
10 const tWater = "desert_sand_wet";
12 const ePalmShort = "gaia/flora_tree_cretan_date_palm_short";
13 const ePalmTall = "gaia/flora_tree_cretan_date_palm_tall";
14 const eBush = "gaia/flora_bush_grapes";
15 const eCamel = "gaia/fauna_camel";
16 const eGazelle = "gaia/fauna_gazelle";
17 const eLion = "gaia/fauna_lion";
18 const eLioness = "gaia/fauna_lioness";
19 const eStoneMine = "gaia/geology_stonemine_desert_quarry";
20 const eMetalMine = "gaia/geology_metal_desert_slabs";
22 const aFlower1 = "actor|props/flora/decals_flowers_daisies.xml";
23 const aWaterFlower = "actor|props/flora/water_lillies.xml";
24 const aReedsA = "actor|props/flora/reeds_pond_lush_a.xml";
25 const aReedsB = "actor|props/flora/reeds_pond_lush_b.xml";
26 const aRock = "actor|geology/stone_desert_med.xml";
27 const aBushA = "actor|props/flora/bush_desert_dry_a.xml";
28 const aBushB = "actor|props/flora/bush_desert_dry_a.xml";
29 const aSand = "actor|particle/blowing_sand.xml";
31 const pForestMain = [tForestFloor + TERRAIN_SEPARATOR + ePalmShort, tForestFloor + TERRAIN_SEPARATOR + ePalmTall, tForestFloor];
32 const pOasisForestLight = [tForestFloor + TERRAIN_SEPARATOR + ePalmShort, tForestFloor + TERRAIN_SEPARATOR + ePalmTall, tForestFloor,tForestFloor,tForestFloor
33                                         ,tForestFloor,tForestFloor,tForestFloor,tForestFloor];
35 const heightSeaGround = -3;
36 const heightFloraMin = -2.5
37 const heightFloraReedsMax = -1.9;
38 const heightFloraMax = -1;
39 const heightLand = 1;
40 const heightSand = 3.4;
41 const heightOasisPath = 4;
42 const heightOffsetBump = 4;
43 const heightOffsetDune = 18;
45 var g_Map = new RandomMap(heightLand, tSand);
47 const numPlayers = getNumPlayers();
48 const mapSize = getMapSize();
49 const mapCenter = g_Map.getCenter();
51 var clPlayer = createTileClass();
52 var clHill = createTileClass();
53 var clForest = createTileClass();
54 var clOasis = createTileClass();
55 var clPassage = createTileClass();
56 var clRock = createTileClass();
57 var clMetal = createTileClass();
58 var clFood = createTileClass();
59 var clBaseResource = createTileClass();
61 var waterRadius = scaleByMapSize(7, 50)
62 var shoreDistance = scaleByMapSize(4, 10);
63 var forestDistance = scaleByMapSize(6, 20);
65 var [playerIDs, playerPosition] = playerPlacementCircle(fractionToTiles(0.35));
67 log("Creating small oasis near the players...")
68 var forestDist = 1.2 * defaultPlayerBaseRadius();
69 for (let i = 0; i < numPlayers; ++i)
71         // Create starting batches of wood
72         let forestPosition;
73         let forestAngle;
75         do {
76                 forestAngle = Math.PI / 3 * randFloat(1, 2);
77                 forestPosition = Vector2D.add(playerPosition[i], new Vector2D(forestDist, 0).rotate(-forestAngle));
78         } while (
79                 !createArea(
80                         new ClumpPlacer(70, 1, 0.5, 10, forestPosition),
81                         [
82                                 new LayeredPainter([tForestFloor, pForestMain], [0]),
83                                 paintClass(clBaseResource)
84                         ],
85                         avoidClasses(clBaseResource, 0)));
87         log("Creating the water patch explaining the forest for player " + playerIDs[i] + "...");
88         let waterPosition;
89         do {
90                 let waterAngle = forestAngle + randFloat(1, 5) / 3 * Math.PI;
91                 waterPosition = Vector2D.add(forestPosition, new Vector2D(6, 0).rotate(-waterAngle)).round();
93                 let flowerPosition = Vector2D.add(forestPosition, new Vector2D(3, 0).rotate(-waterAngle)).round();
94                 createObjectGroup(
95                         new SimpleGroup(
96                                 [new SimpleObject(aFlower1, 1, 5, 0, 3)],
97                                 true,
98                                 undefined,
99                                 flowerPosition.x,
100                                 flowerPosition.y),
101                         0);
103                 let reedsPosition = Vector2D.add(forestPosition, new Vector2D(5, 0).rotate(-waterAngle)).round();
104                 createObjectGroup(
105                         new SimpleGroup(
106                                 [new SimpleObject(aReedsA, 1, 3, 0, 0)],
107                                 true,
108                                 undefined,
109                                 reedsPosition.x,
110                                 reedsPosition.y),
111                         0);
113         } while (
114                 !createArea(
115                         new ClumpPlacer(60, 0.9, 0.4, 5, waterPosition),
116                         [
117                                 new LayeredPainter([tShore, tWater], [1]),
118                                 new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 3)
119                         ],
120                         avoidClasses(clBaseResource, 0)));
122 Engine.SetProgress(20);
124 placePlayerBases({
125         "PlayerPlacement": [playerIDs, playerPosition],
126         "PlayerTileClass": clPlayer,
127         "BaseResourceClass": clBaseResource,
128         "CityPatch": {
129                 "outerTerrain": tRoadWild,
130                 "innerTerrain": tRoad,
131                 "painters": [
132                         paintClass(clPlayer)
133                 ]
134         },
135         "Chicken": {
136         },
137         "Berries": {
138                 "template": eBush
139         },
140         "Mines": {
141                 "types": [
142                         { "template": eMetalMine },
143                         { "template": eStoneMine },
144                 ],
145                 "distance": defaultPlayerBaseRadius(),
146                 "maxAngle": Math.PI / 2,
147                 "groupElements": shuffleArray([aBushA, aBushB, ePalmShort, ePalmTall]).map(t => new SimpleObject(t, 1, 1, 3, 4))
148         }
149         // Starting trees were set above
150         // No decoratives
152 Engine.SetProgress(30);
154 log("Creating central oasis...");
155 createArea(
156         new ClumpPlacer(diskArea(forestDistance + shoreDistance + waterRadius), 0.8, 0.2, 10, mapCenter),
157         [
158                 new LayeredPainter([pOasisForestLight, tWater], [forestDistance]),
159                 new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, forestDistance + shoreDistance),
160                 paintClass(clOasis)
161         ]);
163 Engine.SetProgress(40);
165 log("Creating bumps...");
166 createAreas(
167         new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1),
168         new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetBump, 3),
169         avoidClasses(clPlayer, 10, clBaseResource, 6, clOasis, 4),
170         scaleByMapSize(30, 70));
172 log("Creating dirt patches...");
173 createAreas(
174         new ClumpPlacer(80, 0.3, 0.06, 1),
175         new TerrainPainter(tDirt),
176         avoidClasses(clPlayer, 10, clBaseResource, 6, clOasis, 4, clForest, 4),
177         scaleByMapSize(15, 50));
179 log("Creating dunes...");
180 createAreas(
181         new ClumpPlacer(120, 0.3, 0.06, 1),
182         [
183                 new TerrainPainter(tDune),
184                 new SmoothElevationPainter(ELEVATION_MODIFY, heightOffsetDune, 30)
185         ],
186         avoidClasses(clPlayer, 10, clBaseResource, 6, clOasis, 4, clForest, 4),
187         scaleByMapSize(15, 50));
189 Engine.SetProgress(50);
191 if (mapSize > 150 && randBool())
193         log("Creating path though the oasis...");
194         let pathWidth = scaleByMapSize(7, 18);
195         let points = distributePointsOnCircle(2, randomAngle(), waterRadius + shoreDistance + forestDistance + pathWidth, mapCenter)[0];
196         createArea(
197                 new PathPlacer(points[0], points[1], pathWidth, 0.4, 1, 0.2, 0),
198                 [
199                         new TerrainPainter(tSand),
200                         new SmoothElevationPainter(ELEVATION_SET, heightOasisPath, 5),
201                         paintClass(clPassage)
202                 ]);
204 log("Creating some straggler trees around the passage...");
205 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);
206 createObjectGroupsDeprecated(group, 0, stayClasses(clPassage, 3), scaleByMapSize(60, 250), 100);
208 log("Creating stone mines...");
209 group = new SimpleGroup([new SimpleObject(eStoneMine, 1,1, 0,0),new SimpleObject(ePalmShort, 1,2, 3,3),new SimpleObject(ePalmTall, 0,1, 3,3)
210                                                  ,new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3)], true, clRock);
211 createObjectGroupsDeprecated(group, 0,
212         avoidClasses(clOasis, 10, clForest, 1, clPlayer, 30, clRock, 10,clBaseResource, 2, clHill, 1),
213         scaleByMapSize(6,25), 100
216 log("Creating metal mines...");
217 group = new SimpleGroup([new SimpleObject(eMetalMine, 1,1, 0,0),new SimpleObject(ePalmShort, 1,2, 2,3),new SimpleObject(ePalmTall, 0,1, 2,2)
218                                                  ,new SimpleObject(aBushB, 1,1, 2,2), new SimpleObject(aBushA, 0,2, 1,3)], true, clMetal);
219 createObjectGroupsDeprecated(group, 0,
220         avoidClasses(clOasis, 10, clForest, 1, clPlayer, 30, clMetal, 10,clBaseResource, 2, clRock, 10, clHill, 1),
221         scaleByMapSize(6,25), 100
223 Engine.SetProgress(65);
225 log("Creating small decorative rocks...");
226 group = new SimpleGroup( [new SimpleObject(aRock, 2,4, 0,2)], true, undefined );
227 createObjectGroupsDeprecated(group, 0, avoidClasses(clOasis, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20), 30, scaleByMapSize(10, 50));
229 Engine.SetProgress(70);
231 log("Creating camels...");
232 group = new SimpleGroup(
233         [new SimpleObject(eCamel, 1,2, 0,4)],
234         true, clFood
236 createObjectGroupsDeprecated(group, 0,
237         avoidClasses(clOasis, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20),
238         1 * numPlayers, 50
240 Engine.SetProgress(75);
242 log("Creating gazelles...");
243 group = new SimpleGroup(
244         [new SimpleObject(eGazelle, 2,4, 0,2)],
245         true, clFood
247 createObjectGroupsDeprecated(group, 0,
248         avoidClasses(clOasis, 3, clForest, 0, clPlayer, 10, clHill, 1, clFood, 20),
249         1 * numPlayers, 50
251 Engine.SetProgress(85);
253 log("Creating oasis animals...");
254 for (let i = 0; i < scaleByMapSize(5, 30); ++i)
256         let animalPos = Vector2D.add(mapCenter, new Vector2D(forestDistance + shoreDistance + waterRadius, 0).rotate(randomAngle()));
258         createObjectGroup(
259                 new RandomGroup(
260                         [
261                                 new SimpleObject(eLion, 1, 2, 0, 4),
262                                 new SimpleObject(eLioness, 1, 2, 2, 4),
263                                 new SimpleObject(eGazelle, 4, 6, 1, 5),
264                                 new SimpleObject(eCamel, 1, 2, 1, 5)
265                         ],
266                         true,
267                         clFood,
268                         animalPos.x,
269                         animalPos.y),
270                 0);
272 Engine.SetProgress(90);
274 log("Creating bushes...");
275 var group = new SimpleGroup(
276         [new SimpleObject(aBushB, 1,2, 0,2), new SimpleObject(aBushA, 2,4, 0,2)]
278 createObjectGroupsDeprecated(group, 0,
279         avoidClasses(clOasis, 2, clHill, 1, clPlayer, 1, clPassage, 1),
280         scaleByMapSize(10, 40), 20
283 log("Creating sand blows and beautifications");
284 for (var sandx = 0; sandx < mapSize; sandx += 4)
285         for (var sandz = 0; sandz < mapSize; sandz += 4)
286         {
287                 let position = new Vector2D(sandx, sandz);
288                 let height = g_Map.getHeight(position);
290                 if (height > heightSand)
291                 {
292                         if (randBool((height - heightSand) / 1.4))
293                         {
294                                 group = new SimpleGroup( [new SimpleObject(aSand, 0,1, 0,2)], true, undefined, sandx,sandz );
295                                 createObjectGroup(group, 0);
296                         }
297                 }
298                 else if (height > heightFloraMin && height < heightFloraMax)
299                 {
300                         if (randBool(0.4))
301                         {
302                                 group = new SimpleGroup( [new SimpleObject(aWaterFlower, 1,4, 1,2)], true, undefined, sandx,sandz );
303                                 createObjectGroup(group, 0);
304                         }
305                         else if (randBool(0.7) && height < heightFloraReedsMax)
306                         {
307                                 group = new SimpleGroup( [new SimpleObject(aReedsA, 5,12, 0,2),new SimpleObject(aReedsB, 5,12, 0,2)], true, undefined, sandx,sandz );
308                                 createObjectGroup(group, 0);
309                         }
311                         if (getTileClass(clPassage).countMembersInRadius(sandx, sandz, 2) > 0)
312                         {
313                                 if (randBool(0.4))
314                                 {
315                                         group = new SimpleGroup( [new SimpleObject(aWaterFlower, 1,4, 1,2)], true, undefined, sandx,sandz );
316                                         createObjectGroup(group, 0);
317                                 }
318                                 else if (randBool(0.7) && height < heightFloraReedsMax)
319                                 {
320                                         group = new SimpleGroup( [new SimpleObject(aReedsA, 5,12, 0,2),new SimpleObject(aReedsB, 5,12, 0,2)], true, undefined, sandx,sandz );
321                                         createObjectGroup(group, 0);
322                                 }
323                         }
324                 }
325         }
327 placePlayersNomad(clPlayer, avoidClasses(clOasis, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2));
329 setSkySet("sunny");
330 setSunColor(0.914,0.827,0.639);
331 setSunRotation(Math.PI/3);
332 setSunElevation(0.5);
333 setWaterColor(0, 0.227, 0.843);
334 setWaterTint(0, 0.545, 0.859);
335 setWaterWaviness(1.0);
336 setWaterType("clap");
337 setWaterMurkiness(0.5);
338 setTerrainAmbientColor(0.45, 0.5, 0.6);
339 setUnitsAmbientColor(0.501961, 0.501961, 0.501961);
341 g_Map.ExportMap();