1 RMS.LoadLibrary("rmgen");
4 const tCity = "desert_city_tile";
5 const tCityPlaza = "desert_city_tile_plaza";
6 const tSand = "desert_dirt_rough";
7 const tDunes = "desert_sand_dunes_100";
8 const tFineSand = "desert_sand_smooth";
9 const tCliff = ["desert_cliff_badlands", "desert_cliff_badlands_2"];
10 const tForestFloor = "desert_forestfloor_palms";
11 const tGrass = "desert_grass_a";
12 const tGrassSand50 = "desert_grass_a_sand";
13 const tGrassSand25 = "desert_grass_a_stones";
14 const tDirt = "desert_dirt_rough";
15 const tDirtCracks = "desert_dirt_cracks";
16 const tShore = "desert_shore_stones";
17 const tWaterDeep = "desert_shore_stones_wet";
20 const oBerryBush = "gaia/flora_bush_grapes";
21 const oCamel = "gaia/fauna_camel";
22 const oFish = "gaia/fauna_fish";
23 const oGazelle = "gaia/fauna_gazelle";
24 const oGiraffe = "gaia/fauna_giraffe";
25 const oGoat = "gaia/fauna_goat";
26 const oWildebeest = "gaia/fauna_wildebeest";
27 const oStoneLarge = "gaia/geology_stonemine_desert_badlands_quarry";
28 const oStoneSmall = "gaia/geology_stone_desert_small";
29 const oMetalLarge = "gaia/geology_metal_desert_slabs";
30 const oDatePalm = "gaia/flora_tree_date_palm";
31 const oSDatePalm = "gaia/flora_tree_senegal_date_palm";
34 const aBush1 = "actor|props/flora/bush_desert_a.xml";
35 const aBush2 = "actor|props/flora/bush_desert_dry_a.xml";
36 const aBush3 = "actor|props/flora/bush_dry_a.xml";
37 const aBush4 = "actor|props/flora/plant_desert_a.xml";
38 const aBushes = [aBush1, aBush2, aBush3, aBush4];
39 const aDecorativeRock = "actor|geology/stone_desert_med.xml";
41 // terrain + entity (for painting)
42 const pForest = [tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERRAIN_SEPARATOR + oSDatePalm, tForestFloor];
43 const pForestOasis = [tGrass + TERRAIN_SEPARATOR + oDatePalm, tGrass + TERRAIN_SEPARATOR + oSDatePalm, tGrass];
45 log("Initializing map...");
48 const numPlayers = getNumPlayers();
49 const mapSize = getMapSize();
50 const mapArea = mapSize*mapSize;
52 var clPlayer = createTileClass();
53 var clHill1 = createTileClass();
54 var clHill2 = createTileClass();
55 var clHill3 = createTileClass();
56 var clForest = createTileClass();
57 var clPatch = createTileClass();
58 var clRock = createTileClass();
59 var clMetal = createTileClass();
60 var clFood = createTileClass();
61 var clBaseResource = createTileClass();
63 // randomize player order
65 for (var i = 0; i < numPlayers; i++)
68 playerIDs = sortPlayers(playerIDs);
75 var startAngle = randFloat(0, TWO_PI);
76 for (var i = 0; i < numPlayers; i++)
78 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
79 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
80 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
83 for (var i = 0; i < numPlayers; i++)
85 var id = playerIDs[i];
86 log("Creating base for player " + id + "...");
88 // scale radius of player area by map size
89 var radius = scaleByMapSize(15,25);
91 // get the x and z in tiles
92 var fx = fractionToTiles(playerX[i]);
93 var fz = fractionToTiles(playerZ[i]);
97 // calculate size based on the radius
98 var size = PI * radius * radius;
100 // create the player area
101 var placer = new ClumpPlacer(size, 0.9, 0.5, 10, ix, iz);
102 createArea(placer, paintClass(clPlayer), null);
104 // create the city patch
106 placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
107 var painter = new LayeredPainter([tCity, tCityPlaza], [3]);
108 createArea(placer, painter, null);
110 // create starting units
111 placeCivDefaultEntities(fx, fz, id);
113 placeDefaultChicken(fx, fz, clBaseResource);
115 // create berry bushes
116 var bbAngle = randFloat(0, TWO_PI);
118 var bbX = round(fx + bbDist * cos(bbAngle));
119 var bbZ = round(fz + bbDist * sin(bbAngle));
120 var group = new SimpleGroup(
121 [new SimpleObject(oBerryBush, 5,5, 0,3)],
122 true, clBaseResource, bbX, bbZ
124 createObjectGroup(group, 0);
127 var mAngle = bbAngle;
128 while(abs(mAngle - bbAngle) < PI/3)
129 mAngle = randFloat(0, TWO_PI);
132 var mX = round(fx + mDist * cos(mAngle));
133 var mZ = round(fz + mDist * sin(mAngle));
134 group = new SimpleGroup(
135 [new SimpleObject(oMetalLarge, 1,1, 0,0), new RandomObject(aBushes, 2,4, 0,2)],
136 true, clBaseResource, mX, mZ
138 createObjectGroup(group, 0);
140 // create stone mines
141 mAngle += randFloat(PI/8, PI/4);
142 mX = round(fx + mDist * cos(mAngle));
143 mZ = round(fz + mDist * sin(mAngle));
144 group = new SimpleGroup(
145 [new SimpleObject(oStoneLarge, 1,1, 0,2), new RandomObject(aBushes, 2,4, 0,2)],
146 true, clBaseResource, mX, mZ
148 createObjectGroup(group, 0);
150 var hillSize = PI * radius * radius;
151 // create starting trees
152 var num = floor(hillSize / 100);
153 var tAngle = randFloat(-PI/3, 4*PI/3);
154 var tDist = randFloat(12, 14);
155 var tX = round(fx + tDist * cos(tAngle));
156 var tZ = round(fz + tDist * sin(tAngle));
157 group = new SimpleGroup(
158 [new SimpleObject(oDatePalm, num, num, 0,5)],
159 false, clBaseResource, tX, tZ
161 createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
165 log("Creating dune patches...");
166 placer = new ClumpPlacer(scaleByMapSize(40, 150), 0.2, 0.1, 0);
167 painter = new TerrainPainter(tDunes);
168 createAreas(placer, [painter, paintClass(clPatch)],
169 avoidClasses(clPatch, 2, clPlayer, 0),
170 scaleByMapSize(5, 20)
174 log("Creating sand patches...");
175 var placer = new ClumpPlacer(scaleByMapSize(25, 100), 0.2, 0.1, 0);
176 var painter = new TerrainPainter([tSand, tFineSand]);
177 createAreas(placer, [painter, paintClass(clPatch)],
178 avoidClasses(clPatch, 2, clPlayer, 0),
179 scaleByMapSize(15, 50)
183 log("Creating dirt patches...");
184 placer = new ClumpPlacer(scaleByMapSize(25, 100), 0.2, 0.1, 0);
185 painter = new TerrainPainter([tDirt]);
186 createAreas(placer, [painter, paintClass(clPatch)],
187 avoidClasses(clPatch, 2, clPlayer, 0),
188 scaleByMapSize(15, 50)
192 log("Creating oasis...");
193 var oRadius = scaleByMapSize(14, 40);
194 placer = new ClumpPlacer(PI*oRadius*oRadius, 0.6, 0.15, 0, mapSize/2, mapSize/2);
195 painter = new LayeredPainter([[tSand, pForest], [tGrassSand25, pForestOasis], tGrassSand25, tShore, tWaterDeep], [2, 3, 1, 1]);
196 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, -11, 8);
197 createArea(placer, [painter, elevationPainter, paintClass(clForest)], null);
200 log("Creating oasis wildlife...");
201 var num = round(PI * oRadius / 8);
202 var constraint = new AndConstraint([borderClasses(clForest, 0, 3), avoidClasses(clForest, 0)]);
203 var halfSize = mapSize/2;
204 for (var i = 0; i < num; ++i)
207 var angle = TWO_PI / num * i;
209 // Work outward until constraint met
210 var gx = round(halfSize + r * cos(angle));
211 var gz = round(halfSize + r * sin(angle));
213 } while (!constraint.allows(gx,gz) && r < halfSize);
215 group = new RandomGroup(
216 [ new SimpleObject(oGiraffe, 2,4, 0,3), // select from these groups randomly
217 new SimpleObject(oWildebeest, 3,5, 0,3),
218 new SimpleObject(oGazelle, 5,7, 0,3)
219 ], true, clFood, gx, gz
221 createObjectGroup(group, 0);
224 constraint = new AndConstraint([borderClasses(clForest, 15, 0), avoidClasses(clFood, 5)]);
225 num = round(PI * oRadius / 16);
226 for (var i = 0; i < num; ++i)
229 var angle = TWO_PI / num * i;
231 // Work outward until constraint met
232 var gx = round(halfSize + r * cos(angle));
233 var gz = round(halfSize + r * sin(angle));
235 } while (!constraint.allows(gx,gz) && r < halfSize);
237 group = new SimpleGroup(
238 [new SimpleObject(oFish, 1,1, 0,1)],
241 createObjectGroup(group, 0);
245 log("Creating level 1 hills...");
246 placer = new ClumpPlacer(scaleByMapSize(50,300), 0.25, 0.1, 0.5);
247 var terrainPainter = new LayeredPainter(
248 [tCliff, tSand], // terrains
251 var elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1);
252 var hillAreas = createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill1)],
253 avoidClasses(clForest, 3, clPlayer, 0, clHill1, 10),
254 scaleByMapSize(10,20), 100
258 log("Creating small level 1 hills...");
259 placer = new ClumpPlacer(scaleByMapSize(25,150), 0.25, 0.1, 0.5);
260 terrainPainter = new LayeredPainter(
261 [tCliff, tSand], // terrains
264 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1);
265 var tempAreas = createAreas(placer, [terrainPainter, elevationPainter, paintClass(clHill1)],
266 avoidClasses(clForest, 3, clPlayer, 0, clHill1, 3),
267 scaleByMapSize(15,25), 100
269 for (var i = 0; i < tempAreas.length; ++i)
270 hillAreas.push(tempAreas[i]);
273 log("Creating decorative rocks...");
274 group = new SimpleGroup(
275 [new RandomObject([aDecorativeRock, aBush2, aBush3], 3,8, 0,2)],
278 createObjectGroupsByAreas(group, 0,
279 borderClasses(clHill1, 0, 3),
280 scaleByMapSize(40,200), 50,
286 log("Creating level 2 hills...");
287 placer = new ClumpPlacer(scaleByMapSize(25,150), 0.25, 0.1, 0);
288 terrainPainter = new LayeredPainter(
289 [tCliff, tSand], // terrains
292 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1);
293 createAreasInAreas(placer, [terrainPainter, elevationPainter],
294 [stayClasses(clHill1, 0)],
295 scaleByMapSize(15,25), 50,
300 log("Creating level 3 hills...");
301 placer = new ClumpPlacer(scaleByMapSize(12, 75), 0.25, 0.1, 0);
302 terrainPainter = new LayeredPainter(
303 [tCliff, tSand], // terrains
306 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 16, 1);
307 createAreas(placer, [terrainPainter, elevationPainter],
308 [stayClasses(clHill1, 0)],
309 scaleByMapSize(15,25), 50,
314 log("Creating bumps...");
315 placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 0);
316 elevationPainter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2);
320 avoidClasses(clForest, 0, clPlayer, 0, clHill1, 2),
321 scaleByMapSize(100, 200)
326 // calculate desired number of trees for map (based on size)
327 const MIN_TREES = 500;
328 const MAX_TREES = 2500;
329 const P_FOREST = 0.5;
331 var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES);
332 var numForest = totalTrees * P_FOREST;
333 var numStragglers = totalTrees * (1.0 - P_FOREST);
336 log("Creating forests...");
337 var num = scaleByMapSize(10,30);
338 placer = new ClumpPlacer(numForest / num, 0.15, 0.1, 0.5);
339 painter = new TerrainPainter([tSand, pForest]);
340 createAreas(placer, [painter, paintClass(clForest)],
341 avoidClasses(clPlayer, 1, clForest, 10, clHill1, 1),
347 log("Creating stone mines...");
348 group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4), new RandomObject(aBushes, 2,4, 0,2)], true, clRock);
349 createObjectGroups(group, 0,
350 [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill1, 1)],
351 scaleByMapSize(4,16), 100
354 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3), new RandomObject(aBushes, 2,4, 0,2)], true, clRock);
355 createObjectGroups(group, 0,
356 [avoidClasses(clForest, 1, clPlayer, 10, clRock, 10, clHill1, 1)],
357 scaleByMapSize(4,16), 100
360 log("Creating metal mines...");
361 group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4), new RandomObject(aBushes, 2,4, 0,2)], true, clMetal);
362 createObjectGroups(group, 0,
363 [avoidClasses(clForest, 1, clPlayer, 10, clMetal, 10, clRock, 5, clHill1, 1)],
364 scaleByMapSize(4,16), 100
369 log("Creating gazelles...");
370 group = new SimpleGroup([new SimpleObject(oGazelle, 5,7, 0,4)], true, clFood);
371 createObjectGroups(group, 0,
372 avoidClasses(clForest, 0, clPlayer, 5, clHill1, 1, clFood, 10),
373 scaleByMapSize(5,20), 50
376 log("Creating goats...");
377 group = new SimpleGroup([new SimpleObject(oGoat, 2,4, 0,3)], true, clFood);
378 createObjectGroups(group, 0,
379 avoidClasses(clForest, 0, clPlayer, 5, clHill1, 1, clFood, 10),
380 scaleByMapSize(5,20), 50
383 log("Creating camels...");
384 group = new SimpleGroup([new SimpleObject(oCamel, 2,4, 0,2)], true, clFood);
385 createObjectGroups(group, 0,
386 avoidClasses(clForest, 0, clPlayer, 5, clHill1, 1, clFood, 10),
387 scaleByMapSize(5,20), 50
391 log("Creating straggler trees...");
392 var types = [oDatePalm, oSDatePalm]; // some variation
393 var num = floor(numStragglers / types.length);
394 for (var i = 0; i < types.length; ++i)
396 group = new SimpleGroup([new SimpleObject(types[i], 1,1, 0,0)], true);
397 createObjectGroups(group, 0,
398 avoidClasses(clForest, 0, clHill1, 1, clPlayer, 4, clMetal, 1, clRock, 1),
404 log("Creating bushes...");
405 group = new SimpleGroup([new RandomObject(aBushes, 2,3, 0,2)]);
406 createObjectGroups(group, 0,
407 avoidClasses(clHill1, 1, clPlayer, 0, clForest, 0),
408 scaleByMapSize(16, 262)
411 log("Creating more decorative rocks...");
412 group = new SimpleGroup([new SimpleObject(aDecorativeRock, 1,2, 0,2)]);
413 createObjectGroups(group, 0,
414 avoidClasses(clHill1, 1, clPlayer, 0, clForest, 0),
415 scaleByMapSize(16, 262)
418 setWaterColor(0, 0.227, 0.843);
419 setWaterTint(0, 0.545, 0.859);
420 setWaterWaviness(1.0);
421 setWaterType("clap");
422 setWaterMurkiness(0.75);