1
0
forked from mirrors/0ad

paintRiver cleanup.

Pass vectors, refs #4845.
Pass tile sizes rather than percent numbers of the map, refs #4939.
Replace some water- and land-functions with more common
createArea+RectPlacer and paintTerrainBasedOnHeight calls.

Implement getMapBounds to make references easier to read, refs #4854
(and thus less error-prone, refs db9a52b94a).
Move height constants to the top of the files.

Fix Aegean Sea, English Channel and Danubius fadeWidth off by factor of
2 in 7d0cc59136.
Fix forgotton clWater in unknown_common of c74bd3425f and move that
createUnknownObjects call to common.

This was SVN commit r20871.
This commit is contained in:
elexis
2018-01-15 04:02:00 +00:00
parent 31284bac83
commit e9e983c2d4
15 changed files with 219 additions and 233 deletions
@@ -15,10 +15,10 @@ const tDirt = "medit_dirt_b";
const tDirt2 = "medit_rocks_grass";
const tDirt3 = "medit_rocks_shrubs";
const tDirtCracks = "medit_dirt_c";
const tShore = "medit_sand";
const tWater = "medit_sand_wet";
const tCorals1 = "medit_sea_coral_plants";
const tCorals2 = "medit_sea_coral_deep";
const tShoreUpper = "medit_sand";
const tShoreLower = "medit_sand_wet";
const tCoralsUpper = "medit_sea_coral_plants";
const tCoralsLower = "medit_sea_coral_deep";
const tSeaDepths = "medit_sea_depths";
const oBerryBush = "gaia/flora_bush_berry";
@@ -47,7 +47,8 @@ const pForest = [tForestFloor, tForestFloor + TERRAIN_SEPARATOR + oCarob, tFores
InitMap();
const numPlayers = getNumPlayers();
const mapSize = getMapSize();
const mapCenter = getMapCenter();
const mapBounds = getMapBounds();
var clPlayer = createTileClass();
var clForest = createTileClass();
@@ -61,6 +62,12 @@ var clGrass = createTileClass();
var clHill = createTileClass();
var clIsland = createTileClass();
var waterHeight = -3;
var corralsHeightLower = -2;
var corralsHeightUpper = -1.5;
var shoreHeight = 1;
var landHeight = 2;
placePlayerBases({
"PlayerPlacement": playerPlacementRiver(0, 0.6),
"PlayerTileClass": clPlayer,
@@ -92,28 +99,23 @@ Engine.SetProgress(30);
paintRiver({
"parallel": false,
"startX": 0.5,
"startZ": 0,
"endX": 0.5,
"endZ": 1,
"width": 0.35,
"fadeDist": 0.025,
"start": new Vector2D(mapCenter.x, mapBounds.top),
"end": new Vector2D(mapCenter.x, mapBounds.bottom),
"width": fractionToTiles(0.35),
"fadeDist": scaleByMapSize(6, 25),
"deviation": 0,
"waterHeight": -3,
"landHeight": 2,
"waterHeight": waterHeight,
"landHeight": landHeight,
"meanderShort": 20,
"meanderLong": 0,
"waterFunc": (ix, iz, height, riverFraction) => {
if (height < 0.7)
addToClass(ix, iz, clWater);
}
"meanderLong": 0
});
paintTerrainBasedOnHeight(-20, 1, 0, tWater);
paintTerrainBasedOnHeight(1, 2, 0, tShore);
paintTileClassBasedOnHeight(-Infinity, 0.7, Elevation_ExcludeMin_ExcludeMax, clWater);
paintTerrainBasedOnHeight(-Infinity, shoreHeight, Elevation_ExcludeMin_ExcludeMax, tShoreLower);
paintTerrainBasedOnHeight(shoreHeight, landHeight, Elevation_ExcludeMin_ExcludeMax, tShoreUpper);
Engine.SetProgress(40);
createBumps(avoidClasses(clWater, 2, clPlayer, 20));
var [forestTrees, stragglerTrees] = getTreeCounts(500, 3000, 0.7);
@@ -157,14 +159,13 @@ createAreas(
new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.5),
new SmoothElevationPainter(ELEVATION_SET, -2.5, 3),
stayClasses(clWater, 6),
scaleByMapSize(10, 50)
);
scaleByMapSize(10, 50));
log("Creating islands...");
createAreas(
new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(30, 80)), 0.5),
[
new LayeredPainter([tWater, tShore, tHill], [2 ,1]),
new LayeredPainter([tShoreLower, tShoreUpper, tHill], [2 ,1]),
new SmoothElevationPainter(ELEVATION_SET, 6, 4),
paintClass(clIsland)
],
@@ -172,9 +173,9 @@ createAreas(
scaleByMapSize(1, 4) * numPlayers
);
paintTerrainBasedOnHeight(-20, -3, 3, tSeaDepths);
paintTerrainBasedOnHeight(-3, -2, 2, tCorals2);
paintTerrainBasedOnHeight(-2, -1.5, 2, tCorals1);
paintTerrainBasedOnHeight(-Infinity, waterHeight, Elevation_IncludeMin_IncludeMax, tSeaDepths);
paintTerrainBasedOnHeight(waterHeight, corralsHeightLower, Elevation_ExcludeMin_IncludeMax, tCoralsLower);
paintTerrainBasedOnHeight(corralsHeightLower, corralsHeightUpper, Elevation_ExcludeMin_IncludeMax, tCoralsUpper);
log("Creating island stone mines...");
createMines(
@@ -121,6 +121,8 @@ InitMap();
const numPlayers = getNumPlayers();
const mapSize = getMapSize();
const mapCenter = getMapCenter();
const mapBounds = getMapBounds();
var clMiddle = createTileClass();
var clPlayer = createTileClass();
@@ -148,8 +150,10 @@ var clOutpost = createTileClass();
var clPath = createTileClass();
var clRitualPlace = createTileClass();
// Percentage of the mapsize that the river takes up
const waterWidth = 0.3;
var waterWidth = fractionToTiles(0.3);
var waterHeight = -3;
var shoreHeight = 1;
var landHeight = 2;
// How many treasures will be placed near the gallic civic centers
var gallicCCTreasureCount = randIntInclusive(8, 12);
@@ -171,19 +175,14 @@ if (gallicCC)
// One village left and right of the river
for (let i = 0; i < 2; ++i)
{
let gX = i == 0 ? gaulCityBorderDistance : mapSize - gaulCityBorderDistance;
let gZ = mapSize / 2;
let gX = i == 0 ? mapBounds.left + gaulCityBorderDistance : mapBounds.right - gaulCityBorderDistance;
let gZ = mapCenter.y;
if (addCelticRitual)
{
// Don't position the meeting place at the center of the map
let mLocation = randFloat(0.1, 0.4) * (randBool() ? 1 : -1);
// Center of the meeting place
let mX = i == 0 ?
mapSize * waterWidth :
mapSize * (1 - waterWidth);
let mZ = gZ + mapSize * mLocation;
let mX = i == 0 ? mapBounds.left + waterWidth : mapBounds.right - waterWidth;
let mZ = mapCenter.y + fractionToTiles(randFloat(0.1, 0.4)) * (randBool() ? 1 : -1);
// Radius of the meeting place
let mRadius = scaleByMapSize(4, 6);
@@ -212,8 +211,11 @@ if (gallicCC)
// Create the meeting place near the shoreline at the end of the path
createArea(
new ClumpPlacer(mRadius * mRadius * Math.PI, 0.6, 0.3, 10, mX, mZ),
[new LayeredPainter([tShore, tShore], [1]), paintClass(clPath), paintClass(clRitualPlace)],
null);
[
new LayeredPainter([tShore, tShore], [1]),
paintClass(clPath),
paintClass(clRitualPlace)
]);
placeObject(mX, mZ, aCampfire, 0, randFloat(0, 2 * Math.PI));
@@ -257,9 +259,11 @@ if (gallicCC)
// Create the city patch
createArea(
new ClumpPlacer(gaulCityRadius * gaulCityRadius * Math.PI, 0.6, 0.3, 10, gX, gZ),
[new LayeredPainter([tShore, tShore], [1]), paintClass(clGauls)],
null);
new ClumpPlacer(diskArea(gaulCityRadius), 0.6, 0.3, 10, gX, gZ),
[
new LayeredPainter([tShore, tShore], [1]),
paintClass(clGauls)
]);
// Place palisade fortress and some city buildings
// Use actors to avoid players capturing the buildings
@@ -350,25 +354,19 @@ Engine.SetProgress(20);
paintRiver({
"parallel": true,
"startX": 0.5,
"startZ": 0,
"endX": 0.5,
"endZ": 1,
"start": new Vector2D(mapCenter.x, mapBounds.top),
"end": new Vector2D(mapCenter.x, mapBounds.bottom),
"width": waterWidth,
"fadeDist": 0.025,
"fadeDist": scaleByMapSize(6, 25),
"deviation": 0,
"waterHeight": -3,
"landHeight": 2,
"waterHeight": waterHeight,
"landHeight": landHeight,
"meanderShort": 30,
"meanderLong": 0,
"waterFunc": (ix, iz, height, riverFraction) => {
if (height < 0.7)
addToClass(ix, iz, clWater);
// Distinguish left and right shoreline
if (0 < height && height < 1 && iz > ShorelineDistance && iz < mapSize - ShorelineDistance)
addToClass(ix, iz, clShore[ix < mapSize / 2 ? 0 : 1]);
addToClass(ix, iz, clShore[ix < mapCenter.x ? 0 : 1]);
},
"landFunc": (ix, iz, shoreDist1, shoreDist2) => {
@@ -379,12 +377,13 @@ paintRiver({
addToClass(ix, iz, clLand[1]);
}
});
Engine.SetProgress(30);
paintTileClassBasedOnHeight(-Infinity, 0.7, Elevation_ExcludeMin_ExcludeMax, clWater);
log("Creating shores...");
paintTerrainBasedOnHeight(-20, 1, 0, tWater);
paintTerrainBasedOnHeight(1, 2, 0, tShore);
paintTerrainBasedOnHeight(-Infinity, shoreHeight, 0, tWater);
paintTerrainBasedOnHeight(shoreHeight, landHeight, 0, tShore);
Engine.SetProgress(35);
log("Creating bumps...");
@@ -41,6 +41,8 @@ const pForestD = [tGrassDForest + TERRAIN_SEPARATOR + oBeech, tGrassDForest];
InitMap();
const numPlayers = getNumPlayers();
const mapCenter = getMapCenter();
const mapBounds = getMapBounds();
var clPlayer = createTileClass();
var clHill = createTileClass();
@@ -87,12 +89,10 @@ Engine.SetProgress(10);
paintRiver({
"parallel": false,
"startX": 0,
"startZ": 0.5,
"endX": 1,
"endZ": 0.5,
"width": 0.25,
"fadeDist": 0.01,
"start": new Vector2D(mapBounds.left, mapCenter.y),
"end": new Vector2D(mapBounds.right, mapCenter.y),
"width": fractionToTiles(0.25),
"fadeDist": scaleByMapSize(3, 10),
"deviation": 0,
"waterHeight": waterHeight,
"landHeight": landHeight,
@@ -39,6 +39,8 @@ InitMap();
const numPlayers = getNumPlayers();
const mapSize = getMapSize();
const mapCenter = getMapCenter();
const mapBounds = getMapBounds();
var clPlayer = createTileClass();
var clForest = createTileClass();
@@ -112,13 +114,11 @@ Engine.SetProgress(20);
paintRiver({
"parallel": true,
"constraint": stayClasses(clLand, 0),
"startX": 0.5,
"startZ": 0,
"endX": 0.5,
"endZ": 1,
"width": 0.07,
"fadeDist": 0.025,
"deviation": 0.0025,
"start": new Vector2D(mapCenter.x, mapBounds.top),
"end": new Vector2D(mapCenter.x, mapBounds.bottom),
"width": fractionToTiles(0.07),
"fadeDist": scaleByMapSize(3, 12),
"deviation": 1,
"waterHeight": waterHeight,
"landHeight": shoreHeight,
"meanderShort": 12,
@@ -128,9 +128,9 @@ paintRiver({
placeTerrain(ix, iz, tWater);
if (height < shallowHeight && (
z > 0.3 && z < 0.4 ||
z > 0.5 && z < 0.6 ||
z > 0.7 && z < 0.8))
z > 0.3 && z < 0.4 ||
z > 0.5 && z < 0.6 ||
z > 0.7 && z < 0.8))
{
setHeight(ix, iz, shallowHeight);
addToClass(ix, iz, clShallow);
@@ -39,6 +39,8 @@ const pForestP = [tGrassPForest + TERRAIN_SEPARATOR + oOak, tGrassPForest];
InitMap();
const mapCenter = getMapCenter();
const mapBounds = getMapBounds();
const numPlayers = getNumPlayers();
var clPlayer = createTileClass();
@@ -52,6 +54,8 @@ var clFood = createTileClass();
var clBaseResource = createTileClass();
var clHighlands = createTileClass();
var highlandsPosition = fractionToTiles(0.25);
placePlayerBases({
"PlayerPlacement": playerPlacementLine(true, 0.5, 0.2),
"PlayerTileClass": clPlayer,
@@ -83,12 +87,10 @@ Engine.SetProgress(10);
paintRiver({
"parallel": true,
"startX": 0,
"startZ": 1,
"endX": 1,
"endZ": 1,
"width": 0.5,
"fadeDist": 0.05,
"start": new Vector2D(mapBounds.left, mapBounds.top),
"end": new Vector2D(mapBounds.right, mapBounds.top),
"width": fractionToTiles(0.5),
"fadeDist": scaleByMapSize(6, 25),
"deviation": 0,
"waterHeight": -3,
"landHeight": 1,
@@ -107,10 +109,6 @@ paintRiver({
});
Engine.SetProgress(20);
createArea(
new RectPlacer(fractionToTiles(0), fractionToTiles(0), fractionToTiles(1), fractionToTiles(0.25)),
paintClass(clHighlands));
log("Creating fish...");
for (let i = 0; i < scaleByMapSize(10, 20); ++i)
createObjectGroupsDeprecated(
@@ -121,6 +119,10 @@ for (let i = 0; i < scaleByMapSize(10, 20); ++i)
50);
Engine.SetProgress(25);
createArea(
new RectPlacer(mapBounds.left, mapBounds.bottom + highlandsPosition, mapBounds.right, mapBounds.bottom),
paintClass(clHighlands));
log("Creating bumps...");
createAreas(
new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1),
+12 -13
View File
@@ -36,6 +36,8 @@ InitMap();
const numPlayers = getNumPlayers();
const mapSize = getMapSize();
const mapCenter = getMapCenter();
const mapBounds = getMapBounds();
var clPlayer = createTileClass();
var clHill = createTileClass();
@@ -48,8 +50,8 @@ var clFood = createTileClass();
var clBaseResource = createTileClass();
var clMountains = createTileClass();
const waterPos = 0.31;
const mountainPos = 0.69;
var waterPosition = fractionToTiles(0.31);
var mountainPosition = fractionToTiles(0.69);
placePlayerBases({
"PlayerPlacement": playerPlacementLine(false, 0.55, 0.2),
@@ -84,12 +86,10 @@ Engine.SetProgress(15);
paintRiver({
"parallel": true,
"startX": 0,
"startZ": 0,
"endX": 0,
"endZ": 1,
"width": 2 * waterPos,
"fadeDist": 0.025,
"start": new Vector2D(mapBounds.left, mapBounds.top),
"end": new Vector2D(mapBounds.left, mapBounds.bottom),
"width": 2 * waterPosition,
"fadeDist": 8,
"deviation": 0,
"waterHeight": -5,
"landHeight": 3,
@@ -101,7 +101,7 @@ paintRiver({
});
createArea(
new RectPlacer(fractionToTiles(mountainPos), fractionToTiles(0), fractionToTiles(1), fractionToTiles(1)),
new RectPlacer(mountainPosition, mapBounds.top, mapBounds.right, mapBounds.bottom),
paintClass(clMountains));
log("Creating shores...");
@@ -112,14 +112,13 @@ for (let i = 0; i < scaleByMapSize(20, 120); ++i)
Math.floor(scaleByMapSize(4, 6)),
Math.floor(scaleByMapSize(16, 30)),
1,
randIntExclusive(0.28 * mapSize, 0.34 * mapSize),
randIntExclusive(0.1 * mapSize, 0.9 * mapSize)),
Math.floor(fractionToTiles(randFloat(0.28, 0.34))),
Math.floor(fractionToTiles(randFloat(0.1, 0.9)))),
[
new LayeredPainter([tGrass, tGrass], [2]),
new SmoothElevationPainter(ELEVATION_SET, 3, 3),
unPaintClass(clWater)
],
null);
]);
paintTerrainBasedOnHeight(-6, 1, 1, tWater);
paintTerrainBasedOnHeight(1, 2.8, 1, tShoreBlend);
@@ -30,6 +30,8 @@ InitMap();
const numPlayers = getNumPlayers();
const mapSize = getMapSize();
const mapCenter = getMapCenter();
const mapBounds = getMapBounds();
var clPlayer = createTileClass();
var clHill = createTileClass();
@@ -42,6 +44,8 @@ var clMetal = createTileClass();
var clFood = createTileClass();
var clBaseResource = createTileClass();
var landHeight = getMapBaseHeight();
placePlayerBases({
"PlayerPlacement": playerPlacementLine(true, 0.45, 0.2),
"PlayerTileClass": clPlayer,
@@ -67,54 +71,46 @@ Engine.SetProgress(15);
paintRiver({
"parallel": true,
"startX": 0,
"startZ": 1,
"endX": 1,
"endZ": 1,
"width": 0.62,
"fadeDist": tilesToFraction(8),
"start": new Vector2D(mapBounds.left, mapBounds.top),
"end": new Vector2D(mapBounds.right, mapBounds.top),
"width": 2 * fractionToTiles(0.31),
"fadeDist": 8,
"deviation": 0,
"waterHeight": -5,
"landHeight": 3,
"landHeight": landHeight,
"meanderShort": 0,
"meanderLong": 0,
"waterFunc": (ix, iz, height, riverFraction) => {
addToClass(ix, iz, clWater);
},
"landFunc": (ix, iz, shoreDist1, shoreDist2) => {
if (getHeight(ix, iz) < 0.5)
addToClass(ix, iz, clWater);
}
"meanderLong": 0
});
paintTileClassBasedOnHeight(-Infinity, 0.5, Elevation_ExcludeMin_ExcludeMax, clWater);
log("Creating shores...");
for (var i = 0; i < scaleByMapSize(20,120); i++)
for (let i = 0; i < scaleByMapSize(20, 120); ++i)
createArea(
new ChainPlacer(
1,
Math.floor(scaleByMapSize(4, 6)),
Math.floor(scaleByMapSize(16, 30)),
1,
randIntExclusive(0.1 * mapSize, 0.9 * mapSize),
randIntExclusive(0.67 * mapSize, 0.74 * mapSize)),
Math.floor(fractionToTiles(randFloat(0.1, 0.9))),
Math.floor(fractionToTiles(randFloat(0.67, 0.74)))),
[
new LayeredPainter([tSnowA, tSnowA], [2]),
new SmoothElevationPainter(ELEVATION_SET, 3, 3), unPaintClass(clWater)
],
null);
new SmoothElevationPainter(ELEVATION_SET, landHeight, 3),
unPaintClass(clWater)
]);
log("Creating islands...");
createAreas(
new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.1),
[
new LayeredPainter([tSnowA, tSnowA], [3]),
new SmoothElevationPainter(ELEVATION_SET, 3, 3),
new SmoothElevationPainter(ELEVATION_SET, landHeight, 3),
paintClass(clIsland),
unPaintClass(clWater)
],
stayClasses(clWater, 7),
scaleByMapSize(10, 80)
);
scaleByMapSize(10, 80));
paintTerrainBasedOnHeight(-6, 1, 1, tWater);
@@ -42,6 +42,8 @@ const pForest = [tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TE
InitMap();
const numPlayers = getNumPlayers();
const mapSize = getMapSize();
const mapBounds = getMapBounds();
var clPlayer = createTileClass();
var clForest = createTileClass();
@@ -55,6 +57,10 @@ var clGrass = createTileClass();
var clHill = createTileClass();
var clIsland = createTileClass();
var waterHeight = -3;
var shoreHeight = -1.5;
var landHeight = getMapBaseHeight();
placePlayerBases({
"PlayerPlacement": playerPlacementLine(false, 0.76, 0.2),
"PlayerTileClass": clPlayer,
@@ -86,31 +92,22 @@ Engine.SetProgress(30);
paintRiver({
"parallel": true,
"startX": 0,
"startZ": 0,
"endX": 0,
"endZ": 1,
"width": 1,
"fadeDist": 0.05,
"start": new Vector2D(mapBounds.left, mapBounds.top),
"end": new Vector2D(mapBounds.left, mapBounds.bottom),
"width": mapSize,
"fadeDist": scaleByMapSize(6, 25),
"deviation": 0,
"waterHeight": -3,
"landHeight": 1,
"waterHeight": waterHeight,
"landHeight": landHeight,
"meanderShort": 20,
"meanderLong": 0,
"waterFunc": (ix, iz, height, riverFraction) => {
if (height < 0)
addToClass(ix, iz, clWater);
if (height < -1.5)
placeTerrain(ix, iz, tWater);
else
placeTerrain(ix, iz, tShore);
}
"meanderLong": 0
});
Engine.SetProgress(40);
paintTileClassBasedOnHeight(-Infinity, landHeight, Elevation_ExcludeMin_ExcludeMax, clWater);
paintTerrainBasedOnHeight(-Infinity, shoreHeight, Elevation_ExcludeMin_ExcludeMax, tWater);
paintTerrainBasedOnHeight(shoreHeight, landHeight, Elevation_ExcludeMin_ExcludeMax, tShore);
log("Creating bumps...");
createAreas(
new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1),
@@ -173,7 +170,7 @@ Engine.SetProgress(60);
log("Creating cyprus...");
createAreas(
new ClumpPlacer(diskArea(getMapSize() / 13), 0.2, 0.1, 0.01),
new ClumpPlacer(diskArea(fractionToTiles(0.08)), 0.2, 0.1, 0.01),
[
new LayeredPainter([tShore, tHill], [12]),
new SmoothElevationPainter(ELEVATION_SET, 6, 8),
@@ -286,9 +283,10 @@ createObjectGroupsDeprecated(group, 0,
Engine.SetProgress(90);
var stragglerTreeConfig = [
[1, avoidClasses(clForest, 0, clWater, 1, clPlayer, 8, clMetal, 6, clHill, 1)],
[1, avoidClasses(clForest, 0, clWater, 4, clPlayer, 8, clMetal, 6, clHill, 1)],
[3, [stayClasses(clIsland, 9), avoidClasses(clRock, 4, clMetal, 4)]]
];
for (let [amount, constraint] of stragglerTreeConfig)
createStragglerTrees(
[oDatePalm, oSDatePalm, oCarob, oFanPalm, oPoplar, oCypress],
@@ -117,7 +117,7 @@ createArea(
log("Creating rivers between opponents...");
let numRivers = isNomad() ? randIntInclusive(4, 8) : numPlayers;
let rivers = distributePointsOnCircle(numPlayers, startAngle + Math.PI / numRivers, fractionToTiles(0.5), mapCenter)[0];
let rivers = distributePointsOnCircle(numRivers, startAngle + Math.PI / numRivers, fractionToTiles(0.5), mapCenter)[0];
for (let i = 0; i < numRivers; ++i)
{
if (isNomad() ? randBool() : areAllies(playerIDs[i], playerIDs[(i + 1) % numPlayers]))
@@ -128,17 +128,15 @@ for (let i = 0; i < numRivers; ++i)
paintRiver({
"parallel": true,
"startX": tilesToFraction(rivers[i].x),
"startZ": tilesToFraction(rivers[i].y),
"endX": tilesToFraction(mapCenter.x),
"endZ": tilesToFraction(mapCenter.y),
"width": tilesToFraction(scaleByMapSize(10, 30)),
"fadeDist": tilesToFraction(5),
"start": rivers[i],
"end": mapCenter,
"width": scaleByMapSize(10, 30),
"fadeDist": 5,
"deviation": 0,
"landHeight": getMapBaseHeight(),
"waterHeight": waterHeight,
"minHeight": waterHeight,
"meanderShort": tilesToFraction(scaleByMapSize(20, 60) * scaleByMapSize(35, 160)),
"meanderShort": 10,
"meanderLong": 0,
"waterFunc": (ix, iz, height, riverFraction) => {
@@ -317,9 +317,9 @@ function createLayeredPatches(sizes, terrains, terrainWidths, constraint, count,
* Optionally calls a function on the affected tiles.
* Horizontal locations and widths (including fadeDist, meandering) are fractions of the mapsize.
*
* @property horizontal - Whether the river is horizontal or vertical
* @property start - A Vector2D in tile coordinates stating where the river starts.
* @property end - A Vector2D in tile coordinates stating where the river ends.
* @property parallel - Whether the shorelines should be parallel or meander separately.
* @property position - Location of the river.
* @property width - Size between the two shorelines.
* @property fadeDist - Size of the shoreline.
* @property deviation - Fuzz effect on the shoreline if greater than 0.
@@ -354,23 +354,17 @@ function paintRiver(args)
meanderShort * rndRiver(startAngle + fractionToTiles(riverFraction) / 128, seed) +
meanderLong * rndRiver(startAngle + fractionToTiles(riverFraction) / 256, seed);
// Describe river width and length of the shoreline.
let halfWidth = fractionToTiles(args.width / 2);
let fadeDist = fractionToTiles(args.fadeDist);
// Describe river location in vectors.
let mapSize = getMapSize();
let vecStart = new Vector2D(args.startX, args.startZ).mult(mapSize);
let vecEnd = new Vector2D(args.endX, args.endZ).mult(mapSize);
let riverLength = vecStart.distanceTo(vecEnd);
let unitVecRiver = Vector2D.sub(vecStart, vecEnd).normalize();
let riverLength = args.start.distanceTo(args.end);
let unitVecRiver = Vector2D.sub(args.start, args.end).normalize();
// Describe river boundaries.
let riverMinX = Math.min(vecStart.x, vecEnd.x);
let riverMinZ = Math.min(vecStart.y, vecEnd.y);
let riverMaxX = Math.max(vecStart.x, vecEnd.x);
let riverMaxZ = Math.max(vecStart.y, vecEnd.y);
let riverMinX = Math.min(args.start.x, args.end.x);
let riverMinZ = Math.min(args.start.y, args.end.y);
let riverMaxX = Math.max(args.start.x, args.end.x);
let riverMaxZ = Math.max(args.start.y, args.end.y);
let mapSize = getMapSize();
for (let ix = 0; ix < mapSize; ++ix)
for (let iz = 0; iz < mapSize; ++iz)
{
@@ -380,7 +374,7 @@ function paintRiver(args)
let vecPoint = new Vector2D(ix, iz);
// Compute the shortest distance to the river.
let distanceToRiver = distanceOfPointFromLine(vecStart, vecEnd, vecPoint);
let distanceToRiver = distanceOfPointFromLine(args.start, args.end, vecPoint);
// Closest point on the river (i.e the foot of the perpendicular).
let river = Vector2D.sub(vecPoint, unitVecRiver.perpendicular().mult(distanceToRiver));
@@ -391,29 +385,29 @@ function paintRiver(args)
continue;
// Coordinate between 0 and 1 on the axis parallel to the river.
let riverFraction = river.distanceTo(vecStart) / riverLength;
let riverFraction = river.distanceTo(args.start) / riverLength;
// Amplitude of the river at this location.
let riverCurve1 = riverCurve(riverFraction, startingAngle1, seed1);
let riverCurve2 = args.parallel ? riverCurve1 : riverCurve(riverFraction, startingAngle2, seed2);
// Add noise.
let deviation = fractionToTiles(args.deviation) * randFloat(-1, 1);
let deviation = args.deviation * randFloat(-1, 1);
// Compute the distance to the shoreline.
let sign = Math.sign(distanceToRiver || 1);
let shoreDist1 = sign * riverCurve1 + Math.abs(distanceToRiver) - deviation - halfWidth;
let shoreDist2 = sign * riverCurve2 + Math.abs(distanceToRiver) - deviation + halfWidth;
let shoreDist1 = sign * riverCurve1 + Math.abs(distanceToRiver) - deviation - args.width / 2;
let shoreDist2 = sign * riverCurve2 + Math.abs(distanceToRiver) - deviation + args.width / 2;
// Create the elevation for the water and the slopy shoreline and call the user functions.
if (shoreDist1 < 0 && shoreDist2 > 0)
{
let height = args.waterHeight;
if (shoreDist1 > -fadeDist)
height += (args.landHeight - args.waterHeight) * (1 + shoreDist1 / fadeDist);
else if (shoreDist2 < fadeDist)
height += (args.landHeight - args.waterHeight) * (1 - shoreDist2 / fadeDist);
if (shoreDist1 > -args.fadeDist)
height += (args.landHeight - args.waterHeight) * (1 + shoreDist1 / args.fadeDist);
else if (shoreDist2 < args.fadeDist)
height += (args.landHeight - args.waterHeight) * (1 - shoreDist2 / args.fadeDist);
if (args.minHeight === undefined || height < args.minHeight)
setHeight(ix, iz, height);
@@ -314,6 +314,16 @@ function getMapCenter()
return deepfreeze(new Vector2D(g_Map.size / 2, g_Map.size / 2));
}
function getMapBounds()
{
return deepfreeze({
"left": fractionToTiles(0),
"right": fractionToTiles(1),
"top": fractionToTiles(1),
"bottom": fractionToTiles(0)
});
}
function isNomad()
{
return !!g_MapSettings.Nomad;
@@ -40,7 +40,10 @@ var pForest = [tForestFloor + TERRAIN_SEPARATOR + oDatePalm, tForestFloor + TERR
InitMap();
var mapSize = getMapSize();
const mapSize = getMapSize();
const mapCenter = getMapCenter();
const mapBounds = getMapBounds();
var aPlants = mapSize < 256 ?
"actor|props/flora/grass_tropical.xml" :
"actor|props/flora/grass_tropic_field_tall.xml";
@@ -61,6 +64,8 @@ var clPond = createTileClass();
var clShore = createTileClass();
var clTreasure = createTileClass();
var desertWidth = fractionToTiles(0.25);
placePlayerBases({
"PlayerPlacement": playerPlacementRiver(0, 0.4),
"PlayerTileClass": clPlayer,
@@ -113,13 +118,11 @@ var plantID = 0;
paintRiver({
"parallel": true,
"startX": 0.5,
"startZ": 0,
"endX": 0.5,
"endZ": 1,
"width": 0.1,
"fadeDist": 0.025,
"deviation": 0.0025,
"start": new Vector2D(mapCenter.x, mapBounds.top),
"end": new Vector2D(mapCenter.x, mapBounds.bottom),
"width": fractionToTiles(0.1),
"fadeDist": scaleByMapSize(3, 12),
"deviation": 0.5,
"waterHeight": -3,
"landHeight": 2,
"meanderShort": 12,
@@ -142,9 +145,6 @@ paintRiver({
},
"landFunc": (ix, iz, shoreDist1, shoreDist2) => {
if (ix < fractionToTiles(0.25) || ix > fractionToTiles(0.75))
addToClass(ix, iz, clDesert);
for (let riv of riverTextures)
if (riv.left < +shoreDist1 && +shoreDist1 < riv.right ||
riv.left < -shoreDist2 && -shoreDist2 < riv.right)
@@ -154,9 +154,14 @@ paintRiver({
}
}
});
Engine.SetProgress(40);
log("Marking desert...");
for (let [left, right] of [[mapBounds.left, mapBounds.left + desertWidth], [mapBounds.right - desertWidth, mapBounds.right]])
createArea(
new RectPlacer(left, mapBounds.top, right, mapBounds.bottom),
paintClass(clDesert));
log("Creating bumps...");
createAreas(
new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1),
@@ -174,8 +179,7 @@ var waterAreas = createAreas(
paintClass(clPond)
],
avoidClasses(clPlayer, 25, clWater, 20, clPond, 10),
numLakes
);
numLakes);
log("Creating reeds...");
createObjectGroupsByAreasDeprecated(
@@ -195,8 +199,6 @@ createObjectGroupsByAreasDeprecated(
100,
waterAreas);
waterAreas = [];
log("Creating forests...");
var [forestTrees, stragglerTrees] = getTreeCounts(700, 3500, 0.5);
var num = scaleByMapSize(10,30);
@@ -56,6 +56,8 @@ const numPlayers = getNumPlayers();
const mapSize = getMapSize();
const mapArea = getMapArea();
const mapCenter = getMapCenter();
const mapBounds = getMapBounds();
const lSize = Math.pow(scaleByMapSize(1, 6), 1/8);
var clPlayer = createTileClass();
@@ -117,10 +119,11 @@ function createUnknownMap()
paintUnknownMapBasedOnHeight();
if (isNomad())
placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2));
else
createUnknownPlayerBases();
createUnknownPlayerBases();
createUnknownObjects();
placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2, clWater, 10));
}
/**
@@ -284,15 +287,13 @@ function unknownCentralSea()
let waterHeight = -3;
let horizontal = randBool();
let [start, end] = centralRiverCoordinates(horizontal);
let [riverStart, riverEnd] = centralRiverCoordinates(horizontal);
paintRiver({
"parallel": false,
"startX": tilesToFraction(start[0]),
"startZ": tilesToFraction(start[1]),
"endX": tilesToFraction(end[0]),
"endZ": tilesToFraction(end[1]),
"width": randFloat(0.22, 0.3) + scaleByMapSize(0.05, 0.2),
"fadeDist": 0.025,
"start": riverStart,
"end": riverEnd,
"width": fractionToTiles(scaleByMapSize(0.27, 0.42) + randFloat(0, 0.08)),
"fadeDist": scaleByMapSize(3, 12),
"deviation": 0,
"waterHeight": waterHeight,
"landHeight": landHeight,
@@ -317,13 +318,14 @@ function unknownCentralSea()
if (!g_AllowNaval || randBool())
{
log("Creating isthmus (i.e. connecting the two riversides with a big land passage)...");
let [coord1, coord2] = centralRiverCoordinates(!horizontal);
let [isthmusStart, isthmusEnd] = centralRiverCoordinates(!horizontal);
createArea(
new PathPlacer(
...coord1,
...coord2,
scaleByMapSize(randIntInclusive(16, 24),
randIntInclusive(100, 140)),
isthmusStart.x,
isthmusStart.y,
isthmusEnd.x,
isthmusEnd.y,
scaleByMapSize(randIntInclusive(16, 24), randIntInclusive(100, 140)),
0.5,
3 * scaleByMapSize(1, 4),
0.1,
@@ -360,7 +362,7 @@ function unknownCentralRiver()
log("Creating the main river...");
let [coord1, coord2] = centralRiverCoordinates(horizontal);
createArea(
new PathPlacer(...coord1, ...coord2, scaleByMapSize(14, 24), 0.5, scaleByMapSize(3, 12), 0.1, 0.01),
new PathPlacer(coord1.x, coord1.y, coord2.x, coord2.y, scaleByMapSize(14, 24), 0.5, scaleByMapSize(3, 12), 0.1, 0.01),
new SmoothElevationPainter(ELEVATION_SET, waterHeight, 4),
avoidClasses(clPlayerTerritory, 4));
@@ -494,22 +496,15 @@ function unknownEdgeSeas()
markPlayerArea("small");
}
for (let location of pickRandom([["first"], ["second"], ["first", "second"]]))
for (let side of pickRandom([[0], [Math.PI], [0, Math.PI]]))
{
let positionX = location == "first" ? [0, 0] : [1, 1];
let positionZ = [0, 1];
if (horizontal)
[positionX, positionZ] = [positionZ, positionX];
let angle = side + (horizontal ? 0 : Math.PI / 2);
paintRiver({
"parallel": true,
"startX": positionX[0],
"startZ": positionZ[0],
"endX": positionX[1],
"endZ": positionZ[1],
"width": 0.62 - randFloat(0, scaleByMapSize(0, 0.1)),
"fadeDist": 0.015,
"start": new Vector2D(mapBounds.left, mapBounds.top).rotateAround(angle, mapCenter),
"end": new Vector2D(mapBounds.left, mapBounds.bottom).rotateAround(angle, mapCenter),
"width": scaleByMapSize(80, randFloat(270, 320)),
"fadeDist": scaleByMapSize(2, 8),
"deviation": 0,
"waterHeight": waterHeight,
"landHeight": landHeight,
@@ -738,16 +733,10 @@ function unknownMainland()
function centralRiverCoordinates(horizontal)
{
let coord1 = [0, fractionToTiles(0.5)];
let coord2 = [fractionToTiles(1), fractionToTiles(0.5)];
if (!horizontal)
{
coord1.reverse();
coord2.reverse();
}
return [coord1, coord2];
return [
new Vector2D(mapBounds.left, mapCenter.y),
new Vector2D(mapBounds.right, mapCenter.y)
].map(v => v.rotateAround(horizontal ? 0 : Math.PI / 2, mapCenter));
}
function createShoreJaggedness(waterHeight, borderClass, shoreDist, inwards = true)
@@ -5,6 +5,5 @@ Engine.LoadLibrary("the_unknown");
g_AllowNaval = true;
createUnknownMap();
createUnknownObjects();
ExportMap();
@@ -5,6 +5,5 @@ Engine.LoadLibrary("the_unknown");
g_AllowNaval = false;
createUnknownMap();
createUnknownObjects();
ExportMap();