Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/maps/random/alpine_mountains.js
Engine.LoadLibrary("rmgen"); | |||||
Engine.LoadLibrary("rmgen-common"); | |||||
const tForestfloor = "alpine_forrestfloor"; | |||||
const tForestfloorSnow = "alpine_forrestfloor_snow"; | |||||
const tGrassA = "grass_field_a"; | |||||
const tGrassB = "grass_field_b"; | |||||
const tGrassC = "grass_moss"; | |||||
const tRoad = "alpine_dirt"; | |||||
const tCliff = "temp_cliff_c"; | |||||
const tMontainTop = "alpine_cliff_snow"; | |||||
const tMontainPeak = "alpine_snow_a"; | |||||
const oPine = "gaia/flora_tree_pine"; | |||||
const oPineSnow = "gaia/flora_tree_pine_w" | |||||
const oBerryBush = "gaia/flora_bush_berry"; | |||||
const oDeer = "gaia/fauna_deer"; | |||||
const oGoat = "gaia/fauna_goat"; | |||||
const oWolf = "gaia/fauna_wolf"; | |||||
const oStoneLarge = "gaia/geology_stonemine_alpine_quarry"; | |||||
const oStoneSmallA = "gaia/geology_stone_alpine_a"; | |||||
const oStoneSmallB = "gaia/geology_stone_temperate"; | |||||
const oMetalLarge = "gaia/geology_metal_alpine_slabs"; | |||||
const oMetalSmall = "gaia/geology_metal_alpine"; | |||||
const aDryGrass = "actor|props/flora/grass_soft_dry_small_tall.xml"; | |||||
const aGrassFieldDry = "actor|props/flora/grass_temp_field_dry.xml"; | |||||
const aStoneSnow1 = "actor|geology/snow1.xml"; | |||||
const aStoneSnow2 = "actor|geology/snow2.xml"; | |||||
const aStoneDecoratives = [ | |||||
"actor|geology/highland1.xml", | |||||
"actor|geology/highland2.xml", | |||||
"actor|geology/highland3.xml", | |||||
"actor|geology/highland_c.xml", | |||||
"actor|geology/highland_d.xml", | |||||
"actor|geology/highland_e.xml", | |||||
"actor|geology/gray1.xml", | |||||
]; | |||||
const aBlowingSnow = "actor|particle/blowing_snow.xml"; | |||||
const pForestPine = [tForestfloor + TERRAIN_SEPARATOR + oPine, tForestfloor]; | |||||
const pForestPineSnow = [tForestfloorSnow + TERRAIN_SEPARATOR + oPineSnow, tForestfloorSnow]; | |||||
const heightLand = 30; | |||||
const heightOffsetBump = 2; | |||||
const surroundingPlayerAreaMin = 20; | |||||
const surroundingPlayerAreaMax = 50; | |||||
var g_Map = new RandomMap(heightLand, tGrassA); | |||||
const numPlayers = getNumPlayers(); | |||||
const mapSize = g_Map.getSize(); | |||||
const mapCenter = g_Map.getCenter(); | |||||
const mapBounds = g_Map.getBounds(); | |||||
const neighbouringPlayerTiles = 50; | |||||
var clPlayer; | |||||
var clMountain; | |||||
var clForest; | |||||
var clHill = g_Map.createTileClass(); | |||||
var clDirt = g_Map.createTileClass(); | |||||
var clGrass = g_Map.createTileClass(); | |||||
var clRock = g_Map.createTileClass(); | |||||
var clMetal = g_Map.createTileClass(); | |||||
var clFood = g_Map.createTileClass(); | |||||
var clWolf =g_Map.createTileClass(); | |||||
var clBaseResource = g_Map.createTileClass(); | |||||
var surroundingPlayersAreas; | |||||
var mountainBorderArea; | |||||
var startAngle = randomAngle(); | |||||
var playerIDs = sortAllPlayers(); | |||||
var playerPosition; | |||||
Engine.SetProgress(5); | |||||
while(true) { | |||||
g_Map = new RandomMap(heightLand, tGrassA); | |||||
clMountain = g_Map.createTileClass(); | |||||
clForest = g_Map.createTileClass(); | |||||
clPlayer = g_Map.createTileClass(); | |||||
surroundingPlayersAreas = []; | |||||
// Perlin/simplex noise is used to create the mountains. | |||||
// Multiple layers of noise are stacked, each new ones with smaller amplitude but greater scale. | |||||
g_Map.log("Generating terrain height"); | |||||
/*noise.seed(Math.random()); | |||||
for (let i = 0; i < mapSize; ++i) | |||||
lyv: ```var frequency = 12;
var octaves = 1;
var heightScale = 10;
var noise2D = new Noise2D… | |||||
{ | |||||
for (let j = 0; j < mapSize; ++j) { | |||||
let value = noise.simplex2(i / 75, j / 75) - 0.2; | |||||
if (value > 0) { | |||||
let position = new Vector2D(i, j); | |||||
clMountain.add(position); | |||||
g_Map.height[i][j] = (value) * 100 + heightLand; | |||||
} | |||||
else { | |||||
g_Map.height[i][j] = heightLand; | |||||
} | |||||
} | |||||
} | |||||
noise.seed(Math.random()); | |||||
for (let i = 0; i < mapSize; ++i) | |||||
{ | |||||
for (let j = 0; j < mapSize; ++j) { | |||||
let value = noise.simplex2(i / 50, j / 50); | |||||
g_Map.height[i][j] += (value) * 15; | |||||
} | |||||
} | |||||
noise.seed(Math.random()); | |||||
for (let i = 0; i < mapSize; ++i) | |||||
{ | |||||
for (let j = 0; j < mapSize; ++j) { | |||||
let value = noise.simplex2(i / 10, j / 10); | |||||
let position = new Vector2D(i, j); | |||||
if (clMountain.has(position)) { | |||||
g_Map.height[i][j] += (value + 1) * 4; | |||||
} | |||||
} | |||||
} | |||||
noise.seed(Math.random()); | |||||
for (let i = 0; i < mapSize; ++i) | |||||
{ | |||||
for (let j = 0; j < mapSize; ++j) { | |||||
let value = noise.simplex2(i / 5, j / 5); | |||||
let position = new Vector2D(i, j); | |||||
if (clMountain.has(position)) { | |||||
g_Map.height[i][j] += (value + 1) * 4; | |||||
} | |||||
} | |||||
}*/ | |||||
// ------------------------------------------------------------------------------------- | |||||
var noise = new Noise2D(8); | |||||
for (let x = 0; x < mapSize; ++x) | |||||
{ | |||||
for (let y = 0; y < mapSize; ++y) { | |||||
let value = noise.get(x / (mapSize + 1.0), y / (mapSize + 1.0)) - 0.54; | |||||
if (value > 0) { | |||||
let position = new Vector2D(x, y); | |||||
clMountain.add(position); | |||||
g_Map.height[x][y] = (value) * 275 + heightLand; | |||||
} | |||||
else { | |||||
g_Map.height[x][y] = heightLand; | |||||
} | |||||
} | |||||
} | |||||
/*var noise = new Noise2D(5); | |||||
for (let x = 0; x < mapSize; ++x) | |||||
{ | |||||
for (let y = 0; y < mapSize; ++y) { | |||||
let value = noise.get(x / (mapSize + 1.0), y / (mapSize + 1.0)) - 0.54; | |||||
if (value > 0) { | |||||
let position = new Vector2D(x, y); | |||||
clMountain.add(position); | |||||
g_Map.height[x][y] = (value) * 275 + heightLand; | |||||
} | |||||
else { | |||||
g_Map.height[x][y] = heightLand; | |||||
} | |||||
} | |||||
}*/ | |||||
noise = new Noise2D(10); | |||||
for (let x = 0; x < mapSize; ++x) | |||||
{ | |||||
for (let y = 0; y < mapSize; ++y) { | |||||
let value = noise.get(x / (mapSize + 1.0), y / (mapSize + 1.0)) - 0.565; | |||||
let position = new Vector2D(x, y); | |||||
g_Map.height[x][y] += (value) * 52; | |||||
} | |||||
} | |||||
noise = new Noise2D(50); | |||||
for (let x = 0; x < mapSize; ++x) | |||||
{ | |||||
for (let y = 0; y < mapSize; ++y) { | |||||
let value = noise.get(x / (mapSize + 1.0), y / (mapSize + 1.0)); | |||||
let position = new Vector2D(x, y); | |||||
if (clMountain.has(position)) { | |||||
g_Map.height[x][y] += (value) * 12; | |||||
} | |||||
} | |||||
} | |||||
noise = new Noise2D(100); | |||||
for (let x = 0; x < mapSize; ++x) | |||||
{ | |||||
for (let y = 0; y < mapSize; ++y) { | |||||
let value = noise.get(x / (mapSize + 1.0), y / (mapSize + 1.0)); | |||||
let position = new Vector2D(x, y); | |||||
if (clMountain.has(position)) { | |||||
g_Map.height[x][y] += (value) * 12; | |||||
} | |||||
} | |||||
} | |||||
mountainBorderArea = createArea(new MapBoundsPlacer(), null, borderClasses(clMountain, 0, 8)); | |||||
createArea( | |||||
new MapBoundsPlacer(), | |||||
new SmoothingPainter(1, 0.5, 2), | |||||
borderClasses(clMountain, 1, 1) | |||||
); | |||||
createArea( | |||||
new MapBoundsPlacer(), | |||||
new SmoothingPainter(3, 0.5, 1), | |||||
stayClasses(clMountain, 7) | |||||
); | |||||
if (!isNomad()) | |||||
{ | |||||
g_Map.log("Finding player locations"); | |||||
let players = playerPlacementRandom( | |||||
playerIDs, | |||||
avoidClasses(clMountain, 20) | |||||
); | |||||
if (!players) { | |||||
g_Map.log("Too few player locations, starting over"); | |||||
continue; | |||||
} | |||||
[playerIDs, playerPosition] = players; | |||||
} | |||||
if (!isNomad()) | |||||
{ | |||||
g_Map.log("Flattening initial CC area"); | |||||
let playerRadius = defaultPlayerBaseRadius() * 0.8; | |||||
for (let position of playerPosition) | |||||
createArea( | |||||
new ClumpPlacer(diskArea(playerRadius), 0.95, 0.6, Infinity, position), | |||||
new SmoothElevationPainter(ELEVATION_SET, g_Map.getHeight(position), playerRadius / 2)); | |||||
Engine.SetProgress(38); | |||||
} | |||||
for (let i = 0; i < numPlayers; ++i) | |||||
{ | |||||
if (isNomad()) | |||||
break; | |||||
placePlayerBase({ | |||||
"playerID": playerIDs[i], | |||||
"playerPosition": playerPosition[i], | |||||
"PlayerTileClass": clPlayer, | |||||
"Walls": "towers", | |||||
"BaseResourceClass": clBaseResource, | |||||
"Chicken": { | |||||
}, | |||||
"Berries": { | |||||
"template": oBerryBush | |||||
}, | |||||
"Mines": { | |||||
"types": [ | |||||
{ "template": oMetalLarge }, | |||||
{ "template": oStoneLarge } | |||||
] | |||||
}, | |||||
"Trees": { | |||||
"template": oPine, | |||||
"count": 30 | |||||
} | |||||
}); | |||||
} | |||||
if (!isNomad()) { | |||||
for (let i = 0; i < numPlayers; ++i) { | |||||
surroundingPlayersAreas[i] = createArea(new DiskPlacer(surroundingPlayerAreaMax, playerPosition[i]), null, avoidClasses(clPlayer, surroundingPlayerAreaMin)); | |||||
} | |||||
} | |||||
g_Map.log("Creating forests"); | |||||
const treesPerForests = scaleByMapSize(30, 40); | |||||
createAreasInAreas( | |||||
new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), treesPerForests, 0.5), | |||||
[ | |||||
new LayeredPainter([tForestfloor, pForestPine], [1]), | |||||
new TileClassPainter(clForest) | |||||
], | |||||
new AndConstraint([avoidClasses(clPlayer, 15), borderClasses(clMountain, 2, 30)]), | |||||
50, | |||||
0.5, | |||||
[mountainBorderArea]); | |||||
if (!isNomad()) { | |||||
g_Map.log("Creating player owned forest"); | |||||
for (let i = 0; i < numPlayers; ++i) | |||||
createAreasInAreas( | |||||
new ChainPlacer(3, 3, 30, 0.15), | |||||
[ | |||||
new LayeredPainter([tForestfloor, pForestPine], [2]), | |||||
new TileClassPainter(clForest) | |||||
], | |||||
[new AndConstraint([avoidClasses(clPlayer, 15, clMountain, 9), borderClasses(clPlayer, 0, 30)]), new PassableMapAreaConstraint()], | |||||
1, | |||||
100, | |||||
[surroundingPlayersAreas[i]]); | |||||
} | |||||
if (isNomad()) { | |||||
break; | |||||
} | |||||
g_Map.log("Checking if players are connected"); | |||||
if (areConnected(playerPosition, [clMountain, clForest])) { | |||||
break; | |||||
} | |||||
g_Map.log("Players are not connected, starting over"); | |||||
} | |||||
Engine.SetProgress(55); | |||||
g_Map.log("Creating primary grass patches"); | |||||
createAreas( | |||||
new ChainPlacer(1, 2, randIntInclusive(10, 80), 0.6), | |||||
[new TerrainPainter(tGrassB), new TileClassPainter(clGrass)], | |||||
avoidClasses(clMountain, 0, clForest, 0, clPlayer, 6), | |||||
scaleByMapSize(40, 250) | |||||
); | |||||
g_Map.log("Creating secondary grass patches"); | |||||
createAreas( | |||||
new ChainPlacer(1, 2, randIntInclusive(2, 15), 0.6), | |||||
[new TerrainPainter(tGrassC), new TileClassPainter(clGrass)], | |||||
avoidClasses(clMountain, 0, clForest, 0, clPlayer, 6), | |||||
scaleByMapSize(80, 300) | |||||
); | |||||
createAreas(new ChainPlacer(1, 10, randIntInclusive(1, 5), 1), | |||||
new SmoothElevationPainter(ELEVATION_MODIFY, 0, 100), | |||||
new AndConstraint([stayClasses(clMountain, 2), new SlopeConstraint(0.5, 1.7), new HeightConstraint(heightLand, heightLand + 60)]), | |||||
scaleByMapSize(7, 35), | |||||
20 | |||||
); | |||||
g_Map.log("Painting mountains"); | |||||
createArea( | |||||
new MapBoundsPlacer(), | |||||
new TerrainPainter(tCliff), | |||||
[ | |||||
stayClasses(clMountain, 0), | |||||
new SlopeConstraint(1.7, Infinity) | |||||
]); | |||||
createArea( | |||||
new MapBoundsPlacer(), | |||||
new TerrainPainter(tMontainTop), | |||||
[ | |||||
stayClasses(clMountain, 0), | |||||
new SlopeConstraint(0.7, 1.7) | |||||
]); | |||||
createArea( | |||||
new MapBoundsPlacer(), | |||||
new TerrainPainter(tMontainPeak), | |||||
[ | |||||
stayClasses(clMountain, 0), | |||||
new SlopeConstraint(0, 0.7) | |||||
]); | |||||
createArea( | |||||
new MapBoundsPlacer(), | |||||
new TerrainPainter(tMontainPeak), | |||||
[ | |||||
new HeightConstraint(heightLand + 60, Infinity) | |||||
]); | |||||
createAreas( | |||||
new ChainPlacer(1, 3, randIntInclusive(1, 10), 1), | |||||
[ | |||||
new TerrainPainter(pForestPineSnow[0]), | |||||
new TileClassPainter(clForest) | |||||
], | |||||
new AndConstraint([stayClasses(clMountain, 2), new SlopeConstraint(0, 1.7), new HeightConstraint(heightLand, heightLand + 40)]), | |||||
scaleByMapSize(3, 15), | |||||
20 | |||||
); | |||||
Engine.SetProgress(65); | |||||
g_Map.log("Creating minerals"); | |||||
var group = new SimpleGroup([new SimpleObject(oMetalSmall, 1, 4, 0, 1.5)], true, clMetal); | |||||
createObjectGroupsByAreas(group, 0, | |||||
[avoidClasses(clPlayer, 15, clForest, 1, clMetal, 8, clMountain, 1), borderClasses(clMountain, 0, 3), new SlopeConstraint(0, 1.2)], | |||||
Math.floor(scaleByMapSize(8, 55) * randFloat(1, 1.5)), 100, [mountainBorderArea]); | |||||
group = new SimpleGroup([new SimpleObject(oStoneLarge, 1, 1, 0, 1.5)], true, clRock); | |||||
createObjectGroupsByAreas(group, 0, | |||||
[avoidClasses(clPlayer, 15, clForest, 1, clMetal, 12, clRock, 12), borderClasses(clMountain, 0, 3)], | |||||
Math.floor(scaleByMapSize(2, 10) * randFloat(1, 1.5)), 100, [mountainBorderArea]); | |||||
group = new SimpleGroup([new SimpleObject(oStoneSmallA, 1, 4, 0, 1.5)], true, clRock); | |||||
createObjectGroupsByAreas(group, 0, | |||||
[avoidClasses(clPlayer, 15, clForest, 1, clMetal, 8, clRock, 2, clMountain, 1), borderClasses(clMountain, 0, 3), new SlopeConstraint(0, 1.2)], | |||||
Math.floor(scaleByMapSize(4, 20) * randFloat(1, 1.5)), 100, [mountainBorderArea]); | |||||
group = new SimpleGroup([new SimpleObject(oStoneSmallA, 1, 4, 0, 3)], true, clRock); | |||||
createObjectGroups(group, 0, | |||||
[avoidClasses(clPlayer, 25, clForest, 1, clMetal, 8, clRock, 2, clMountain, 5)], | |||||
Math.floor(scaleByMapSize(1, 8) * randFloat(1, 2)), 100); | |||||
group = new SimpleGroup([new SimpleObject(oStoneSmallB, 1, 4, 0, 3)], true, clRock); | |||||
createObjectGroups(group, 0, | |||||
[avoidClasses(clPlayer, 25, clForest, 1, clMetal, 8, clRock, 6, clMountain, 8)], | |||||
Math.floor(scaleByMapSize(1, 8) * randFloat(1, 2)), 100); | |||||
Engine.SetProgress(75); | |||||
if (!isNomad()) { | |||||
g_Map.log("Creating additionnal food for players (balance)"); | |||||
// Player ressource balance calculation | |||||
var initialFoodAmount = randIntInclusive(0, 25);// 1 unit = 100 food | |||||
// I want it likely that there is no additionnal food for the player. | |||||
if (initialFoodAmount < 6) | |||||
initialFoodAmount = 0; | |||||
for (let i = 0; i < numPlayers; ++i) { | |||||
let remainingFood = initialFoodAmount; | |||||
while (remainingFood > 0) { | |||||
if (remainingFood <= 2) { | |||||
remainingFood = 0; | |||||
} | |||||
else if (remainingFood <= 4) { | |||||
placeFoodForPlayer(oGoat, remainingFood, remainingFood, remainingFood, i); | |||||
remainingFood = 0; | |||||
} | |||||
else if (remainingFood <= 10) { | |||||
remainingFood -= placeFoodForPlayer(pickRandom([oDeer, oGoat]), 5, 8, remainingFood, i); | |||||
} | |||||
else { | |||||
if (randBool(0.5)) { | |||||
remainingFood -= 2 * placeFoodForPlayer(oBerryBush, 5, 7, Math.floor(remainingFood/2), i); | |||||
} | |||||
else { | |||||
remainingFood -= placeFoodForPlayer(pickRandom([oDeer, oGoat]), 5, 8, remainingFood, i); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
Done Inline ActionsPlease don't use deprecated functions. Imarok: Please don't use deprecated functions.
At some point we need to get rid of them. Adding more to… | |||||
Done Inline Actions(See #4695 for background info) Imarok: (See #4695 for background info) | |||||
Engine.SetProgress(85); | |||||
g_Map.log("Creating berries"); | |||||
group = new SimpleGroup( | |||||
[new SimpleObject(oBerryBush, 4,6, 0,4)], | |||||
true, clFood | |||||
); | |||||
createObjectGroups(group, 0, | |||||
[avoidClasses(clPlayer, neighbouringPlayerTiles, clMountain, 3, clMetal, 4, clRock, 4, clFood, 10), borderClasses(clForest, 1, 1)], | |||||
randFloat(0.5, 1) * scaleByMapSize(6, 30), 20 | |||||
); | |||||
g_Map.log("Creating deer"); | |||||
group = new SimpleGroup( | |||||
[new SimpleObject(oDeer, 5,7, 0,4)], | |||||
true, clFood | |||||
); | |||||
createObjectGroups(group, 0, | |||||
avoidClasses(clForest, 0, clPlayer, neighbouringPlayerTiles, clMountain, 3, clMetal, 4, clRock, 4, clFood, 10), | |||||
randFloat(0.2, 1) * scaleByMapSize(2, 10), 5 | |||||
); | |||||
g_Map.log("Creating goats"); | |||||
group = new SimpleGroup( | |||||
[new SimpleObject(oGoat, 5,7, 0,4)], | |||||
true, clFood | |||||
); | |||||
createObjectGroups(group, 0, | |||||
avoidClasses(clForest, 0, clPlayer, neighbouringPlayerTiles, clMountain, 3, clMetal, 4, clRock, 4, clFood, 10), | |||||
randFloat(0.2, 1) * scaleByMapSize(3, 15), 5 | |||||
); | |||||
g_Map.log("Creating wolves"); | |||||
group = new SimpleGroup( | |||||
[new SimpleObject(oWolf, 1,3, 0,4)], | |||||
true, clWolf | |||||
); | |||||
createObjectGroups(group, 0, | |||||
avoidClasses(clForest, 0, clPlayer, neighbouringPlayerTiles, clMountain, 3, clMetal, 4, clRock, 4, clFood, 1), | |||||
randFloat(0.2, 1) * scaleByMapSize(2, 10), 5 | |||||
); | |||||
Engine.SetProgress(90); | |||||
g_Map.log("Creating straggler trees"); | |||||
createStragglerTrees([oPine], | |||||
avoidClasses(clMountain, 3, clPlayer, 15, clMetal, 4, clRock, 4, clFood, 1, clWolf, 1, clForest, 3), | |||||
clForest, | |||||
scaleByMapSize(40, 380), | |||||
100); | |||||
g_Map.log("Creating straggler trees on mountains"); | |||||
createStragglerTrees([oPineSnow], | |||||
new AndConstraint([stayClasses(clMountain, 1), new HeightConstraint(heightLand + 5, heightLand + 40), new SlopeConstraint(0, 1)]), | |||||
clForest, | |||||
scaleByMapSize(200, 1900), | |||||
50); | |||||
g_Map.log("Creating grass"); | |||||
group = new SimpleGroup( | |||||
[new SimpleObject(aGrassFieldDry, 1, 4, 0,1.8, -Math.PI / 8, Math.PI / 8)] | |||||
); | |||||
createObjectGroupsDeprecated(group, 0, | |||||
avoidClasses(clMountain, 6, clPlayer, 2, clForest, 0), | |||||
scaleByMapSize(36, 300) | |||||
); | |||||
group = new SimpleGroup( | |||||
[new SimpleObject(aDryGrass, 1, 3, 0,1.8, -Math.PI / 8, Math.PI / 8)] | |||||
); | |||||
createObjectGroupsDeprecated(group, 0, | |||||
avoidClasses(clMountain, 6, clPlayer, 2, clForest, 0), | |||||
scaleByMapSize(36, 300) | |||||
); | |||||
g_Map.log("Creating decorative rocks"); | |||||
group = new SimpleGroup( | |||||
[new RandomObject(aStoneDecoratives, 1, 3, 0,1.8, -Math.PI / 8, Math.PI / 8)] | |||||
); | |||||
createObjectGroupsDeprecated(group, 0, | |||||
avoidClasses(clMountain, 0, clPlayer, 2, clForest, 0), | |||||
scaleByMapSize(12, 100) | |||||
); | |||||
group = new SimpleGroup( | |||||
[new RandomObject([aStoneSnow1, aStoneSnow2], 1, 1, 0,1.8, -Math.PI / 8, Math.PI / 8)] | |||||
); | |||||
createObjectGroupsDeprecated(group, 0, | |||||
new AndConstraint([stayClasses(clMountain, 2), new SlopeConstraint(0, 1.7), new HeightConstraint(heightLand, heightLand + 60)]), | |||||
scaleByMapSize(72, 600) | |||||
); | |||||
g_Map.log("Creating blowing snow"); | |||||
group = new SimpleGroup( | |||||
[new SimpleObject(aBlowingSnow, 1, 1, 0,1.8, -Math.PI / 8, Math.PI / 8)] | |||||
); | |||||
createObjectGroupsDeprecated(group, 0, | |||||
new AndConstraint([stayClasses(clMountain, 2), new SlopeConstraint(0, 1.7), new HeightConstraint(heightLand + 30, Infinity)]), | |||||
scaleByMapSize(18, 150) | |||||
); | |||||
placePlayersNomadConnected(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clMountain, 4, clFood, 2, clWolf, 25)); | |||||
setSkySet("sunset"); | |||||
setSunColor(1, 0.87451, 0.611765); | |||||
setSunElevation(0.524621); | |||||
setSunRotation(-0.785396); | |||||
setTerrainAmbientColor(0.501961, 0.501961, 0.501961); | |||||
setUnitsAmbientColor(0.501961, 0.501961, 0.501961); | |||||
setFogFactor(0.00046875); | |||||
setFogThickness(0.14); | |||||
setFogColor(0.8, 0.8, 0.8); | |||||
g_Map.ExportMap(); | |||||
// Places a bounded amount of corresponding type food to the specified player and returns the amount placed. | |||||
function placeFoodForPlayer(type, min, max, remainingFood, areaId) { | |||||
// Since the placing function doesn't specify (i think ?) the number of objects placed, randomization is done there. | |||||
max = max < remainingFood ? max : remainingFood; | |||||
let amountPlaced = randIntInclusive(min, max); | |||||
// Hunt should spawn farther from the CC in general. | |||||
let minTileBound = 20; | |||||
let maxTileBound = 30; | |||||
if (type != oBerryBush) { | |||||
minTileBound += 5; | |||||
maxTileBound += 5; | |||||
} | |||||
let food = new SimpleGroup( | |||||
[new SimpleObject(type, amountPlaced, amountPlaced, 0,4)], | |||||
true, clFood | |||||
); | |||||
createObjectGroupsByAreas(food, 0, | |||||
new AndConstraint([avoidClasses(clForest, 0, clPlayer, minTileBound, clMountain, 1, clMetal, 4, clRock, 4, clFood, 10), borderClasses(clPlayer, 0, maxTileBound)]), | |||||
1, 400, [surroundingPlayersAreas[areaId]] | |||||
); | |||||
return amountPlaced; | |||||
} | |||||
function placePlayersNomadConnected(playerClass, constraints) | |||||
{ | |||||
if (!isNomad()) | |||||
return undefined; | |||||
g_Map.log("Placing nomad starting units"); | |||||
let distance = scaleByMapSize(60, 240); | |||||
let numPlayers = getNumPlayers(); | |||||
let playerIDs = shuffleArray(sortAllPlayers()); | |||||
let playerPosition = []; | |||||
let constraint = new AndConstraint(constraints); | |||||
do { | |||||
for (let i = 0; i < numPlayers; ++i) { | |||||
let validCoordinates = false; | |||||
let position; | |||||
do { | |||||
position = g_Map.randomCoordinate(); | |||||
} while (!constraint.allows(position)); | |||||
playerPosition[i] = position; | |||||
} | |||||
} while (!areConnected(playerPosition, [clMountain, clForest])); | |||||
for (let i = 0; i < numPlayers; ++i) | |||||
{ | |||||
let objects = getStartingEntities(playerIDs[i]).filter(ents => ents.Template.startsWith("units/")).map( | |||||
ents => new SimpleObject(ents.Template, ents.Count || 1, ents.Count || 1, 1, 3)); | |||||
// Add treasure if too few resources for a civic center | |||||
let ccCost = Engine.GetTemplate("structures/" + getCivCode(playerIDs[i]) + "_civil_centre").Cost.Resources; | |||||
for (let resourceType in ccCost) | |||||
{ | |||||
let treasureTemplate = g_NomadTreasureTemplates[resourceType]; | |||||
let count = Math.max(0, Math.ceil( | |||||
(ccCost[resourceType] - (g_MapSettings.StartingResources || 0)) / | |||||
Engine.GetTemplate(treasureTemplate).ResourceSupply.Amount)); | |||||
objects.push(new SimpleObject(treasureTemplate, count, count, 3, 5)); | |||||
} | |||||
// Try place these entities at a random location | |||||
let group = new SimpleGroup(objects, true, playerClass); | |||||
group.setCenterPosition(playerPosition[i]); | |||||
group.place(i + 1, new NullConstraint()); | |||||
} | |||||
return [playerIDs, playerPosition]; | |||||
} |
Wildfire Games · Phabricator
Snippet of some code that was generating terrain using multiple octaves of perlin noise from our own implementation. You should be able to generate the same landscape by tuning values if the current map is also using simplex noise since Perlin and simplex noise generally look the same when scaled.