1
0
forked from mirrors/0ad
Files
0ad/binaries/data/mods/public/maps/random/river_archipelago.js
T
phosit df5cdbe8f1 Load map scripts as modules
Because its a function `GenerateMap` is renamed to `generateMap`.

Allows to rewrite the libraries as modules and to remove the costum
`Engine.LoadLibrary` mechanism in the future.
2025-06-14 09:10:47 +02:00

546 lines
13 KiB
JavaScript

Engine.LoadLibrary("rmgen");
Engine.LoadLibrary("rmgen-common");
export function* generateMap()
{
const tGrass = [
"tropic_grass_c",
"tropic_grass_c",
"tropic_grass_c",
"tropic_grass_c",
"tropic_grass_plants",
"tropic_plants",
"tropic_plants_b"
];
const tGrassA = "tropic_plants_c";
const tGrassB = "tropic_plants_c";
const tGrassC = "tropic_grass_c";
const tForestFloor = "tropic_grass_plants";
const tCliff = ["tropic_cliff_a", "tropic_cliff_a", "tropic_cliff_a", "tropic_cliff_a_plants"];
const tPlants = "tropic_plants";
const tRoad = "tropic_citytile_a";
const tRoadWild = "tropic_citytile_plants";
const tShoreBlend = "tropic_beach_dry_plants";
const tShore = "tropic_beach_dry";
const tWater = "tropic_beach_wet";
const oTree = "gaia/tree/toona";
const oPalm1 = "gaia/tree/palm_tropic";
const oPalm2 = "gaia/tree/palm_tropical";
const oStoneLarge = "gaia/rock/tropical_large";
const oStoneSmall = "gaia/rock/tropical_small";
const oMetalLarge = "gaia/ore/tropical_large";
const oFish = "gaia/fish/generic";
const oDeer = "gaia/fauna_deer";
const oTiger = "gaia/fauna_tiger";
const oBoar = "gaia/fauna_boar";
const oPeacock = "gaia/fauna_peacock";
const oBush = "gaia/fruit/berry_01";
const oSpearman = "units/maur/infantry_spearman_b";
const oArcher = "units/maur/infantry_archer_b";
const oArcherElephant = "units/maur/elephant_archer_b";
const aRockLarge = "actor|geology/stone_granite_large.xml";
const aRockMedium = "actor|geology/stone_granite_med.xml";
const aBush1 = "actor|props/flora/plant_tropic_a.xml";
const aBush2 = "actor|props/flora/plant_lg.xml";
const aBush3 = "actor|props/flora/plant_tropic_large.xml";
const pForestD = [
tForestFloor + TERRAIN_SEPARATOR + oTree,
tForestFloor
];
const pForestP1 = [
tForestFloor + TERRAIN_SEPARATOR + oPalm1,
tForestFloor
];
const pForestP2 = [
tForestFloor + TERRAIN_SEPARATOR + oPalm2,
tForestFloor
];
const heightSeaGround = -8;
const heightWaterLevel = 0;
const heightShore = 1;
const heightShoreBlend = 2.8;
const heightLand = 3;
const heightHill = 25;
globalThis.g_Map = new RandomMap(heightSeaGround, tGrass);
const numPlayers = getNumPlayers();
const mapCenter = g_Map.getCenter();
const mapBounds = g_Map.getBounds();
const clPlayer = g_Map.createTileClass();
const clPlayerTerritory = g_Map.createTileClass();
const clHill = g_Map.createTileClass();
const clForest = g_Map.createTileClass();
const clWater = g_Map.createTileClass();
const clDirt = g_Map.createTileClass();
const clRock = g_Map.createTileClass();
const clMetal = g_Map.createTileClass();
const clFood = g_Map.createTileClass();
const clBaseResource = g_Map.createTileClass();
const clGaia = g_Map.createTileClass();
const clStrip = [];
const startAngle = randomAngle();
const connectPlayers = randBool();
// Map layout
const stripWidthsLeft = connectPlayers ?
[[0.03, 0.09], [0.14, 0.25], [0.36, 0.46]] :
[[0, 0.06], [0.12, 0.23], [0.33, 0.43]];
// Mirror
let stripWidthsRight = clone(stripWidthsLeft);
stripWidthsRight.reverse();
stripWidthsRight = stripWidthsRight.map(strip => [1 - strip[1], 1 - strip[0]]);
const stripWidths = stripWidthsLeft.concat(stripWidthsRight);
g_Map.log("Creating strips");
for (let i = 0; i < stripWidths.length; ++i)
{
clStrip[i] = g_Map.createTileClass();
const isPlayerStrip = i == 2 || i == 3;
for (let j = 0; j < scaleByMapSize(20, 100); ++j)
{
const position = new Vector2D(
randFloat(mapBounds.bottom, mapBounds.top),
fractionToTiles(randFloat(...stripWidths[i])))
.rotateAround(startAngle, mapCenter).round();
createArea(
new ChainPlacer(
1,
Math.floor(scaleByMapSize(3, connectPlayers && isPlayerStrip ? 8 : 7)),
Math.floor(scaleByMapSize(30, 60)),
Infinity,
position),
[
new TerrainPainter(tGrass),
new SmoothElevationPainter(ELEVATION_SET, heightLand, 3),
new TileClassPainter(clStrip[i])
]);
}
}
yield 20;
const playerPosition = playerPlacementLine(startAngle, mapCenter,
fractionToTiles(1 - stripWidthsLeft[2][0] - stripWidthsLeft[2][1]));
// Either left vs right or top vs bottom
const playerIDs = randBool() ? sortAllPlayers() : primeSortAllPlayers();
g_Map.log("Ensuring player territory");
const playerRadius = scaleByMapSize(12, 20);
for (let i = 0; i < numPlayers; ++i)
createArea(
new ChainPlacer(1, 6, 40, 1, playerPosition[i], 0, [Math.floor(playerRadius)]),
[
new TerrainPainter(tGrass),
new SmoothElevationPainter(ELEVATION_SET, heightLand, 4),
new TileClassPainter(clPlayerTerritory)
]);
placePlayerBases({
"PlayerPlacement": [playerIDs, playerPosition],
"PlayerTileClass": clPlayer,
"BaseResourceClass": clBaseResource,
"baseResourceConstraint": stayClasses(clPlayerTerritory, 4),
"Walls": "towers",
"CityPatch": {
"outerTerrain": tRoadWild,
"innerTerrain": tRoad,
"radius": playerRadius / 3
},
"StartingAnimal": {
"template": oPeacock
},
"Berries": {
"template": oBush
},
"Mines": {
"types": [
{ "template": oMetalLarge },
{ "template": oStoneLarge }
]
},
"Trees": {
"template": oTree,
"count": 40
}
// No decoratives
});
yield 35;
const areaWater = createArea(
new HeightPlacer(Elevation_IncludeMin_ExcludeMax, -Infinity, heightWaterLevel),
[
new TerrainPainter(tWater),
new TileClassPainter(clWater)
]);
createArea(
new HeightPlacer(Elevation_IncludeMin_ExcludeMax, heightWaterLevel, heightShore),
new TerrainPainter(tShore));
createArea(
new HeightPlacer(Elevation_IncludeMin_ExcludeMax, heightShore, heightShoreBlend),
new TerrainPainter(tShoreBlend));
yield 40;
if (!isNomad())
{
g_Map.log("Creating gaia");
for (let i = 0; i < 2; ++i)
for (let j = 0; j < scaleByMapSize(1, 8); ++j)
createObjectGroups(
new SimpleGroup(
[
new SimpleObject(oSpearman, 8, 12, 2, 3),
new SimpleObject(oArcher, 8, 12, 2, 3),
new SimpleObject(oArcherElephant, 2, 3, 4, 5)
],
true,
clGaia),
0,
[
avoidClasses(
clWater, 2,
clForest, 1,
clPlayerTerritory, 0,
clHill, 1,
clGaia, 15),
stayClasses(clStrip[i == 0 ? 0 : stripWidths.length - 1], 1)
],
scaleByMapSize(5, 10),
50);
}
g_Map.log("Creating hills");
createAreas(
new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.1),
[
new LayeredPainter([tCliff, tGrass], [3]),
new SmoothElevationPainter(ELEVATION_SET, heightHill, 3),
new TileClassPainter(clHill)
],
[
avoidClasses(
clPlayerTerritory, 0,
clHill, 5,
clGaia, 1,
clWater, 2)
],
scaleByMapSize(1, 5));
createBumps(avoidClasses(clPlayer, 8, clWater, 2), scaleByMapSize(20, 150), 2, 8, 4, 1, 4);
yield 50;
g_Map.log("Creating forests");
const [forestTrees, stragglerTrees] = getTreeCounts(1000, 4000, 0.7);
const types = [
[[tGrass, tGrass, tGrass, tGrass, pForestD], [tGrass, tGrass, tGrass, pForestD]],
[[tGrass, tGrass, tGrass, tGrass, pForestP1], [tGrass, tGrass, tGrass, pForestP1]],
[[tGrass, tGrass, tGrass, tGrass, pForestP2], [tGrass, tGrass, tGrass, pForestP2]]
];
const forestSize = forestTrees / (scaleByMapSize(3, 6) * numPlayers);
const num = Math.floor(forestSize / types.length);
for (const type of types)
createAreas(
new ChainPlacer(
1,
Math.floor(scaleByMapSize(3, 5)),
forestTrees / (num * Math.floor(scaleByMapSize(2, 4))),
0.5),
[
new LayeredPainter(type, [2]),
new TileClassPainter(clForest)
],
avoidClasses(
clPlayer, 12,
clForest, 6,
clHill, 0,
clGaia, 1,
clWater, 2),
num);
createStragglerTrees(
[oTree, oPalm1, oPalm2],
avoidClasses(
clWater, 5,
clForest, 1,
clHill, 1,
clPlayer, 8,
clBaseResource, 4,
clGaia, 1,
clMetal, 4,
clRock, 4),
clForest,
stragglerTrees);
yield 60;
g_Map.log("Creating grass patches");
for (const size of [scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)])
createAreas(
new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5),
[
new LayeredPainter([tGrassC, tGrassA, tGrassB], [2, 1]),
new TileClassPainter(clDirt)
],
avoidClasses(
clWater, 8,
clForest, 0,
clHill, 0,
clGaia, 1,
clPlayerTerritory, 0,
clDirt, 16),
scaleByMapSize(20, 80));
g_Map.log("Creating dirt patches");
for (const size of [scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)])
createAreas(
new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), size, 0.5),
[
new TerrainPainter(tPlants),
new TileClassPainter(clDirt)
],
avoidClasses(
clWater, 8,
clForest, 0,
clHill, 0,
clGaia, 1,
clPlayerTerritory, 0,
clDirt, 16),
scaleByMapSize(20, 80));
g_Map.log("Creating stone mines");
createObjectGroups(
new SimpleGroup(
[
new SimpleObject(oStoneSmall, 0, 2, 0, 4),
new SimpleObject(oStoneLarge, 1, 1, 0, 4)
],
true,
clRock),
0,
avoidClasses(
clWater, 3,
clForest, 1,
clPlayerTerritory, 0,
clGaia, 1,
clRock, 10,
clHill, 1),
scaleByMapSize(4, 16),
50);
g_Map.log("Creating small stone mines");
createObjectGroups(
new SimpleGroup([new SimpleObject(oStoneSmall, 2, 5, 1, 3)], true, clRock),
0,
avoidClasses(
clWater, 4,
clForest, 1,
clPlayerTerritory, 0,
clGaia, 1,
clRock, 10,
clHill, 1),
scaleByMapSize(2, 8),
50);
g_Map.log("Creating metal mines");
createObjectGroups(
new SimpleGroup([new SimpleObject(oMetalLarge, 1, 1, 0, 4)], true, clMetal),
0,
avoidClasses(
clWater, 4,
clForest, 1,
clPlayerTerritory, 0,
clGaia, 1,
clMetal, 10,
clRock, 5,
clHill, 1),
scaleByMapSize(4, 16),
50);
g_Map.log("Creating small decorative rocks");
createObjectGroups(
new SimpleGroup([new SimpleObject(aRockMedium, 1, 3, 0, 1)], true),
0,
avoidClasses(
clWater, 2,
clForest, 1,
clGaia, 1,
clPlayer, 8,
clBaseResource, 4,
clHill, 0),
scaleByMapSize(50, 800),
20);
g_Map.log("Creating large decorative rocks");
createObjectGroups(
new SimpleGroup(
[
new SimpleObject(aRockLarge, 1, 2, 0, 1),
new SimpleObject(aRockMedium, 1, 3, 0, 2)
],
true),
0,
avoidClasses(
clWater, 2,
clForest, 1,
clGaia, 1,
clPlayer, 8,
clBaseResource, 4,
clHill, 0),
scaleByMapSize(25, 400),
50);
g_Map.log("Creating small grass tufts");
createObjectGroups(
new SimpleGroup([new SimpleObject(aBush1, 1, 2, 0, 1)]),
0,
avoidClasses(
clWater, 4,
clHill, 2,
clPlayer, 8,
clGaia, 1,
clBaseResource, 4,
clDirt, 0),
scaleByMapSize(100, 500));
yield 70;
g_Map.log("Creating large grass tufts");
createObjectGroups(
new SimpleGroup([
new SimpleObject(aBush2, 2, 4, 0, 1.8, -Math.PI / 8, Math.PI / 8),
new SimpleObject(aBush1, 3, 6, 1.2, 2.5, -Math.PI / 8, Math.PI / 8)
]),
0,
avoidClasses(
clWater, 4,
clHill, 2,
clGaia, 1,
clPlayer, 8,
clBaseResource, 4,
clDirt, 1,
clForest, 0),
scaleByMapSize(100, 500));
yield 85;
g_Map.log("Creating bushes");
createObjectGroups(
new SimpleGroup([
new SimpleObject(aBush3, 1, 2, 0, 2),
new SimpleObject(aBush2, 2, 4, 0, 2)
]), 0,
avoidClasses(
clWater, 4,
clHill, 1,
clPlayerTerritory, 0,
clGaia, 1,
clDirt, 1),
scaleByMapSize(100, 500));
g_Map.log("Creating deer");
createObjectGroups(
new SimpleGroup([new SimpleObject(oDeer, 5, 7, 0, 4)], true, clFood),
0,
avoidClasses(
clWater, 4,
clForest, 0,
clPlayerTerritory, 0,
clGaia, 1,
clHill, 1,
clFood, 20),
3 * numPlayers,
20);
g_Map.log("Creating boar");
createObjectGroups(
new SimpleGroup([new SimpleObject(oBoar, 2, 4, 0, 4)], true, clFood),
0,
avoidClasses(
clWater, 4,
clForest, 0,
clPlayerTerritory, 0,
clGaia, 1,
clHill, 1,
clRock, 4,
clMetal, 4,
clFood, 20),
2 * numPlayers,
20);
g_Map.log("Creating tigers");
createObjectGroups(
new SimpleGroup([new SimpleObject(oTiger, 1, 1, 0, 4)], true, clFood),
0,
avoidClasses(
clWater, 4,
clForest, 0,
clPlayerTerritory, 0,
clGaia, 1,
clHill, 1,
clRock, 4,
clMetal, 4,
clFood, 20),
2 * numPlayers,
20);
yield 95;
g_Map.log("Creating berry bush");
createObjectGroups(
new SimpleGroup([new SimpleObject(oBush, 5, 7, 0, 4)], true, clFood),
0,
avoidClasses(
clWater, 4,
clForest, 0,
clPlayerTerritory, 0,
clGaia, 1,
clHill, 1,
clRock, 4,
clMetal, 4,
clFood, 10),
randIntInclusive(1, 4) * numPlayers,
20);
g_Map.log("Creating fish");
createObjectGroupsByAreas(
new SimpleGroup([new SimpleObject(oFish, 2, 3, 0, 2)], true, clFood),
0,
[avoidClasses(clFood, 15), stayClasses(clWater, 4)],
scaleByMapSize(20, 100),
20,
[areaWater]);
placePlayersNomad(clPlayer,
avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2, clHill, 4));
setSunColor(0.6, 0.6, 0.6);
setSunElevation(Math.PI/ 3);
setWaterColor(0.424, 0.534, 0.639);
setWaterTint(0.369, 0.765, 0.745);
setWaterWaviness(1.0);
setWaterType("default");
setWaterMurkiness(0.35);
setFogFactor(0.03);
setFogThickness(0.2);
setPPEffect("hdr");
setPPContrast(0.7);
setPPSaturation(0.65);
setPPBloom(0.6);
setSkySet("stratus");
return g_Map;
}