Index: binaries/data/mods/public/maps/random/belgian_uplands.js =================================================================== --- binaries/data/mods/public/maps/random/belgian_uplands.js +++ binaries/data/mods/public/maps/random/belgian_uplands.js @@ -260,7 +260,7 @@ for (let i = 0; i < numPlayers; ++i) { - placeCivDefaultStartingEntities(playerPosition[i], playerIDs[i], false); + placeCivDefaultStartingEntities(playerPosition[i], undefined, playerIDs[i], false); for (let j = 1; j <= 4; ++j) { Index: binaries/data/mods/public/maps/random/caledonian_meadows.js =================================================================== --- binaries/data/mods/public/maps/random/caledonian_meadows.js +++ binaries/data/mods/public/maps/random/caledonian_meadows.js @@ -398,7 +398,9 @@ else for (let p = 0; p < playerIDs.length; ++p) { - placeCivDefaultStartingEntities(playerPosition[p], playerIDs[p], true); + const otherPlayerPositions = Array.from(playerPosition); + const currentPlayerPosition = otherPlayerPositions.splice(p, 1)[0]; + placeCivDefaultStartingEntities(currentPlayerPosition, otherPlayerPositions, playerIDs[p], true); placeStartLocationResources(playerPosition[p]); } Index: binaries/data/mods/public/maps/random/hellas.js =================================================================== --- binaries/data/mods/public/maps/random/hellas.js +++ binaries/data/mods/public/maps/random/hellas.js @@ -242,10 +242,14 @@ if (isNomad()) break; - let localBiome = constraintHighlands.allows(playerPosition[i]) ? biomes.highlands : biomes.lowlands; + const otherPlayerPositions = Array.from(playerPosition); + const currentPlayerPosition = otherPlayerPositions.splice(i, 1)[0]; + + let localBiome = constraintHighlands.allows(currentPlayerPosition) ? biomes.highlands : biomes.lowlands; placePlayerBase({ "playerID": playerIDs[i], - "playerPosition": playerPosition[i], + "playerPosition": currentPlayerPosition, + "otherPlayerPositions": otherPlayerPositions, "PlayerTileClass": clPlayer, "Walls": "towers", "BaseResourceClass": clBaseResource, Index: binaries/data/mods/public/maps/random/island_stronghold.js =================================================================== --- binaries/data/mods/public/maps/random/island_stronghold.js +++ binaries/data/mods/public/maps/random/island_stronghold.js @@ -98,7 +98,7 @@ new TileClassPainter(clLand) ]); - placeCivDefaultStartingEntities(playerPosition[p], teams[i][p], false); + placeCivDefaultStartingEntities(playerPosition[p], undefined, teams[i][p], false); } let mineAngle = randFloat(-1, 1) * Math.PI / teams[i].length; Index: binaries/data/mods/public/maps/random/jebel_barkal.js =================================================================== --- binaries/data/mods/public/maps/random/jebel_barkal.js +++ binaries/data/mods/public/maps/random/jebel_barkal.js @@ -582,10 +582,14 @@ for (let i = 0; i < numPlayers; ++i) { - let isDesert = clDesert.has(playerPosition[i]); + const otherPlayerPositions = Array.from(playerPosition); + const currentPlayerPosition = otherPlayerPositions.splice(i, 1)[0]; + + let isDesert = clDesert.has(currentPlayerPosition); placePlayerBase({ "playerID": playerIDs[i], - "playerPosition": playerPosition[i], + "playerPosition": currentPlayerPosition, + "otherPlayerPositions": otherPlayerPositions, "PlayerTileClass": clPlayer, "BaseResourceClass": clBaseResource, "baseResourceConstraint": avoidClasses(clPlayer, 4, clWater, 4), Index: binaries/data/mods/public/maps/random/mediterranean.js =================================================================== --- binaries/data/mods/public/maps/random/mediterranean.js +++ binaries/data/mods/public/maps/random/mediterranean.js @@ -180,7 +180,9 @@ new ClumpPlacer(diskArea(defaultPlayerBaseRadius() * 0.8), 0.95, 0.6, Infinity, playerPosition[i]), new SmoothElevationPainter(ELEVATION_SET, g_Map.getHeight(playerPosition[i]), 6)); - createBase(playerIDs[i], playerPosition[i], mapSize >= 384); + const otherPlayerPositions = Array.from(playerPosition); + const currentPlayerPosition = otherPlayerPositions.splice(i, 1)[0]; + createBase(playerIDs[i], currentPlayerPosition, otherPlayerPositions, mapSize >= 384); } } Engine.SetProgress(50); Index: binaries/data/mods/public/maps/random/rmgen-common/player.js =================================================================== --- binaries/data/mods/public/maps/random/rmgen-common/player.js +++ binaries/data/mods/public/maps/random/rmgen-common/player.js @@ -106,20 +106,23 @@ /** * Places the default starting entities as defined by the civilization definition, optionally including city walls. */ -function placeCivDefaultStartingEntities(position, playerID, wallType, dist = 6, orientation = BUILDING_ORIENTATION) +function placeCivDefaultStartingEntities(position, otherPlayerPositions, playerID, wallType, dist = 6, orientation = BUILDING_ORIENTATION) { placeStartingEntities(position, playerID, getStartingEntities(playerID), dist, orientation); - placeStartingWalls(position, playerID, wallType, orientation); + placeStartingWalls(position, otherPlayerPositions, playerID, wallType, orientation); } /** * If the map is large enough and the civilization defines them, places the initial city walls or towers. + * @param {Vector2D} position - Position of the player. + * @param {array->Vector2D} otherPlayerPositions - Array with positions of the other players. + * @param {number} playerID - ID of the player. * @param {string|boolean} wallType - Either "towers" to only place the wall turrets or a boolean indicating enclosing city walls. */ -function placeStartingWalls(position, playerID, wallType, orientation = BUILDING_ORIENTATION) +function placeStartingWalls(position, otherPlayerPositions, playerID, wallType, orientation = BUILDING_ORIENTATION) { let civ = getCivCode(playerID); - if (civ != "iber" || g_Map.getSize() <= 128) + if (civ != "iber" || g_Map.getSize() <= 128 || distanceToClosestPlayer(position, otherPlayerPositions) < 50) return; // TODO: should prevent trees inside walls @@ -130,7 +133,24 @@ else if (wallType) placeGenericFortress(position, 20, playerID); } +/** + * Calulate the distance to the closest other player + * @param {Vector2D} playerPosition position of the player + * @param {array->Vector2D} otherPlayerPositions array with positions of the other players + */ +function distanceToClosestPlayer(playerPosition, otherPlayerPositions) +{ + let distance = Infinity; + if (otherPlayerPositions === undefined || otherPlayerPositions.length == 0) + return distance; + for (let i = 0; i < otherPlayerPositions.length; ++i) + distance = Math.min(distance, playerPosition.distanceToSquared(otherPlayerPositions[i])); + + distance = Math.sqrt(distance); + return distance; +} + /** * Places the civic center and starting resources for all given players. */ @@ -143,7 +163,9 @@ for (let i = 0; i < getNumPlayers(); ++i) { playerBaseArgs.playerID = playerIDs[i]; - playerBaseArgs.playerPosition = playerPosition[i]; + playerBaseArgs.otherPlayerPositions = Array.from(playerPosition); + playerBaseArgs.playerPosition = playerBaseArgs.otherPlayerPositions.splice(i, 1)[0]; + placePlayerBase(playerBaseArgs); } } @@ -158,6 +180,7 @@ placeCivDefaultStartingEntities( playerBaseArgs.playerPosition, + playerBaseArgs.otherPlayerPositions, playerBaseArgs.playerID, playerBaseArgs.Walls !== undefined ? playerBaseArgs.Walls : true, 6, Index: binaries/data/mods/public/maps/random/rmgen2/setup.js =================================================================== --- binaries/data/mods/public/maps/random/rmgen2/setup.js +++ binaries/data/mods/public/maps/random/rmgen2/setup.js @@ -163,9 +163,11 @@ { g_Map.log("Creating bases"); - for (let i = 0; i < getNumPlayers(); ++i) - createBase(playerIDs[i], playerPosition[i], walls); - + for (let i = 0; i < getNumPlayers(); ++i){ + const otherPlayerPositions = Array.from(playerPosition); + const currentPlayerPosition = otherPlayerPositions.splice(i, 1)[0]; + createBase(playerIDs[i], currentPlayerPosition, otherPlayerPositions, walls); + } return [playerIDs, playerPosition]; } @@ -175,11 +177,12 @@ * @param {Object} player - contains id, angle, x, z * @param {boolean} walls - Whether or not iberian gets starting walls */ -function createBase(playerID, playerPosition, walls) +function createBase(playerID, playerPosition, otherPlayerPositions, walls) { placePlayerBase({ "playerID": playerID, "playerPosition": playerPosition, + "otherPlayerPositions": otherPlayerPositions, "PlayerTileClass": g_TileClasses.player, "BaseResourceClass": g_TileClasses.baseResource, "baseResourceConstraint": avoidClasses(g_TileClasses.water, 0, g_TileClasses.mountain, 0), Index: binaries/data/mods/public/maps/random/wild_lake.js =================================================================== --- binaries/data/mods/public/maps/random/wild_lake.js +++ binaries/data/mods/public/maps/random/wild_lake.js @@ -536,8 +536,14 @@ else for (let p = 0; p < playerIDs.length; ++p) { - placeCivDefaultStartingEntities(playerPosition[p], playerIDs[p], g_Map.size > 192); - placeStartLocationResources(playerPosition[p]); + const otherPlayerPositions = Array.from(playerPosition); + const currentPlayerPosition = otherPlayerPositions.splice(p, 1)[0]; + placeCivDefaultStartingEntities( + currentPlayerPosition, + otherPlayerPositions, + playerIDs[p], + g_Map.size > 192); + placeStartLocationResources(currentPlayerPosition); } let mercenaryCamps = isNomad() ? 0 : Math.ceil(g_Map.size / 256);