1 RMS.LoadLibrary("rmgen");
3 TILE_CENTERED_HEIGHT_MAP = true;
4 //random terrain textures
5 var random_terrain = randomizeBiome();
7 const tMainTerrain = rBiomeT1();
8 const tForestFloor1 = rBiomeT2();
9 const tForestFloor2 = rBiomeT3();
10 const tCliff = rBiomeT4();
11 const tTier1Terrain = rBiomeT5();
12 const tTier2Terrain = rBiomeT6();
13 const tTier3Terrain = rBiomeT7();
14 const tHill = rBiomeT8();
15 const tDirt = rBiomeT9();
16 const tRoad = rBiomeT10();
17 const tRoadWild = rBiomeT11();
18 const tTier4Terrain = rBiomeT12();
19 const tShoreBlend = rBiomeT13();
20 const tShore = rBiomeT14();
21 const tWater = rBiomeT15();
24 const oTree1 = rBiomeE1();
25 const oTree2 = rBiomeE2();
26 const oTree3 = rBiomeE3();
27 const oTree4 = rBiomeE4();
28 const oTree5 = rBiomeE5();
29 const oFruitBush = rBiomeE6();
30 const oMainHuntableAnimal = rBiomeE8();
31 const oFish = rBiomeE9();
32 const oSecondaryHuntableAnimal = rBiomeE10();
33 const oStoneLarge = rBiomeE11();
34 const oStoneSmall = rBiomeE12();
35 const oMetalLarge = rBiomeE13();
36 const oWood = "gaia/special_treasure_wood";
39 const aGrass = rBiomeA1();
40 const aGrassShort = rBiomeA2();
41 const aReeds = rBiomeA3();
42 const aLillies = rBiomeA4();
43 const aRockLarge = rBiomeA5();
44 const aRockMedium = rBiomeA6();
45 const aBushMedium = rBiomeA7();
46 const aBushSmall = rBiomeA8();
48 const pForest1 = [tForestFloor2 + TERRAIN_SEPARATOR + oTree1, tForestFloor2 + TERRAIN_SEPARATOR + oTree2, tForestFloor2];
49 const pForest2 = [tForestFloor1 + TERRAIN_SEPARATOR + oTree4, tForestFloor1 + TERRAIN_SEPARATOR + oTree5, tForestFloor1];
51 log("Initializing map...");
55 const numPlayers = getNumPlayers();
56 const mapSize = getMapSize();
57 const mapArea = mapSize*mapSize;
59 // create tile classes
60 var clPlayer = createTileClass();
61 var clHill = createTileClass();
62 var clForest = 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 clLand = createTileClass();
71 // randomize player order
73 for (var i = 0; i < numPlayers; i++)
77 playerIDs = sortPlayers(playerIDs);
80 var playerX = new Array(numPlayers);
81 var playerZ = new Array(numPlayers);
82 var playerAngle = new Array(numPlayers);
84 var startAngle = randFloat(0, TWO_PI);
85 for (var i = 0; i < numPlayers; i++)
87 playerAngle[i] = startAngle + i*TWO_PI/numPlayers;
88 playerX[i] = 0.5 + 0.35*cos(playerAngle[i]);
89 playerZ[i] = 0.5 + 0.35*sin(playerAngle[i]);
92 for (var i = 0; i < numPlayers; i++)
94 var id = playerIDs[i];
95 log("Creating base for player " + id + "...");
98 var radius = scaleByMapSize(20,29);
102 var hillSize = PI * radius * radius;
103 // get the x and z in tiles
104 var fx = fractionToTiles(playerX[i]);
105 var fz = fractionToTiles(playerZ[i]);
109 var placer = new ClumpPlacer(hillSize, 0.80, 0.1, 10, ix, iz);
110 var terrainPainter = new LayeredPainter(
111 [tMainTerrain , tMainTerrain, tMainTerrain], // terrains
112 [1, shoreRadius] // widths
114 var elevationPainter = new SmoothElevationPainter(
115 ELEVATION_SET, // type
116 elevation, // elevation
117 shoreRadius // blend radius
119 createArea(placer, [terrainPainter, elevationPainter, paintClass(clPlayer)], null);
121 // create starting units
122 placeCivDefaultEntities(fx, fz, id, { 'iberWall': 'towers' });
124 placeDefaultChicken(fx, fz, clBaseResource);
126 // create berry bushes
127 var bbAngle = randFloat(0, TWO_PI);
129 var bbX = round(fx + bbDist * cos(bbAngle));
130 var bbZ = round(fz + bbDist * sin(bbAngle));
131 var group = new SimpleGroup(
132 [new SimpleObject(oFruitBush, 5,5, 0,3)],
133 true, clBaseResource, bbX, bbZ
135 createObjectGroup(group, 0);
138 var bbAngle = randFloat(0, TWO_PI);
140 var bbX = round(fx + bbDist * cos(bbAngle));
141 var bbZ = round(fz + bbDist * sin(bbAngle));
142 group = new SimpleGroup(
143 [new SimpleObject(oWood, 14,14, 0,3)],
144 true, clBaseResource, bbX, bbZ
146 createObjectGroup(group, 0);
149 var mAngle = bbAngle;
150 while(abs(mAngle - bbAngle) < PI/3)
152 mAngle = randFloat(0, TWO_PI);
155 var mX = round(fx + mDist * cos(mAngle));
156 var mZ = round(fz + mDist * sin(mAngle));
157 group = new SimpleGroup(
158 [new SimpleObject(oMetalLarge, 1,1, 0,0)],
159 true, clBaseResource, mX, mZ
161 createObjectGroup(group, 0);
163 // create stone mines
164 mAngle += randFloat(PI/8, PI/4);
165 mX = round(fx + mDist * cos(mAngle));
166 mZ = round(fz + mDist * sin(mAngle));
167 group = new SimpleGroup(
168 [new SimpleObject(oStoneLarge, 1,1, 0,2)],
169 true, clBaseResource, mX, mZ
171 createObjectGroup(group, 0);
172 var hillSize = PI * radius * radius;
173 // create starting trees
175 var tAngle = randFloat(-PI/3, 4*PI/3);
176 var tDist = randFloat(12, 13);
177 var tX = round(fx + tDist * cos(tAngle));
178 var tZ = round(fz + tDist * sin(tAngle));
179 group = new SimpleGroup(
180 [new SimpleObject(oTree1, num, num, 0,3)],
181 false, clBaseResource, tX, tZ
183 createObjectGroup(group, 0, avoidClasses(clBaseResource,2));
185 // create grass tufts
186 var num = hillSize / 250;
187 for (var j = 0; j < num; j++)
189 var gAngle = randFloat(0, TWO_PI);
190 var gDist = radius - (5 + randInt(7));
191 var gX = round(fx + gDist * cos(gAngle));
192 var gZ = round(fz + gDist * sin(gAngle));
193 group = new SimpleGroup(
194 [new SimpleObject(aGrassShort, 2,5, 0,1, -PI/8,PI/8)],
195 false, clBaseResource, gX, gZ
197 createObjectGroup(group, 0);
201 var dockLocation = getTIPIADBON([ix, iz], [mapSize / 2, mapSize / 2], [-3 , 2.6], 0.5, 3);
202 if (dockLocation !== undefined)
203 placeObject(dockLocation[0], dockLocation[1], "structures/" + getCivCode(id-1) + "_dock", id, playerAngle[i] + PI);
207 var playerConstraint = new AvoidTileClassConstraint(clPlayer, floor(scaleByMapSize(12,16)));
208 var landConstraint = new AvoidTileClassConstraint(clLand, floor(scaleByMapSize(12,16)));
210 for (var x = 0; x < mapSize; ++x)
211 for (var z = 0; z < mapSize; ++z)
212 if (playerConstraint.allows(x, z) && landConstraint.allows(x, z))
213 landAreas.push([x, z]);
218 log("Creating big islands...");
219 var numIslands = scaleByMapSize(4, 14);
220 for (var i = 0; i < numIslands; ++i)
222 landAreaLen = landAreas.length;
226 chosenPoint = landAreas[randInt(landAreaLen)];
228 // create big islands
229 placer = new ChainPlacer(floor(scaleByMapSize(4, 8)), floor(scaleByMapSize(8, 14)), floor(scaleByMapSize(25, 60)), 0.07, chosenPoint[0], chosenPoint[1], scaleByMapSize(30,70));
230 //placer = new ClumpPlacer(floor(hillSize*randFloat(0.9,2.1)), 0.80, 0.1, 0.07, chosenPoint[0], chosenPoint[1]);
231 terrainPainter = new LayeredPainter(
232 [tMainTerrain, tMainTerrain], // terrains
235 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 6);
236 var newIsland = createAreas(
238 [terrainPainter, elevationPainter, paintClass(clLand)],
239 avoidClasses(clLand, 3, clPlayer, 3),
242 if (newIsland && newIsland.length)
245 for (var j = 0; j < landAreaLen; ++j)
247 var x = landAreas[j][0], z = landAreas[j][1];
248 if (playerConstraint.allows(x, z) && landConstraint.allows(x, z))
249 landAreas[n++] = landAreas[j];
251 landAreas.length = n;
255 playerConstraint = new AvoidTileClassConstraint(clPlayer, floor(scaleByMapSize(9,12)));
256 landConstraint = new AvoidTileClassConstraint(clLand, floor(scaleByMapSize(9,12)));
258 log("Creating small islands...");
259 numIslands = scaleByMapSize(6, 18) * scaleByMapSize(1,3);
260 for (var i = 0; i < numIslands; ++i)
262 landAreaLen = landAreas.length;
266 chosenPoint = landAreas[randInt(0, landAreaLen)];
268 placer = new ChainPlacer(floor(scaleByMapSize(4, 7)), floor(scaleByMapSize(7, 10)), floor(scaleByMapSize(16, 40)), 0.07, chosenPoint[0], chosenPoint[1], scaleByMapSize(22,40));
269 terrainPainter = new LayeredPainter(
270 [tMainTerrain, tMainTerrain], // terrains
273 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 3, 6);
276 [terrainPainter, elevationPainter, paintClass(clLand)],
277 avoidClasses(clLand, 3, clPlayer, 3),
280 if (newIsland !== undefined)
283 for (var j = 0; j < landAreaLen; ++j)
285 var x = landAreas[j][0], z = landAreas[j][1];
286 if (playerConstraint.allows(x, z) && landConstraint.allows(x, z))
292 paintTerrainBasedOnHeight(1, 3, 0, tShore);
293 paintTerrainBasedOnHeight(-8, 1, 2, tWater);
295 for (var i = 0; i < numPlayers; i++)
297 var fx = fractionToTiles(playerX[i]);
298 var fz = fractionToTiles(playerZ[i]);
301 // create the city patch
302 var cityRadius = radius/3;
303 placer = new ClumpPlacer(PI*cityRadius*cityRadius, 0.6, 0.3, 10, ix, iz);
304 var painter = new LayeredPainter([tRoadWild, tRoad], [1]);
305 createArea(placer, painter, null);
309 log("Creating bumps...");
310 placer = new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1);
311 painter = new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2);
315 [avoidClasses(clPlayer, 0), stayClasses(clLand, 3)],
316 scaleByMapSize(20, 100)
320 log("Creating hills...");
321 placer = new ChainPlacer(1, floor(scaleByMapSize(4, 6)), floor(scaleByMapSize(16, 40)), 0.5);
322 terrainPainter = new LayeredPainter(
323 [tCliff, tHill], // terrains
326 elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 18, 2);
329 [terrainPainter, elevationPainter, paintClass(clHill)],
330 [avoidClasses(clPlayer, 2, clHill, 15), stayClasses(clLand, 0)],
331 scaleByMapSize(4, 13)
335 // calculate desired number of trees for map (based on size)
336 if (random_terrain == g_BiomeSavanna)
339 var MAX_TREES = 1250;
342 else if (random_terrain == g_BiomeTropic)
344 var MIN_TREES = 1000;
345 var MAX_TREES = 6000;
351 var MAX_TREES = 3000;
354 var totalTrees = scaleByMapSize(MIN_TREES, MAX_TREES);
355 var numForest = totalTrees * P_FOREST;
356 var numStragglers = totalTrees * (1.0 - P_FOREST);
359 log("Creating forests...");
361 [[tForestFloor2, tMainTerrain, pForest1], [tForestFloor2, pForest1]],
362 [[tForestFloor1, tMainTerrain, pForest2], [tForestFloor1, pForest2]]
365 if (random_terrain != g_BiomeSavanna)
367 var size = numForest / (scaleByMapSize(3,6) * numPlayers);
368 var num = floor(size / types.length);
369 for (var i = 0; i < types.length; ++i)
371 placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), numForest / (num * floor(scaleByMapSize(2,5))), 0.5);
372 painter = new LayeredPainter(
373 types[i], // terrains
378 [painter, paintClass(clForest)],
379 [avoidClasses(clPlayer, 0, clForest, 10, clHill, 0), stayClasses(clLand, 6)],
386 // create dirt patches
387 log("Creating dirt patches...");
388 var sizes = [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)];
390 if (random_terrain == g_BiomeSavanna)
392 for (var i = 0; i < sizes.length; i++)
394 placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5);
395 painter = new LayeredPainter(
396 [[tMainTerrain,tTier1Terrain],[tTier1Terrain,tTier2Terrain], [tTier2Terrain,tTier3Terrain]], // terrains
401 [painter, paintClass(clDirt)],
402 [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 6)],
403 numb*scaleByMapSize(15, 45)
407 // create grass patches
408 log("Creating grass patches...");
409 var sizes = [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)];
410 for (var i = 0; i < sizes.length; i++)
412 placer = new ChainPlacer(1, floor(scaleByMapSize(3, 5)), sizes[i], 0.5);
413 painter = new TerrainPainter(tTier4Terrain);
417 [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 6)],
418 numb*scaleByMapSize(15, 45)
424 log("Creating stone mines...");
425 // create large stone quarries
426 group = new SimpleGroup([new SimpleObject(oStoneSmall, 0,2, 0,4), new SimpleObject(oStoneLarge, 1,1, 0,4)], true, clRock);
427 createObjectGroups(group, 0,
428 [avoidClasses(clForest, 1, clPlayer, 0, clRock, 10, clHill, 1), stayClasses(clLand, 5)],
429 scaleByMapSize(4,16), 100
432 // create small stone quarries
433 group = new SimpleGroup([new SimpleObject(oStoneSmall, 2,5, 1,3)], true, clRock);
434 createObjectGroups(group, 0,
435 [avoidClasses(clForest, 1, clPlayer, 0, clRock, 10, clHill, 1), stayClasses(clLand, 5)],
436 scaleByMapSize(4,16), 100
439 log("Creating metal mines...");
440 // create large metal quarries
441 group = new SimpleGroup([new SimpleObject(oMetalLarge, 1,1, 0,4)], true, clMetal);
442 createObjectGroups(group, 0,
443 [avoidClasses(clForest, 1, clPlayer, 0, clMetal, 10, clRock, 5, clHill, 1), stayClasses(clLand, 5)],
444 scaleByMapSize(4,16), 100
449 // create small decorative rocks
450 log("Creating small decorative rocks...");
451 group = new SimpleGroup(
452 [new SimpleObject(aRockMedium, 1,3, 0,1)],
457 [avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 5)],
458 scaleByMapSize(16, 262), 50
462 // create large decorative rocks
463 log("Creating large decorative rocks...");
464 group = new SimpleGroup(
465 [new SimpleObject(aRockLarge, 1,2, 0,1), new SimpleObject(aRockMedium, 1,3, 0,2)],
470 [avoidClasses(clForest, 0, clPlayer, 0, clHill, 0), stayClasses(clLand, 5)],
471 scaleByMapSize(8, 131), 50
477 log("Creating deer...");
478 group = new SimpleGroup(
479 [new SimpleObject(oMainHuntableAnimal, 5,7, 0,4)],
482 createObjectGroups(group, 0,
483 [avoidClasses(clForest, 0, clPlayer, 0, clHill, 1, clFood, 20), stayClasses(clLand, 5)],
490 log("Creating sheep...");
491 group = new SimpleGroup(
492 [new SimpleObject(oSecondaryHuntableAnimal, 2,3, 0,2)],
495 createObjectGroups(group, 0,
496 [avoidClasses(clForest, 0, clPlayer, 0, clHill, 1, clFood, 20), stayClasses(clLand, 5)],
501 log("Creating fruit bush...");
502 group = new SimpleGroup(
503 [new SimpleObject(oFruitBush, 5,7, 0,4)],
506 createObjectGroups(group, 0,
507 [avoidClasses(clForest, 0, clPlayer, 8, clHill, 1, clFood, 20), stayClasses(clLand, 5)],
508 randInt(1, 4) * numPlayers + 2, 50
512 log("Creating fish...");
513 group = new SimpleGroup(
514 [new SimpleObject(oFish, 2,3, 0,2)],
517 createObjectGroups(group, 0,
518 avoidClasses(clLand, 4, clForest, 2, clPlayer, 2, clHill, 2, clFood, 20),
525 // create straggler trees
526 log("Creating straggler trees...");
527 var types = [oTree1, oTree2, oTree4, oTree3]; // some variation
528 var num = floor(numStragglers / types.length);
529 for (var i = 0; i < types.length; ++i)
531 group = new SimpleGroup(
532 [new SimpleObject(types[i], 1,1, 0,3)],
535 createObjectGroups(group, 0,
536 [avoidClasses(clForest, 1, clHill, 1, clPlayer, 0, clMetal, 1, clRock, 1), stayClasses(clLand, 6)],
542 if (random_terrain == g_BiomeTropic)
545 //create small grass tufts
546 log("Creating small grass tufts...");
547 group = new SimpleGroup(
548 [new SimpleObject(aGrassShort, 1,2, 0,1, -PI/8,PI/8)]
550 createObjectGroups(group, 0,
551 [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 6)],
552 planetm * scaleByMapSize(13, 200)
557 // create large grass tufts
558 log("Creating large grass tufts...");
559 group = new SimpleGroup(
560 [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)]
562 createObjectGroups(group, 0,
563 [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 5)],
564 planetm * scaleByMapSize(13, 200)
570 log("Creating bushes...");
571 group = new SimpleGroup(
572 [new SimpleObject(aBushMedium, 1,2, 0,2), new SimpleObject(aBushSmall, 2,4, 0,2)]
574 createObjectGroups(group, 0,
575 [avoidClasses(clHill, 1, clPlayer, 1, clDirt, 1), stayClasses(clLand, 6)],
576 planetm * scaleByMapSize(13, 200), 50
579 random_terrain = randInt(1,3);
580 if (random_terrain == 1)
582 else if (random_terrain == 2)
583 setSkySet("cumulus");
584 else if (random_terrain == 3)
587 setSunRotation(randFloat(0, TWO_PI));
588 setSunElevation(randFloat(PI/ 5, PI / 3));