Remove confusing rmgen2 g_MapInfo and initMapSettings, fixes #4813.

Rename initBiome to initForestFloor, getTeams to getTeamsArray.
Unifying duplicate coordinate computation and inlining unneeded
createArea helper variables in Lions Den.

This was SVN commit r20278.
This commit is contained in:
elexis
2017-10-09 21:21:35 +00:00
parent 87ff880445
commit 9e931b6fbe
20 changed files with 315 additions and 288 deletions
@@ -9,7 +9,7 @@ InitMap();
log("Initializing tile classes...");
setBiome("tropic");
initMapSettings();
initForestFloor();
initTileClasses();
log("Initializing environment...");
@@ -60,11 +60,11 @@ g_Decoratives.rockLarge = "actor|geology/stone_savanna_med.xml";
g_Decoratives.rockMedium = "actor|geology/stone_savanna_med.xml";
g_Decoratives.bushMedium = "actor|props/flora/bush_tropic_a.xml";
g_Decoratives.bushSmall = "actor|props/flora/bush_tropic_b.xml";
initBiome();
initForestFloor();
RMS.SetProgress(5);
log("Resetting terrain...");
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
log("Copying heightmap...");
@@ -91,7 +91,7 @@ var strongholdBases = [
[80, 240],
[190, 60]
];
randomPlayerPlacementAt(singleBases, strongholdBases, scale, 0.06);
randomPlayerPlacementAt(getTeamsArray(), singleBases, strongholdBases, scale, 0.06);
RMS.SetProgress(50);
addElements([
@@ -5,19 +5,20 @@ RMS.LoadLibrary("rmbiome");
InitMap();
setSelectedBiome();
initMapSettings();
initForestFloor();
initTileClasses();
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 2);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
var pos = randomStartingPositionPattern();
addBases(pos.setup, pos.distance, pos.separation);
const pos = randomStartingPositionPattern(getTeamsArray());
addBases(pos.setup, pos.distance, pos.separation, randFloat(0, 2 * Math.PI));
RMS.SetProgress(20);
addElements([
{
"func": addBluffs,
"baseHeight": getMapBaseHeight(),
"avoid": [
g_TileClasses.bluff, 12,
g_TileClasses.hill, 5,
@@ -7,9 +7,8 @@ RMS.LoadLibrary("rmbiome");
InitMap();
log("Initializing tile classes...");
setBiome("desert");
initMapSettings();
initForestFloor();
initTileClasses(["island"]);
log("Initializing environment...");
@@ -38,7 +37,6 @@ setPPSaturation(0.42);
setPPBloom(0.23);
log("Initializing biome...");
g_Terrains.mainTerrain = "desert_dirt_rough_2";
g_Terrains.forestFloor1 = "grass_dead";
g_Terrains.forestFloor2 = "desert_dirt_persia_1";
@@ -63,12 +61,11 @@ g_Decoratives.rockLarge = "actor|geology/stone_savanna_med.xml";
g_Decoratives.rockMedium = "actor|geology/stone_granite_greek_small.xml";
g_Decoratives.bushMedium = "actor|props/flora/bush_desert_dry_a.xml";
g_Decoratives.bushSmall = "actor|props/flora/bush_medit_la_dry";
initBiome();
initForestFloor();
RMS.SetProgress(5);
log("Resetting terrain...");
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
log("Copying heightmap...");
@@ -83,6 +80,9 @@ paintTileClassBasedOnHeight(-100, -1, 3, g_TileClasses.water);
RMS.SetProgress(40);
log("Placing players...");
const numPlayers = getNumPlayers();
const teamsArray = getTeamsArray();
//Coordinate system of the heightmap
var singleBases = [
[30, 220],
@@ -93,7 +93,7 @@ var singleBases = [
[240, 220]
];
if (g_MapInfo.numPlayers > singleBases.length)
if (numPlayers > singleBases.length)
singleBases.push(
[40, 55],
[280, 150]
@@ -104,13 +104,13 @@ var strongholdBases = [
[250, 55]
];
if (g_MapInfo.teams.length > strongholdBases.length)
if (teamsArray.length > strongholdBases.length)
strongholdBases.push(
[45, 180],
[260, 195]
);
randomPlayerPlacementAt(singleBases, strongholdBases, scale, 0.06);
randomPlayerPlacementAt(teamsArray, singleBases, strongholdBases, scale, 0.06);
RMS.SetProgress(50);
log("Render mainland...");
@@ -279,7 +279,7 @@ g_Terrains.tier1Terrain = "sand_scrub_25";
g_Terrains.tier2Terrain = "sand_scrub_75";
g_Terrains.tier3Terrain = "sand_scrub_50";
g_Terrains.tier4Terrain = "sand";
initBiome();
initForestFloor();
log("Render island...");
addElements([
@@ -414,7 +414,7 @@ for (let treasure of ["wood", "food_bin"])
g_TileClasses.player, 25,
g_TileClasses.forest, 2
),
3 * g_MapInfo.numPlayers,
3 * numPlayers,
200
);
}
@@ -428,7 +428,7 @@ createObjectGroupsDeprecated(
),
0,
stayClasses(g_TileClasses.water, 2),
g_MapInfo.numPlayers,
numPlayers,
200
);
RMS.SetProgress(95);
@@ -5,27 +5,27 @@ RMS.LoadLibrary("rmbiome");
InitMap();
setSelectedBiome();
initMapSettings();
initForestFloor();
initTileClasses();
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, randIntInclusive(0, 4));
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
addBases("stronghold", 0.37, 0.04);
const teamsArray = getTeamsArray();
const startAngle = randFloat(0, 2 * Math.PI);
addBases("stronghold", 0.37, 0.04, startAngle);
RMS.SetProgress(20);
// Change the starting angle and add the players again
var rotation = PI;
if (g_MapInfo.teams.length == 2)
if (teamsArray.length == 2)
rotation = PI / 2;
if (g_MapInfo.teams.length == 4)
if (teamsArray.length == 4)
rotation = PI + PI / 4;
g_MapInfo.startAngle = g_MapInfo.startAngle + rotation;
addBases("stronghold", 0.15, 0.04);
addBases("stronghold", 0.15, 0.04, startAngle + rotation);
RMS.SetProgress(40);
addElements(shuffleArray([
@@ -5,9 +5,8 @@ RMS.LoadLibrary("rmbiome");
InitMap();
setSelectedBiome();
initMapSettings();
initForestFloor();
initTileClasses();
RMS.SetProgress(10);
// Pick a random elevation with a bias towards lower elevations
@@ -18,13 +17,14 @@ if (randElevation < 25)
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, randElevation);
RMS.SetProgress(20);
var pos = randomStartingPositionPattern();
addBases(pos.setup, pos.distance, pos.separation);
const startPositions = randomStartingPositionPattern(getTeamsArray());
addBases(startPositions.setup, startPositions.distance, startPositions.separation, randFloat(0, 2 * Math.PI));
RMS.SetProgress(40);
var features = [
{
"func": addBluffs,
"baseHeight": randElevation,
"avoid": [
g_TileClasses.bluff, 20,
g_TileClasses.hill, 10,
@@ -104,6 +104,7 @@ if (randElevation < 4)
if (randElevation > 20)
features.push({
"func": addValleys,
"baseHeight": randElevation,
"avoid": [
g_TileClasses.bluff, 5,
g_TileClasses.hill, 5,
+24 -18
View File
@@ -5,21 +5,23 @@ RMS.LoadLibrary("rmbiome");
InitMap();
setSelectedBiome();
initMapSettings();
initForestFloor();
initTileClasses();
setFogFactor(0.04);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 2);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
var players = addBases("radial", 0.38);
const mapSize = getMapSize();
const startAngle = randFloat(0, 2 * Math.PI);
const players = addBases("radial", 0.38, 0.05, startAngle);
RMS.SetProgress(20);
addCenterLake();
RMS.SetProgress(30);
if (g_MapInfo.mapSize >= 192)
if (mapSize >= 192)
{
addHarbors(players);
RMS.SetProgress(40);
@@ -77,6 +79,7 @@ addElements(shuffleArray([
},
{
"func": addBluffs,
"baseHeight": getMapBaseHeight(),
"avoid": [
g_TileClasses.bluff, 20,
g_TileClasses.mountain, 25,
@@ -252,6 +255,7 @@ ExportMap();
function addCenterLake()
{
let lSize = sqrt(sqrt(sqrt(scaleByMapSize(1, 6))));
let center = Math.round(fractionToTiles(0.5));
createArea(
new ChainPlacer(
@@ -259,10 +263,10 @@ function addCenterLake()
Math.floor(scaleByMapSize(2, 12)),
Math.floor(scaleByMapSize(35, 160)),
1,
g_MapInfo.centerOfMap,
g_MapInfo.centerOfMap,
center,
center,
0,
[floor(g_MapInfo.mapSize * 0.17 * lSize)]
[Math.floor(mapSize * 0.17 * lSize)]
),
[
new LayeredPainter(
@@ -280,7 +284,7 @@ function addCenterLake()
);
let fDist = 50;
if (g_MapInfo.mapSize <= 192)
if (mapSize <= 192)
fDist = 20;
// create a bunch of fish
@@ -289,8 +293,8 @@ function addCenterLake()
[new SimpleObject(g_Gaia.fish, 20, 30, 0, fDist)],
true,
g_TileClasses.baseResource,
g_MapInfo.centerOfMap,
g_MapInfo.centerOfMap
center,
center
),
0,
[
@@ -302,14 +306,15 @@ function addCenterLake()
function addHarbors(players)
{
let center = Math.round(fractionToTiles(0.5));
for (let i = 0; i < players.length; ++i)
{
let ix = round(fractionToTiles(players[i].x));
let iz = round(fractionToTiles(players[i].z));
let playerDistX = g_MapInfo.centerOfMap - ix;
let playerDistZ = g_MapInfo.centerOfMap - iz;
let offsetX = round(playerDistX / 2.5);
let offsetZ = round(playerDistZ / 2.5);
let offsetX = Math.round((center - ix) / 2.5);
let offsetZ = Math.round((center - iz) / 2.5);
createArea(
new ClumpPlacer(scaleByMapSize(1200, 1200), 0.5, 0.5, 1, ix + offsetX, iz + offsetZ),
@@ -344,6 +349,7 @@ function addHarbors(players)
function addSpines()
{
let numPlayers = getNumPlayers();
let spineTile = g_Terrains.dirt;
let elevation = 35;
@@ -357,12 +363,12 @@ function addSpines()
spineTile = g_Terrains.tier4Terrain;
let split = 1;
if (g_MapInfo.numPlayers <= 3 || (g_MapInfo.mapSize >= 320 && g_MapInfo.numPlayers <= 4))
if (numPlayers <= 3 || mapSize >= 320 && numPlayers <= 4)
split = 2;
for (let i = 0; i < g_MapInfo.numPlayers * split; ++i)
for (let i = 0; i < numPlayers * split; ++i)
{
let tang = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / (g_MapInfo.numPlayers * split);
let tang = startAngle + (i + 0.5) * 2 * Math.PI / (numPlayers * split);
let fx = fractionToTiles(0.5);
let fz = fractionToTiles(0.5);
@@ -377,7 +383,7 @@ function addSpines()
let mTaper = -1.4;
// make small mountain dividers if we're on a small map
if (g_MapInfo.mapSize <= 192)
if (mapSize <= 192)
{
mSize = 0.02;
mTaper = -0.1;
@@ -5,13 +5,15 @@ RMS.LoadLibrary("rmbiome");
InitMap();
setSelectedBiome();
initMapSettings();
initForestFloor();
initTileClasses();
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
addBases("line", 0.2, 0.08);
const teamsArray = getTeamsArray();
const startAngle = randFloat(0, 2 * Math.PI);
addBases("line", 0.2, 0.08, startAngle);
RMS.SetProgress(20);
placeBarriers();
@@ -20,6 +22,7 @@ RMS.SetProgress(40);
addElements(shuffleArray([
{
"func": addBluffs,
"baseHeight": getMapBaseHeight(),
"avoid": [
g_TileClasses.bluff, 20,
g_TileClasses.hill, 5,
@@ -222,7 +225,6 @@ RMS.SetProgress(90);
ExportMap();
// place the mountainous barriers between the teams
function placeBarriers()
{
var spineTerrain = g_Terrains.dirt;
@@ -236,11 +238,8 @@ function placeBarriers()
if (currentBiome() == "autumn")
spineTerrain = g_Terrains.tier4Terrain;
// create mountain ranges
for (var i = 0; i < g_MapInfo.teams.length; ++i)
for (let i = 0; i < teamsArray.length; ++i)
{
var tang = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / g_MapInfo.teams.length;
var fx = fractionToTiles(0.5);
var fz = fractionToTiles(0.5);
@@ -251,14 +250,14 @@ function placeBarriers()
var mOffset = 0.5;
var mTaper = -1.5;
if (g_MapInfo.teams.length > 3 || g_MapInfo.mapSize <= 192)
if (teamsArray.length > 3 || getMapSize() <= 192)
{
mWaviness = 0.2;
mOffset = 0.2;
mTaper = -1;
}
if (g_MapInfo.teams.length >= 5)
if (teamsArray.length >= 5)
{
mSize = 4;
mWaviness = 0.2;
@@ -266,11 +265,24 @@ function placeBarriers()
mTaper = -0.7;
}
// place barrier
var placer = new PathPlacer(fractionToTiles(0.5 + mStartCo * cos(tang)), fractionToTiles(0.5 + mStartCo * sin(tang)), fractionToTiles(0.5 + mStopCo * cos(tang)), fractionToTiles(0.5 + mStopCo * sin(tang)), scaleByMapSize(14, mSize), mWaviness, 0.1, mOffset, mTaper);
var terrainPainter = new LayeredPainter([g_Terrains.cliff, spineTerrain], [2]);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 30, 2);
createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.spine)], avoidClasses(g_TileClasses.player, 5, g_TileClasses.baseResource, 5));
let angle = startAngle + (i + 0.5) * 2 * Math.PI / teamsArray.length;
createArea(
new PathPlacer(
fractionToTiles(0.5 + mStartCo * Math.cos(angle)),
fractionToTiles(0.5 + mStartCo * Math.sin(angle)),
fractionToTiles(0.5 + mStopCo * Math.cos(angle)),
fractionToTiles(0.5 + mStopCo * Math.sin(angle)),
scaleByMapSize(14, mSize),
mWaviness,
0.1,
mOffset,
mTaper),
[
new LayeredPainter([g_Terrains.cliff, spineTerrain], [2]),
new SmoothElevationPainter(ELEVATION_SET, 30, 2),
paintClass(g_TileClasses.spine)
],
avoidClasses(g_TileClasses.player, 5, g_TileClasses.baseResource, 5));
}
addElements([
@@ -7,13 +7,11 @@ RMS.LoadLibrary("rmbiome");
InitMap();
log("Initializing tile classes...");
setBiome("snowy");
initMapSettings();
initForestFloor();
initTileClasses(["island"]);
log("Initializing environment...");
setSunColor(0.733, 0.746, 0.574);
setSkySet("stratus");
@@ -38,7 +36,6 @@ setPPSaturation(0.42);
setPPBloom(0.23);
log("Initializing biome...");
g_Terrains.mainTerrain = "snow rough";
g_Terrains.forestFloor1 = "snow grass 2";
g_Terrains.forestFloor2 = "snow 50";
@@ -64,12 +61,11 @@ g_Decoratives.rockLarge = "actor|props/special/eyecandy/standing_stones.xml";
g_Decoratives.rockMedium = "actor|geology/stone_granite_small.xml";
g_Decoratives.bushMedium = "actor|props/flora/bush_medit_me_dry.xml";
g_Decoratives.bushSmall = "actor|props/flora/bush_medit_sm_dry.xml";
initBiome();
initForestFloor();
RMS.SetProgress(5);
log("Resetting terrain...");
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
log("Copying heightmap...");
@@ -98,7 +94,7 @@ var strongholdBases = [
[90, 210],
[255, 120]
];
randomPlayerPlacementAt(singleBases, strongholdBases, scale, 0.06);
randomPlayerPlacementAt(getTeamsArray(), singleBases, strongholdBases, scale, 0.06);
RMS.SetProgress(50);
log("Render mainland...");
@@ -5,18 +5,27 @@ RMS.LoadLibrary("rmbiome");
InitMap();
setSelectedBiome();
initMapSettings();
initForestFloor();
initTileClasses(["step"]);
var topTerrain = g_Terrains.tier2Terrain;
const topTerrain = g_Terrains.tier2Terrain;
resetTerrain(topTerrain, g_TileClasses.land, 50);
const valleyHeight = 0;
const pathHeight = 10;
const denHeight = 15;
const hillHeight = getMapBaseHeight();
const mapArea = getMapArea();
const numPlayers = getNumPlayers();
const startAngle = randFloat(0, 2 * Math.PI);
resetTerrain(topTerrain, g_TileClasses.land, hillHeight);
RMS.SetProgress(10);
var players = addBases("radial", 0.4, randFloat(0.05, 0.1));
addBases("radial", 0.4, randFloat(0.05, 0.1), startAngle);
RMS.SetProgress(20);
createSunkenTerrain(players);
createSunkenTerrain();
RMS.SetProgress(30);
addElements([
@@ -375,8 +384,7 @@ RMS.SetProgress(95);
ExportMap();
// Create the sunken terrain
function createSunkenTerrain(players)
function createSunkenTerrain()
{
var base = g_Terrains.mainTerrain;
var middle = g_Terrains.dirt;
@@ -413,96 +421,103 @@ function createSunkenTerrain(players)
if (currentBiome() == "autumn")
middle = g_Terrains.shore;
var expSize = g_MapInfo.mapArea * 0.015 / (g_MapInfo.numPlayers / 4);
var expDist = 0.1 + (g_MapInfo.numPlayers / 200);
var expSize = mapArea * 0.015 / (numPlayers / 4);
var expDist = 0.1 + numPlayers / 200;
var expAngle = 0.75;
if (g_MapInfo.numPlayers == 2)
if (numPlayers == 2)
{
expSize = g_MapInfo.mapArea * 0.015 / 0.8;
expSize = mapArea * 0.015 / 0.8;
expAngle = 0.72;
}
var nRoad = 0.44;
var nExp = 0.425;
if (g_MapInfo.numPlayers < 4)
if (numPlayers < 4)
{
nRoad = 0.42;
nExp = 0.4;
}
// Create central valley
var placer = new ClumpPlacer(g_MapInfo.mapArea * 0.26, 1, 1, 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap);
var terrainPainter = new LayeredPainter([g_Terrains.cliff, lower], [3]);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 0, 3);
createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.valley)]);
log("Creating central valley...");
let center = Math.floor(fractionToTiles(0.5));
createArea(
new ClumpPlacer(mapArea * 0.26, 1, 1, 1, center, center),
[
new LayeredPainter([g_Terrains.cliff, lower], [3]),
new SmoothElevationPainter(ELEVATION_SET, valleyHeight, 3),
paintClass(g_TileClasses.valley)
]);
// Create the center hill
var placer = new ClumpPlacer(g_MapInfo.mapArea * 0.14, 1, 1, 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap);
var terrainPainter = new LayeredPainter([g_Terrains.cliff, topTerrain], [3]);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, g_MapInfo.mapHeight, 3);
createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.mountain)]);
log("Creating central hill...");
createArea(
new ClumpPlacer(mapArea * 0.14, 1, 1, 1, center, center),
[
new LayeredPainter([g_Terrains.cliff, topTerrain], [3]),
new SmoothElevationPainter(ELEVATION_SET, hillHeight, 3),
paintClass(g_TileClasses.mountain)
]);
for(var i = 0; i < players.length; ++i)
let getCoords = (distance, playerID, playerIDOffset) => {
let angle = startAngle + (playerID + playerIDOffset) * 2 * Math.PI / numPlayers;
return [
Math.round(fractionToTiles(0.5 + distance * Math.cos(angle))),
Math.round(fractionToTiles(0.5 + distance * Math.sin(angle)))
];
};
for (let i = 0; i < numPlayers; ++i)
{
var playerAngle = g_MapInfo.startAngle + i * TWO_PI / g_MapInfo.numPlayers;
var pX = round(fractionToTiles(0.5 + 0.4 * cos(playerAngle)));
var pZ = round(fractionToTiles(0.5 + 0.4 * sin(playerAngle)));
var expX = round(fractionToTiles(0.5 + expDist * cos(g_MapInfo.startAngle + (i + expAngle) * TWO_PI / g_MapInfo.numPlayers)));
var expZ = round(fractionToTiles(0.5 + expDist * sin(g_MapInfo.startAngle + (i + expAngle) * TWO_PI / g_MapInfo.numPlayers)));
var rearX = round(fractionToTiles(0.5 + 0.47 * cos(playerAngle)));
var rearZ = round(fractionToTiles(0.5 + 0.47 * sin(playerAngle)));
var prePlayerAngle = g_MapInfo.startAngle + (i - 0.5) * TWO_PI / g_MapInfo.numPlayers;
var preX = round(fractionToTiles(0.5 + nRoad * cos(prePlayerAngle)));
var preZ = round(fractionToTiles(0.5 + nRoad * sin(prePlayerAngle)));
var nextPlayerAngle = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / g_MapInfo.numPlayers;
var nextX = round(fractionToTiles(0.5 + nRoad * cos(nextPlayerAngle)));
var nextZ = round(fractionToTiles(0.5 + nRoad * sin(nextPlayerAngle)));
let playerCoords = getCoords(0.4, i, 0);
// Create path to expansion
var placer = new PathPlacer(pX, pZ, expX, expZ, scaleByMapSize(12, 12), 0.7, 0.5, 0.1, -1);
var terrainPainter = new LayeredPainter([g_Terrains.cliff, middle, road], [3, 4]);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 10, 3);
createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.step)]);
log("Creating path from player to expansion...");
let expansionCoords = getCoords(expDist, i, expAngle);
createArea(
new PathPlacer(...playerCoords, ...expansionCoords, 12, 0.7, 0.5, 0.1, -1),
[
new LayeredPainter([g_Terrains.cliff, middle, road], [3, 4]),
new SmoothElevationPainter(ELEVATION_SET, pathHeight, 3),
paintClass(g_TileClasses.step)
]);
// Create path to neighbor
var placer = new PathPlacer(rearX, rearZ, nextX, nextZ, scaleByMapSize(19, 19), 0.4, 0.5, 0.1, -0.6);
var terrainPainter = new LayeredPainter([g_Terrains.cliff, middle, road], [3, 6]);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 10, 3);
createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.step)]);
log("Creating path from player to the neighbor...");
for (let neighborOffset of [-0.5, 0.5])
createArea(
new PathPlacer(...getCoords(0.47, i, 0), ...getCoords(nRoad, i, neighborOffset), 19, 0.4, 0.5, 0.1, -0.6),
[
new LayeredPainter([g_Terrains.cliff, middle, road], [3, 6]),
new SmoothElevationPainter(ELEVATION_SET, pathHeight, 3),
paintClass(g_TileClasses.step)
]);
// Create path to neighbor
var placer = new PathPlacer(rearX, rearZ, preX, preZ, scaleByMapSize(19, 19), 0.4, 0.5, 0.1, -0.6);
var terrainPainter = new LayeredPainter([g_Terrains.cliff, middle, road], [3, 6]);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 10, 3);
createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.step)]);
log("Creating the den of the player...");
createArea(
new ClumpPlacer(mapArea * 0.03, 0.9, 0.3, 1, ...playerCoords),
[
new LayeredPainter([g_Terrains.cliff, base], [3]),
new SmoothElevationPainter(ELEVATION_SET, denHeight, 3),
paintClass(g_TileClasses.valley)
]);
// Create the den
var placer = new ClumpPlacer(g_MapInfo.mapArea * 0.03, 0.9, 0.3, 1, pX, pZ);
var terrainPainter = new LayeredPainter([g_Terrains.cliff, base], [3]);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 15, 3);
createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.valley)]);
// Create the expansion
var placer = new ClumpPlacer(expSize, 0.9, 0.3, 1, expX, expZ);
var terrainPainter = new LayeredPainter([g_Terrains.cliff, base], [3]);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 15, 3);
var area = createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.settlement)], [avoidClasses(g_TileClasses.settlement, 2)]);
var unpainter = new TileClassUnPainter(new TileClass(g_MapInfo.mapSize, g_TileClasses.mountain));
unpainter.paint(area);
log("Creating the expansion of the player...");
createArea(
new ClumpPlacer(expSize, 0.9, 0.3, 1, ...expansionCoords),
[
new LayeredPainter([g_Terrains.cliff, base], [3]),
new SmoothElevationPainter(ELEVATION_SET, denHeight, 3),
paintClass(g_TileClasses.settlement)
],
[avoidClasses(g_TileClasses.settlement, 2)]);
}
// Create the neighbor expansions
for (var i = 0; i < g_MapInfo.numPlayers; ++i)
{
var nextPlayerAngle = g_MapInfo.startAngle + (i + 0.5) * TWO_PI / g_MapInfo.numPlayers;
var nextX = round(fractionToTiles(0.5 + nExp * cos(nextPlayerAngle)));
var nextZ = round(fractionToTiles(0.5 + nExp * sin(nextPlayerAngle)));
// Create the neightbor expansion
var placer = new ClumpPlacer(expSize, 0.9, 0.3, 1, nextX, nextZ);
var terrainPainter = new LayeredPainter([g_Terrains.cliff, lower], [3]);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, 0, 3);
var area = createArea(placer, [terrainPainter, elevationPainter, paintClass(g_TileClasses.settlement)]);
}
log("Creating the expansions between players after the paths were created...");
for (let i = 0; i < numPlayers; ++i)
createArea(
new ClumpPlacer(expSize, 0.9, 0.3, 1, ...getCoords(nExp, i, 0.5)),
[
new LayeredPainter([g_Terrains.cliff, lower], [3]),
new SmoothElevationPainter(ELEVATION_SET, valleyHeight, 3),
paintClass(g_TileClasses.settlement)
]);
}
@@ -9,7 +9,7 @@ InitMap();
log("Initializing tile classes...");
setBiome("mediterranean");
initMapSettings();
initForestFloor();
initTileClasses();
log("Initializing environment...");
@@ -39,7 +39,6 @@ setPPSaturation(0.42);
setPPBloom(0.23);
log("Initializing biome...");
g_Terrains.mainTerrain = "grass_mediterranean_dry_1024test";
g_Terrains.forestFloor1 = "steppe_grass_dirt_66";
g_Terrains.forestFloor2 = "steppe_dirt_a";
@@ -66,12 +65,11 @@ g_Decoratives.rockMedium = "actor|geology/stone_granite_small.xml";
g_Decoratives.bushMedium = "actor|props/flora/bush_medit_me_dry.xml";
g_Decoratives.bushSmall = "actor|props/flora/bush_medit_sm_dry.xml";
g_Decoratives.reeds = "actor|props/flora/reeds_pond_lush_a.xml";
initBiome();
initForestFloor();
RMS.SetProgress(5);
log("Resetting terrain...");
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
log("Copying heightmap...");
@@ -95,7 +93,7 @@ var singleBases = [
[200, 50]
];
if (g_MapInfo.mapSize >= 320 || g_MapInfo.numPlayers > singleBases.length)
if (getMapSize() >= 320 || getNumPlayers() > singleBases.length)
singleBases.push(
[45, 70],
[280, 80],
@@ -107,7 +105,7 @@ var strongholdBases = [
[60, 220],
[105, 60]
];
randomPlayerPlacementAt(singleBases, strongholdBases, scale, 0.06);
randomPlayerPlacementAt(getTeamsArray(), singleBases, strongholdBases, scale, 0.06);
RMS.SetProgress(50);
addElements([
@@ -9,7 +9,7 @@ InitMap();
log("Initializing environment...");
setBiome("temperate");
initMapSettings();
initForestFloor();
initTileClasses(["autumn", "desert", "medit", "polar", "steppe", "temp"]);
setSunColor(0.733, 0.746, 0.574);
@@ -37,7 +37,7 @@ setPPSaturation(0.42);
setPPBloom(0.23);
log("Resetting terrain...");
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
var biomes = {
@@ -251,7 +251,7 @@ var singleBases = [
[160,180]
];
if (g_MapInfo.mapSize >= 320 || g_MapInfo.numPlayers > singleBases.length)
if (getMapSize() >= 320 || getNumPlayers() > singleBases.length)
singleBases.push(
[140,60],
[170,250],
@@ -266,7 +266,7 @@ var strongholdBases = [
[260,55]
];
randomPlayerPlacementAt(singleBases, strongholdBases, scale, 0.06, (tileX, tileY) => {
randomPlayerPlacementAt(getTeamsArray(), singleBases, strongholdBases, scale, 0.06, (tileX, tileY) => {
for (let biome in biomes)
if (checkIfInClass(tileX, tileY, g_TileClasses[biome]))
@@ -302,7 +302,7 @@ function setLocalBiome(b)
g_Decoratives.rockMedium = b.rockMedium;
g_Decoratives.bushMedium = b.bushMedium;
g_Decoratives.bushSmall = b.bushSmall;
initBiome();
initForestFloor();
}
log("Placing fish...");
@@ -7,9 +7,8 @@ RMS.LoadLibrary("rmbiome");
InitMap();
log("Initializing tile classes...");
setBiome("savanna");
initMapSettings();
initForestFloor();
initTileClasses(["eden", "highlands"]);
log("Initializing environment...");
@@ -63,11 +62,11 @@ g_Decoratives.rockLarge = "actor|geology/stone_savanna_med.xml";
g_Decoratives.rockMedium = "actor|geology/stone_savanna_med.xml";
g_Decoratives.bushMedium = "actor|props/flora/bush_desert_dry_a.xml";
g_Decoratives.bushSmall = "actor|props/flora/bush_dry_a.xml";
initBiome();
initForestFloor();
RMS.SetProgress(5);
log("Resetting terrain...");
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
log("Copying heightmap...");
@@ -104,7 +103,7 @@ var strongholdBases = [
[80, 250],
[205, 65]
];
randomPlayerPlacementAt(singleBases, strongholdBases, scale, 0.06);
randomPlayerPlacementAt(getTeamsArray(), singleBases, strongholdBases, scale, 0.06);
RMS.SetProgress(50);
log("Render lowlands...");
@@ -390,7 +389,7 @@ RMS.SetProgress(70);
g_Gaia.mainHuntableAnimal = "gaia/fauna_rhino";
g_Gaia.secondaryHuntableAnimal = "gaia/fauna_elephant_african_bush";
initBiome();
initForestFloor();
log("Render eden...");
addElements([
@@ -9,7 +9,7 @@ InitMap();
log("Initializing tile classes...");
setBiome("mediterranean");
initMapSettings();
initForestFloor();
initTileClasses(["decorative", "lava"]);
log("Initializing environment...");
@@ -62,11 +62,11 @@ g_Decoratives.grass = "actor|props/flora/grass_field_parched_short.xml";
g_Decoratives.grassShort = "actor|props/flora/grass_soft_dry_tuft_a.xml";
g_Decoratives.bushMedium = "actor|props/special/eyecandy/barrels_buried.xml";
g_Decoratives.bushSmall = "actor|props/special/eyecandy/handcart_1_broken.xml";
initBiome();
initForestFloor();
RMS.SetProgress(5);
log("Resetting terrain...");
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
log("Copying heightmap...");
@@ -91,14 +91,14 @@ var singleBases = [
[50,270]
];
if (g_MapInfo.mapSize >= 320 || g_MapInfo.numPlayers > singleBases.length)
if (getMapSize() >= 320 || getNumPlayers() > singleBases.length)
singleBases.push(
[50,200],
[125,190],
[180,140]
);
randomPlayerPlacementAt(singleBases, [], scale, 0.06);
randomPlayerPlacementAt(getTeamsArray(), singleBases, [], scale, 0.06);
RMS.SetProgress(40);
addElements([
@@ -9,7 +9,7 @@ InitMap();
log("Initializing tile classes...");
setBiome("alpine");
initMapSettings();
initForestFloor();
initTileClasses(["shallowWater"]);
log("Initializing environment...");
@@ -64,12 +64,11 @@ g_Decoratives.bushMedium = "actor|props/flora/bush_tempe_a.xml";
g_Decoratives.bushSmall = "actor|props/flora/bush_tempe_b.xml";
g_Decoratives.reeds = "actor|props/flora/reeds_pond_lush_a.xml";
g_Decoratives.lillies = "actor|props/flora/water_lillies.xml";
initBiome();
initForestFloor();
RMS.SetProgress(5);
log("Resetting terrain...");
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
log("Copying heightmap...");
@@ -104,7 +103,7 @@ var strongholdBases = [
[260, 190],
[120, 270]
];
randomPlayerPlacementAt(singleBases, strongholdBases, scale, 0.06);
randomPlayerPlacementAt(getTeamsArray(), singleBases, strongholdBases, scale, 0.06);
RMS.SetProgress(50);
log("Render gaia...");
@@ -7,9 +7,8 @@ RMS.LoadLibrary("rmbiome");
InitMap();
log("Initializing biome...");
setBiome("desert");
initMapSettings();
initForestFloor();
initTileClasses();
setSunColor(0.733, 0.746, 0.574);
@@ -35,6 +34,7 @@ setPPContrast(0.67);
setPPSaturation(0.42);
setPPBloom(0.23);
log("Initializing biome...");
g_Terrains.mainTerrain = "desert_dirt_rocks_2";
g_Terrains.forestFloor1 = "desert_grass_a_sand";
g_Terrains.forestFloor2 = "desert_grass_a_sand";
@@ -57,10 +57,10 @@ g_Decoratives.rockMedium = "actor|geology/stone_savanna_med.xml";
g_Decoratives.bushMedium = "actor|props/flora/bush_desert_dry_a.xml";
g_Decoratives.bushSmall = "actor|props/flora/bush_medit_sm_dry.xml";
g_Decoratives.dust = "actor|particle/dust_storm_reddish.xml";
initBiome();
initForestFloor();
log("Resetting terrain...");
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 1);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(10);
log("Copying heightmap...");
@@ -93,7 +93,7 @@ var strongholdBases = [
[170, 260],
[260, 160]
];
randomPlayerPlacementAt(singleBases, strongholdBases, scale, 0.04);
randomPlayerPlacementAt(getTeamsArray(), singleBases, strongholdBases, scale, 0.04);
RMS.SetProgress(50);
log("Adding mines and forests...");
@@ -302,7 +302,7 @@ function isCircularMap()
function getMapBaseHeight()
{
return g_MapSettings.BaseHeight || 0;
return g_MapSettings.BaseHeight;
}
function createTileClass()
@@ -787,7 +787,7 @@ function createVolcano(fx, fz, tileClass, terrainTexture, lavaTextures, smoke, e
let ix = Math.round(fractionToTiles(fx));
let iz = Math.round(fractionToTiles(fz));
let baseSize = mapArea / scaleByMapSize(1, 8);
let baseSize = getMapArea() / scaleByMapSize(1, 8);
let coherence = 0.7;
let smoothness = 0.05;
@@ -16,8 +16,9 @@ var g_DefaultDeviation = 0.1;
* @param {number} size - size of the bluffs (1.2 would be 120% of normal)
* @param {number} deviation - degree of deviation from the defined size (0.2 would be 20% plus/minus)
* @param {number} fill - size of map to fill (1.5 would be 150% of normal)
* @param {number} baseHeight - elevation of the floor, making the bluff reachable
*/
function addBluffs(constraint, size, deviation, fill)
function addBluffs(constraint, size, deviation, fill, baseHeight)
{
deviation = deviation || g_DefaultDeviation;
size = size || 1;
@@ -77,8 +78,8 @@ function addBluffs(constraint, size, deviation, fill)
var bluffCat = 2;
while (bluffCat != 0 && retries < 5)
{
baseLine = findClearLine(bb, corners, angle);
endLine = findClearLine(bb, corners, opAngle);
baseLine = findClearLine(bb, corners, angle, baseHeight);
endLine = findClearLine(bb, corners, opAngle, baseHeight);
bluffCat = unreachableBluff(bb, corners, baseLine, endLine);
++angle;
@@ -686,17 +687,12 @@ function addProps(constraint, size, deviation, fill)
createObjectGroupsDeprecated(new SimpleGroup([trees], true), 0, constraint, counts[0] * 5 * fill, 5);
}
/**
* Create valleys.
*/
function addValleys(constraint, size, deviation, fill)
function addValleys(constraint, size, deviation, fill, baseHeight)
{
if (g_MapInfo.mapHeight < 6)
if (baseHeight < 6)
return;
var minElevation = (-1 * g_MapInfo.mapHeight) / (size * (1 + deviation)) + 1;
if (minElevation < -1 * g_MapInfo.mapHeight)
minElevation = -1 * g_MapInfo.mapHeight;
let minElevation = Math.max(-baseHeight, 1 - baseHeight / (size * (deviation + 1)));
var valleySlope = g_Terrains.tier1Terrain;
var valleyFloor = g_Terrains.tier4Terrain;
@@ -932,7 +928,7 @@ function addStragglerTrees(constraint, size, deviation, fill)
var trees = [g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree3, g_Gaia.tree4];
var treesPerPlayer = 40;
var playerBonus = Math.max(1, (g_MapInfo.numPlayers - 3) / 2);
var playerBonus = Math.max(1, (getNumPlayers() - 3) / 2);
var offset = getRandomDeviation(size, deviation);
var treeCount = treesPerPlayer * playerBonus * fill;
@@ -1112,7 +1108,7 @@ function fadeToGround(bb, minX, minZ, elevation)
/**
* Find a 45 degree line in a bounding box that does not intersect any terrain feature.
*/
function findClearLine(bb, corners, angle)
function findClearLine(bb, corners, angle, baseHeight)
{
// Angle - 0: northwest; 1: northeast; 2: southeast; 3: southwest
var z = corners.maxZ;
@@ -1170,7 +1166,7 @@ function findClearLine(bb, corners, angle)
"z2": lastZ,
"midX": midX,
"midZ": midZ,
"height": g_MapInfo.mapHeight
"height": baseHeight
};
}
@@ -1190,8 +1186,9 @@ function findClearLine(bb, corners, angle)
function findCorners(points)
{
// Find the bounding box of the terrain feature
var minX = g_MapInfo.mapSize + 1;
var minZ = g_MapInfo.mapSize + 1;
var mapSize = getMapSize();
var minX = mapSize + 1;
var minZ = mapSize + 1;
var maxX = -1;
var maxZ = -1;
@@ -52,7 +52,6 @@ var g_DefaultTileClasses = [
"water"
];
var g_MapInfo;
var g_TileClasses;
var g_Forests;
@@ -69,8 +68,8 @@ function addElements(elements)
],
pickSize(element.sizes),
pickMix(element.mixes),
pickAmount(element.amounts)
);
pickAmount(element.amounts),
element.baseHeight || 0);
}
/**
@@ -113,45 +112,45 @@ function pickSize(sizes)
}
/**
* Paints the entire map with a single tile type.
* Paints the entire map with the given terrain texture, tileclass and elevation.
*/
function resetTerrain(terrain, tc, elevation)
function resetTerrain(terrain, tileClass, elevation)
{
g_MapInfo.mapSize = getMapSize();
g_MapInfo.mapArea = g_MapInfo.mapSize * g_MapInfo.mapSize;
g_MapInfo.centerOfMap = Math.floor(g_MapInfo.mapSize / 2);
g_MapInfo.mapRadius = -PI / 4;
var placer = new ClumpPlacer(g_MapInfo.mapArea, 1, 1, 1, g_MapInfo.centerOfMap, g_MapInfo.centerOfMap);
var terrainPainter = new LayeredPainter([terrain], []);
var elevationPainter = new SmoothElevationPainter(ELEVATION_SET, elevation, 1);
createArea(placer, [terrainPainter, elevationPainter, paintClass(tc)], null);
g_MapInfo.mapHeight = elevation;
let center = Math.round(fractionToTiles(0.5));
createArea(
new ClumpPlacer(getMapArea(), 1, 1, 1, center, center),
[
new LayeredPainter([terrain], []),
new SmoothElevationPainter(ELEVATION_SET, elevation, 1),
paintClass(tileClass)
],
null);
}
/**
* Choose starting locations for the given players.
* Choose starting locations for all players.
*
* @param {string} type - "radial", "line", "stronghold", "random"
* @param {number} distance - radial distance from the center of the map
*
* @param {number} groupedDistance - space between players within a team
* @param {number} startAngle - determined by the map that might want to place something between players
* @returns {Array|undefined} - If successful, each element is an object that contains id, angle, x, z for each player
*/
function addBases(type = "radial", distance = 0.3, groupedDistance = 0.05)
function addBases(type, distance, groupedDistance, startAngle)
{
let playerIDs = sortAllPlayers();
let teamsArray = getTeamsArray();
switch(type)
{
case "line":
return placeLine(playerIDs, distance, groupedDistance);
return placeLine(teamsArray, distance, groupedDistance, startAngle);
case "radial":
return placeRadial(playerIDs, distance);
return placeRadial(playerIDs, distance, startAngle);
case "random":
return placeRandom(playerIDs) || placeRadial(playerIDs, distance);
return placeRandom(playerIDs) || placeRadial(playerIDs, distance, startAngle);
case "stronghold":
return placeStronghold(playerIDs, distance, groupedDistance);
return placeStronghold(teamsArray, distance, groupedDistance, startAngle);
default:
warn("Unknown base placement type:" + type);
return undefined;
@@ -166,6 +165,8 @@ function addBases(type = "radial", distance = 0.3, groupedDistance = 0.05)
*/
function createBase(player, walls = true)
{
var mapSize = getMapSize();
// Get the x and z in tiles
var fx = fractionToTiles(player.x);
var fz = fractionToTiles(player.z);
@@ -174,13 +175,14 @@ function createBase(player, walls = true)
addCivicCenterAreaToClass(ix, iz, g_TileClasses.player);
if (walls && g_MapInfo.mapSize > 192)
if (walls && mapSize > 192)
placeCivDefaultEntities(fx, fz, player.id);
else
placeCivDefaultEntities(fx, fz, player.id, { 'iberWall': false });
// Create the city patch
var cityRadius = scaleByMapSize(15, 25) / 3;
var radius = scaleByMapSize(15, 25);
var cityRadius = radius / 3;
var placer = new ClumpPlacer(PI * cityRadius * cityRadius, 0.6, 0.3, 10, ix, iz);
var painter = new LayeredPainter([g_Terrains.roadWild, g_Terrains.road], [1]);
createArea(placer, painter, null);
@@ -253,15 +255,17 @@ function createBase(player, walls = true)
fz,
g_Decoratives.grassShort,
g_TileClasses.baseResource,
g_MapInfo.mapRadius,
radius,
avoidClasses(g_TileClasses.baseResource, 4));
}
/**
* Return an array where each element is an array of playerIndices of a team.
*/
function getTeams(numPlayers)
function getTeamsArray()
{
var numPlayers = getNumPlayers();
// Group players by team
var teams = [];
for (let i = 0; i < numPlayers; ++i)
@@ -288,20 +292,22 @@ function getTeams(numPlayers)
/**
* Choose a random pattern for placing the bases of the players.
*/
function randomStartingPositionPattern()
function randomStartingPositionPattern(teamsArray)
{
var formats = ["radial"];
var mapSize = getMapSize();
var numPlayers = getNumPlayers();
// Enable stronghold if we have a few teams and a big enough map
if (g_MapInfo.teams.length >= 2 && g_MapInfo.numPlayers >= 4 && g_MapInfo.mapSize >= 256)
if (teamsArray.length >= 2 && numPlayers >= 4 && mapSize >= 256)
formats.push("stronghold");
// Enable random if we have enough teams or enough players on a big enough map
if (g_MapInfo.mapSize >= 256 && (g_MapInfo.teams.length >= 3 || g_MapInfo.numPlayers > 4))
if (mapSize >= 256 && (teamsArray.length >= 3 || numPlayers > 4))
formats.push("random");
// Enable line if we have enough teams and players on a big enough map
if (g_MapInfo.teams.length >= 2 && g_MapInfo.numPlayers >= 4 && g_MapInfo.mapSize >= 384)
if (teamsArray.length >= 2 && numPlayers >= 4 && mapSize >= 384)
formats.push("line");
return {
@@ -317,30 +323,31 @@ function randomStartingPositionPattern()
* @param {Array} playerIDs - typically randomized indices of players of a single team
* @param {number} distance - radial distance from the center of the map
* @param {number} groupedDistance - distance between players
* @param {number} startAngle - determined by the map that might want to place something between players.
*
* @returns {Array} - contains id, angle, x, z for every player
*/
function placeLine(playerIDs, distance, groupedDistance)
function placeLine(teamsArray, distance, groupedDistance, startAngle)
{
var players = [];
for (var i = 0; i < g_MapInfo.teams.length; ++i)
for (let i = 0; i < teamsArray.length; ++i)
{
var safeDist = distance;
if (distance + g_MapInfo.teams[i].length * groupedDistance > 0.45)
safeDist = 0.45 - g_MapInfo.teams[i].length * groupedDistance;
if (distance + teamsArray[i].length * groupedDistance > 0.45)
safeDist = 0.45 - teamsArray[i].length * groupedDistance;
var teamAngle = g_MapInfo.startAngle + (i + 1) * TWO_PI / g_MapInfo.teams.length;
var teamAngle = startAngle + (i + 1) * 2 * Math.PI / teamsArray.length;
// Create player base
for (var p = 0; p < g_MapInfo.teams[i].length; ++p)
for (var p = 0; p < teamsArray[i].length; ++p)
{
players[g_MapInfo.teams[i][p]] = {
"id": g_MapInfo.teams[i][p],
players[teamsArray[i][p]] = {
"id": teamsArray[i][p],
"x": 0.5 + (safeDist + p * groupedDistance) * cos(teamAngle),
"z": 0.5 + (safeDist + p * groupedDistance) * sin(teamAngle)
};
createBase(players[g_MapInfo.teams[i][p]], false);
createBase(players[teamsArray[i][p]], false);
}
}
@@ -350,15 +357,18 @@ function placeLine(playerIDs, distance, groupedDistance)
/**
* Place players in a circle-pattern.
*
* @param {Array} playerIDs - order of playerIDs to be placed
* @param {number} distance - radial distance from the center of the map
* @param {number} startAngle - determined by the map that might want to place something between players
*/
function placeRadial(playerIDs, distance)
function placeRadial(playerIDs, distance, startAngle)
{
var players = [];
let players = [];
let numPlayers = getNumPlayers();
for (var i = 0; i < g_MapInfo.numPlayers; ++i)
for (let i = 0; i < numPlayers; ++i)
{
var angle = g_MapInfo.startAngle + i * TWO_PI / g_MapInfo.numPlayers;
let angle = startAngle + i * 2 * Math.PI / numPlayers;
players[i] = {
"id": playerIDs[i],
"x": 0.5 + distance * cos(angle),
@@ -379,7 +389,7 @@ function placeRandom(playerIDs)
var attempts = 0;
var resets = 0;
for (let i = 0; i < g_MapInfo.numPlayers; ++i)
for (let i = 0; i < getNumPlayers(); ++i)
{
var playerAngle = randFloat(0, TWO_PI);
@@ -483,40 +493,42 @@ function groupPlayersByLocations(playerIDs, locations)
/**
* Place given players in a stronghold-pattern.
*
* @param teamsArray - each item is an array of playerIDs placed per stronghold
* @param distance - radial distance from the center of the map
* @param groupedDistance - distance between neighboring players
* @param {number} startAngle - determined by the map that might want to place something between players
*/
function placeStronghold(playerIDs, distance, groupedDistance)
function placeStronghold(teamsArray, distance, groupedDistance, startAngle)
{
var players = [];
for (var i = 0; i < g_MapInfo.teams.length; ++i)
for (let i = 0; i < teamsArray.length; ++i)
{
var teamAngle = g_MapInfo.startAngle + (i + 1) * TWO_PI / g_MapInfo.teams.length;
var teamAngle = startAngle + (i + 1) * 2 * Math.PI / teamsArray.length;
var fractionX = 0.5 + distance * cos(teamAngle);
var fractionZ = 0.5 + distance * sin(teamAngle);
var teamGroupDistance = groupedDistance;
// If we have a team of above average size, make sure they're spread out
if (g_MapInfo.teams[i].length > 4)
if (teamsArray[i].length > 4)
teamGroupDistance = Math.max(0.08, groupedDistance);
// If we have a solo player, place them on the center of the team's location
if (g_MapInfo.teams[i].length == 1)
if (teamsArray[i].length == 1)
teamGroupDistance = 0;
// TODO: Ensure players are not placed outside of the map area, similar to placeLine
// Create player base
for (var p = 0; p < g_MapInfo.teams[i].length; ++p)
for (var p = 0; p < teamsArray[i].length; ++p)
{
var angle = g_MapInfo.startAngle + (p + 1) * TWO_PI / g_MapInfo.teams[i].length;
players[g_MapInfo.teams[i][p]] = {
"id": g_MapInfo.teams[i][p],
var angle = startAngle + (p + 1) * 2 * Math.PI / teamsArray[i].length;
players[teamsArray[i][p]] = {
"id": teamsArray[i][p],
"x": fractionX + teamGroupDistance * cos(angle),
"z": fractionZ + teamGroupDistance * sin(angle)
};
createBase(players[g_MapInfo.teams[i][p]], false);
createBase(players[teamsArray[i][p]], false);
}
}
@@ -526,30 +538,34 @@ function placeStronghold(playerIDs, distance, groupedDistance)
/**
* Places players either randomly or in a stronghold-pattern at a set of given heightmap coordinates.
*
* @param teamsArray - Array where each item is an array of playerIDs, possibly going to be grouped.
* @param singleBases - pair of coordinates of the heightmap to place isolated bases.
* @param singleBases - pair of coordinates of the heightmap to place team bases.
* @param groupedDistance - distance between neighboring players.
* @param func - A function called for every player base or stronghold placed.
*/
function randomPlayerPlacementAt(singleBases, strongholdBases, heightmapScale, groupedDistance, func)
function randomPlayerPlacementAt(teamsArray, singleBases, strongholdBases, heightmapScale, groupedDistance, func)
{
let strongholdBasesRandom = shuffleArray(strongholdBases);
let mapSize = getMapSize();
if (randBool(1/3) &&
g_MapInfo.mapSize >= 256 &&
g_MapInfo.teams.length >= 2 &&
g_MapInfo.teams.length < g_MapInfo.numPlayers &&
g_MapInfo.teams.length <= strongholdBasesRandom.length)
mapSize >= 256 &&
teamsArray.length >= 2 &&
teamsArray.length < getNumPlayers() &&
teamsArray.length <= strongholdBasesRandom.length)
{
for (let t = 0; t < g_MapInfo.teams.length; ++t)
let startAngle = randFloat(0, 2 * Math.PI);
for (let t = 0; t < teamsArray.length; ++t)
{
let tileX = Math.floor(strongholdBasesRandom[t][0] / heightmapScale);
let tileY = Math.floor(strongholdBasesRandom[t][1] / heightmapScale);
let x = tileX / g_MapInfo.mapSize;
let z = tileY / g_MapInfo.mapSize;
let x = tileX / mapSize;
let z = tileY / mapSize;
let team = g_MapInfo.teams[t].map(playerID => ({ "id": playerID }));
let team = teamsArray[t].map(playerID => ({ "id": playerID }));
let players = [];
if (func)
@@ -557,7 +573,7 @@ function randomPlayerPlacementAt(singleBases, strongholdBases, heightmapScale, g
for (let p = 0; p < team.length; ++p)
{
let angle = g_MapInfo.startAngle + (p + 1) * TWO_PI / team.length;
let angle = startAngle + (p + 1) * TWO_PI / team.length;
players[p] = {
"id": team[p].id,
@@ -572,14 +588,14 @@ function randomPlayerPlacementAt(singleBases, strongholdBases, heightmapScale, g
else
{
let players = groupPlayersByLocations(sortAllPlayers(), singleBases.map(l => ({
"x": l[0] / heightmapScale / g_MapInfo.mapSize,
"z": l[1] / heightmapScale / g_MapInfo.mapSize
"x": l[0] / heightmapScale / mapSize,
"z": l[1] / heightmapScale / mapSize
})));
for (let player of players)
{
if (func)
func(Math.floor(player.x * g_MapInfo.mapSize), Math.floor(player.z * g_MapInfo.mapSize));
func(Math.floor(player.x * mapSize), Math.floor(player.z * mapSize));
createBase(player);
}
@@ -607,7 +623,7 @@ function initTileClasses(newClasses)
/**
* Get biome-specific names of entities and terrain after randomization.
*/
function initBiome()
function initForestFloor()
{
g_Forests = {
"forest1": [
@@ -622,18 +638,3 @@ function initBiome()
]
};
}
/**
* Creates an object of commonly used functions.
*/
function initMapSettings()
{
initBiome();
let numPlayers = getNumPlayers();
g_MapInfo = {
"numPlayers": numPlayers,
"teams": getTeams(numPlayers),
"startAngle": randFloat(0, TWO_PI)
};
}
@@ -5,18 +5,19 @@ RMS.LoadLibrary("rmbiome");
InitMap();
setSelectedBiome();
initMapSettings();
initForestFloor();
initTileClasses();
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, 30);
resetTerrain(g_Terrains.mainTerrain, g_TileClasses.land, getMapBaseHeight());
RMS.SetProgress(20);
addBases("stronghold", randFloat(0.2, 0.35), randFloat(0.05, 0.1));
addBases("stronghold", randFloat(0.2, 0.35), randFloat(0.05, 0.1), randFloat(0, 2 * Math.PI));
RMS.SetProgress(30);
addElements(shuffleArray([
{
"func": addBluffs,
"baseHeight": getMapBaseHeight(),
"avoid": [
g_TileClasses.bluff, 20,
g_TileClasses.hill, 5,
@@ -75,6 +76,7 @@ addElements(shuffleArray([
},
{
"func": addValleys,
"baseHeight": getMapBaseHeight(),
"avoid": [
g_TileClasses.bluff, 5,
g_TileClasses.hill, 5,