1 RMS.LoadLibrary("rmgen");
3 const tGrass = "savanna_grass_a";
4 const tForestFloor = "savanna_forestfloor_a";
5 const tCliff = "savanna_cliff_b";
6 const tDirtRocksA = "savanna_dirt_rocks_c";
7 const tDirtRocksB = "savanna_dirt_rocks_a";
8 const tDirtRocksC = "savanna_dirt_rocks_b";
9 const tHill = "savanna_cliff_a";
10 const tRoad = "savanna_tile_a_red";
11 const tRoadWild = "savanna_tile_a_red";
12 const tGrassPatch = "savanna_grass_b";
13 const tShoreBlend = "savanna_riparian";
14 const tShore = "savanna_riparian_bank";
15 const tWater = "savanna_riparian_wet";
18 const oBaobab = "gaia/flora_tree_baobab";
19 const oFig = "gaia/flora_tree_fig";
20 const oBerryBush = "gaia/flora_bush_berry";
21 const oWildebeest = "gaia/fauna_wildebeest";
22 const oFish = "gaia/fauna_fish";
23 const oGazelle = "gaia/fauna_gazelle";
24 const oElephant = "gaia/fauna_elephant_african_bush";
25 const oGiraffe = "gaia/fauna_giraffe";
26 const oZebra = "gaia/fauna_zebra";
27 const oStoneLarge = "gaia/geology_stonemine_desert_quarry";
28 const oStoneSmall = "gaia/geology_stone_savanna_small";
29 const oMetalLarge = "gaia/geology_metal_savanna_slabs";
32 const aGrass = "actor|props/flora/grass_savanna.xml";
33 const aGrassShort = "actor|props/flora/grass_medit_field.xml";
34 const aReeds = "actor|props/flora/reeds_pond_lush_a.xml";
35 const aLillies = "actor|props/flora/reeds_pond_lush_b.xml";
36 const aRockLarge = "actor|geology/stone_savanna_med.xml";
37 const aRockMedium = "actor|geology/stone_savanna_med.xml";
38 const aBushMedium = "actor|props/flora/bush_desert_dry_a.xml";
39 const aBushSmall = "actor|props/flora/bush_dry_a.xml";
41 const pForest = [tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor + TERRAIN_SEPARATOR + oBaobab, tForestFloor];
43 log("Initializing map...");
47 const numPlayers = getNumPlayers();
48 const mapSize = getMapSize();
49 const mapArea = mapSize*mapSize;
51 // create tile classes
53 var clPlayer = createTileClass();
54 var clHill = createTileClass();
55 var clForest = createTileClass();
56 var clWater = createTileClass();
57 var clDirt = createTileClass();
58 var clRock = createTileClass();
59 var clMetal = createTileClass();
60 var clFood = createTileClass();
61 var clBaseResource = createTileClass();
62 var clSettlement = createTileClass();
63 var clShallows = createTileClass();
65 // randomize player order
67 for (var i = 0; i < numPlayers; i++)
71 playerIDs = sortPlayers(playerIDs);
75 var playerX = new Array(numPlayers);
76 var playerZ = new Array(numPlayers);
77 var playerAngle = new Array(numPlayers);
79 var startAngle = randFloat(0, TWO_PI);
80 for (var i = 0; i < numPlayers; i++)
82 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
83 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
84 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
87 for (var i = 0; i < numPlayers; i++)
89 var id = playerIDs[i];
90 log("Creating base for player " + id + "...");
93 var radius = scaleByMapSize(15,25);
97 // get the x and z in tiles
98 var fx = fractionToTiles(playerX[i]);
99 var fz = fractionToTiles(playerZ[i]);
102 addToClass(ix, iz, clPlayer);
103 addToClass(ix+5, iz, clPlayer);
104 addToClass(ix, iz+5, clPlayer);
105 addToClass(ix-5, iz, clPlayer);
106 addToClass(ix, iz-5, clPlayer);
108 // create the city patch
109 var cityRadius = radius/3;
110 var placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
111 var painter = new LayeredPainter([tRoadWild, tRoad], [1]);
112 createArea(placer, painter, null);
114 // create starting units
115 placeCivDefaultEntities(fx, fz, id);
117 placeDefaultChicken(fx, fz, clBaseResource);
119 // create berry bushes
120 var bbAngle = randFloat(0, TWO_PI);
122 var bbX = round(fx + bbDist * cos(bbAngle));
123 var bbZ = round(fz + bbDist * sin(bbAngle));
124 var group = new SimpleGroup(
125 [new SimpleObject(oBerryBush, 5,5, 0,3)],
126 true, clBaseResource, bbX, bbZ
128 createObjectGroup(group, 0);
131 var mAngle = bbAngle;
132 while(abs(mAngle - bbAngle) < PI/3)
134 mAngle = randFloat(0, TWO_PI);
137 var mX = round(fx + mDist * cos(mAngle));
138 var mZ = round(fz + mDist * sin(mAngle));
139 group = new SimpleGroup(
140 [new SimpleObject(oMetalLarge, 1,1, 0,0)],
141 true, clBaseResource, mX, mZ
143 createObjectGroup(group, 0);
145 // create stone mines
146 mAngle += randFloat(PI/8, PI/4);
147 mX = round(fx + mDist * cos(mAngle));
148 mZ = round(fz + mDist * sin(mAngle));
149 group = new SimpleGroup(
150 [new SimpleObject(oStoneLarge, 1,1, 0,2)],
151 true, clBaseResource, mX, mZ
153 createObjectGroup(group, 0);
154 var hillSize = PI * radius * radius;
155 // create starting trees
157 var tAngle = randFloat(-PI/3, 4*PI/3);
158 var tDist = randFloat(12, 13);
159 var tX = round(fx + tDist * cos(tAngle));
160 var tZ = round(fz + tDist * sin(tAngle));
161 group = new SimpleGroup(
162 [new SimpleObject(oBaobab, num, num, 0,3)],
163 false, clBaseResource, tX, tZ
165 createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
167 // create grass tufts
168 var num = hillSize / 250;
169 for (var j = 0; j < num; j++)
171 var gAngle = randFloat(0, TWO_PI);
172 var gDist = radius - (5 + randInt(7));
173 var gX = round(fx + gDist * cos(gAngle));
174 var gZ = round(fz + gDist * sin(gAngle));
175 group = new SimpleGroup(
176 [new SimpleObject(aGrassShort, 2,5, 0,1, -PI/8,PI/8)],
177 false, clBaseResource, gX, gZ
179 createObjectGroup(group, 0);
186 log ("Creating rivers...");
187 for (var m = 0; m < numPlayers; m++)
189 var tang = startAngle + (m + 0.5) * TWO_PI / numPlayers;
190 placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,50)*scaleByMapSize(10,50)/3), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.15*cos(tang)), fractionToTiles(0.5 + 0.15*sin(tang)));
191 var painter = new LayeredPainter([tShore, tWater, tWater], [1, 3]);
192 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 4);
193 createArea(placer, [painter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
194 var placer = new PathPlacer(fractionToTiles(0.5 + 0.15*cos(tang)), fractionToTiles(0.5 + 0.15*sin(tang)), fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)), scaleByMapSize(10,50), 0.2, 3*(scaleByMapSize(1,4)), 0.2, 0.05);
195 var terrainPainter = new LayeredPainter(
196 [tShore, tWater, tWater], // terrains
199 var elevationPainter = new SmoothElevationPainter(
200 ELEVATION_SET, // type
204 createArea(placer, [terrainPainter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
205 placer = new ClumpPlacer(floor(PI*scaleByMapSize(10,50)*scaleByMapSize(10,50)/5), 0.95, 0.6, 10, fractionToTiles(0.5 + 0.49*cos(tang)), fractionToTiles(0.5 + 0.49*sin(tang)));
206 var painter = new LayeredPainter([tWater, tWater], [1]);
207 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, -4, 4);
208 createArea(placer, [painter, elevationPainter, paintClass(clWater)], avoidClasses(clPlayer, 5));
212 for (var i = 0; i < numPlayers; i++)
214 if (i+1 == numPlayers)
217 round(fractionToTiles(playerX[i])),
218 round(fractionToTiles(playerZ[i])),
219 round(fractionToTiles(playerX[0])),
220 round(fractionToTiles(playerZ[0])),
221 6, -2, -2, 4, clShallows, undefined, -4);
223 // create animals in shallows
224 log("Creating animals in shallows...");
225 var group = new SimpleGroup(
226 [new SimpleObject(oElephant, 2,3, 0,4)],
227 true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[0]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[0]))/2)
229 createObjectGroup(group, 0);
231 var group = new SimpleGroup(
232 [new SimpleObject(oWildebeest, 5,6, 0,4)],
233 true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[0]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[0]))/2)
235 createObjectGroup(group, 0);
241 fractionToTiles(playerX[i]),
242 fractionToTiles(playerZ[i]),
243 fractionToTiles(playerX[i+1]),
244 fractionToTiles(playerZ[i+1]),
245 6, -2, -2, 4, clShallows, undefined, -4);
247 // create animals in shallows
248 log("Creating animals in shallows...");
249 var group = new SimpleGroup(
250 [new SimpleObject(oElephant, 2,3, 0,4)],
251 true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[i+1]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[i+1]))/2)
253 createObjectGroup(group, 0);
255 var group = new SimpleGroup(
256 [new SimpleObject(oWildebeest, 5,6, 0,4)],
257 true, clFood, round((fractionToTiles(playerX[i]) + fractionToTiles(playerX[i+1]))/2), round((fractionToTiles(playerZ[i]) + fractionToTiles(playerZ[i+1]))/2)
259 createObjectGroup(group, 0);
264 paintTerrainBasedOnHeight(-6, 2, 1, tWater);
268 log("Creating bumps...");
269 placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1);
270 painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2);
274 avoidClasses(clWater, 2, clPlayer, 20),
275 scaleByMapSize(100, 200)
279 log("Creating hills...");
280 placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1);
281 terrainPainter = new LayeredPainter(
282 [tGrass, tCliff, tHill], // terrains
285 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 35, 3);
288 [terrainPainter, elevationPainter, paintClass(clHill)],
289 avoidClasses(clPlayer, 20, clHill, 15, clWater, 3),
290 scaleByMapSize(1, 4) * numPlayers
294 // calculate desired number of trees for map (based on size)
299 var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES);
300 var numForest = totalTrees * P_FOREST;
301 var numStragglers = totalTrees * (1.0 - P_FOREST);
304 log("Creating forests...");
306 [[tForestFloor, tGrass, pForest], [tForestFloor, pForest]]
310 var size = numForest / (0.5 * scaleByMapSize(2,8) * numPlayers);
311 var num = floor(size / types.length);
312 for (var i = 0; i < types.length; ++i)
314 placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 1);
315 painter = new LayeredPainter(
316 types[i], // terrains
321 [painter, paintClass(clForest)],
322 avoidClasses(clPlayer, 20, clForest, 10, clHill, 0, clWater, 2),
329 // create dirt patches
330 log("Creating dirt patches...");
331 var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)];
332 for (var i = 0; i < sizes.length; i++)
334 placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
335 painter = new LayeredPainter(
336 [[tGrass,tDirtRocksA],[tDirtRocksA,tDirtRocksB], [tDirtRocksB,tDirtRocksC]], // terrains
341 [painter, paintClass(clDirt)],
342 avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20),
343 scaleByMapSize(15, 45)
347 // create grass patches
348 log("Creating grass patches...");
349 var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)];
350 for (var i = 0; i < sizes.length; i++)
352 placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
353 painter = new TerrainPainter(tGrassPatch);
357 avoidClasses(clWater, 3, clForest, 0, clHill, 0, clPlayer, 20),
358 scaleByMapSize(15, 45)
364 log("Creating stone mines...");
365 // create large stone quarries
366 group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock);
367 createObjectGroups(group, 0,
368 avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
369 scaleByMapSize(4,16), 100
372 // create small stone quarries
373 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock);
374 createObjectGroups(group, 0,
375 avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clRock, 10, clHill, 1),
376 scaleByMapSize(4,16), 100
379 log("Creating metal mines...");
380 // create large metal quarries
381 group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal);
382 createObjectGroups(group, 0,
383 avoidClasses(clWater, 3, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clHill, 1),
384 scaleByMapSize(4,16), 100
389 // create small decorative rocks
390 log("Creating small decorative rocks...");
391 group = new SimpleGroup(
392 [new SimpleObject(aRockMedium, 1,3, 0,1)],
397 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0),
398 scaleByMapSize(16, 262), 50
402 // create large decorative rocks
403 log("Creating large decorative rocks...");
404 group = new SimpleGroup(
405 [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)],
410 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0),
411 scaleByMapSize(8, 131), 50
417 log("Creating wildebeest...");
418 group = new SimpleGroup(
419 [new SimpleObject(oWildebeest, 5,7, 0,4)],
422 createObjectGroups(group, 0,
423 avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
430 log("Creating gazelle...");
431 group = new SimpleGroup(
432 [new SimpleObject(oGazelle, 2,3, 0,2)],
435 createObjectGroups(group, 0,
436 avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
441 log("Creating elephant...");
442 group = new SimpleGroup(
443 [new SimpleObject(oElephant, 2,3, 0,2)],
446 createObjectGroups(group, 0,
447 avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
452 log("Creating giraffe...");
453 group = new SimpleGroup(
454 [new SimpleObject(oGiraffe, 2,3, 0,2)],
457 createObjectGroups(group, 0,
458 avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
463 log("Creating zebra...");
464 group = new SimpleGroup(
465 [new SimpleObject(oZebra, 2,3, 0,2)],
468 createObjectGroups(group, 0,
469 avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 5),
474 log("Creating fish...");
475 group = new SimpleGroup(
476 [new SimpleObject(oFish, 2,3, 0,2)],
479 createObjectGroups(group, 0,
480 [avoidClasses(clFood, 20), stayClasses(clWater, 6)],
485 log("Creating berry bush...");
486 group = new SimpleGroup(
487 [new SimpleObject(oBerryBush, 5,7, 0,4)],
490 createObjectGroups(group, 0,
491 avoidClasses(clWater, 3, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10),
492 randInt(1, 4) * numPlayers + 2, 50
497 // create straggler trees
498 log("Creating straggler trees...");
499 var types = [oBaobab, oBaobab, oBaobab, oFig]; // some variation
500 var num = floor(numStragglers / types.length);
501 for (var i = 0; i < types.length; ++i)
503 group = new SimpleGroup(
504 [new SimpleObject(types[i], 1,1, 0,3)],
507 createObjectGroups(group, 0,
508 avoidClasses(clWater, 5, clForest, 1, clHill, 1, clPlayer, 12, clMetal, 1, clRock, 1),
514 //create small grass tufts
515 log("Creating small grass tufts...");
516 group = new SimpleGroup(
517 [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)]
519 createObjectGroups(group, 0,
520 avoidClasses(clWater, 2, clHill, 2, clPlayer, 2),
521 planetm * scaleByMapSize(13, 200)
526 // create large grass tufts
527 log("Creating large grass tufts...");
528 group = new SimpleGroup(
529 [new SimpleObject(aGrass, 2,4, 0,1.8, -PI/8,PI/8), new SimpleObject(aGrassShort, 3,6, 1.2,2.5, -PI/8,PI/8)]
531 createObjectGroups(group, 0,
532 avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clForest, 0),
533 planetm * scaleByMapSize(13, 200)
539 log("Creating bushes...");
540 group = new SimpleGroup(
541 [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)]
543 createObjectGroups(group, 0,
544 avoidClasses(clWater, 2, clHill, 1, clPlayer, 1),
545 planetm * scaleByMapSize(13, 200), 50
551 setSunRotation(randFloat(0, TWO_PI));
552 setSunElevation(randFloat(PI/ 5, PI / 4));
553 setWaterColor(0.478,0.42,0.384); // greyish
554 setWaterTint(0.58,0.22,0.067); // reddish
555 setWaterMurkiness(0.87);
556 setWaterWaviness(0.5);
557 setWaterType("clap");