1 Engine.LoadLibrary("rmgen");
2 Engine.LoadLibrary("rmgen2");
3 Engine.LoadLibrary("rmbiome");
4 Engine.LoadLibrary("heightmap");
6 const g_InitialMineDistance = 14;
7 const g_InitialTrees = 50;
11 const tMainTerrain = g_Terrains.mainTerrain;
12 const tForestFloor1 = g_Terrains.forestFloor1;
13 const tForestFloor2 = g_Terrains.forestFloor2;
14 const tCliff = g_Terrains.cliff;
15 const tTier1Terrain = g_Terrains.tier1Terrain;
16 const tTier2Terrain = g_Terrains.tier2Terrain;
17 const tTier3Terrain = g_Terrains.tier3Terrain;
18 const tHill = g_Terrains.hill;
19 const tTier4Terrain = g_Terrains.tier4Terrain;
20 const tShore = g_Terrains.shore;
21 const tWater = g_Terrains.water;
23 const oTree1 = g_Gaia.tree1;
24 const oTree2 = g_Gaia.tree2;
25 const oTree3 = g_Gaia.tree3;
26 const oTree4 = g_Gaia.tree4;
27 const oTree5 = g_Gaia.tree5;
28 const oFruitBush = g_Gaia.fruitBush;
29 const oMainHuntableAnimal = g_Gaia.mainHuntableAnimal;
30 const oFish = g_Gaia.fish;
31 const oSecondaryHuntableAnimal = g_Gaia.secondaryHuntableAnimal;
32 const oStoneLarge = g_Gaia.stoneLarge;
33 const oStoneSmall = g_Gaia.stoneSmall;
34 const oMetalLarge = g_Gaia.metalLarge;
35 const oWhale = "gaia/fauna_whale_humpback";
36 const oShipwreck = "other/special_treasure_shipwreck";
37 const oShipDebris = "other/special_treasure_shipwreck_debris";
38 const oObelisk = "other/obelisk";
40 const aGrass = g_Decoratives.grass;
41 const aGrassShort = g_Decoratives.grassShort;
42 const aRockLarge = g_Decoratives.rockLarge;
43 const aRockMedium = g_Decoratives.rockMedium;
45 const pForest1 = [tForestFloor2 + TERRAIN_SEPARATOR + oTree1, tForestFloor2 + TERRAIN_SEPARATOR + oTree2, tForestFloor2];
46 const pForest2 = [tForestFloor1 + TERRAIN_SEPARATOR + oTree4, tForestFloor1 + TERRAIN_SEPARATOR + oTree5, tForestFloor1];
48 const heightSeaGround = -10;
50 const heightHill = 18;
52 var g_Map = new RandomMap(heightSeaGround, tWater);
54 const numPlayers = getNumPlayers();
55 const mapSize = getMapSize();
56 const mapCenter = g_Map.getCenter();
58 const clPlayer = createTileClass();
59 const clHill = createTileClass();
60 const clForest = createTileClass();
61 const clDirt = createTileClass();
62 const clRock = createTileClass();
63 const clMetal = createTileClass();
64 const clFood = createTileClass();
65 const clBaseResource = createTileClass();
66 const clLand = createTileClass();
68 var startAngle = randomAngle();
70 var teams = getTeamsArray();
71 var numTeams = teams.filter(team => team).length;
72 var teamPosition = distributePointsOnCircle(numTeams, startAngle, fractionToTiles(0.3), mapCenter)[0];
73 var teamRadius = fractionToTiles(0.05);
76 for (let i = 0; i < teams.length; ++i)
78 if (!teams[i] || isNomad())
83 let [playerPosition, playerAngle] = distributePointsOnCircle(teams[i].length, startAngle + 2 * Math.PI / teams[i].length, teamRadius, teamPosition[i]);
84 playerPosition.forEach(position => position.round());
86 log("Creating island and starting entities for team " + i);
87 for (let p = 0; p < teams[i].length; ++p)
89 addCivicCenterAreaToClass(playerPosition[p], clPlayer);
92 new ChainPlacer(2, Math.floor(scaleByMapSize(5, 11)), Math.floor(scaleByMapSize(60, 250)), 1, playerPosition[p], 0, [Math.floor(fractionToTiles(0.01))]),
94 new LayeredPainter([tMainTerrain, tMainTerrain, tMainTerrain], [1, 6]),
95 new SmoothElevationPainter(ELEVATION_SET, heightLand, 6),
99 placeCivDefaultStartingEntities(playerPosition[p], teams[i][p], false);
102 let mineAngle = randFloat(-1, 1) * Math.PI / teams[i].length;
104 { "template": oMetalLarge, "angle": mineAngle },
105 { "template": oStoneLarge, "angle": mineAngle + Math.PI / 4 }
108 log("Create starting resources for team " + i);
109 for (let p = 0; p < teams[i].length; ++p)
110 for (let mine of mines)
112 let position = Vector2D.add(playerPosition[p], new Vector2D(g_InitialMineDistance, 0).rotate(-playerAngle[p] - mine.angle));
114 new SimpleGroup([new SimpleObject(mine.template, 1, 1, 0, 4)], true, clBaseResource, position.x, position.y),
116 [avoidClasses(clBaseResource, 4, clPlayer, 4), stayClasses(clLand, 5)]);
119 log("Place initial trees for team " + i);
120 for (let p = 0; p < teams[i].length; ++p)
123 for (let x = 0; x < tries; ++x)
125 let tAngle = playerAngle[p] + randFloat(-1, 1) * 2 * Math.PI / teams[i].length;
126 let treePosition = Vector2D.add(playerPosition[p], new Vector2D(16, 0).rotate(-tAngle)).round();
127 let group = new SimpleGroup(
128 [new SimpleObject(oTree2, g_InitialTrees, g_InitialTrees, 0, 7)],
129 true, clBaseResource, treePosition.x, treePosition.y
131 if (createObjectGroup(group, 0, [avoidClasses(clBaseResource, 4, clPlayer, 4), stayClasses(clLand, 4)]))
136 for (let p = 0; p < teams[i].length; ++p)
137 placePlayerBaseBerries({
138 "template": oFruitBush,
139 "playerID": teams[i][p],
140 "playerPosition": playerPosition[p],
141 "BaseResourceClass": clBaseResource,
142 "baseResourceConstraint": new AndConstraint([avoidClasses(clPlayer, 4), stayClasses(clLand, 5)])
145 for (let p = 0; p < teams[i].length; ++p)
146 placePlayerBaseChicken({
147 "playerID": teams[i][p],
148 "playerPosition": playerPosition[p],
149 "BaseResourceClass": clBaseResource,
150 "baseResourceConstraint": new AndConstraint([avoidClasses(clPlayer, 4), stayClasses(clLand, 5)])
153 log("Creating huntable animals for team " + i + "...");
154 for (let p = 0; p < teams[i].length; ++p)
156 let group = new SimpleGroup(
157 [new SimpleObject(oMainHuntableAnimal, 2 * numPlayers / numTeams, 2 * numPlayers / numTeams, 0, Math.floor(fractionToTiles(0.2)))],
158 true, clBaseResource, teamPosition[i].x, teamPosition[i].y
160 createObjectGroup(group, 0, [avoidClasses(clBaseResource, 2, clPlayer, 10), stayClasses(clLand, 5)]);
162 group = new SimpleGroup(
163 [new SimpleObject(oSecondaryHuntableAnimal, 4 * numPlayers / numTeams, 4 * numPlayers / numTeams, 0, Math.floor(fractionToTiles(0.2)))],
164 true, clBaseResource, teamPosition[i].x, teamPosition[i].y
166 createObjectGroup(group, 0, [avoidClasses(clBaseResource, 2, clPlayer, 10), stayClasses(clLand, 5)]);
170 Engine.SetProgress(40);
172 log("Creating big islands...");
175 Math.floor(scaleByMapSize(4, 8) * (isNomad() ? 2 : 1)),
176 Math.floor(scaleByMapSize(8, 16) * (isNomad() ? 2 : 1)),
177 Math.floor(scaleByMapSize(25, 60)),
180 scaleByMapSize(30, 70)),
182 new LayeredPainter([tMainTerrain, tMainTerrain], [2]),
183 new SmoothElevationPainter(ELEVATION_SET, heightLand, 6),
186 avoidClasses(clLand, 3, clPlayer, 3),
187 scaleByMapSize(4, 14) * (isNomad() ? 2 : 1),
190 log("Creating small islands...");
192 new ChainPlacer(Math.floor(scaleByMapSize(4, 7)), Math.floor(scaleByMapSize(7, 10)), Math.floor(scaleByMapSize(16, 40)), 0.07, undefined, scaleByMapSize(22, 40)),
194 new LayeredPainter([tMainTerrain, tMainTerrain], [2]),
195 new SmoothElevationPainter(ELEVATION_SET, heightLand, 6),
198 avoidClasses(clLand, 3, clPlayer, 3),
199 scaleByMapSize(6, 55),
202 Engine.SetProgress(70);
204 log("Smoothing heightmap...");
205 for (let i = 0; i < 5; ++i)
206 globalSmoothHeightmap();
208 // repaint clLand to compensate for smoothing
209 unPaintTileClassBasedOnHeight(-10, 10, 3, clLand);
210 paintTileClassBasedOnHeight(0, 5, 3, clLand);
212 Engine.SetProgress(85);
214 createBumps(avoidClasses(clPlayer, 20));
218 [new SimpleObject(oMetalLarge, 1, 1, 3, (numPlayers * 2) + 1)]
220 [avoidClasses(clForest, 1, clPlayer, 40, clRock, 20), stayClasses(clLand, 4)],
226 [new SimpleObject(oStoneLarge, 1, 1, 3, (numPlayers * 2) + 1)], [new SimpleObject(oStoneSmall, 2, 2, 2, (numPlayers * 2) + 1)]
228 [avoidClasses(clForest, 1, clPlayer, 40, clMetal, 20), stayClasses(clLand, 4)],
232 var [forestTrees, stragglerTrees] = getTreeCounts(...rBiomeTreeCount(1));
234 [tMainTerrain, tForestFloor1, tForestFloor2, pForest1, pForest2],
235 [avoidClasses(clPlayer, 10, clForest, 20, clBaseResource, 5, clRock, 6, clMetal, 6), stayClasses(clLand, 3)],
239 log("Creating hills...");
241 new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.5),
243 new LayeredPainter([tCliff, tHill], [2]),
244 new SmoothElevationPainter(ELEVATION_SET, heightHill, 2),
247 [avoidClasses(clBaseResource, 20, clHill, 15, clRock, 6, clMetal, 6), stayClasses(clLand, 0)],
248 scaleByMapSize(4, 13)
251 for (let i = 0; i < 3; ++i)
252 globalSmoothHeightmap();
254 createStragglerTrees(
255 [oTree1, oTree2, oTree4, oTree3],
257 avoidClasses(clForest, 10, clPlayer, 20, clMetal, 6, clRock, 6, clHill, 1),
258 stayClasses(clLand, 4)
265 [new SimpleObject(oMainHuntableAnimal, 5, 7, 0, 4)],
266 [new SimpleObject(oSecondaryHuntableAnimal, 2, 3, 0, 2)]
268 [3 * numPlayers, 3 * numPlayers],
269 [avoidClasses(clForest, 0, clPlayer, 20, clHill, 1, clRock, 6, clMetal, 6), stayClasses(clLand, 2)],
274 [new SimpleObject(oFruitBush, 5, 7, 0, 4)]
277 [avoidClasses(clForest, 0, clPlayer, 15, clHill, 1, clFood, 4, clRock, 6, clMetal, 6), stayClasses(clLand, 2)],
280 if (currentBiome() == "desert")
282 log("Creating obelisks");
283 let group = new SimpleGroup(
284 [new SimpleObject(oObelisk, 1, 1, 0, 1)],
287 createObjectGroupsDeprecated(
289 [avoidClasses(clBaseResource, 0, clHill, 0, clRock, 0, clMetal, 0, clFood, 0), stayClasses(clLand, 1)],
290 scaleByMapSize(3, 8), 1000
294 log("Creating dirt patches...");
295 let numb = currentBiome() == "savanna" ? 3 : 1;
296 for (let size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)])
298 new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5),
300 new LayeredPainter([[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]], [1, 1]),
303 [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 4)],
304 numb*scaleByMapSize(15, 45));
306 log("Creating grass patches...");
307 for (let size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)])
309 new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5),
310 new TerrainPainter(tTier4Terrain),
311 [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 4)],
312 numb * scaleByMapSize(15, 45));
314 log("Creating small decorative rocks...");
315 let group = new SimpleGroup(
316 [new SimpleObject(aRockMedium, 1, 3, 0, 1)],
319 createObjectGroupsDeprecated(
321 [avoidClasses(clForest, 0, clHill, 0), stayClasses(clLand, 2)],
322 scaleByMapSize(16, 262), 50
325 log("Creating large decorative rocks...");
326 group = new SimpleGroup(
327 [new SimpleObject(aRockLarge, 1, 2, 0, 1), new SimpleObject(aRockMedium, 1, 3, 0, 2)],
330 createObjectGroupsDeprecated(
332 [avoidClasses(clForest, 0, clHill, 0), stayClasses(clLand, 2)],
333 scaleByMapSize(8, 131), 50
336 log("Creating fish...");
337 group = new SimpleGroup(
338 [new SimpleObject(oFish, 2, 3, 0, 2)],
341 createObjectGroupsDeprecated(group, 0,
342 avoidClasses(clLand, 4, clFood, 20),
346 log("Creating Whales...");
347 group = new SimpleGroup(
348 [new SimpleObject(oWhale, 1, 1, 0, 3)],
351 createObjectGroupsDeprecated(group, 0,
352 [avoidClasses(clLand, 4),avoidClasses(clFood, 8)],
353 scaleByMapSize(5, 20), 100
356 log("Creating shipwrecks...");
357 group = new SimpleGroup(
358 [new SimpleObject(oShipwreck, 1, 1, 0, 1)],
361 createObjectGroupsDeprecated(group, 0,
362 [avoidClasses(clLand, 4),avoidClasses(clFood, 8)],
363 scaleByMapSize(12, 16), 100
366 log("Creating shipwreck debris...");
367 group = new SimpleGroup(
368 [new SimpleObject(oShipDebris, 1, 1, 0, 1)],
371 createObjectGroupsDeprecated(group, 0,
372 [avoidClasses(clLand, 4),avoidClasses(clFood, 8)],
373 scaleByMapSize(10, 20), 100
376 log("Creating small grass tufts...");
377 let planetm = currentBiome() == "tropic" ? 8 : 1;
378 group = new SimpleGroup(
379 [new SimpleObject(aGrassShort, 1, 2, 0, 1, -Math.PI / 8, Math.PI / 8)]
381 createObjectGroupsDeprecated(group, 0,
382 [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 0), stayClasses(clLand, 3)],
383 planetm * scaleByMapSize(13, 200)
386 Engine.SetProgress(95);
388 log("Creating large grass tufts...");
389 group = new SimpleGroup(
390 [new SimpleObject(aGrass, 2, 4, 0, 1.8, -Math.PI / 8, Math.PI / 8), new SimpleObject(aGrassShort, 3, 6, 1.2,2.5, -Math.PI / 8, Math.PI / 8)]
392 createObjectGroupsDeprecated(group, 0,
393 [avoidClasses(clHill, 2, clPlayer, 2, clDirt, 1, clForest, 0), stayClasses(clLand, 5)],
394 planetm * scaleByMapSize(13, 200)
397 paintTerrainBasedOnHeight(1, 2, 0, tShore);
398 paintTerrainBasedOnHeight(heightSeaGround, 1, 3, tWater);
400 placePlayersNomad(clPlayer, [stayClasses(clLand, 4), avoidClasses(clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)]);
402 setSkySet(pickRandom(["cloudless", "cumulus", "overcast"]));
403 setSunRotation(randomAngle());
404 setSunElevation(randFloat(1/5, 1/3) * Math.PI);
407 Engine.SetProgress(100);