1 RMS.LoadLibrary("rmgen");
5 const tGrass = ["temp_grass_clovers"];
6 const tGrassPForest = "temp_plants_bog";
7 const tGrassDForest = "alpine_dirt_grass_50";
8 const tCliff = ["temp_cliff_a", "temp_cliff_b"];
9 const tGrassA = "temp_grass_d";
10 const tGrassB = "temp_grass_c";
11 const tGrassC = "temp_grass_clovers_2";
12 const tHill = ["temp_highlands", "temp_grass_long_b"];
13 const tDirt = ["temp_dirt_gravel", "temp_dirt_gravel_b"];
14 const tRoad = "temp_road";
15 const tRoadWild = "temp_road_overgrown";
16 const tGrassPatch = "temp_grass_plants";
17 const tShoreBlend = "temp_mud_plants";
18 const tShore = "medit_sand_wet";
19 const tWater = "medit_sand_wet";
22 const oPoplar = "gaia/flora_tree_poplar";
23 const oPalm = "gaia/flora_tree_cretan_date_palm_short";
24 const oApple = "gaia/flora_tree_apple";
25 const oOak = "gaia/flora_tree_oak";
26 const oBerryBush = "gaia/flora_bush_berry";
27 const oDeer = "gaia/fauna_deer";
28 const oFish = "gaia/fauna_fish";
29 const oGoat = "gaia/fauna_goat";
30 const oBoar = "gaia/fauna_boar";
31 const oStoneLarge = "gaia/geology_stonemine_temperate_quarry";
32 const oStoneSmall = "gaia/geology_stone_temperate";
33 const oMetalLarge = "gaia/geology_metal_temperate_slabs";
36 const aGrass = "actor|props/flora/grass_soft_large_tall.xml";
37 const aGrassShort = "actor|props/flora/grass_soft_large.xml";
38 const aRockLarge = "actor|geology/stone_granite_large.xml";
39 const aRockMedium = "actor|geology/stone_granite_med.xml";
40 const aBushMedium = "actor|props/flora/bush_medit_me_lush.xml";
41 const aBushSmall = "actor|props/flora/bush_medit_sm_lush.xml";
43 // terrain + entity (for painting)
44 const pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oPoplar, tGrassDForest];
45 const pForestP = [tGrassPForest + TERRAIN_SEPARATOR + oOak, tGrassPForest];
47 const WATER_WIDTH = 0.25;
49 log("Initializing map...");
53 const numPlayers = getNumPlayers();
54 const mapSize = getMapSize();
55 const mapArea = mapSize*mapSize;
57 // create tile classes
59 var clPlayer = createTileClass();
60 var clHill = createTileClass();
61 var clForest = createTileClass();
62 var clWater = createTileClass();
63 var clDirt = createTileClass();
64 var clRock = createTileClass();
65 var clMetal = createTileClass();
66 var clFood = createTileClass();
67 var clBaseResource = createTileClass();
68 var clSettlement = createTileClass();
69 var clSea = createTileClass();
70 var clHighlands = createTileClass();
71 var clFlatlands = createTileClass();
73 // randomize player order
75 for (var i = 0; i < numPlayers; i++)
79 playerIDs = sortPlayers(playerIDs);
83 var playerX = new Array(numPlayers);
84 var playerZ = new Array(numPlayers);
85 var playerPos = new Array(numPlayers);
87 for (var i = 0; i < numPlayers; i++)
89 playerPos[i] = (i + 1) / (numPlayers + 1);
90 playerX[i] = playerPos[i];
91 playerZ[i] = 0.4 + 0.2*(i%2);
94 for (var i = 0; i < numPlayers; i++)
96 var id = playerIDs[i];
97 log("Creating base for player " + id + "...");
100 var radius = scaleByMapSize(15,25);
104 // get the x and z in tiles
105 var fx = fractionToTiles(playerX[i]);
106 var fz = fractionToTiles(playerZ[i]);
109 // Setting tile class
110 addToClass(ix, iz, clPlayer);
111 addToClass(ix+5, iz, clPlayer);
112 addToClass(ix, iz+5, clPlayer);
113 addToClass(ix-5, iz, clPlayer);
114 addToClass(ix, iz-5, clPlayer);
116 // calculate size based on the radius
117 var hillSize = PI * radius * radius;
119 // create the city patch
120 var cityRadius = radius/3;
121 var placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
122 var painter = new LayeredPainter([tRoadWild, tRoad], [1]);
123 createArea(placer, painter, null);
125 // create starting units
126 placeCivDefaultEntities(fx, fz, id);
128 placeDefaultChicken(fx, fz, clBaseResource);
130 // create berry bushes
131 var bbAngle = randFloat(0, TWO_PI);
133 var bbX = round(fx + bbDist * cos(bbAngle));
134 var bbZ = round(fz + bbDist * sin(bbAngle));
135 var group = new SimpleGroup(
136 [new SimpleObject(oBerryBush, 5,5, 0,3)],
137 true, clBaseResource, bbX, bbZ
139 createObjectGroup(group, 0);
142 var mAngle = bbAngle;
143 while(abs(mAngle - bbAngle) < PI/3)
145 mAngle = randFloat(0, TWO_PI);
148 var mX = round(fx + mDist * cos(mAngle));
149 var mZ = round(fz + mDist * sin(mAngle));
150 group = new SimpleGroup(
151 [new SimpleObject(oMetalLarge, 1,1, 0,0)],
152 true, clBaseResource, mX, mZ
154 createObjectGroup(group, 0);
156 // create stone mines
157 mAngle += randFloat(PI/8, PI/4);
158 mX = round(fx + mDist * cos(mAngle));
159 mZ = round(fz + mDist * sin(mAngle));
160 group = new SimpleGroup(
161 [new SimpleObject(oStoneLarge, 1,1, 0,2)],
162 true, clBaseResource, mX, mZ
164 createObjectGroup(group, 0);
166 // create starting trees
168 var tAngle = randFloat(-PI/3, 4*PI/3);
169 var tDist = randFloat(11, 13);
170 var tX = round(fx + tDist * cos(tAngle));
171 var tZ = round(fz + tDist * sin(tAngle));
172 group = new SimpleGroup(
173 [new SimpleObject(oOak, num, num, 0,5)],
174 false, clBaseResource, tX, tZ
176 createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
178 // create grass tufts
179 var num = hillSize / 250;
180 for (var j = 0; j < num; j++)
182 var gAngle = randFloat(0, TWO_PI);
183 var gDist = radius - (5 + randInt(7));
184 var gX = round(fx + gDist * cos(gAngle));
185 var gZ = round(fz + gDist * sin(gAngle));
186 group = new SimpleGroup(
187 [new SimpleObject(aGrassShort, 2,5, 0,1, -PI/8,PI/8)],
188 false, clBaseResource, gX, gZ
190 createObjectGroup(group, 0);
196 // create sea and hills
197 log("Creating sea and northern hills...");
198 var theta = randFloat(0, 1);
199 var seed = randFloat(2,3);
200 for (var ix = 0; ix < mapSize; ix++)
202 for (var iz = 0; iz < mapSize; iz++)
204 var x = ix / (mapSize + 1.0);
205 var z = iz / (mapSize + 1.0);
207 // add the rough shape of the water
208 var km = 20/scaleByMapSize(35, 160);
209 var cu = km*rndRiver(theta+x*0.5*(mapSize/64),seed);
215 addToClass(ix, iz, clHighlands);
221 if ((z < (cu + 0.75 + fadeDist))&&(z > (cu + 0.75)))
223 h = 1 - 4.0 * (1 - ((cu + 0.75 + fadeDist) - z)/fadeDist);
232 placeTerrain(ix, iz, tWater);
236 placeTerrain(ix, iz, tShore);
239 setHeight(ix, iz, h);
241 addToClass(ix, iz, clWater);
250 log("Creating fish...");
252 num = scaleByMapSize(10, 20);
253 for (var i=0; i < num; i++){
254 group = new SimpleGroup(
255 [new SimpleObject(oFish, 2,3, 0,2)],
258 createObjectGroups(group, 0,
259 [stayClasses(clWater, 2), avoidClasses(clFood, 3)],
267 log("Creating bumps...");
268 placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1);
269 painter = new SmoothElevationPainter(ELEVATION_MODIFY, 4, 3);
273 stayClasses(clHighlands, 1),
274 scaleByMapSize(300, 600)
280 log("Creating hills...");
281 placer = new ClumpPlacer(scaleByMapSize(20, 150), 0.2, 0.1, 1);
282 var terrainPainter = new LayeredPainter(
283 [tCliff, tHill], // terrains
286 var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 15, 2);
289 [terrainPainter, elevationPainter, paintClass(clHill)],
290 avoidClasses(clSea, 5, clPlayer, 20, clWater, 5, clHill, 15, clHighlands, 5),
291 scaleByMapSize(1, 4) * numPlayers
296 // calculate desired number of trees for map (based on size)
297 const MIN_TREES = 500;
298 const MAX_TREES = 2500;
299 const P_FOREST = 0.7;
301 var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES);
302 var numForest = totalTrees * P_FOREST;
303 var numStragglers = totalTrees * (1.0 - P_FOREST);
305 // create mainland forests
306 log("Creating mainland forests...");
308 [[tGrassDForest, tGrass, pForestD], [tGrassDForest, pForestD]]
310 var size = numForest*1.3 / (scaleByMapSize(2,8) * numPlayers);
311 var num = floor(0.7*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, clWater, 3, clForest, 10, clHill, 0, clSea, 6, clBaseResource, 3),
327 // create highland forests
328 log("Creating highland forests...");
330 [[tGrassDForest, tGrass, pForestP], [tGrassDForest, pForestP]]
332 var size = numForest / (scaleByMapSize(2,8) * numPlayers);
333 var num = floor(size / types.length);
334 for (var i = 0; i < types.length; ++i)
336 placer = new ClumpPlacer(numForest / num, 0.1, 0.1, 1);
337 painter = new LayeredPainter(
338 types[i], // terrains
343 [painter, paintClass(clForest)],
344 avoidClasses(clPlayer, 20, clWater, 3, clForest, 2, clHill, 0, clSea, 6, clFlatlands, 3),
352 // create dirt patches
353 log("Creating dirt patches...");
354 var sizes = [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8, 128)];
355 for (var i = 0; i < sizes.length; i++)
357 placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
358 painter = new LayeredPainter(
359 [[tGrass,tGrassA],[tGrassA,tGrassB], [tGrassB,tGrassC]], // terrains
364 [painter, paintClass(clDirt)],
365 avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 4, clSea, 0),
366 scaleByMapSize(15, 45)
372 // create grass patches
373 log("Creating grass patches...");
374 var sizes = [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5, 80)];
375 for (var i = 0; i < sizes.length; i++)
377 placer = new ClumpPlacer(sizes[i], 0.3, 0.06, 0.5);
378 painter = new LayeredPainter([tGrassC, tGrassPatch], [2]);
382 avoidClasses(clWater, 1, clForest, 0, clHill, 0, clDirt, 5, clPlayer, 4, clSea, 0),
383 scaleByMapSize(15, 45)
389 log("Creating stone mines...");
390 // create large stone quarries
391 group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock);
392 createObjectGroups(group, 0,
393 [avoidClasses(clWater, 0, clForest, 1, clPlayer, 20, clRock, 10, clSea, 2, clHill, 2)],
394 scaleByMapSize(4,16), 100
397 // create small stone quarries
398 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock);
399 createObjectGroups(group, 0,
400 [avoidClasses(clWater, 0, clForest, 1, clPlayer, 20, clRock, 10, clSea, 2, clHill, 2)],
401 scaleByMapSize(4,16), 100
404 log("Creating metal mines...");
405 // create large metal quarries
406 group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal);
407 createObjectGroups(group, 0,
408 [avoidClasses(clWater, 0, clForest, 1, clPlayer, 20, clMetal, 10, clRock, 5, clSea, 0, clHill, 2)],
409 scaleByMapSize(4,16), 100
414 // create small decorative rocks
415 log("Creating small decorative rocks...");
416 group = new SimpleGroup(
417 [new SimpleObject(aRockMedium, 1,3, 0,1)],
422 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0, clSea, 0),
423 scaleByMapSize(16, 262), 50
428 // create large decorative rocks
429 log("Creating large decorative rocks...");
430 group = new SimpleGroup(
431 [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)],
436 avoidClasses(clWater, 0, clForest, 0, clPlayer, 0, clHill, 0, clSea, 0),
437 scaleByMapSize(8, 131), 50
442 log("Creating deer...");
443 group = new SimpleGroup(
444 [new SimpleObject(oDeer, 5,7, 0,4)],
447 createObjectGroups(group, 0,
448 avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 0, clFood, 5, clSea, 0, clFlatlands, 0),
454 log("Creating sheep...");
455 group = new SimpleGroup(
456 [new SimpleObject(oGoat, 2,3, 0,2)],
459 createObjectGroups(group, 0,
460 avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 0, clFood, 20, clSea, 0),
465 log("Creating berry bush...");
466 group = new SimpleGroup(
467 [new SimpleObject(oBerryBush, 5,7, 0,4)],
470 createObjectGroups(group, 0,
471 avoidClasses(clWater, 6, clForest, 0, clPlayer, 20, clHill, 1, clFood, 10),
472 randInt(1, 4) * numPlayers + 2, 50
476 log("Creating boar...");
477 group = new SimpleGroup(
478 [new SimpleObject(oBoar, 2,3, 0,2)],
481 createObjectGroups(group, 0,
482 avoidClasses(clWater, 0, clForest, 0, clPlayer, 20, clHill, 0, clFood, 20, clSea, 0, clFlatlands, 0),
487 // create straggler trees
488 log("Creating straggler trees...");
489 var types = [oPoplar, oPalm, oApple]; // some variation
490 var num = floor(numStragglers / types.length);
491 for (var i = 0; i < types.length; ++i)
493 group = new SimpleGroup(
494 [new SimpleObject(types[i], 1,1, 0,3)],
497 createObjectGroups(group, 0,
498 avoidClasses(clWater, 1, clForest, 1, clHill, 1, clPlayer, 10, clMetal, 1, clRock, 1, clSea, 1, clHighlands, 25),
504 //create small grass tufts
505 log("Creating small grass tufts...");
506 group = new SimpleGroup(
507 [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)]
509 createObjectGroups(group, 0,
510 avoidClasses(clWater, 2, clHill, 2, clPlayer, 2, clDirt, 0, clSea, 1),
511 scaleByMapSize(13, 200)
515 // create large grass tufts
516 log("Creating large grass tufts...");
517 group = new SimpleGroup(
518 [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)]
520 createObjectGroups(group, 0,
521 avoidClasses(clWater, 3, clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0, clSea, 1),
522 scaleByMapSize(13, 200)
528 log("Creating bushes...");
529 group = new SimpleGroup(
530 [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)]
532 createObjectGroups(group, 0,
533 avoidClasses(clWater, 1, clHill, 1, clPlayer, 1, clDirt, 1, clSea, 1),
534 scaleByMapSize(13, 200), 50
539 setWaterColor(0.114, 0.192, 0.463);
540 setWaterTint(0.255, 0.361, 0.651);
541 setWaterWaviness(2.0);
542 setWaterType("ocean");
543 setWaterMurkiness(0.83);