From e2bb3a695bfa156da48d358a2389e23c04e83727 Mon Sep 17 00:00:00 2001 From: elexis Date: Sun, 14 Jan 2018 00:59:06 +0000 Subject: [PATCH] Nomad mode on all random map scripts (except Survival of the Fittest), fixes #3591. Fine-tune random map scripts if nomad mode is enabled by omitting gaia attackers and vast voids. Fix nomad units on the Unknown sometimes being stuck on mountains or tiny islands, refs #3140. Discussed with: bb git-svn-id: https://svn.wildfiregames.com/public/ps/trunk@20866 3db68df2-c116-0410-a063-a993310a9797 --- .../data/mods/public/gui/common/gamedescription.js | 9 ++ .../data/mods/public/gui/gamesetup/gamesetup.js | 16 ++- .../data/mods/public/maps/random/aegean_sea.js | 2 + .../data/mods/public/maps/random/african_plains.js | 2 + .../data/mods/public/maps/random/alpine_lakes.js | 2 + .../data/mods/public/maps/random/alpine_valley.js | 2 + binaries/data/mods/public/maps/random/ambush.js | 11 ++ .../mods/public/maps/random/anatolian_plateau.js | 2 + .../data/mods/public/maps/random/archipelago.js | 6 + .../data/mods/public/maps/random/arctic_summer.js | 2 + .../mods/public/maps/random/ardennes_forest.js | 2 + .../mods/public/maps/random/atlas_mountains.js | 2 + .../mods/public/maps/random/belgian_uplands.js | 8 +- .../mods/public/maps/random/botswanan_haven.js | 2 + .../mods/public/maps/random/caledonian_meadows.js | 19 ++-- .../public/maps/random/cantabrian_highlands.js | 4 +- binaries/data/mods/public/maps/random/canyon.js | 9 +- binaries/data/mods/public/maps/random/continent.js | 4 + .../mods/public/maps/random/corinthian_isthmus.js | 2 + binaries/data/mods/public/maps/random/corsica.js | 2 + .../public/maps/random/cycladic_archipelago.js | 2 + binaries/data/mods/public/maps/random/danubius.js | 34 +++--- .../data/mods/public/maps/random/deep_forest.js | 3 + binaries/data/mods/public/maps/random/empire.js | 10 ++ .../mods/public/maps/random/english_channel.js | 2 + .../mods/public/maps/random/extinct_volcano.js | 94 ++++++++------- binaries/data/mods/public/maps/random/flood.js | 6 + binaries/data/mods/public/maps/random/fortress.js | 5 + binaries/data/mods/public/maps/random/frontier.js | 14 ++- binaries/data/mods/public/maps/random/gear.js | 2 + .../mods/public/maps/random/guadalquivir_river.js | 6 + .../mods/public/maps/random/gulf_of_bothnia.js | 3 + binaries/data/mods/public/maps/random/harbor.js | 13 +++ .../data/mods/public/maps/random/hells_pass.js | 23 +++- .../mods/public/maps/random/hyrcanian_shores.js | 2 + binaries/data/mods/public/maps/random/india.js | 2 + .../mods/public/maps/random/island_stronghold.js | 15 ++- binaries/data/mods/public/maps/random/islands.js | 33 +++--- binaries/data/mods/public/maps/random/kerala.js | 2 + binaries/data/mods/public/maps/random/lake.js | 2 + binaries/data/mods/public/maps/random/latium.js | 2 + binaries/data/mods/public/maps/random/lions_den.js | 13 ++- .../data/mods/public/maps/random/lorraine_plain.js | 2 + binaries/data/mods/public/maps/random/mainland.js | 2 + binaries/data/mods/public/maps/random/migration.js | 21 ++-- .../public/maps/random/neareastern_badlands.js | 23 ++-- .../data/mods/public/maps/random/new_rms_test.js | 9 +- .../mods/public/maps/random/northern_lights.js | 4 + binaries/data/mods/public/maps/random/oasis.js | 2 + .../mods/public/maps/random/persian_highlands.js | 2 + .../mods/public/maps/random/phoenician_levant.js | 5 +- binaries/data/mods/public/maps/random/polar_sea.js | 44 ++++--- .../mods/public/maps/random/pyrenean_sierra.js | 2 + .../mods/public/maps/random/rhine_marshlands.js | 2 + .../mods/public/maps/random/river_archipelago.js | 55 +++++---- binaries/data/mods/public/maps/random/rivers.js | 9 +- .../data/mods/public/maps/random/rmgen/library.js | 5 + .../data/mods/public/maps/random/rmgen/player.js | 62 ++++++++++ .../data/mods/public/maps/random/saharan_oases.js | 2 + binaries/data/mods/public/maps/random/sahel.js | 2 + .../public/maps/random/sahel_watering_holes.js | 2 + .../data/mods/public/maps/random/schwarzwald.js | 2 + .../mods/public/maps/random/snowflake_searocks.js | 9 +- .../data/mods/public/maps/random/stronghold.js | 11 ++ binaries/data/mods/public/maps/random/syria.js | 21 +++- binaries/data/mods/public/maps/random/the_nile.js | 2 + .../maps/random/the_unknown/unknown_common.js | 37 +++--- binaries/data/mods/public/maps/random/unknown.js | 1 - .../data/mods/public/maps/random/unknown_land.js | 1 - .../data/mods/public/maps/random/unknown_nomad.js | 126 --------------------- .../mods/public/maps/random/unknown_nomad.json | 12 -- .../data/mods/public/maps/random/volcanic_lands.js | 2 + binaries/data/mods/public/maps/random/wild_lake.js | 23 ++-- 73 files changed, 560 insertions(+), 338 deletions(-) delete mode 100644 binaries/data/mods/public/maps/random/unknown_nomad.js delete mode 100644 binaries/data/mods/public/maps/random/unknown_nomad.json diff --git a/binaries/data/mods/public/gui/common/gamedescription.js b/binaries/data/mods/public/gui/common/gamedescription.js index 5884f19631..af4de5ff4c 100644 --- a/binaries/data/mods/public/gui/common/gamedescription.js +++ b/binaries/data/mods/public/gui/common/gamedescription.js @@ -342,6 +342,15 @@ function getGameDescription(extended = false) translate("Sorry, no description available.") }); + if (extended || g_GameAttributes.settings.Nomad) + titles.push({ + "label": g_GameAttributes.settings.Nomad ? translate("Nomad Mode") : translate("Civic Centers"), + "value": + g_GameAttributes.settings.Nomad ? + translate("Players start with only few units and have to find a suitable place to build their city.") : + translate("Players start with a Civic Center.") + }); + if (g_GameAttributes.settings.Biome) { let biome = g_Settings.Biomes.find(b => b.Id == g_GameAttributes.settings.Biome); diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.js b/binaries/data/mods/public/gui/gamesetup/gamesetup.js index 1cbe57bbf5..a560684130 100644 --- a/binaries/data/mods/public/gui/gamesetup/gamesetup.js +++ b/binaries/data/mods/public/gui/gamesetup/gamesetup.js @@ -367,6 +367,7 @@ var g_OptionOrderGUI = { "populationCap", "startingResources", "ceasefire", + "nomad", "regicideGarrison", "exploreMap", "revealMap", @@ -768,6 +769,18 @@ var g_Checkboxes = { "enabled": () => g_GameAttributes.mapType != "scenario", "initOrder": 1000 }, + "nomad": { + "title": () => translate("Nomad"), + "tooltip": () => translate("In Nomad mode, players start with only few units and have to find a suitable place to build their city. Ceasefire is recommended."), + "default": () => false, + "defined": () => g_GameAttributes.settings.Nomad !== undefined, + "get": () => g_GameAttributes.settings.Nomad, + "set": checked => { + g_GameAttributes.settings.Nomad = checked; + }, + "hidden": () => g_GameAttributes.mapType != "random", + "initOrder": 1000 + }, "revealMap": { "title": () => // Translation: Make sure to differentiate between the revealed map and explored map options! @@ -1796,9 +1809,10 @@ function selectMap(name) let mapData = loadMapData(name); let mapSettings = mapData && mapData.settings ? clone(mapData.settings) : {}; - // Reset victory conditions if (g_GameAttributes.mapType != "random") { + delete g_GameAttributes.settings.Nomad; + let victoryIdx = g_VictoryConditions.Name.indexOf(mapSettings.GameType || "") != -1 ? g_VictoryConditions.Name.indexOf(mapSettings.GameType) : g_VictoryConditions.Default; g_GameAttributes.settings.GameType = g_VictoryConditions.Name[victoryIdx]; g_GameAttributes.settings.VictoryScripts = g_VictoryConditions.Scripts[victoryIdx]; diff --git a/binaries/data/mods/public/maps/random/aegean_sea.js b/binaries/data/mods/public/maps/random/aegean_sea.js index ec527ca540..1752eea110 100644 --- a/binaries/data/mods/public/maps/random/aegean_sea.js +++ b/binaries/data/mods/public/maps/random/aegean_sea.js @@ -283,6 +283,8 @@ createStragglerTrees( clForest, stragglerTrees * 10); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clIsland, 10, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("cumulus"); setSunColor(0.866667, 0.776471, 0.486275); setWaterColor(0, 0.501961, 1); diff --git a/binaries/data/mods/public/maps/random/african_plains.js b/binaries/data/mods/public/maps/random/african_plains.js index 0ac4d3f72b..55f664fdb1 100644 --- a/binaries/data/mods/public/maps/random/african_plains.js +++ b/binaries/data/mods/public/maps/random/african_plains.js @@ -269,6 +269,8 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setPPEffect("hdr"); setPPSaturation(0.48); setPPContrast(0.53); diff --git a/binaries/data/mods/public/maps/random/alpine_lakes.js b/binaries/data/mods/public/maps/random/alpine_lakes.js index 12f2deb9ae..d077f532f5 100644 --- a/binaries/data/mods/public/maps/random/alpine_lakes.js +++ b/binaries/data/mods/public/maps/random/alpine_lakes.js @@ -288,6 +288,8 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet(pickRandom(["cirrus", "cumulus", "sunny"])); setSunRotation(randFloat(0, 2 * Math.PI)); setSunElevation(Math.PI * randFloat(1/5, 1/3)); diff --git a/binaries/data/mods/public/maps/random/alpine_valley.js b/binaries/data/mods/public/maps/random/alpine_valley.js index 54bd91dcbd..71734cefb3 100644 --- a/binaries/data/mods/public/maps/random/alpine_valley.js +++ b/binaries/data/mods/public/maps/random/alpine_valley.js @@ -533,6 +533,8 @@ createObjectGroupsDeprecated(group, 0, planetm * scaleByMapSize(13, 200), 50 ); +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet(pickRandom(["cirrus", "cumulus", "sunny"])); setSunRotation(randFloat(0, 2 * Math.PI)); setSunElevation(Math.PI * randFloat(1/5, 1/3)); diff --git a/binaries/data/mods/public/maps/random/ambush.js b/binaries/data/mods/public/maps/random/ambush.js index 51f61487fd..a3bff2c6b5 100644 --- a/binaries/data/mods/public/maps/random/ambush.js +++ b/binaries/data/mods/public/maps/random/ambush.js @@ -190,4 +190,15 @@ addElements(shuffleArray([ ])); Engine.SetProgress(90); +placePlayersNomad( + g_TileClasses.player, + avoidClasses( + g_TileClasses.bluff, 4, + g_TileClasses.water, 4, + g_TileClasses.forest, 1, + g_TileClasses.metal, 4, + g_TileClasses.rock, 4, + g_TileClasses.mountain, 4, + g_TileClasses.animals, 2)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/anatolian_plateau.js b/binaries/data/mods/public/maps/random/anatolian_plateau.js index 0d9e81272c..73f7181780 100644 --- a/binaries/data/mods/public/maps/random/anatolian_plateau.js +++ b/binaries/data/mods/public/maps/random/anatolian_plateau.js @@ -231,6 +231,8 @@ createObjectGroupsDeprecated(group, 0, scaleByMapSize(13, 200), 50 ); +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setFogThickness(0.1); setFogFactor(0.2); diff --git a/binaries/data/mods/public/maps/random/archipelago.js b/binaries/data/mods/public/maps/random/archipelago.js index 66efc6fb39..48a5115a0c 100644 --- a/binaries/data/mods/public/maps/random/archipelago.js +++ b/binaries/data/mods/public/maps/random/archipelago.js @@ -256,6 +256,12 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad( + clPlayer, + new AndConstraint([ + stayClasses(clLand, 4), + avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)])); + setWaterWaviness(4.0); setWaterType("ocean"); diff --git a/binaries/data/mods/public/maps/random/arctic_summer.js b/binaries/data/mods/public/maps/random/arctic_summer.js index ed30b5bcc5..d4b56169b4 100644 --- a/binaries/data/mods/public/maps/random/arctic_summer.js +++ b/binaries/data/mods/public/maps/random/arctic_summer.js @@ -305,6 +305,8 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clWater, 4, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("sunset 1"); setSunRotation(randFloat(0, 2 * Math.PI)); setSunColor(0.8, 0.7, 0.6); diff --git a/binaries/data/mods/public/maps/random/ardennes_forest.js b/binaries/data/mods/public/maps/random/ardennes_forest.js index efc6d2e07b..5391145aed 100644 --- a/binaries/data/mods/public/maps/random/ardennes_forest.js +++ b/binaries/data/mods/public/maps/random/ardennes_forest.js @@ -452,6 +452,8 @@ createObjectGroupsByAreasDeprecated(group, 0, [explorableArea] ); +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setTerrainAmbientColor(0.44,0.51,0.56); setUnitsAmbientColor(0.44,0.51,0.56); diff --git a/binaries/data/mods/public/maps/random/atlas_mountains.js b/binaries/data/mods/public/maps/random/atlas_mountains.js index c7b9a29cc2..de8725264f 100644 --- a/binaries/data/mods/public/maps/random/atlas_mountains.js +++ b/binaries/data/mods/public/maps/random/atlas_mountains.js @@ -206,6 +206,8 @@ createStragglerTrees( clForest, stragglerTrees / 5); +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setFogFactor(0.2); setFogThickness(0.14); diff --git a/binaries/data/mods/public/maps/random/belgian_uplands.js b/binaries/data/mods/public/maps/random/belgian_uplands.js index 849b86295c..d8d4f3dddb 100644 --- a/binaries/data/mods/public/maps/random/belgian_uplands.js +++ b/binaries/data/mods/public/maps/random/belgian_uplands.js @@ -94,6 +94,8 @@ var goodStartPositionsFound = false; var minDistBetweenPlayers = 16 + mapSize / 16; // Don't set this higher than 25 for tiny maps! It will take forever with 8 players! var enoughTiles = false; var tries = 0; +var lowerHeightLimit = textueByHeight[3].upperHeightLimit; +var upperHeightLimit = textueByHeight[6].upperHeightLimit; while (!goodStartPositionsFound) { @@ -113,8 +115,6 @@ while (!goodStartPositionsFound) var possibleStartPositions = []; var neededDistance = 7; var distToBorder = 2 * neededDistance; // Has to be greater than neededDistance! Otherwise the check if low/high ground is near will fail... - var lowerHeightLimit = textueByHeight[3].upperHeightLimit; - var upperHeightLimit = textueByHeight[6].upperHeightLimit; // Check for valid points by height for (var x = distToBorder + minTerrainDistToBorder; x < mapSize - distToBorder - minTerrainDistToBorder; x++) @@ -369,8 +369,12 @@ for(var x = minTerrainDistToBorder; x < mapSize - minTerrainDistToBorder; x++) Engine.SetProgress(90); +if (isNomad()) + placePlayersNomad(createTileClass(), new HeightConstraint(lowerHeightLimit, upperHeightLimit)); +else { log("Placing players and starting resources..."); + let playerIDs = sortAllPlayers(); let resourceDistance = 8; let resourceSpacing = 1; diff --git a/binaries/data/mods/public/maps/random/botswanan_haven.js b/binaries/data/mods/public/maps/random/botswanan_haven.js index b909857de2..c84ce11d47 100644 --- a/binaries/data/mods/public/maps/random/botswanan_haven.js +++ b/binaries/data/mods/public/maps/random/botswanan_haven.js @@ -371,6 +371,8 @@ createObjectGroupsDeprecated( scaleByMapSize(13, 200), 50); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("cirrus"); setWaterColor(0.553, 0.635, 0.345); setWaterTint(0.161, 0.514, 0.635); diff --git a/binaries/data/mods/public/maps/random/caledonian_meadows.js b/binaries/data/mods/public/maps/random/caledonian_meadows.js index 2f7a76319b..180a3d28c9 100644 --- a/binaries/data/mods/public/maps/random/caledonian_meadows.js +++ b/binaries/data/mods/public/maps/random/caledonian_meadows.js @@ -421,15 +421,16 @@ for (let h = 0; h < heighLimits.length; ++h) } Engine.SetProgress(80); -/** - * Add start locations and resource spots after terrain texture and path painting - */ -for (let p = 0; p < playerIDs.length; ++p) -{ - let point = startLocations[p]; - placeCivDefaultStartingEntities(point.x, point.y, playerIDs[p], "walls"); - placeStartLocationResources(startLocations[p]); -} +log("Placing players..."); +if (isNomad()) + placePlayersNomad(createTileClass(), new HeightConstraint(heighLimits[4], heighLimits[5])); +else + for (let p = 0; p < playerIDs.length; ++p) + { + let point = startLocations[p]; + placeCivDefaultStartingEntities(point.x, point.y, playerIDs[p], true); + placeStartLocationResources(startLocations[p]); + } log("Placing resources, farmsteads, groves and camps..."); for (let i = 0; i < resourceSpots.length; ++i) diff --git a/binaries/data/mods/public/maps/random/cantabrian_highlands.js b/binaries/data/mods/public/maps/random/cantabrian_highlands.js index e264938b01..4b53068e67 100644 --- a/binaries/data/mods/public/maps/random/cantabrian_highlands.js +++ b/binaries/data/mods/public/maps/random/cantabrian_highlands.js @@ -56,7 +56,7 @@ var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); -var playerHillRadius = defaultPlayerBaseRadius(); +var playerHillRadius = defaultPlayerBaseRadius() / (isNomad() ? 1.5 : 1); var playerHillElevation = 20; var [playerIDs, playerX, playerZ, playerAngle] = playerPlacementCircle(0.35); @@ -259,6 +259,8 @@ createStragglerTrees( stragglerTrees); Engine.SetProgress(90); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("cirrus"); setWaterColor(0.447, 0.412, 0.322); // muddy brown setWaterTint(0.447, 0.412, 0.322); diff --git a/binaries/data/mods/public/maps/random/canyon.js b/binaries/data/mods/public/maps/random/canyon.js index b749d95023..2190f4dc7e 100644 --- a/binaries/data/mods/public/maps/random/canyon.js +++ b/binaries/data/mods/public/maps/random/canyon.js @@ -80,9 +80,8 @@ for (let i = 0; i < numPlayers; ++i) [ new LayeredPainter([tMainTerrain, tMainTerrain], [2]), new SmoothElevationPainter(ELEVATION_SET, landHeight, 2), - paintClass(j == 1 ? clLand : clPlayer) - ], - null); + paintClass(j == 1 || isNomad() ? clLand : clPlayer) + ]); log("Creating center area..."); var center = Math.round(fractionToTiles(0.5)); @@ -370,4 +369,8 @@ for (let i = 0; i < randIntInclusive(3, 8); ++i) for (let template of [oFoodTreasure, oWoodTreasure]) placeObject(center + randFloat(-7, 7), center + randFloat(-7, 7), template, 0, randFloat(0, 2 * Math.PI)); +placePlayersNomad( + clPlayer, + [stayClasses(clLand, 4), avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clHill2, 4, clFood, 2)]); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/continent.js b/binaries/data/mods/public/maps/random/continent.js index 8e14983cf9..e983847910 100644 --- a/binaries/data/mods/public/maps/random/continent.js +++ b/binaries/data/mods/public/maps/random/continent.js @@ -245,6 +245,10 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad( + clPlayer, + [stayClasses(clLand, 4), avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)]); + setWaterWaviness(1.0); setWaterType("ocean"); diff --git a/binaries/data/mods/public/maps/random/corinthian_isthmus.js b/binaries/data/mods/public/maps/random/corinthian_isthmus.js index ef07fe20f2..ee5038da0d 100644 --- a/binaries/data/mods/public/maps/random/corinthian_isthmus.js +++ b/binaries/data/mods/public/maps/random/corinthian_isthmus.js @@ -252,6 +252,8 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("sunny"); setSunColor(0.917, 0.828, 0.734); setWaterColor(0, 0.501961, 1); diff --git a/binaries/data/mods/public/maps/random/corsica.js b/binaries/data/mods/public/maps/random/corsica.js index fa1923caa4..b8da448a45 100644 --- a/binaries/data/mods/public/maps/random/corsica.js +++ b/binaries/data/mods/public/maps/random/corsica.js @@ -500,6 +500,8 @@ createObjectGroupsDeprecated( Engine.SetProgress(95); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clBaseResource, 4, clCliffs, 4)); + setSkySet(pickRandom(["cumulus", "sunny"])); setSunColor(0.8, 0.66, 0.48); diff --git a/binaries/data/mods/public/maps/random/cycladic_archipelago.js b/binaries/data/mods/public/maps/random/cycladic_archipelago.js index 2d73d5b378..8eeeca8f41 100644 --- a/binaries/data/mods/public/maps/random/cycladic_archipelago.js +++ b/binaries/data/mods/public/maps/random/cycladic_archipelago.js @@ -360,6 +360,8 @@ createObjectGroupsDeprecated(group, 0, ); Engine.SetProgress(99); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clBaseResource, 4, clHill, 4)); + setSkySet("sunny"); setWaterColor(0.2,0.294,0.49); setWaterTint(0.208, 0.659, 0.925); diff --git a/binaries/data/mods/public/maps/random/danubius.js b/binaries/data/mods/public/maps/random/danubius.js index 61671f0071..02386d1f2f 100644 --- a/binaries/data/mods/public/maps/random/danubius.js +++ b/binaries/data/mods/public/maps/random/danubius.js @@ -55,7 +55,8 @@ const oCivicCenter = "structures/gaul_civil_centre"; const oHouse = "structures/gaul_house"; const oTemple = "structures/gaul_temple"; const oTavern = "structures/gaul_tavern"; -const oTower= "structures/gaul_defense_tower"; +const oTower = "structures/gaul_defense_tower"; +const oSentryTower = "structures/gaul_sentry_tower"; const oOutpost = "structures/gaul_outpost"; const oHut = "other/celt_hut"; @@ -268,7 +269,7 @@ if (gallicCC) g_WallStyles.gaul.longhouse = { "angle": Math.PI, "length": 0, "indent": 4, "bend": 0, "templateName": oLongHouse }; g_WallStyles.gaul.tavern = { "angle": Math.PI * 3/2, "length": 0, "indent": 4, "bend": 0, "templateName": oTavern }; g_WallStyles.gaul.temple = { "angle": Math.PI * 3/2, "length": 0, "indent": 4, "bend": 0, "templateName": oTemple }; - g_WallStyles.gaul.defense_tower = { "angle": Math.PI / 2, "length": 0, "indent": 4, "bend": 0, "templateName": mapSize >= normalMapSize ? oTower : oPalisadeTower }; + g_WallStyles.gaul.defense_tower = { "angle": Math.PI / 2, "length": 0, "indent": 4, "bend": 0, "templateName": mapSize >= normalMapSize ? (isNomad() ? oSentryTower : oTower) : oPalisadeTower }; // Replace stone walls with palisade walls for (let element of ["gate", "long", "short", "cornerIn", "cornerOut", "tower"]) @@ -569,19 +570,20 @@ createFood( clFood); log("Creating violent animals..."); -createFood( - [ - [new SimpleObject(oWolf, 1, 3, 0, 4)], - [new SimpleObject(oBoar, 1, 1, 0, 4)], - [new SimpleObject(oBear, 1, 1, 0, 4)] - ], - [ - scaleByMapSize(5, 20), - scaleByMapSize(5, 20), - scaleByMapSize(5, 20) - ], - avoidClasses(clIsland, 2, clFood, 10, clWater, 5, clPlayer, 24, clHill, 2, clGauls, 5, clPath, 1), - clFood); +if (!isNomad()) + createFood( + [ + [new SimpleObject(oWolf, 1, 3, 0, 4)], + [new SimpleObject(oBoar, 1, 1, 0, 4)], + [new SimpleObject(oBear, 1, 1, 0, 4)] + ], + [ + scaleByMapSize(5, 20), + scaleByMapSize(5, 20), + scaleByMapSize(5, 20) + ], + avoidClasses(clIsland, 2, clFood, 10, clWater, 5, clPlayer, 24, clHill, 2, clGauls, 5, clPath, 1), + clFood); Engine.SetProgress(85); @@ -757,6 +759,8 @@ createObjectGroupsDeprecated( 100 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clIsland, 4, clGauls, 20, clRitualPlace, 20, clForest, 1, clBaseResource, 4, clHill, 4, clFood, 2)); + if (randBool(2/3)) { // Day diff --git a/binaries/data/mods/public/maps/random/deep_forest.js b/binaries/data/mods/public/maps/random/deep_forest.js index e59c531743..2106dcda89 100644 --- a/binaries/data/mods/public/maps/random/deep_forest.js +++ b/binaries/data/mods/public/maps/random/deep_forest.js @@ -222,6 +222,7 @@ Engine.SetProgress(60); // Place eyecandy placeObject(mapCenterX, mapCenterZ, templateEC, 0, randFloat(0, 2 * Math.PI)); +addToClass(mapCenterX, mapCenterZ, clBaseResource); createArea( new ClumpPlacer(Math.square(radiusEC), 1/2, 1/8, 1, mapCenterX, mapCenterZ), [ @@ -268,4 +269,6 @@ for (var x = 0; x < mapSize; x++) } Engine.SetProgress(95); +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clBaseResource, 4)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/empire.js b/binaries/data/mods/public/maps/random/empire.js index b4dd0a58ae..21fbce244b 100644 --- a/binaries/data/mods/public/maps/random/empire.js +++ b/binaries/data/mods/public/maps/random/empire.js @@ -216,4 +216,14 @@ addElements(shuffleArray([ ])); Engine.SetProgress(90); +placePlayersNomad( + g_TileClasses.player, + avoidClasses( + g_TileClasses.plateau, 4, + g_TileClasses.forest, 1, + g_TileClasses.metal, 4, + g_TileClasses.rock, 4, + g_TileClasses.mountain, 4, + g_TileClasses.animals, 2)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/english_channel.js b/binaries/data/mods/public/maps/random/english_channel.js index 279fa87947..2e2d15bde4 100644 --- a/binaries/data/mods/public/maps/random/english_channel.js +++ b/binaries/data/mods/public/maps/random/english_channel.js @@ -257,4 +257,6 @@ setPPSaturation(0.62); setPPContrast(0.62); setPPBloom(0.37); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/extinct_volcano.js b/binaries/data/mods/public/maps/random/extinct_volcano.js index adc399221f..8dceec8fd8 100644 --- a/binaries/data/mods/public/maps/random/extinct_volcano.js +++ b/binaries/data/mods/public/maps/random/extinct_volcano.js @@ -74,34 +74,35 @@ var ccMountainSize = defaultPlayerBaseRadius(); var [playerIDs, playerX, playerZ] = playerPlacementCircle(0.35); log("Creating CC mountains..."); -for (let i = 0; i < numPlayers; ++i) -{ - let ix = Math.round(fractionToTiles(playerX[i])); - let iz = Math.round(fractionToTiles(playerZ[i])); - - // This one consists of many bumps, creating an omnidirectional ramp - createMountain( - ccMountainHeight, - Math.floor(scaleByMapSize(15, 15)), - Math.floor(scaleByMapSize(15, 15)), - Math.floor(scaleByMapSize(4, 10)), - avoidClasses(), - ix, - iz, - tHillDark, - clPlayer, - 14); - - // Flatten the initial CC area - createArea( - new ClumpPlacer(diskArea(ccMountainSize), 0.95, 0.6, 10, ix, iz), - [ - new LayeredPainter([tHillVeryDark, tHillMedium1], [ccMountainSize]), - new SmoothElevationPainter(ELEVATION_SET, ccMountainHeight, ccMountainSize), - paintClass(clPlayer) - ], - null); -} +if (!isNomad()) + for (let i = 0; i < numPlayers; ++i) + { + let ix = Math.round(fractionToTiles(playerX[i])); + let iz = Math.round(fractionToTiles(playerZ[i])); + + // This one consists of many bumps, creating an omnidirectional ramp + createMountain( + ccMountainHeight, + ccMountainSize, + ccMountainSize, + Math.floor(scaleByMapSize(4, 10)), + undefined, + ix, + iz, + tHillDark, + clPlayer, + 14); + + // Flatten the initial CC area + createArea( + new ClumpPlacer(diskArea(ccMountainSize), 0.95, 0.6, 10, ix, iz), + [ + new LayeredPainter([tHillVeryDark, tHillMedium1], [ccMountainSize]), + new SmoothElevationPainter(ELEVATION_SET, ccMountainHeight, ccMountainSize), + paintClass(clPlayer) + ]); + } + Engine.SetProgress(8); placePlayerBases({ @@ -277,22 +278,25 @@ createObjectGroupsDeprecated( 100); Engine.SetProgress(65); -log("Creating towers..."); -createObjectGroupsDeprecated( - new SimpleGroup([new SimpleObject(oTower, 1, 1, 0, 4)], true, clTower), - 0, - [ - stayClasses(clBumps, 3), - avoidClasses( - clMetal, 5, - clRock, 5, - clHill, 0, - clTower, 60, - clPlayer, 10, - clForest, 2) - ], - 500, - 1); +if (!isNomad()) +{ + log("Creating towers..."); + createObjectGroupsDeprecated( + new SimpleGroup([new SimpleObject(oTower, 1, 1, 0, 4)], true, clTower), + 0, + [ + stayClasses(clBumps, 3), + avoidClasses( + clMetal, 5, + clRock, 5, + clHill, 0, + clTower, 60, + clPlayer, 10, + clForest, 2) + ], + 500, + 1); +} Engine.SetProgress(67); createDecoration( @@ -445,6 +449,8 @@ createObjectGroupsDeprecated( scaleByMapSize(80, 250)); Engine.SetProgress(95); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clHill, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("rain"); setWaterType("lake"); setWaterWaviness(2); diff --git a/binaries/data/mods/public/maps/random/flood.js b/binaries/data/mods/public/maps/random/flood.js index 0a4a7c13f2..0b0b590020 100644 --- a/binaries/data/mods/public/maps/random/flood.js +++ b/binaries/data/mods/public/maps/random/flood.js @@ -312,6 +312,12 @@ createObjectGroupsDeprecated( [avoidClasses(clMountain, 2, clPlayer, 2, clDirt, 0), stayClasses(clHill, 8)], planetm * scaleByMapSize(13, 200)); +placePlayersNomad( + clPlayer, + new AndConstraint([ + stayClasses(clHill, 2), + avoidClasses(clMountain, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)])); + setSkySet(pickRandom(["cloudless", "cumulus", "overcast"])); setWaterMurkiness(0.4); diff --git a/binaries/data/mods/public/maps/random/fortress.js b/binaries/data/mods/public/maps/random/fortress.js index b2d3232b68..c98d9dd84a 100644 --- a/binaries/data/mods/public/maps/random/fortress.js +++ b/binaries/data/mods/public/maps/random/fortress.js @@ -59,6 +59,9 @@ var [playerIDs, playerX, playerZ] = playerPlacementCircle(0.35); for (var i=0; i < numPlayers; i++) { + if (isNomad()) + break; + log("Creating base for player " + playerIDs[i] + "..."); playerX[i] *= mapSize; playerZ[i] *= mapSize; @@ -304,6 +307,8 @@ createStragglerTrees( stragglerTrees); Engine.SetProgress(95); +placePlayersNomad(clPlayer, avoidClasses(clWater, 2, clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("sunny"); setWaterColor(0.157, 0.149, 0.443); setWaterTint(0.443,0.42,0.824); diff --git a/binaries/data/mods/public/maps/random/frontier.js b/binaries/data/mods/public/maps/random/frontier.js index e8a614104d..3942ad8767 100644 --- a/binaries/data/mods/public/maps/random/frontier.js +++ b/binaries/data/mods/public/maps/random/frontier.js @@ -95,7 +95,7 @@ if (randElevation < 4) g_TileClasses.valley, 10, g_TileClasses.water, 25 ], - "sizes": g_AllSizes, + "sizes": ["small"], "mixes": g_AllMixes, "amounts": g_AllAmounts }); @@ -264,4 +264,16 @@ addElements(shuffleArray([ ])); Engine.SetProgress(90); +placePlayersNomad( + g_TileClasses.player, + avoidClasses( + g_TileClasses.bluff, 4, + g_TileClasses.water, 4, + g_TileClasses.forest, 1, + g_TileClasses.metal, 4, + g_TileClasses.rock, 4, + g_TileClasses.mountain, 4, + g_TileClasses.plateau, 4, + g_TileClasses.animals, 2)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/gear.js b/binaries/data/mods/public/maps/random/gear.js index 52a8503233..acb7df679f 100644 --- a/binaries/data/mods/public/maps/random/gear.js +++ b/binaries/data/mods/public/maps/random/gear.js @@ -316,4 +316,6 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/guadalquivir_river.js b/binaries/data/mods/public/maps/random/guadalquivir_river.js index 0798f27b72..29c94d0b69 100644 --- a/binaries/data/mods/public/maps/random/guadalquivir_river.js +++ b/binaries/data/mods/public/maps/random/guadalquivir_river.js @@ -260,6 +260,12 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad( + clPlayer, + new AndConstraint([ + stayClasses(clLand, 4), + avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clFood, 2)])); + setSkySet("cumulus"); setWaterColor(0.2,0.312,0.522); setWaterTint(0.1,0.1,0.8); diff --git a/binaries/data/mods/public/maps/random/gulf_of_bothnia.js b/binaries/data/mods/public/maps/random/gulf_of_bothnia.js index ac471aeb27..4395bde262 100644 --- a/binaries/data/mods/public/maps/random/gulf_of_bothnia.js +++ b/binaries/data/mods/public/maps/random/gulf_of_bothnia.js @@ -308,6 +308,9 @@ createStragglerTrees( clForest, stragglerTrees); +// Avoid the lake, even if frozen +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("stormy"); setSunRotation(randFloat(0, 2 * Math.PI)); setSunElevation(Math.PI * randFloat(1/6, 1/4)); diff --git a/binaries/data/mods/public/maps/random/harbor.js b/binaries/data/mods/public/maps/random/harbor.js index bdd4d043d3..b597c82d3a 100644 --- a/binaries/data/mods/public/maps/random/harbor.js +++ b/binaries/data/mods/public/maps/random/harbor.js @@ -249,6 +249,19 @@ addElements([ Engine.SetProgress(90); +placePlayersNomad( + g_TileClasses.player, + avoidClasses( + g_TileClasses.bluff, 4, + g_TileClasses.water, 4, + g_TileClasses.spine, 4, + g_TileClasses.plateau, 4, + g_TileClasses.forest, 1, + g_TileClasses.metal, 4, + g_TileClasses.rock, 4, + g_TileClasses.mountain, 4, + g_TileClasses.animals, 2)); + ExportMap(); function addCenterLake() diff --git a/binaries/data/mods/public/maps/random/hells_pass.js b/binaries/data/mods/public/maps/random/hells_pass.js index e505d8af22..2400214c1a 100644 --- a/binaries/data/mods/public/maps/random/hells_pass.js +++ b/binaries/data/mods/public/maps/random/hells_pass.js @@ -222,6 +222,19 @@ addElements(shuffleArray([ ])); Engine.SetProgress(90); +placePlayersNomad( + g_TileClasses.player, + avoidClasses( + g_TileClasses.bluff, 4, + g_TileClasses.water, 4, + g_TileClasses.spine, 4, + g_TileClasses.plateau, 4, + g_TileClasses.forest, 1, + g_TileClasses.metal, 4, + g_TileClasses.rock, 4, + g_TileClasses.mountain, 4, + g_TileClasses.animals, 2)); + ExportMap(); function placeBarriers() @@ -237,7 +250,9 @@ function placeBarriers() if (currentBiome() == "autumn") spineTerrain = g_Terrains.tier4Terrain; - for (let i = 0; i < teamsArray.length; ++i) + let spineCount = isNomad() ? randIntInclusive(1, 4) : teamsArray.length; + + for (let i = 0; i < spineCount; ++i) { var mStartCo = 0.07; var mStopCo = 0.42; @@ -246,14 +261,14 @@ function placeBarriers() var mOffset = 0.5; var mTaper = -1.5; - if (teamsArray.length > 3 || getMapSize() <= 192) + if (spineCount > 3 || getMapSize() <= 192) { mWaviness = 0.2; mOffset = 0.2; mTaper = -1; } - if (teamsArray.length >= 5) + if (spineCount >= 5) { mSize = 4; mWaviness = 0.2; @@ -261,7 +276,7 @@ function placeBarriers() mTaper = -0.7; } - let angle = startAngle + (i + 0.5) * 2 * Math.PI / teamsArray.length; + let angle = startAngle + (i + 0.5) * 2 * Math.PI / spineCount; createArea( new PathPlacer( fractionToTiles(0.5 + mStartCo * Math.cos(angle)), diff --git a/binaries/data/mods/public/maps/random/hyrcanian_shores.js b/binaries/data/mods/public/maps/random/hyrcanian_shores.js index 996c7506b1..22c5e73e41 100644 --- a/binaries/data/mods/public/maps/random/hyrcanian_shores.js +++ b/binaries/data/mods/public/maps/random/hyrcanian_shores.js @@ -320,6 +320,8 @@ createObjectGroupsDeprecated(group, 0, scaleByMapSize(13, 200), 50 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("cirrus"); setWaterColor(0.114, 0.192, 0.463); setWaterTint(0.255, 0.361, 0.651); diff --git a/binaries/data/mods/public/maps/random/india.js b/binaries/data/mods/public/maps/random/india.js index 553c30b20a..f4b01b0138 100644 --- a/binaries/data/mods/public/maps/random/india.js +++ b/binaries/data/mods/public/maps/random/india.js @@ -248,6 +248,8 @@ createObjectGroupsDeprecated( scaleByMapSize(100, 1200) ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setSunColor(0.87451, 0.847059, 0.647059); setWaterColor(0.741176, 0.592157, 0.27451); setWaterTint(0.741176, 0.592157, 0.27451); diff --git a/binaries/data/mods/public/maps/random/island_stronghold.js b/binaries/data/mods/public/maps/random/island_stronghold.js index a0dab2ec14..ac39c60e1b 100644 --- a/binaries/data/mods/public/maps/random/island_stronghold.js +++ b/binaries/data/mods/public/maps/random/island_stronghold.js @@ -87,7 +87,7 @@ var numTeams = teams.filter(team => team).length; var teamNo = 0; for (let i = 0; i < teams.length; ++i) { - if (!teams[i]) + if (!teams[i] || isNomad()) continue; ++teamNo; @@ -209,7 +209,7 @@ for (let x = 0; x < mapSize; ++x) landAreas.push([x, z]); log("Creating big islands..."); -let numIslands = scaleByMapSize(4, 14); +let numIslands = scaleByMapSize(4, 14) * (isNomad() ? 2 : 1); for (let i = 0; i < numIslands; ++i) { let landAreaLen = landAreas.length; @@ -219,7 +219,14 @@ for (let i = 0; i < numIslands; ++i) let chosenPoint = pickRandom(landAreas); let newIsland = createAreas( - new ChainPlacer(Math.floor(scaleByMapSize(4, 8)), Math.floor(scaleByMapSize(8, 14)), Math.floor(scaleByMapSize(25, 60)), 0.07, chosenPoint[0], chosenPoint[1], scaleByMapSize(30, 70)), + new ChainPlacer( + Math.floor(scaleByMapSize(4, 8) * (isNomad() ? 2 : 1)), + Math.floor(scaleByMapSize(8, 16) * (isNomad() ? 2 : 1)), + Math.floor(scaleByMapSize(25, 60)), + 0.07, + chosenPoint[0], + chosenPoint[1], + scaleByMapSize(30, 70)), [ new LayeredPainter([tMainTerrain, tMainTerrain], [2]), new SmoothElevationPainter(ELEVATION_SET, landHeight, 6), @@ -480,6 +487,8 @@ createObjectGroupsDeprecated(group, 0, paintTerrainBasedOnHeight(1, 2, 0, tShore); paintTerrainBasedOnHeight(getMapBaseHeight(), 1, 3, tWater); +placePlayersNomad(clPlayer, [stayClasses(clLand, 4), avoidClasses(clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)]); + setSkySet(pickRandom(["cloudless", "cumulus", "overcast"])); setSunRotation(randFloat(0, 2 * Math.PI)); setSunElevation(randFloat(1/5, 1/3) * Math.PI); diff --git a/binaries/data/mods/public/maps/random/islands.js b/binaries/data/mods/public/maps/random/islands.js index e7140e5282..55d7db1112 100644 --- a/binaries/data/mods/public/maps/random/islands.js +++ b/binaries/data/mods/public/maps/random/islands.js @@ -65,21 +65,24 @@ var playerIslandRadius = scaleByMapSize(20, 29); var [playerIDs, playerX, playerZ, playerAngle] = playerPlacementCircle(0.35); -log("Creating player islands and docks..."); -for (let i = 0; i < numPlayers; i++) +if (!isNomad()) { - let playerPos = new Vector2D(playerX[i], playerZ[i]).mult(mapSize); - createArea( - new ClumpPlacer(diskArea(playerIslandRadius), 0.8, 0.1, 10, playerPos.x, playerPos.y), - [ - new LayeredPainter([tMainTerrain , tMainTerrain, tMainTerrain], [1, 6]), - new SmoothElevationPainter(ELEVATION_SET, landHeight, 6), - paintClass(clLand), - paintClass(clPlayer) - ]); - - let dockLocation = findLocationInDirectionBasedOnHeight(playerPos, mapCenter, -3 , landHeight - 0.5, landHeight); - placeObject(dockLocation.x, dockLocation.y, oDock, playerIDs[i], playerAngle[i] + Math.PI); + log("Creating player islands and docks..."); + for (let i = 0; i < numPlayers; i++) + { + let playerPos = new Vector2D(playerX[i], playerZ[i]).mult(mapSize); + createArea( + new ClumpPlacer(diskArea(playerIslandRadius), 0.8, 0.1, 10, playerPos.x, playerPos.y), + [ + new LayeredPainter([tMainTerrain , tMainTerrain, tMainTerrain], [1, 6]), + new SmoothElevationPainter(ELEVATION_SET, landHeight, 6), + paintClass(clLand), + paintClass(clPlayer) + ]); + + let dockLocation = findLocationInDirectionBasedOnHeight(playerPos, mapCenter, -3 , landHeight - 0.5, landHeight); + placeObject(dockLocation.x, dockLocation.y, oDock, playerIDs[i], playerAngle[i] + Math.PI); + } } log("Creating big islands..."); @@ -348,6 +351,8 @@ createObjectGroupsDeprecated(group, 0, planetm * scaleByMapSize(13, 200), 50 ); +placePlayersNomad(clPlayer, [stayClasses(clLand, 4), avoidClasses(clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)]); + setSkySet(pickRandom(["cirrus", "cumulus", "sunny"])); setSunRotation(randFloat(0, 2 * Math.PI)); setSunElevation(randFloat(1/5, 1/3) * Math.PI); diff --git a/binaries/data/mods/public/maps/random/kerala.js b/binaries/data/mods/public/maps/random/kerala.js index 6254f3c454..f4a0c92db5 100644 --- a/binaries/data/mods/public/maps/random/kerala.js +++ b/binaries/data/mods/public/maps/random/kerala.js @@ -308,6 +308,8 @@ createObjectGroupsDeprecated(group, 0, 25 * numPlayers, 60 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setSunColor(0.6, 0.6, 0.6); setSunElevation(Math.PI / 3); diff --git a/binaries/data/mods/public/maps/random/lake.js b/binaries/data/mods/public/maps/random/lake.js index cf5c56bf26..43cb35d292 100644 --- a/binaries/data/mods/public/maps/random/lake.js +++ b/binaries/data/mods/public/maps/random/lake.js @@ -246,6 +246,8 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clHill, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setWaterWaviness(4.0); setWaterType("lake"); diff --git a/binaries/data/mods/public/maps/random/latium.js b/binaries/data/mods/public/maps/random/latium.js index 3e09219e94..37dd30e40d 100644 --- a/binaries/data/mods/public/maps/random/latium.js +++ b/binaries/data/mods/public/maps/random/latium.js @@ -454,6 +454,8 @@ createObjectGroupsDeprecated(group, 0, 1.5 * numPlayers, 100 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clCliff, 2, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setSkySet("sunny"); setWaterColor(0.024,0.262,0.224); setWaterTint(0.133, 0.325,0.255); diff --git a/binaries/data/mods/public/maps/random/lions_den.js b/binaries/data/mods/public/maps/random/lions_den.js index d4d2c22833..578bf6fa06 100644 --- a/binaries/data/mods/public/maps/random/lions_den.js +++ b/binaries/data/mods/public/maps/random/lions_den.js @@ -408,6 +408,17 @@ addElements([ ]); Engine.SetProgress(95); +placePlayersNomad( + g_TileClasses.player, + [ + new HeightConstraint(valleyHeight, pathHeight), + avoidClasses( + g_TileClasses.forest, 1, + g_TileClasses.metal, 4, + g_TileClasses.rock, 4, + g_TileClasses.animals, 2) + ]); + ExportMap(); function createSunkenTerrain() @@ -519,7 +530,7 @@ function createSunkenTerrain() log("Creating the den of the player..."); createArea( - new ClumpPlacer(mapArea * 0.03, 0.9, 0.3, 1, ...playerCoords), + new ClumpPlacer(mapArea * 0.03 / (isNomad() ? 2 : 1), 0.9, 0.3, 1, ...playerCoords), [ new LayeredPainter([g_Terrains.cliff, base], [3]), new SmoothElevationPainter(ELEVATION_SET, denHeight, 3), diff --git a/binaries/data/mods/public/maps/random/lorraine_plain.js b/binaries/data/mods/public/maps/random/lorraine_plain.js index 6f5b9f4e6f..2379beb000 100644 --- a/binaries/data/mods/public/maps/random/lorraine_plain.js +++ b/binaries/data/mods/public/maps/random/lorraine_plain.js @@ -298,6 +298,8 @@ createObjectGroupsDeprecated(group, 0, 60 * scaleByMapSize(13, 200), 80 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("cirrus"); setWaterColor(0.1,0.212,0.422); setWaterTint(0.3,0.1,0.949); diff --git a/binaries/data/mods/public/maps/random/mainland.js b/binaries/data/mods/public/maps/random/mainland.js index dcb57aacd0..1dabe182ea 100644 --- a/binaries/data/mods/public/maps/random/mainland.js +++ b/binaries/data/mods/public/maps/random/mainland.js @@ -191,4 +191,6 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/migration.js b/binaries/data/mods/public/maps/random/migration.js index 5e640bfa2a..a76180d1a2 100644 --- a/binaries/data/mods/public/maps/random/migration.js +++ b/binaries/data/mods/public/maps/random/migration.js @@ -58,6 +58,7 @@ var clMetal = createTileClass(); var clFood = createTileClass(); var clBaseResource = createTileClass(); var clLand = createTileClass(); +var clIsland = createTileClass(); var landHeight = 3; @@ -79,9 +80,13 @@ for (let i = 0; i < numPlayers; ++i) [ new LayeredPainter([tWater, tShore, tMainTerrain], [1, 4]), new SmoothElevationPainter(ELEVATION_SET, landHeight, 4), - paintClass(clPlayer) + paintClass(clIsland), + paintClass(isNomad() ? clLand : clPlayer) ]); + if (isNomad()) + continue; + let dockLocation = findLocationInDirectionBasedOnHeight(playerPosition, mapCenter, -3 , 2.6, 3); placeObject(dockLocation.x, dockLocation.y, oDock, playerIDs[i], playerAngle[i] + Math.PI); } @@ -130,7 +135,7 @@ createArea( new SmoothElevationPainter(ELEVATION_SET, landHeight, 4), paintClass(clLand) ], - avoidClasses(clPlayer, 8)); + avoidClasses(clIsland, 8)); Engine.SetProgress(20); log("Creating shore jaggedness..."); @@ -143,7 +148,7 @@ createAreas( ], [ borderClasses(clLand, 6, 3), - avoidClasses(clPlayer, 8) + avoidClasses(clIsland, 8) ], scaleByMapSize(2, 15) * 20, 150); @@ -156,7 +161,7 @@ log("Creating bumps..."); createAreas( new ClumpPlacer(scaleByMapSize(20, 50), 0.3, 0.06, 1), new SmoothElevationPainter(ELEVATION_MODIFY, 2, 2), - [avoidClasses(clPlayer, 10), stayClasses(clLand, 3)], + [avoidClasses(clIsland, 10), stayClasses(clLand, 3)], scaleByMapSize(100, 200) ); Engine.SetProgress(30); @@ -169,7 +174,7 @@ createAreas( new SmoothElevationPainter(ELEVATION_SET, 18, 2), paintClass(clHill) ], - [avoidClasses(clPlayer, 10, clHill, 15), stayClasses(clLand, 7)], + [avoidClasses(clIsland, 10, clHill, 15), stayClasses(clLand, 7)], scaleByMapSize(1, 4) * numPlayers ); Engine.SetProgress(34); @@ -211,7 +216,7 @@ for (let size of [scaleByMapSize(3, 48), scaleByMapSize(5, 84), scaleByMapSize(8 clForest, 0, clHill, 0, clDirt, 5, - clPlayer, 0), + clIsland, 0), stayClasses(clLand, 7) ], scaleByMapSize(15, 45)); @@ -223,7 +228,7 @@ for (let size of [scaleByMapSize(2, 32), scaleByMapSize(3, 48), scaleByMapSize(5 createAreas( new ClumpPlacer(size, 0.3, 0.06, 0.5), new TerrainPainter(tTier4Terrain), - [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clPlayer, 0), stayClasses(clLand, 7)], + [avoidClasses(clForest, 0, clHill, 0, clDirt, 5, clIsland, 0), stayClasses(clLand, 7)], scaleByMapSize(15, 45)); Engine.SetProgress(46); @@ -362,4 +367,6 @@ setSunRotation(randFloat(0, 2 * Math.PI)); setSunElevation(randFloat(1/5, 1/3) * Math.PI); setWaterWaviness(2); +placePlayersNomad(clPlayer, [stayClasses(clIsland, 4), avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)]); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/neareastern_badlands.js b/binaries/data/mods/public/maps/random/neareastern_badlands.js index 35b485b0a1..c808fb93ee 100644 --- a/binaries/data/mods/public/maps/random/neareastern_badlands.js +++ b/binaries/data/mods/public/maps/random/neareastern_badlands.js @@ -61,16 +61,17 @@ var hillHeight3 = 16; var [playerIDs, playerX, playerZ] = playerPlacementCircle(0.35); -for (let i = 0; i < numPlayers; ++i) - createArea( - new ClumpPlacer( - diskArea(defaultPlayerBaseRadius()), - 0.9, - 0.5, - 10, - Math.round(fractionToTiles(playerX[i])), - Math.round(fractionToTiles(playerZ[i]))), - paintClass(clPlayer)); +if (!isNomad()) + for (let i = 0; i < numPlayers; ++i) + createArea( + new ClumpPlacer( + diskArea(defaultPlayerBaseRadius()), + 0.9, + 0.5, + 10, + Math.round(fractionToTiles(playerX[i])), + Math.round(fractionToTiles(playerZ[i]))), + paintClass(clPlayer)); placePlayerBases({ "PlayerPlacement": [playerIDs, playerX, playerZ], @@ -350,6 +351,8 @@ createObjectGroupsDeprecated(group, 0, scaleByMapSize(16, 262) ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill1, 4, clFood, 2)); + setWaterColor(0, 0.227, 0.843); setWaterTint(0, 0.545, 0.859); setWaterWaviness(1.0); diff --git a/binaries/data/mods/public/maps/random/new_rms_test.js b/binaries/data/mods/public/maps/random/new_rms_test.js index c2d3a5a506..e627ec8523 100644 --- a/binaries/data/mods/public/maps/random/new_rms_test.js +++ b/binaries/data/mods/public/maps/random/new_rms_test.js @@ -2,8 +2,11 @@ Engine.LoadLibrary("rmgen"); InitMap(); -placePlayerBases({ - "PlayerPlacement": playerPlacementCircle(0.39) -}); +if (isNomad()) + placePlayersNomad(createTileClass()); +else + placePlayerBases({ + "PlayerPlacement": playerPlacementCircle(0.39) + }); ExportMap(); diff --git a/binaries/data/mods/public/maps/random/northern_lights.js b/binaries/data/mods/public/maps/random/northern_lights.js index 25f7628705..5c263e007b 100644 --- a/binaries/data/mods/public/maps/random/northern_lights.js +++ b/binaries/data/mods/public/maps/random/northern_lights.js @@ -35,6 +35,7 @@ var clPlayer = createTileClass(); var clHill = createTileClass(); var clForest = createTileClass(); var clWater = createTileClass(); +var clIsland = createTileClass(); var clDirt = createTileClass(); var clRock = createTileClass(); var clMetal = createTileClass(); @@ -108,6 +109,7 @@ createAreas( [ new LayeredPainter([tSnowA, tSnowA], [3]), new SmoothElevationPainter(ELEVATION_SET, 3, 3), + paintClass(clIsland), unPaintClass(clWater) ], stayClasses(clWater, 7), @@ -264,6 +266,8 @@ createObjectGroupsDeprecated(group, 0, 25 * numPlayers, 60 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2, clIsland, 4)); + setSunColor(0.6, 0.6, 0.6); setSunElevation(Math.PI/ 6); diff --git a/binaries/data/mods/public/maps/random/oasis.js b/binaries/data/mods/public/maps/random/oasis.js index 6a2680dfd1..c66b6f9722 100644 --- a/binaries/data/mods/public/maps/random/oasis.js +++ b/binaries/data/mods/public/maps/random/oasis.js @@ -315,6 +315,8 @@ for (var sandx = 0; sandx < mapSize; sandx += 4) } } +placePlayersNomad(clPlayer, avoidClasses(clOasis, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + setSkySet("sunny"); setSunColor(0.914,0.827,0.639); setSunRotation(Math.PI/3); diff --git a/binaries/data/mods/public/maps/random/persian_highlands.js b/binaries/data/mods/public/maps/random/persian_highlands.js index 0ee171959d..34e42267c9 100644 --- a/binaries/data/mods/public/maps/random/persian_highlands.js +++ b/binaries/data/mods/public/maps/random/persian_highlands.js @@ -323,4 +323,6 @@ setPPContrast(0.75); setPPSaturation(0.45); setPPBloom(0.3); +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/phoenician_levant.js b/binaries/data/mods/public/maps/random/phoenician_levant.js index 5b7e301a38..7a19a51eaa 100644 --- a/binaries/data/mods/public/maps/random/phoenician_levant.js +++ b/binaries/data/mods/public/maps/random/phoenician_levant.js @@ -177,7 +177,8 @@ createAreas( [ new LayeredPainter([tShore, tHill], [12]), new SmoothElevationPainter(ELEVATION_SET, 6, 8), - paintClass(clIsland) + paintClass(clIsland), + unPaintClass(clWater) ], [stayClasses (clWater, 8)], 1, @@ -318,4 +319,6 @@ setPPContrast(0.53); setPPSaturation(0.47); setPPBloom(0.52); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/polar_sea.js b/binaries/data/mods/public/maps/random/polar_sea.js index 312deb1235..0134671499 100644 --- a/binaries/data/mods/public/maps/random/polar_sea.js +++ b/binaries/data/mods/public/maps/random/polar_sea.js @@ -45,14 +45,19 @@ var clArcticWolf = createTileClass(); var [playerIDs, playerX, playerZ] = playerPlacementCircle(0.35); +var treasures = [{ + "template": oWoodTreasure, + "count": isNomad() ? 16 : 14 +}]; + log("Creating player markets..."); -var marketDist = 12; -for (let i = 0; i < numPlayers; ++i) -{ - let marketPos = Vector2D.add(new Vector2D(playerX[i], playerZ[i]).mult(mapSize), new Vector2D(marketDist, 0).rotate(randFloat(0, 2 * Math.PI))).round(); - placeObject(marketPos.x, marketPos.y, oMarket, playerIDs[i], BUILDING_ORIENTATION); - addCivicCenterAreaToClass(marketPos.x, marketPos.y, clBaseResource); -} +if (!isNomad()) + for (let i = 0; i < numPlayers; ++i) + { + let marketPos = Vector2D.add(new Vector2D(playerX[i], playerZ[i]).mult(mapSize), new Vector2D(12, 0).rotate(randFloat(0, 2 * Math.PI))).round(); + placeObject(marketPos.x, marketPos.y, oMarket, playerIDs[i], BUILDING_ORIENTATION); + addCivicCenterAreaToClass(marketPos.x, marketPos.y, clBaseResource); + } placePlayerBases({ "PlayerPlacement": [playerIDs, playerX, playerZ], @@ -74,12 +79,7 @@ placePlayerBases({ ] }, "Treasures": { - "types": [ - { - "template": oWoodTreasure, - "count": 14 - } - ] + "types": treasures }, }); Engine.SetProgress(30); @@ -216,7 +216,7 @@ Engine.SetProgress(80); createFood( [ [new SimpleObject(oArcticFox, 1, 2, 0, 3)], - [new SimpleObject(oArcticWolf, 4, 6, 0, 4)], + [new SimpleObject(isNomad() ? oArcticFox : oArcticWolf, 4, 6, 0, 4)], [new SimpleObject(oWalrus, 2, 3, 0, 2)], [new SimpleObject(oMuskox, 2, 3, 0, 2)] ], @@ -275,6 +275,22 @@ else setSunElevation(Math.PI * randFloat(1/9, 1/7)); } +if (isNomad()) +{ + let constraint = avoidClasses(clWater, 4, clMetal, 4, clRock, 4, clHill, 4, clFood, 2); + [playerIDs, playerX, playerZ] = placePlayersNomad(clPlayer, constraint); + + for (let i = 0; i < numPlayers; ++i) + placePlayerBaseTreasures({ + "playerID": playerIDs[i], + "playerX": tilesToFraction(playerX[i]), + "playerZ": tilesToFraction(playerZ[i]), + "BaseResourceClass": clBaseResource, + "baseResourceConstraint": constraint, + "types": treasures + }); +} + setSunRotation(randFloat(0, 2 * Math.PI)); setWaterColor(0.3, 0.3, 0.4); diff --git a/binaries/data/mods/public/maps/random/pyrenean_sierra.js b/binaries/data/mods/public/maps/random/pyrenean_sierra.js index 048aaac696..edc847df01 100644 --- a/binaries/data/mods/public/maps/random/pyrenean_sierra.js +++ b/binaries/data/mods/public/maps/random/pyrenean_sierra.js @@ -449,6 +449,8 @@ log("Creating fish..."); group = new SimpleGroup( [new SimpleObject(oFish, 2,3, 0,2)], true, clFood ); createObjectGroupsDeprecated(group, 0, [avoidClasses(clFood, 15), stayClasses(clWater, 6)], 20 * numPlayers, 60 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clPyrenneans, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setSunElevation(Math.PI * randFloat(1/5, 1/3)); setSunRotation(randFloat(0, 2 * Math.PI)); diff --git a/binaries/data/mods/public/maps/random/rhine_marshlands.js b/binaries/data/mods/public/maps/random/rhine_marshlands.js index 5f08e6dee2..645cc0bf36 100644 --- a/binaries/data/mods/public/maps/random/rhine_marshlands.js +++ b/binaries/data/mods/public/maps/random/rhine_marshlands.js @@ -284,6 +284,8 @@ createObjectGroupsDeprecated( scaleByMapSize(13, 200), 50); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setSkySet("cirrus"); setWaterColor(0.753,0.635,0.345); // muddy brown setWaterTint(0.161,0.514,0.635); // clear blue for blueness diff --git a/binaries/data/mods/public/maps/random/river_archipelago.js b/binaries/data/mods/public/maps/random/river_archipelago.js index 05f7c8a007..d1ac4cf294 100644 --- a/binaries/data/mods/public/maps/random/river_archipelago.js +++ b/binaries/data/mods/public/maps/random/river_archipelago.js @@ -141,37 +141,40 @@ placePlayerBases({ }); Engine.SetProgress(35); -log("Creating gaia..."); -for (let i = 0; i < 2; ++i) - for (let j = 0; j < scaleByMapSize(1, 8); ++j) - createObjectGroupsDeprecated( - new SimpleGroup( - [ - new SimpleObject(oSpearman, 8, 12, 2, 3), - new SimpleObject(oArcher, 8, 12, 2, 3), - new SimpleObject(oArcherElephant, 2, 3, 4, 5) - ], - true, - clGaia), - 0, - [ - avoidClasses( - clWater, 2, - clForest, 1, - clPlayerTerritory, 0, - clHill, 1, - clGaia, 15), - stayClasses(clStrip[i == 0 ? 0 : stripWidths.length - 1], 1) - ], - scaleByMapSize(5, 10), - 50); - paintTerrainBasedOnHeight(-10, 0, 1, tWater); paintTileClassBasedOnHeight(-10, 0, 1, clWater); paintTerrainBasedOnHeight(1, 2.8, 1, tShoreBlend); paintTerrainBasedOnHeight(0, 1, 1, tShore); Engine.SetProgress(40); +if (!isNomad()) +{ + log("Creating gaia..."); + for (let i = 0; i < 2; ++i) + for (let j = 0; j < scaleByMapSize(1, 8); ++j) + createObjectGroupsDeprecated( + new SimpleGroup( + [ + new SimpleObject(oSpearman, 8, 12, 2, 3), + new SimpleObject(oArcher, 8, 12, 2, 3), + new SimpleObject(oArcherElephant, 2, 3, 4, 5) + ], + true, + clGaia), + 0, + [ + avoidClasses( + clWater, 2, + clForest, 1, + clPlayerTerritory, 0, + clHill, 1, + clGaia, 15), + stayClasses(clStrip[i == 0 ? 0 : stripWidths.length - 1], 1) + ], + scaleByMapSize(5, 10), + 50); +} + log("Creating hills..."); createAreas( new ChainPlacer(1, Math.floor(scaleByMapSize(4, 6)), Math.floor(scaleByMapSize(16, 40)), 0.1), @@ -463,6 +466,8 @@ createObjectGroupsDeprecated( 200, 100); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setSunColor(0.6, 0.6, 0.6); setSunElevation(Math.PI/ 3); diff --git a/binaries/data/mods/public/maps/random/rivers.js b/binaries/data/mods/public/maps/random/rivers.js index 7400823600..06ecc5a98f 100644 --- a/binaries/data/mods/public/maps/random/rivers.js +++ b/binaries/data/mods/public/maps/random/rivers.js @@ -116,10 +116,11 @@ createArea( null); log("Creating rivers between opponents..."); -let rivers = distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers, fractionToTiles(0.5), mapCenter)[0]; -for (let i = 0; i < numPlayers; ++i) +let numRivers = isNomad() ? randIntInclusive(4, 8) : numPlayers; +let rivers = distributePointsOnCircle(numPlayers, startAngle + Math.PI / numRivers, fractionToTiles(0.5), mapCenter)[0]; +for (let i = 0; i < numRivers; ++i) { - if (areAllies(playerIDs[i], playerIDs[(i + 1) % numPlayers])) + if (isNomad() ? randBool() : areAllies(playerIDs[i], playerIDs[(i + 1) % numPlayers])) continue; let shallowLocation = randFloat(0.2, 0.7); @@ -291,6 +292,8 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setWaterWaviness(3.0); setWaterType("lake"); diff --git a/binaries/data/mods/public/maps/random/rmgen/library.js b/binaries/data/mods/public/maps/random/rmgen/library.js index 8a047bb72c..b8755de454 100644 --- a/binaries/data/mods/public/maps/random/rmgen/library.js +++ b/binaries/data/mods/public/maps/random/rmgen/library.js @@ -314,6 +314,11 @@ function getMapCenter() return deepfreeze(new Vector2D(g_Map.size / 2, g_Map.size / 2)); } +function isNomad() +{ + return !!g_MapSettings.Nomad; +} + function getNumPlayers() { return g_MapSettings.PlayerData.length - 1; diff --git a/binaries/data/mods/public/maps/random/rmgen/player.js b/binaries/data/mods/public/maps/random/rmgen/player.js index 0dc294be8b..36c3bcd8f3 100644 --- a/binaries/data/mods/public/maps/random/rmgen/player.js +++ b/binaries/data/mods/public/maps/random/rmgen/player.js @@ -2,6 +2,13 @@ * @file These functions locate and place the starting entities of players. */ +var g_NomadTreasureTemplates = { + "food": "gaia/special_treasure_food_jars", + "wood": "gaia/special_treasure_wood", + "stone": "gaia/special_treasure_stone", + "metal": "gaia/special_treasure_metal" +}; + /** * These are identifiers of functions that can generate parts of a player base. * There must be a function starting with placePlayerBase and ending with this name. @@ -106,6 +113,9 @@ function placePlayerBases(playerBaseArgs) */ function placePlayerBase(playerBaseArgs) { + if (isNomad()) + return; + log("Creating base for player " + playerBaseArgs.playerID + "..."); let fx = fractionToTiles(playerBaseArgs.playerX); @@ -400,6 +410,58 @@ function placePlayerBaseDecoratives(args) } } +function placePlayersNomad(playerClass, constraints) +{ + if (!isNomad()) + return; + + let distance = scaleByMapSize(60, 240); + let constraint = new AndConstraint(constraints); + + let numPlayers = getNumPlayers(); + let playerIDs = shuffleArray(sortAllPlayers()); + let playerX = []; + let playerZ = []; + + for (let i = 0; i < numPlayers; ++i) + { + log("Determine starting units for player " + playerIDs[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)); + + log("Ensure 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)); + } + + log("Placing player units..."); + let group = new SimpleGroup(objects, true, playerClass); + let success = false; + for (let distanceFactor of [1, 1/2, 1/4, 0]) + { + if (createObjectGroups(group, playerIDs[i], new AndConstraint([constraint, avoidClasses(playerClass, distance * distanceFactor)]), 1, 200, false)) + { + success = true; + playerX[i] = group.x; + playerZ[i] = group.z; + break; + } + } + if (!success) + throw new Error("Could not place starting units for player " + playerIDs[i] + "!"); + } + + return [playerIDs, playerX, playerZ]; +} + /** * Sorts an array of player IDs by team index. Players without teams come first. * Randomize order for players of the same team. diff --git a/binaries/data/mods/public/maps/random/saharan_oases.js b/binaries/data/mods/public/maps/random/saharan_oases.js index 118cdc4d95..6041df8be0 100644 --- a/binaries/data/mods/public/maps/random/saharan_oases.js +++ b/binaries/data/mods/public/maps/random/saharan_oases.js @@ -224,6 +224,8 @@ createObjectGroupsDeprecated(group, 0, 5*scaleByMapSize(5,20), 50 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2, clTreasure, 2)); + setSkySet("sunny"); setSunColor(0.746, 0.718, 0.539); setWaterColor(0, 0.227, 0.843); diff --git a/binaries/data/mods/public/maps/random/sahel.js b/binaries/data/mods/public/maps/random/sahel.js index b8de4c46b4..4534cd9449 100644 --- a/binaries/data/mods/public/maps/random/sahel.js +++ b/binaries/data/mods/public/maps/random/sahel.js @@ -219,6 +219,8 @@ createObjectGroupsDeprecated(group, 0, scaleByMapSize(100, 1200) ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clHill, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setSunColor(0.87451, 0.847059, 0.647059); setWaterColor(0.741176, 0.592157, 0.27451); setWaterTint(0.741176, 0.592157, 0.27451); diff --git a/binaries/data/mods/public/maps/random/sahel_watering_holes.js b/binaries/data/mods/public/maps/random/sahel_watering_holes.js index 3cc3246836..6facb5c34f 100644 --- a/binaries/data/mods/public/maps/random/sahel_watering_holes.js +++ b/binaries/data/mods/public/maps/random/sahel_watering_holes.js @@ -372,6 +372,8 @@ createObjectGroupsDeprecated(group, 0, planetm * scaleByMapSize(13, 200), 50 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clHill, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setSkySet("sunny"); setSunRotation(randFloat(0, 2 * Math.PI)); diff --git a/binaries/data/mods/public/maps/random/schwarzwald.js b/binaries/data/mods/public/maps/random/schwarzwald.js index dabfd9537a..7f10389be0 100644 --- a/binaries/data/mods/public/maps/random/schwarzwald.js +++ b/binaries/data/mods/public/maps/random/schwarzwald.js @@ -405,6 +405,8 @@ for (var x = 0; x < mapSize; x++) avoidClasses(clPath, 2, clOpen, 3, clWater, 4, clMetal, 4, clRock, 4)); } +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clFood, 2, clMetal, 4, clRock, 4)); + Engine.SetProgress(100); ExportMap(); diff --git a/binaries/data/mods/public/maps/random/snowflake_searocks.js b/binaries/data/mods/public/maps/random/snowflake_searocks.js index cec5f843c9..a5ec8924b0 100644 --- a/binaries/data/mods/public/maps/random/snowflake_searocks.js +++ b/binaries/data/mods/public/maps/random/snowflake_searocks.js @@ -214,7 +214,7 @@ log("Creating player islands..."); for (let i = 0; i < numPlayers; ++i) { islandPos[i] = new Vector2D(playerX[i], playerZ[i]).mult(mapSize).round(); - createIsland(i, 1, clPlayer); + createIsland(i, 1, isNomad() ? clLand : clPlayer); } placePlayerBases({ @@ -426,6 +426,13 @@ createObjectGroupsDeprecated(group, 0, planetm * scaleByMapSize(13, 200), 50 ); +placePlayersNomad( + clPlayer, + [ + stayClasses(clLand, 8), + avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clFood, 2) + ]); + setSkySet(pickRandom(["cirrus", "cumulus", "sunny"])); setSunRotation(randFloat(0, 2 * Math.PI)); setSunElevation(Math.PI * randFloat(1/5, 1/3)); diff --git a/binaries/data/mods/public/maps/random/stronghold.js b/binaries/data/mods/public/maps/random/stronghold.js index 6548367212..8c6f5d3714 100644 --- a/binaries/data/mods/public/maps/random/stronghold.js +++ b/binaries/data/mods/public/maps/random/stronghold.js @@ -239,4 +239,15 @@ addElements(shuffleArray([ ])); Engine.SetProgress(90); +placePlayersNomad( + g_TileClasses.player, + avoidClasses( + g_TileClasses.bluff, 4, + g_TileClasses.plateau, 4, + g_TileClasses.forest, 1, + g_TileClasses.metal, 4, + g_TileClasses.rock, 4, + g_TileClasses.mountain, 4, + g_TileClasses.animals, 2)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/syria.js b/binaries/data/mods/public/maps/random/syria.js index 9f8de83861..13ee91b40f 100644 --- a/binaries/data/mods/public/maps/random/syria.js +++ b/binaries/data/mods/public/maps/random/syria.js @@ -52,13 +52,22 @@ for (let i = 0; i < numPlayers; ++i) let iz = Math.round(fractionToTiles(playerZ[i])); log("Marking player territory larger than the city patch..."); - createArea( - new ClumpPlacer(diskArea(scaleByMapSize(15, 25)), 0.9, 0.5, 10, ix, iz), - paintClass(clPlayer)); + if (!isNomad()) + createArea( + new ClumpPlacer(diskArea(defaultPlayerBaseRadius()), 0.9, 0.5, 10, ix, iz), + paintClass(clPlayer)); log("Creating big grass patches surrounding the city patches..."); createArea( - new ChainPlacer(2, Math.floor(scaleByMapSize(5, 12)), Math.floor(scaleByMapSize(25, 60)), 1, ix, iz, 0, [Math.floor(scaleByMapSize(16, 30))]), + new ChainPlacer( + 2, + Math.floor(scaleByMapSize(5, 12)), + Math.floor(scaleByMapSize(25, 60)) / (isNomad() ? 2 : 1), + 1, + ix, + iz, + 0, + [Math.floor(scaleByMapSize(16, 30))]), [ new LayeredPainter([tGrassSands, tGrass], [3]), paintClass(clGrass) @@ -243,7 +252,9 @@ createStragglerTrees( [oPalm, oTamarix, oPine], [avoidClasses(clForest, 1, clHill, 1, clPlayer, 1, clMetal, 6, clRock, 6), stayClasses(clGrass, 3)], clForest, - stragglerTrees); + stragglerTrees * (isNomad() ? 3 : 1)); + +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); setSkySet("sunny"); setSunElevation(Math.PI / 8); diff --git a/binaries/data/mods/public/maps/random/the_nile.js b/binaries/data/mods/public/maps/random/the_nile.js index 1810149e8a..93af799b8f 100644 --- a/binaries/data/mods/public/maps/random/the_nile.js +++ b/binaries/data/mods/public/maps/random/the_nile.js @@ -384,6 +384,8 @@ createObjectGroupsDeprecated( scaleByMapSize(2, 6), 50 ); +placePlayersNomad(clPlayer, avoidClasses(clWater, 4, clForest, 1, clMetal, 4, clRock, 4, clFood, 2)); + setSkySet("sunny"); setSunColor(0.711, 0.746, 0.574); setWaterColor(0.541,0.506,0.416); diff --git a/binaries/data/mods/public/maps/random/the_unknown/unknown_common.js b/binaries/data/mods/public/maps/random/the_unknown/unknown_common.js index 169aacaf7f..c3a2cc6657 100644 --- a/binaries/data/mods/public/maps/random/the_unknown/unknown_common.js +++ b/binaries/data/mods/public/maps/random/the_unknown/unknown_common.js @@ -3,11 +3,6 @@ */ /** - * True if city centers should be placed or false for nomad. - */ -var g_PlayerBases; - -/** * True if all players should be connected via land and false if river or islands can split some if not all the players. */ var g_AllowNaval; @@ -122,7 +117,9 @@ function createUnknownMap() paintUnknownMapBasedOnHeight(); - if (g_PlayerBases) + if (isNomad()) + placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4, clFood, 2)); + else createUnknownPlayerBases(); } @@ -135,7 +132,7 @@ function unknownArchipelago() g_StartingTreasures = true; let [pIDs, islandX, islandZ] = playerPlacementCircle(0.35); - if (g_PlayerBases) + if (!isNomad()) { [playerIDs, playerX, playerZ] = [pIDs, islandX, islandZ]; markPlayerArea("large"); @@ -148,7 +145,7 @@ function unknownArchipelago() new ClumpPlacer(islandSize, 0.8, 0.1, 10, fractionToTiles(islandX[i]), fractionToTiles(islandZ[i])), landElevationPainter); - let type = randIntInclusive(1, 3); + let type = isNomad() ? randIntInclusive(1, 2) : randIntInclusive(1, 3); if (type == 1) { log("Creating archipelago..."); @@ -216,7 +213,7 @@ function unknownContinent() { let waterHeight = -5; - if (g_PlayerBases) + if (!isNomad()) { log("Ensuring player area..."); [playerIDs, playerX, playerZ] = playerPlacementCircle(0.25); @@ -311,7 +308,7 @@ function unknownCentralSea() } }); - if (g_PlayerBases) + if (!isNomad()) { [playerIDs, playerX, playerZ] = playerPlacementRiver(horizontal ? Math.PI / 2 : 0, 0.6); markPlayerArea("small"); @@ -354,7 +351,7 @@ function unknownCentralRiver() let horizontal = randBool(); let riverAngle = horizontal ? 0 : Math.PI / 2; - if (g_PlayerBases) + if (!isNomad()) { [playerIDs, playerX, playerZ] = playerPlacementRiver(horizontal ? Math.PI / 2 : 0, 0.5); markPlayerArea("large"); @@ -416,7 +413,7 @@ function unknownRiversAndLake() initHeight(landHeight); let startAngle; - if (g_PlayerBases) + if (!isNomad()) { let playerAngle; [playerIDs, playerX, playerZ, playerAngle, startAngle] = playerPlacementCircle(0.35); @@ -438,7 +435,7 @@ function unknownRiversAndLake() } // Don't do this on nomad because the imbalances on the different islands are too drastic - if (g_PlayerBases && (!lake || randBool(1/3))) + if (!isNomad() && (!lake || randBool(1/3))) { log("Creating small rivers separating players..."); for (let river of distributePointsOnCircle(numPlayers, startAngle + Math.PI / numPlayers, fractionToTiles(0.5), mapCenter)[0]) @@ -469,7 +466,7 @@ function unknownRiversAndLake() ]); } - if (lake && randBool()) + if (!isNomad && lake && randBool()) { log("Creating small central island..."); createArea( @@ -490,7 +487,7 @@ function unknownEdgeSeas() initHeight(landHeight); let horizontal = randBool(); - if (g_PlayerBases) + if (!isNomad()) { [playerIDs, playerX, playerZ] = playerPlacementLine(horizontal, 0.5, 0.2); // Don't place the shoreline inside the CC, but possibly into the players territory @@ -535,7 +532,7 @@ function unknownGulf() initHeight(landHeight); let startAngle = randFloat(0, 2) * Math.PI; - if (g_PlayerBases) + if (!isNomad()) { log("Determining player locations..."); @@ -573,7 +570,7 @@ function unknownLakes() initHeight(landHeight); - if (g_PlayerBases) + if (!isNomad()) { [playerIDs, playerX, playerZ] = playerPlacementCircle(0.35); markPlayerArea("large"); @@ -601,7 +598,7 @@ function unknownPasses() let playerAngle; let startAngle; - if (g_PlayerBases) + if (!isNomad()) { [playerIDs, playerX, playerZ, playerAngle, startAngle] = playerPlacementCircle(0.35); markPlayerArea("small"); @@ -680,7 +677,7 @@ function unknownLowlands() let playerAngle; let startAngle; - if (g_PlayerBases) + if (!isNomad()) { [playerIDs, playerX, playerZ, playerAngle, startAngle] = playerPlacementCircle(0.35); markPlayerArea("small"); @@ -732,7 +729,7 @@ function unknownMainland() { initHeight(3); - if (g_PlayerBases) + if (!isNomad()) { [playerIDs, playerX, playerZ] = playerPlacementCircle(0.35); markPlayerArea("small"); diff --git a/binaries/data/mods/public/maps/random/unknown.js b/binaries/data/mods/public/maps/random/unknown.js index 9d17727243..e8cd4d9cda 100644 --- a/binaries/data/mods/public/maps/random/unknown.js +++ b/binaries/data/mods/public/maps/random/unknown.js @@ -2,7 +2,6 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); Engine.LoadLibrary("the_unknown"); -g_PlayerBases = true; g_AllowNaval = true; createUnknownMap(); diff --git a/binaries/data/mods/public/maps/random/unknown_land.js b/binaries/data/mods/public/maps/random/unknown_land.js index 46042e17d9..b26e4c9dc3 100644 --- a/binaries/data/mods/public/maps/random/unknown_land.js +++ b/binaries/data/mods/public/maps/random/unknown_land.js @@ -2,7 +2,6 @@ Engine.LoadLibrary("rmgen"); Engine.LoadLibrary("rmbiome"); Engine.LoadLibrary("the_unknown"); -g_PlayerBases = true; g_AllowNaval = false; createUnknownMap(); diff --git a/binaries/data/mods/public/maps/random/unknown_nomad.js b/binaries/data/mods/public/maps/random/unknown_nomad.js deleted file mode 100644 index 2112480b72..0000000000 --- a/binaries/data/mods/public/maps/random/unknown_nomad.js +++ /dev/null @@ -1,126 +0,0 @@ -Engine.LoadLibrary("rmgen"); -Engine.LoadLibrary("rmbiome"); -Engine.LoadLibrary("the_unknown"); - -g_PlayerBases = false; -g_AllowNaval = true; - -createUnknownMap(); - -var distmin = Math.square(scaleByMapSize(60, 240)); -playerIDs = sortAllPlayers(); - -for (var i = 0; i < numPlayers; i++) -{ - var placableArea = []; - for (var mx = 0; mx < mapSize; mx++) - { - for (var mz = 0; mz < mapSize; mz++) - { - if (!g_Map.validT(mx, mz, 3)) - continue; - - var placable = true; - for (var c = 0; c < i; c++) - if ((playerX[c] - mx)*(playerX[c] - mx) + (playerZ[c] - mz)*(playerZ[c] - mz) < distmin) - placable = false; - if (!placable) - continue; - - if (g_Map.getHeight(mx, mz) >= 3 && g_Map.getHeight(mx, mz) <= 3.12) - placableArea.push([mx, mz]); - } - } - - if (!placableArea.length) - { - for (var mx = 0; mx < mapSize; ++mx) - { - for (var mz = 0; mz < mapSize; mz++) - { - if (!g_Map.validT(mx, mz, 3)) - continue; - - var placable = true; - for (var c = 0; c < i; c++) - if ((playerX[c] - mx)*(playerX[c] - mx) + (playerZ[c] - mz)*(playerZ[c] - mz) < distmin/4) - placable = false; - if (!placable) - continue; - - if (g_Map.getHeight(mx, mz) >= 3 && g_Map.getHeight(mx, mz) <= 3.12) - placableArea.push([mx, mz]); - } - } - } - - if (!placableArea.length) - for (var mx = 0; mx < mapSize; ++mx) - for (var mz = 0; mz < mapSize; ++mz) - if (g_Map.getHeight(mx, mz) >= 3 && g_Map.getHeight(mx, mz) <= 3.12) - placableArea.push([mx, mz]); - - [playerX[i], playerZ[i]] = pickRandom(placableArea); -} - -for (var i = 0; i < numPlayers; ++i) -{ - var id = playerIDs[i]; - log("Creating units for player " + id + "..."); - - // get the x and z in tiles - var ix = playerX[i]; - var iz = playerZ[i]; - - playerX[i] = tilesToFraction(playerX[i]); - playerZ[i] = tilesToFraction(playerZ[i]); - - var civEntities = getStartingEntities(playerIDs[i]); - var angle = randFloat(0, 2 * Math.PI); - for (var j = 0; j < civEntities.length; ++j) - { - // TODO: Make an rmlib function to get only non-structure starting entities and loop over those - if (!civEntities[j].Template.startsWith("units/")) - continue; - - var count = civEntities[j].Count || 1; - var jx = ix + 2 * Math.cos(angle); - var jz = iz + 2 * Math.sin(angle); - var kAngle = randFloat(0, 2 * Math.PI); - for (var k = 0; k < count; ++k) - placeObject(jx + Math.cos(kAngle + k*2 * Math.PI/count), jz + Math.sin(kAngle + k*2 * Math.PI/count), civEntities[j].Template, id, randFloat(0, 2 * Math.PI)); - angle += 2 * Math.PI / 3; - } - - { - if (g_MapSettings.StartingResources < 500) - { - var loop = (g_MapSettings.StartingResources < 200) ? 2 : 1; - for (let l = 0; l < loop; ++l) - { - var angle = randFloat(0, 2 * Math.PI); - var rad = randFloat(3, 5); - var jx = ix + rad * Math.cos(angle); - var jz = iz + rad * Math.sin(angle); - placeObject(jx, jz, "gaia/special_treasure_wood", 0, randFloat(0, 2 * Math.PI)); - var angle = randFloat(0, 2 * Math.PI); - var rad = randFloat(3, 5); - var jx = ix + rad * Math.cos(angle); - var jz = iz + rad * Math.sin(angle); - placeObject(jx, jz, "gaia/special_treasure_stone", 0, randFloat(0, 2 * Math.PI)); - var angle = randFloat(0, 2 * Math.PI); - var rad = randFloat(3, 5); - var jx = ix + rad * Math.cos(angle); - var jz = iz + rad * Math.sin(angle); - placeObject(jx, jz, "gaia/special_treasure_metal", 0, randFloat(0, 2 * Math.PI)); - } - } - } -} - -// Don't place resources into the starting units -markPlayerArea("small"); - -createUnknownObjects(); - -ExportMap(); diff --git a/binaries/data/mods/public/maps/random/unknown_nomad.json b/binaries/data/mods/public/maps/random/unknown_nomad.json deleted file mode 100644 index f5e6f0305a..0000000000 --- a/binaries/data/mods/public/maps/random/unknown_nomad.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "settings" : { - "Name" : "Unknown Nomad", - "Script" : "unknown_nomad.js", - "Description" : "The unknown. Players start with only some citizen soldiers and female citizens. [color=\"red\"]Warning: The starting resources should be set at least at Medium.[/color]", - "BaseTerrain" : ["medit_sand_wet"], - "BaseHeight" : -5, - "Preview" : "unknown.png", - "SupportedBiomes": true, - "CircularMap" : true - } -} diff --git a/binaries/data/mods/public/maps/random/volcanic_lands.js b/binaries/data/mods/public/maps/random/volcanic_lands.js index 82f8d4d25e..8c00aa02b0 100644 --- a/binaries/data/mods/public/maps/random/volcanic_lands.js +++ b/binaries/data/mods/public/maps/random/volcanic_lands.js @@ -176,4 +176,6 @@ createStragglerTrees( clForest, stragglerTrees); +placePlayersNomad(clPlayer, avoidClasses(clForest, 1, clMetal, 4, clRock, 4, clHill, 4)); + ExportMap(); diff --git a/binaries/data/mods/public/maps/random/wild_lake.js b/binaries/data/mods/public/maps/random/wild_lake.js index 7c579373ee..9a2083128e 100644 --- a/binaries/data/mods/public/maps/random/wild_lake.js +++ b/binaries/data/mods/public/maps/random/wild_lake.js @@ -588,18 +588,19 @@ for (let i = 0; i < avoidPoints.length; ++i) let resourceSpots = getPointsByHeight(resourceSpotHeightRange, avoidPoints, clPath); Engine.SetProgress(55); -/** - * Add start locations and resource spots after terrain texture and path painting - */ -for (let p = 0; p < playerIDs.length; ++p) -{ - let point = startLocations[p]; - placeCivDefaultStartingEntities(point.x, point.y, playerIDs[p], g_Map.size > 192); - placeStartLocationResources(point); -} +log("Placing players..."); +if (isNomad()) + placePlayersNomad(createTileClass(), new HeightConstraint(playerHeightRange.min, playerHeightRange.max)); +else + for (let p = 0; p < playerIDs.length; ++p) + { + let point = startLocations[p]; + placeCivDefaultStartingEntities(point.x, point.y, playerIDs[p], g_Map.size > 192); + placeStartLocationResources(point); + } -let mercenaryCamps = Math.ceil(g_Map.size / 256); -log("Maximum number of mercenary camps: " + uneval(mercenaryCamps)); +let mercenaryCamps = isNomad() ? 0 : Math.ceil(g_Map.size / 256); +log("Maximum number of mercenary camps: " + mercenaryCamps); for (let i = 0; i < resourceSpots.length; ++i) { let choice = i % 5; -- 2.11.4.GIT